/** * A deferred output of a not-yet-created resource — the object a handle emits * (e.g. `model.uuid`), carrying the `resourceId`/`field` the deploy engine * reads to build the dependency graph and later substitute the real value. * * `@cargo-ai/workflow-sdk` accepts one of these in its input positions via a * *structural* counterpart, `TokenRef` (`{ __token: true }`) — a minimal subset * it matches without importing this package, since it sits below `@cargo-ai/cdk` * in the dependency graph. This rich nominal type is the producer side; * `TokenRef` is the acceptor side of the same brand. */ export type Token = { readonly __token: true; readonly resourceId: string; readonly field: string; }; export declare function token(resourceId: string, field: string): Token; export declare function isToken(value: unknown): value is Token; /** * A config-input position that accepts either a literal `T` or a deferred * `Token` (a resource handle's output, e.g. `model.uuid`). Deliberately shares * the name of `@cargo-ai/workflow-sdk`'s `In` — the same "input position" * concept — so the two packages read consistently; CDK's just carries two arms * (`T | Token`) where the workflow-sdk's adds a `Ref` arm for its builder * context. (The token brand itself stays package-specific: nominal `Token` * here, structural `TokenRef` there, to keep the dependency boundary one-way.) * * `cargo-ai cdk types` prints `In` at uuid-reference schema positions * (e.g. `modelUuid`), so a handle's `uuid` is assignable there with no cast, * while a raw uuid string still typechecks. The runtime is unchanged: * `dependenciesOf` records the edge and `resolveTokens` substitutes the real * value the producer returned. Because a `Token` is an object (not a string), * `handle.uuid.toString()` no longer typechecks in these positions — a guard * against silently collapsing the token to `"[object Object]"`. */ export type In = T | Token; export type ResourceKind = "connector" | "customIntegration" | "model" | "agent" | "play" | "alert" | "tool" | "mcpServer" | "folder" | "file" | "worker" | "app" | "context" | "capacity" | "territory" | "member" | "segment" | "relationship" | "domain" | "mailbox"; export declare const DRAFTABLE_KINDS: ReadonlySet; export type ResourceNode = { readonly id: string; readonly kind: ResourceKind; readonly slug: string; readonly spec: Record; }; /** * Register a resource. Re-registering the SAME id with identical content is a * no-op (the loader may evaluate a file more than once when it's imported both * directly and transitively); re-registering an id with DIFFERENT content is a * genuine duplicate slug and throws. */ export declare function register(node: ResourceNode): void; /** * Where each registered resource was declared: resource id → the absolute path * of the module whose `define*` call registered it. `cdk info` renders this. * * It has to come from the call stack rather than from which file the loader was * importing: a file reached through another file's `import` registers while its * importer is the one being loaded, so import order credits the wrong file for * exactly the layout the templates teach (`agents/sdr.ts` importing * `models/contacts.ts`). The stack knows which module actually ran the call. */ export declare function declarationSites(): Map; export declare const CDK_MODULE_DIR: string; export declare const CDK_INTERNAL_PREFIXES: readonly string[]; /** Every resource declared so far. */ export declare function resources(): ResourceNode[]; /** Clear the registry — the loader resets between runs; tests between cases. */ export declare function resetRegistry(): void; /** Compose a resource's stable id from its kind + slug, validating the slug. */ export declare function resourceId(kind: ResourceKind, slug: string): string; /** Collect the resource ids a spec depends on (every token reachable in it). */ export declare function dependenciesOf(value: unknown, acc?: Set): Set; /** Deep-replace every token in a spec with the real value its producer returned. */ export declare function resolveTokens(value: unknown, outputs: Map>): unknown; /** * Read a config value from the environment at load time. Its value enters the * spec — and therefore the content hash — so changing it shows as drift. Use for * non-secret config you WANT to track; use `secret()` for rotating secrets. * Returns a visible `${NAME}` placeholder when unset so it surfaces in a plan. */ export declare function env(name: string): string; /** * What `secret("NAME")` returns: a deferred reference to a local environment * secret, resolved at APPLY time into the `{ type: "encryption", isEncrypted, * value }` envelope every secret field holds server-side, and excluded from the * content hash (the spec stores the reference, not the value). Rotating the * secret therefore doesn't read as code drift — but a plain deploy won't push * the new value either, since nothing in the hash changed; re-apply the resource * (any other edit, or `--refresh`) to roll a rotated secret. * * Resolution has to be deferred: the spec is built at import time, so reading * `process.env` then would make loading a project throw over a secret belonging * to a resource the deploy never touches. * * Named for what it resolves to, and `Ref` because it models a reference rather * than the value. (The resource-output `Token` above keeps its bare name — see * its own doc.) */ export type EncryptionRef = { readonly __secret: true; readonly name: string; }; export declare function secret(name: string): EncryptionRef; export declare function isSecret(value: unknown): value is EncryptionRef; /** * What `workspaceEnv("NAME")` returns: a deferred pointer at a workspace env-var * catalog entry, resolved at APPLY time into {@link WorkspaceEnvVarValue}. Nothing is read * locally, and nothing can fail — there is no lookup. The value stays on the * server and is read on every use, so rotating it in the workspace reaches the * resource without a redeploy. * * A brand rather than the wire shape directly, even though no lookup forces the * deferral: the walk that finds these is position-blind, so a config field that * happens to carry `type: "workspaceEnvVar"` must not be mistaken for a pointer. */ export type WorkspaceEnvRef = { readonly __envVar: true; readonly name: string; }; export declare function workspaceEnv(name: string): WorkspaceEnvRef; export declare function isWorkspaceEnv(value: unknown): value is WorkspaceEnvRef; /** * What a secret-typed config field accepts: a value this deploy supplies from * the local environment (`secret()`), or a pointer the server resolves on every * use (`workspaceEnv()`). `cargo-ai cdk types` prints this at exactly the schema * positions typed as `secret`, so both are accepted there and ONLY there. * * A resource's own `env` takes `env()` or `secret()` and rejects a pointer, * because a worker, app, agent or script inherits the whole catalog already — * a pointer there could only restate a variable it can read anyway. */ export type CredentialRef = EncryptionRef | WorkspaceEnvRef; /** * The wire shape a {@link WorkspaceEnvRef} resolves to. Stored as-is, and * resolved server-side on every use. */ export type WorkspaceEnvVarValue = { type: "workspaceEnvVar"; key: string; }; /** * How to fix a `secret()` whose name is set nowhere locally. Shared with the * plan-time preflight so both halves say the same thing. * * Deliberately silent about the workspace catalog: `secret()` does not read it. * A config field reaches a catalog entry through `workspaceEnv("NAME")`, which * is a different edit to the source, not a different place to put the value. */ export declare function unresolvedSecretRemedy(count: number): string; /** * How to fix a `workspaceEnv()` naming a variable the workspace holds no entry * for. Exporting it locally would not help — the pointer is resolved on the * server, on every use. */ export declare function missingWorkspaceEnvRemedy(count: number): string; /** * Deep-replace every deferred reference with what it resolves to, at apply time * (after token resolution): * * - `secret("X")` becomes the encryption envelope holding `process.env.X`. Every * secret field is typed as that envelope server-side — the same shape the UI * submits — so a bare string would be rejected as invalid config, and the * backend encrypts it at rest. Throws when X is not set locally. * - `workspaceEnv("X")` becomes `{ type: "workspaceEnvVar", key: "X" }`. Cannot fail: * whether the workspace holds X is checked at plan time, not here. * * One reference, one outcome. Neither falls back to the other, which is what * makes whether a credential tracks rotation a property of the source rather * than of what the deploying machine happened to have exported. */ export declare function resolveSecrets(value: unknown): unknown; /** * Config keys whose value is authored JavaScript, not a config string. A script * body legitimately contains `${...}` template literals (`?page=${page}`) that * match the placeholder shape without being one — a JavaScript workflow * action's `script`, and a `defineScript` model's `script`, which * `bundleScript` fills with a whole compiled module. Scanning those would * reject valid code, so they are exempt: a literal `env("X")` interpolated * into a script string is not caught anywhere (author secrets as `secret()` in * the model's `env` instead). * * One set, shared by the plan-time preflight and `assertNoPlaceholders` at * apply, and it has to be: the preflight aborts deploys over what apply would * have thrown on, so a key exempt there and not here would fail deploys apply * runs happily. */ export declare const CODE_KEYS: ReadonlySet; /** * The `${NAME}` names in a string, or an empty array. One scanner for the plan * check and the apply check, for the same reason `CODE_KEYS` is one set. * * Built per call rather than shared: a `/g` regex carries `lastIndex`, and one * module-level instance reused across two callers answers differently on the * same input depending on who asked last. */ export declare function envPlaceholdersIn(value: string): string[]; export type EnvDependencies = { secrets: Set; workspaceEnvVars: Set; placeholders: Set; }; /** * The environment variables a spec depends on, split by WHERE and WHEN they * resolve. * * The same traversal `resolveSecrets` runs at apply time, run instead at plan * time. That is the whole point: all three of these are knowable offline, from * the compiled graph, before a single resource is created. Checked inside the * apply loop instead, a missing variable fails the deploy partway through, with * every resource ahead of it already created and written to state. * * The three are NOT interchangeable: * * - `secrets` are `secret("X")` references. They hold a name, not a value, and * resolve against `process.env` at apply. Exporting X (or putting it in .env) * any time before the deploy fixes them. * - `workspaceEnvVars` are `workspaceEnv("X")` pointers. They resolve on the * server, so only creating the catalog entry fixes them; exporting X locally * does nothing. Matched on the brand rather than a `type` word, so config that * happens to carry `type: "workspaceEnvVar"` is not mistaken for one. * - `placeholders` are the `${X}` strings `env("X")` leaves behind when X was * unset AT IMPORT TIME. The spec already carries the literal placeholder and * is already hashed with it, so setting X afterwards does NOT fix them: the * project has to be re-loaded. `assertNoPlaceholders` rejects them at apply, * and reporting them as "not set" once the variable exists would be a lie. * * A caller acting on `placeholders` has to scope itself the way apply does — * to the resources actually being applied. Any string can hold a literal * `${...}`, so a resource apply would skip is not evidence of anything. */ export declare function collectEnvDependencies(value: unknown): EnvDependencies; //# sourceMappingURL=core.d.ts.map