@cargo-ai/cdk 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +187 -0
- package/build/src/core.d.ts +83 -0
- package/build/src/core.d.ts.map +1 -0
- package/build/src/core.js +205 -0
- package/build/src/deploy/apply.d.ts +55 -0
- package/build/src/deploy/apply.d.ts.map +1 -0
- package/build/src/deploy/apply.js +219 -0
- package/build/src/deploy/audit.d.ts +14 -0
- package/build/src/deploy/audit.d.ts.map +1 -0
- package/build/src/deploy/audit.js +25 -0
- package/build/src/deploy/compile.d.ts +36 -0
- package/build/src/deploy/compile.d.ts.map +1 -0
- package/build/src/deploy/compile.js +99 -0
- package/build/src/deploy/destroy.d.ts +20 -0
- package/build/src/deploy/destroy.d.ts.map +1 -0
- package/build/src/deploy/destroy.js +153 -0
- package/build/src/deploy/executors.live.d.ts +4 -0
- package/build/src/deploy/executors.live.d.ts.map +1 -0
- package/build/src/deploy/executors.live.js +623 -0
- package/build/src/deploy/import.d.ts +13 -0
- package/build/src/deploy/import.d.ts.map +1 -0
- package/build/src/deploy/import.js +87 -0
- package/build/src/deploy/index.d.ts +39 -0
- package/build/src/deploy/index.d.ts.map +1 -0
- package/build/src/deploy/index.js +51 -0
- package/build/src/deploy/load.d.ts +7 -0
- package/build/src/deploy/load.d.ts.map +1 -0
- package/build/src/deploy/load.js +58 -0
- package/build/src/deploy/lock.d.ts +10 -0
- package/build/src/deploy/lock.d.ts.map +1 -0
- package/build/src/deploy/lock.js +101 -0
- package/build/src/deploy/plan.d.ts +3 -0
- package/build/src/deploy/plan.d.ts.map +1 -0
- package/build/src/deploy/plan.js +39 -0
- package/build/src/deploy/readers.live.d.ts +4 -0
- package/build/src/deploy/readers.live.d.ts.map +1 -0
- package/build/src/deploy/readers.live.js +273 -0
- package/build/src/deploy/refresh.d.ts +32 -0
- package/build/src/deploy/refresh.d.ts.map +1 -0
- package/build/src/deploy/refresh.js +76 -0
- package/build/src/deploy/state.d.ts +23 -0
- package/build/src/deploy/state.d.ts.map +1 -0
- package/build/src/deploy/state.js +107 -0
- package/build/src/index.d.ts +30 -0
- package/build/src/index.d.ts.map +1 -0
- package/build/src/index.js +30 -0
- package/build/src/refs.d.ts +28 -0
- package/build/src/refs.d.ts.map +1 -0
- package/build/src/refs.js +34 -0
- package/build/src/resources/actions.d.ts +31 -0
- package/build/src/resources/actions.d.ts.map +1 -0
- package/build/src/resources/actions.js +44 -0
- package/build/src/resources/agent.d.ts +71 -0
- package/build/src/resources/agent.d.ts.map +1 -0
- package/build/src/resources/agent.js +96 -0
- package/build/src/resources/app.d.ts +18 -0
- package/build/src/resources/app.d.ts.map +1 -0
- package/build/src/resources/app.js +33 -0
- package/build/src/resources/bundle.d.ts +15 -0
- package/build/src/resources/bundle.d.ts.map +1 -0
- package/build/src/resources/bundle.js +61 -0
- package/build/src/resources/connector.d.ts +30 -0
- package/build/src/resources/connector.d.ts.map +1 -0
- package/build/src/resources/connector.js +41 -0
- package/build/src/resources/context.d.ts +15 -0
- package/build/src/resources/context.d.ts.map +1 -0
- package/build/src/resources/context.js +58 -0
- package/build/src/resources/file.d.ts +15 -0
- package/build/src/resources/file.d.ts.map +1 -0
- package/build/src/resources/file.js +35 -0
- package/build/src/resources/folder.d.ts +20 -0
- package/build/src/resources/folder.d.ts.map +1 -0
- package/build/src/resources/folder.js +28 -0
- package/build/src/resources/mcpServer.d.ts +25 -0
- package/build/src/resources/mcpServer.d.ts.map +1 -0
- package/build/src/resources/mcpServer.js +34 -0
- package/build/src/resources/model.d.ts +34 -0
- package/build/src/resources/model.d.ts.map +1 -0
- package/build/src/resources/model.js +43 -0
- package/build/src/resources/play.d.ts +35 -0
- package/build/src/resources/play.d.ts.map +1 -0
- package/build/src/resources/play.js +49 -0
- package/build/src/resources/tool.d.ts +40 -0
- package/build/src/resources/tool.d.ts.map +1 -0
- package/build/src/resources/tool.js +36 -0
- package/build/src/resources/worker.d.ts +18 -0
- package/build/src/resources/worker.d.ts.map +1 -0
- package/build/src/resources/worker.js +40 -0
- package/build/tsconfig.tsbuildinfo +1 -0
- package/package.json +71 -0
- package/templates/blank/README.md +24 -0
- package/templates/blank/cargo.ts +44 -0
- package/templates/blank/package.json +17 -0
- package/templates/blank/tsconfig.json +14 -0
- package/templates/full/README.md +69 -0
- package/templates/full/agents/enricher.ts +13 -0
- package/templates/full/agents/sdr.ts +28 -0
- package/templates/full/apps/dashboard/index.html +12 -0
- package/templates/full/apps/dashboard/package-lock.json +1080 -0
- package/templates/full/apps/dashboard/package.json +15 -0
- package/templates/full/apps/dashboard/src/main.tsx +12 -0
- package/templates/full/apps/dashboard/tsconfig.json +13 -0
- package/templates/full/apps/dashboard.ts +9 -0
- package/templates/full/connectors/hubspot.ts +12 -0
- package/templates/full/connectors/openai.ts +9 -0
- package/templates/full/context/context.ts +7 -0
- package/templates/full/context/icp.md +22 -0
- package/templates/full/context/personas/head-of-growth.md +26 -0
- package/templates/full/files/playbook.md +19 -0
- package/templates/full/files/playbook.ts +8 -0
- package/templates/full/folders/crm.ts +14 -0
- package/templates/full/mcp/crm.ts +15 -0
- package/templates/full/models/contacts.ts +15 -0
- package/templates/full/package.json +17 -0
- package/templates/full/plays/onboarding.ts +41 -0
- package/templates/full/tools/enrich.ts +34 -0
- package/templates/full/tsconfig.json +17 -0
- package/templates/full/workers/webhook/index.js +12 -0
- package/templates/full/workers/webhook/manifest.json +1 -0
- package/templates/full/workers/webhook/package-lock.json +12 -0
- package/templates/full/workers/webhook/package.json +6 -0
- package/templates/full/workers/webhook.ts +13 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type ConnectorRef, type ResourceRef } from "../refs.js";
|
|
2
|
+
/** Options shared by every action an agent or MCP server can call. */
|
|
3
|
+
export type ActionOptions = {
|
|
4
|
+
/** Override the action's display name. */
|
|
5
|
+
readonly name?: string;
|
|
6
|
+
readonly description?: string;
|
|
7
|
+
/** Allow the action to run in bulk. Defaults to false. */
|
|
8
|
+
readonly isBulkAllowed?: boolean;
|
|
9
|
+
/** Block until the action finishes before continuing. Defaults to true. */
|
|
10
|
+
readonly waitUntilFinished?: boolean;
|
|
11
|
+
};
|
|
12
|
+
/** A tool to call — the tool handle / `toolRef(uuid)`, bare or `{ ref, …options }`. */
|
|
13
|
+
export type ToolUse = ResourceRef<"tool"> | (ActionOptions & {
|
|
14
|
+
readonly ref: ResourceRef<"tool">;
|
|
15
|
+
});
|
|
16
|
+
/** Another agent to call — the agent handle / `agentRef(uuid)`, bare or wrapped. */
|
|
17
|
+
export type AgentUse = ResourceRef<"agent"> | (ActionOptions & {
|
|
18
|
+
readonly ref: ResourceRef<"agent">;
|
|
19
|
+
});
|
|
20
|
+
/** A connector action to call (e.g. an enrichment endpoint). */
|
|
21
|
+
export type ConnectorActionSpec = ActionOptions & {
|
|
22
|
+
integration: string;
|
|
23
|
+
actionSlug: string;
|
|
24
|
+
/** The connector (handle or `connectorRef(uuid)`); omit for native actions. */
|
|
25
|
+
connector?: ConnectorRef;
|
|
26
|
+
config?: Record<string, unknown>;
|
|
27
|
+
};
|
|
28
|
+
export declare function normalizeTools(uses: readonly ToolUse[] | undefined): unknown[];
|
|
29
|
+
export declare function normalizeSubAgents(uses: readonly AgentUse[] | undefined): unknown[];
|
|
30
|
+
export declare function normalizeConnectorActions(refs: readonly ConnectorActionSpec[] | undefined): unknown[];
|
|
31
|
+
//# sourceMappingURL=actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../../src/resources/actions.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,YAAY,EAAW,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1E,sEAAsE;AACtE,MAAM,MAAM,aAAa,GAAG;IAC1B,0CAA0C;IAC1C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,0DAA0D;IAC1D,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,2EAA2E;IAC3E,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;CACtC,CAAC;AAEF,uFAAuF;AACvF,MAAM,MAAM,OAAO,GACf,WAAW,CAAC,MAAM,CAAC,GACnB,CAAC,aAAa,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC,CAAC;AAE5D,oFAAoF;AACpF,MAAM,MAAM,QAAQ,GAChB,WAAW,CAAC,OAAO,CAAC,GACpB,CAAC,aAAa,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;CAAE,CAAC,CAAC;AAE7D,gEAAgE;AAChE,MAAM,MAAM,mBAAmB,GAAG,aAAa,GAAG;IAChD,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,YAAY,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,CAAC;AAgCF,wBAAgB,cAAc,CAC5B,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,SAAS,GACnC,OAAO,EAAE,CAKX;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,SAAS,QAAQ,EAAE,GAAG,SAAS,GACpC,OAAO,EAAE,CAKX;AAED,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,SAAS,mBAAmB,EAAE,GAAG,SAAS,GAC/C,OAAO,EAAE,CAQX"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Action references shared by `defineAgent` and `defineMcpServer`: both expose
|
|
2
|
+
// the same tools / sub-agents / connector actions, each with the same per-call
|
|
3
|
+
// options. A tool/agent is referenced by handle or `xxRef(uuid)` — bare when it
|
|
4
|
+
// needs no options, or wrapped `{ ref, …options }`. Normalized here (defaults
|
|
5
|
+
// baked in) so the stored spec — and the content hash — is stable.
|
|
6
|
+
import { refUuid } from "../refs.js";
|
|
7
|
+
function normalizeOptions(opts) {
|
|
8
|
+
return {
|
|
9
|
+
name: opts.name === undefined ? null : opts.name,
|
|
10
|
+
description: opts.description === undefined ? null : opts.description,
|
|
11
|
+
isBulkAllowed: opts.isBulkAllowed === undefined ? false : opts.isBulkAllowed,
|
|
12
|
+
waitUntilFinished: opts.waitUntilFinished === undefined ? true : opts.waitUntilFinished,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
// Split a use into its uuid + options, whether it's a bare handle/ref or a
|
|
16
|
+
// `{ ref, …options }` wrapper.
|
|
17
|
+
function splitUse(use) {
|
|
18
|
+
if ("ref" in use) {
|
|
19
|
+
const { ref, ...options } = use;
|
|
20
|
+
return { uuid: refUuid(ref), options };
|
|
21
|
+
}
|
|
22
|
+
return { uuid: refUuid(use), options: {} };
|
|
23
|
+
}
|
|
24
|
+
export function normalizeTools(uses) {
|
|
25
|
+
return (uses === undefined ? [] : uses).map((t) => {
|
|
26
|
+
const { uuid, options } = splitUse(t);
|
|
27
|
+
return { uuid, ...normalizeOptions(options) };
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
export function normalizeSubAgents(uses) {
|
|
31
|
+
return (uses === undefined ? [] : uses).map((s) => {
|
|
32
|
+
const { uuid, options } = splitUse(s);
|
|
33
|
+
return { uuid, ...normalizeOptions(options) };
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
export function normalizeConnectorActions(refs) {
|
|
37
|
+
return (refs === undefined ? [] : refs).map((c) => ({
|
|
38
|
+
integration: c.integration,
|
|
39
|
+
actionSlug: c.actionSlug,
|
|
40
|
+
connectorUuid: c.connector === undefined ? undefined : refUuid(c.connector),
|
|
41
|
+
config: c.config === undefined ? {} : c.config,
|
|
42
|
+
...normalizeOptions(c),
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { AiTypes } from "@cargo-ai/types";
|
|
2
|
+
import { type Token } from "../core.js";
|
|
3
|
+
import { type ConnectorRef, type FolderRef, type ModelRef } from "../refs.js";
|
|
4
|
+
import { type AgentUse, type ConnectorActionSpec, type ToolUse } from "./actions.js";
|
|
5
|
+
import type { ConnectorHandle } from "./connector.js";
|
|
6
|
+
import type { FolderHandle } from "./folder.js";
|
|
7
|
+
import type { ModelHandle } from "./model.js";
|
|
8
|
+
export type { ActionOptions, AgentUse, ConnectorActionSpec, ToolUse, } from "./actions.js";
|
|
9
|
+
export type CapabilitySpec = AiTypes.Capability["slug"] | AiTypes.Capability;
|
|
10
|
+
export type TriggerSpec = {
|
|
11
|
+
type: "cron";
|
|
12
|
+
cron: string;
|
|
13
|
+
text: string;
|
|
14
|
+
name?: string;
|
|
15
|
+
} | {
|
|
16
|
+
type: "connector";
|
|
17
|
+
integration: string;
|
|
18
|
+
/** The triggering connector — a handle or `connectorRef(uuid)`. */
|
|
19
|
+
connector?: ConnectorHandle | ConnectorRef;
|
|
20
|
+
config?: Record<string, unknown>;
|
|
21
|
+
name?: string;
|
|
22
|
+
};
|
|
23
|
+
/** Per-model options when an agent/MCP server exposes a data model. */
|
|
24
|
+
export type ModelOptions = {
|
|
25
|
+
readonly readOnly?: boolean;
|
|
26
|
+
readonly columns?: string[];
|
|
27
|
+
readonly prompt?: string;
|
|
28
|
+
};
|
|
29
|
+
/** A data model to expose — the handle / `modelRef(uuid)`, bare or `{ ref, …options }`. */
|
|
30
|
+
export type ModelUse = ModelHandle | ModelRef | (ModelOptions & {
|
|
31
|
+
readonly ref: ModelHandle | ModelRef;
|
|
32
|
+
});
|
|
33
|
+
export type AgentSpec = {
|
|
34
|
+
name?: string;
|
|
35
|
+
description?: string;
|
|
36
|
+
/** Icon colour. Defaults to "grey". */
|
|
37
|
+
color?: AiTypes.AgentIcon["color"];
|
|
38
|
+
/** The LLM connector — a handle (e.g. `openai`) or `connectorRef(uuid)`. */
|
|
39
|
+
connector?: ConnectorHandle | ConnectorRef;
|
|
40
|
+
/** Language-model slug, e.g. "gpt-4o". */
|
|
41
|
+
languageModel?: string;
|
|
42
|
+
systemPrompt: string;
|
|
43
|
+
temperature?: number;
|
|
44
|
+
maxSteps?: number;
|
|
45
|
+
withReasoning?: boolean;
|
|
46
|
+
capabilities?: CapabilitySpec[];
|
|
47
|
+
triggers?: TriggerSpec[];
|
|
48
|
+
/** Data models the agent can read/write. */
|
|
49
|
+
models?: ModelUse[];
|
|
50
|
+
/** Tools the agent can call (become tool actions). */
|
|
51
|
+
tools?: ToolUse[];
|
|
52
|
+
/** Connector actions the agent can call. */
|
|
53
|
+
connectorActions?: ConnectorActionSpec[];
|
|
54
|
+
/** Sub-agents the agent can call (become agent actions). */
|
|
55
|
+
subAgents?: AgentUse[];
|
|
56
|
+
mcpClients?: AiTypes.McpClient[];
|
|
57
|
+
suggestedActions?: AiTypes.SuggestedAction[];
|
|
58
|
+
output?: AiTypes.Output;
|
|
59
|
+
heartbeat?: AiTypes.Heartbeat;
|
|
60
|
+
evaluator?: AiTypes.Evaluator;
|
|
61
|
+
folder?: FolderHandle | FolderRef;
|
|
62
|
+
};
|
|
63
|
+
export declare function normalizeModels(uses: readonly ModelUse[] | undefined, defaultReadOnly: boolean): unknown[];
|
|
64
|
+
export type AgentHandle = {
|
|
65
|
+
readonly slug: string;
|
|
66
|
+
readonly uuid: Token;
|
|
67
|
+
/** Discriminator so an agent handle can be passed to a workflow's `uses`. */
|
|
68
|
+
readonly resource: "agent";
|
|
69
|
+
};
|
|
70
|
+
export declare function defineAgent(slug: string, spec: AgentSpec): AgentHandle;
|
|
71
|
+
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/resources/agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// defineAgent — the typed builder over a Release + Agent. References dependencies
|
|
2
|
+
// by handle (or `xxRef(uuid)`): `connector` is the LLM connector (its integration
|
|
3
|
+
// slug is resolved at deploy), `models` are data models, and `tools` / `subAgents`
|
|
4
|
+
// / `connectorActions` become the agent's release actions. Compiles to a
|
|
5
|
+
// CreateAgentPayload + DeployDraftReleasePayload once tokens resolve.
|
|
6
|
+
import { register, resourceId, token } from "../core.js";
|
|
7
|
+
import { refUuid, } from "../refs.js";
|
|
8
|
+
import { normalizeConnectorActions, normalizeSubAgents, normalizeTools, } from "./actions.js";
|
|
9
|
+
// Normalize the `models` list (shared with `defineMcpServer`) — each entry is a
|
|
10
|
+
// bare handle/ref or `{ ref, …options }`.
|
|
11
|
+
export function normalizeModels(uses, defaultReadOnly) {
|
|
12
|
+
return (uses === undefined ? [] : uses).map((m) => {
|
|
13
|
+
const hasOptions = "ref" in m;
|
|
14
|
+
const ref = hasOptions ? m.ref : m;
|
|
15
|
+
const opts = hasOptions ? m : {};
|
|
16
|
+
return {
|
|
17
|
+
uuid: refUuid(ref),
|
|
18
|
+
readOnly: opts.readOnly === undefined ? defaultReadOnly : opts.readOnly,
|
|
19
|
+
columns: opts.columns === undefined ? null : opts.columns,
|
|
20
|
+
prompt: opts.prompt === undefined ? null : opts.prompt,
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
// Lower triggers to their wire form — a connector trigger references its
|
|
25
|
+
// connector by handle/ref, which becomes `connectorUuid`.
|
|
26
|
+
function normalizeTriggers(triggers) {
|
|
27
|
+
return (triggers === undefined ? [] : triggers).map((t) => {
|
|
28
|
+
if (t.type === "connector") {
|
|
29
|
+
const { connector, ...rest } = t;
|
|
30
|
+
return {
|
|
31
|
+
...rest,
|
|
32
|
+
connectorUuid: connector === undefined ? undefined : refUuid(connector),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return t;
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function normalizeCapability(capability) {
|
|
39
|
+
if (typeof capability === "string") {
|
|
40
|
+
return { slug: capability, config: {} };
|
|
41
|
+
}
|
|
42
|
+
return capability;
|
|
43
|
+
}
|
|
44
|
+
export function defineAgent(slug, spec) {
|
|
45
|
+
const id = resourceId("agent", slug);
|
|
46
|
+
// The release needs a complete LLM binding (the executor throws otherwise) —
|
|
47
|
+
// catch a missing/partial one here so it fails in `plan`, not mid-deploy.
|
|
48
|
+
if (spec.connector === undefined || spec.languageModel === undefined) {
|
|
49
|
+
throw new Error(`defineAgent("${slug}"): an agent needs both connector (the LLM ` +
|
|
50
|
+
`provider connector, e.g. \`openai\`) and languageModel (e.g. ` +
|
|
51
|
+
`"gpt-4o") to deploy. Got connector=${spec.connector === undefined ? "undefined" : "set"}, ` +
|
|
52
|
+
`languageModel=${spec.languageModel === undefined ? "undefined" : `"${spec.languageModel}"`}.`);
|
|
53
|
+
}
|
|
54
|
+
register({
|
|
55
|
+
id,
|
|
56
|
+
kind: "agent",
|
|
57
|
+
slug,
|
|
58
|
+
spec: {
|
|
59
|
+
slug,
|
|
60
|
+
folderUuid: spec.folder === undefined ? undefined : refUuid(spec.folder),
|
|
61
|
+
name: spec.name === undefined ? toTitle(slug) : spec.name,
|
|
62
|
+
icon: {
|
|
63
|
+
color: spec.color === undefined ? "grey" : spec.color,
|
|
64
|
+
face: "robot",
|
|
65
|
+
},
|
|
66
|
+
description: spec.description === undefined ? null : spec.description,
|
|
67
|
+
systemPrompt: spec.systemPrompt,
|
|
68
|
+
temperature: spec.temperature === undefined ? 0.2 : spec.temperature,
|
|
69
|
+
maxSteps: spec.maxSteps === undefined ? 8 : spec.maxSteps,
|
|
70
|
+
withReasoning: spec.withReasoning === undefined ? false : spec.withReasoning,
|
|
71
|
+
connectorUuid: refUuid(spec.connector),
|
|
72
|
+
languageModelSlug: spec.languageModel,
|
|
73
|
+
capabilities: (spec.capabilities === undefined
|
|
74
|
+
? []
|
|
75
|
+
: spec.capabilities).map(normalizeCapability),
|
|
76
|
+
mcpClients: spec.mcpClients === undefined ? [] : spec.mcpClients,
|
|
77
|
+
suggestedActions: spec.suggestedActions === undefined ? [] : spec.suggestedActions,
|
|
78
|
+
output: spec.output === undefined ? { type: "text" } : spec.output,
|
|
79
|
+
heartbeat: spec.heartbeat === undefined ? null : spec.heartbeat,
|
|
80
|
+
evaluator: spec.evaluator === undefined ? null : spec.evaluator,
|
|
81
|
+
triggers: normalizeTriggers(spec.triggers),
|
|
82
|
+
// resolved → ModelResource[] / Action[] by the apply executor
|
|
83
|
+
models: normalizeModels(spec.models, true),
|
|
84
|
+
tools: normalizeTools(spec.tools),
|
|
85
|
+
subAgents: normalizeSubAgents(spec.subAgents),
|
|
86
|
+
connectorActions: normalizeConnectorActions(spec.connectorActions),
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
return { slug, uuid: token(id, "uuid"), resource: "agent" };
|
|
90
|
+
}
|
|
91
|
+
function toTitle(slug) {
|
|
92
|
+
return slug
|
|
93
|
+
.split(/[-_]/)
|
|
94
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
95
|
+
.join(" ");
|
|
96
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type Token } from "../core.js";
|
|
2
|
+
import { type FolderRef } from "../refs.js";
|
|
3
|
+
import type { FolderHandle } from "./folder.js";
|
|
4
|
+
export type AppSpec = {
|
|
5
|
+
/** Path to the app's code directory (uploaded + built on deploy). */
|
|
6
|
+
path: string;
|
|
7
|
+
name?: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
folder?: FolderHandle | FolderRef;
|
|
10
|
+
};
|
|
11
|
+
export type AppHandle = {
|
|
12
|
+
readonly slug: string;
|
|
13
|
+
readonly uuid: Token;
|
|
14
|
+
/** The live app URL (deferred — known after deploy). */
|
|
15
|
+
readonly url: Token;
|
|
16
|
+
};
|
|
17
|
+
export declare function defineApp(slug: string, spec: AppSpec): AppHandle;
|
|
18
|
+
//# sourceMappingURL=app.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../../src/resources/app.ts"],"names":[],"mappings":"AAIA,OAAO,EAAwB,KAAK,KAAK,EAAS,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,KAAK,SAAS,EAAW,MAAM,YAAY,CAAC;AAErD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAMhD,MAAM,MAAM,OAAO,GAAG;IACpB,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,wDAAwD;IACxD,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC;CACrB,CAAC;AAEF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,SAAS,CAiBhE"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// defineApp — a hosted Cargo app (the resource), deployed from a code directory
|
|
2
|
+
// (a Vite app). On deploy the reconciler creates the app slot, uploads the
|
|
3
|
+
// bundle, and promotes it (the backend runs the build).
|
|
4
|
+
import { register, resourceId, token } from "../core.js";
|
|
5
|
+
import { refUuid } from "../refs.js";
|
|
6
|
+
import { assertBundleFiles, bundleHash } from "./bundle.js";
|
|
7
|
+
// Files the hosting app build requires at the bundle root: an npm-ci'able project
|
|
8
|
+
// and a Vite entry (`vite build` must emit dist/index.html).
|
|
9
|
+
const APP_REQUIRED = ["index.html", "package.json", "package-lock.json"];
|
|
10
|
+
export function defineApp(slug, spec) {
|
|
11
|
+
const id = resourceId("app", slug);
|
|
12
|
+
assertBundleFiles(spec.path, "app", APP_REQUIRED);
|
|
13
|
+
register({
|
|
14
|
+
id,
|
|
15
|
+
kind: "app",
|
|
16
|
+
slug,
|
|
17
|
+
spec: {
|
|
18
|
+
slug,
|
|
19
|
+
name: spec.name === undefined ? toTitle(slug) : spec.name,
|
|
20
|
+
description: spec.description === undefined ? null : spec.description,
|
|
21
|
+
path: spec.path,
|
|
22
|
+
contentHash: bundleHash(spec.path),
|
|
23
|
+
folderUuid: spec.folder === undefined ? undefined : refUuid(spec.folder),
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
return { slug, uuid: token(id, "uuid"), url: token(id, "url") };
|
|
27
|
+
}
|
|
28
|
+
function toTitle(slug) {
|
|
29
|
+
return slug
|
|
30
|
+
.split(/[-_]/)
|
|
31
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
32
|
+
.join(" ");
|
|
33
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type SourceFile = {
|
|
2
|
+
path: string;
|
|
3
|
+
content: string;
|
|
4
|
+
};
|
|
5
|
+
/** All uploadable source files under `root`, paths relative to `root`. */
|
|
6
|
+
export declare function readBundle(root: string): SourceFile[];
|
|
7
|
+
/**
|
|
8
|
+
* Fail at define time (not after a multi-minute server build) when a worker/app
|
|
9
|
+
* bundle is missing a file the hosting build requires. `label` names the kind in
|
|
10
|
+
* the error message.
|
|
11
|
+
*/
|
|
12
|
+
export declare function assertBundleFiles(root: string, label: string, required: string[]): void;
|
|
13
|
+
/** A content hash over the whole bundle — changes when any file changes. */
|
|
14
|
+
export declare function bundleHash(root: string): string;
|
|
15
|
+
//# sourceMappingURL=bundle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../../../src/resources/bundle.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAmB3D,0EAA0E;AAC1E,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,CAOrD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAAE,GACjB,IAAI,CAYN;AAED,4EAA4E;AAC5E,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAS/C"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// Read a directory of source files for a worker/app deployment, and hash it so a
|
|
2
|
+
// code change shows as drift. The bundle is read at define time (to hash) and
|
|
3
|
+
// re-read by the executor (to upload). Text files only — binary assets in apps
|
|
4
|
+
// are a known v1 limitation (the deployment payload's `content` is a string).
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
6
|
+
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
7
|
+
import { isAbsolute, join, relative, resolve } from "node:path";
|
|
8
|
+
const SKIP = new Set(["node_modules", ".git", "build", "dist", ".turbo"]);
|
|
9
|
+
function walk(base, dir, out) {
|
|
10
|
+
for (const entry of readdirSync(dir)) {
|
|
11
|
+
if (SKIP.has(entry))
|
|
12
|
+
continue;
|
|
13
|
+
const full = join(dir, entry);
|
|
14
|
+
if (statSync(full).isDirectory()) {
|
|
15
|
+
walk(base, full, out);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
out.push({
|
|
19
|
+
path: relative(base, full),
|
|
20
|
+
content: readFileSync(full, "utf8"),
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/** All uploadable source files under `root`, paths relative to `root`. */
|
|
26
|
+
export function readBundle(root) {
|
|
27
|
+
const base = isAbsolute(root) ? root : resolve(process.cwd(), root);
|
|
28
|
+
if (!existsSync(base))
|
|
29
|
+
throw new Error(`code path not found: ${base}`);
|
|
30
|
+
const out = [];
|
|
31
|
+
walk(base, base, out);
|
|
32
|
+
out.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Fail at define time (not after a multi-minute server build) when a worker/app
|
|
37
|
+
* bundle is missing a file the hosting build requires. `label` names the kind in
|
|
38
|
+
* the error message.
|
|
39
|
+
*/
|
|
40
|
+
export function assertBundleFiles(root, label, required) {
|
|
41
|
+
const base = isAbsolute(root) ? root : resolve(process.cwd(), root);
|
|
42
|
+
if (!existsSync(base)) {
|
|
43
|
+
throw new Error(`${label} code path not found: ${base}`);
|
|
44
|
+
}
|
|
45
|
+
const missing = required.filter((file) => !existsSync(join(base, file)));
|
|
46
|
+
if (missing.length > 0) {
|
|
47
|
+
throw new Error(`${label} bundle at "${root}" is missing required file(s): ${missing.join(", ")}. ` +
|
|
48
|
+
`A ${label} bundle must contain ${required.join(", ")} at its root.`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/** A content hash over the whole bundle — changes when any file changes. */
|
|
52
|
+
export function bundleHash(root) {
|
|
53
|
+
const hash = createHash("sha256");
|
|
54
|
+
for (const file of readBundle(root)) {
|
|
55
|
+
hash.update(file.path);
|
|
56
|
+
hash.update("\0");
|
|
57
|
+
hash.update(file.content);
|
|
58
|
+
hash.update("\0");
|
|
59
|
+
}
|
|
60
|
+
return `sha256:${hash.digest("hex").slice(0, 16)}`;
|
|
61
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type Token } from "../core.js";
|
|
2
|
+
export type RateLimitSpec = {
|
|
3
|
+
unit: "day" | "hour" | "minute" | "second";
|
|
4
|
+
max: number;
|
|
5
|
+
strategy: "spread" | "burst";
|
|
6
|
+
};
|
|
7
|
+
export interface ConnectorConfigs {
|
|
8
|
+
}
|
|
9
|
+
type ConnectorConfigFor<S extends string> = S extends keyof ConnectorConfigs ? ConnectorConfigs[S] : Record<string, unknown>;
|
|
10
|
+
export type ConnectorSpec<S extends string = string> = {
|
|
11
|
+
integration: S;
|
|
12
|
+
name?: string;
|
|
13
|
+
config?: ConnectorConfigFor<S>;
|
|
14
|
+
rateLimit?: RateLimitSpec;
|
|
15
|
+
cacheTtlMilliseconds?: number;
|
|
16
|
+
adopt?: boolean;
|
|
17
|
+
};
|
|
18
|
+
export type ConnectorHandle<S extends string = string> = {
|
|
19
|
+
readonly slug: string;
|
|
20
|
+
readonly integrationSlug: S;
|
|
21
|
+
readonly uuid: Token;
|
|
22
|
+
readonly datasetUuid: Token;
|
|
23
|
+
/** Discriminator so a connector handle can be passed where a connector (or its
|
|
24
|
+
* dataset, via `defineModel`) is referenced. Carries the integration slug `S`
|
|
25
|
+
* so `defineModel({ dataset })` can type extractor config. */
|
|
26
|
+
readonly resource: "connector";
|
|
27
|
+
};
|
|
28
|
+
export declare function defineConnector<S extends string>(slug: string, spec: ConnectorSpec<S>): ConnectorHandle<S>;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=connector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector.d.ts","sourceRoot":"","sources":["../../../src/resources/connector.ts"],"names":[],"mappings":"AAWA,OAAO,EAAwB,KAAK,KAAK,EAAS,MAAM,YAAY,CAAC;AAErE,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC;CAC9B,CAAC;AAQF,MAAM,WAAW,gBAAgB;CAAG;AAEpC,KAAK,kBAAkB,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,MAAM,gBAAgB,GACxE,gBAAgB,CAAC,CAAC,CAAC,GACnB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE5B,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI;IACrD,WAAW,EAAE,CAAC,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAC/B,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI;IACvD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,eAAe,EAAE,CAAC,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC;IAC5B;;mEAE+D;IAC/D,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;CAChC,CAAC;AAEF,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,EAC9C,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,GACrB,eAAe,CAAC,CAAC,CAAC,CAuBpB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// defineConnector
|
|
2
|
+
//
|
|
3
|
+
// `defineConnector` registers a connector and returns a handle. Outputs are
|
|
4
|
+
// deferred tokens — `connector.uuid` and `connector.datasetUuid` (the dataset
|
|
5
|
+
// auto-created alongside it, which data models source from). The integration
|
|
6
|
+
// slug is known at define time, so it's a plain value on the handle.
|
|
7
|
+
//
|
|
8
|
+
// Two modes: create (config-based integrations, secrets via env) or adopt
|
|
9
|
+
// (`adopt: true`) to link an already-authenticated connector by slug — the
|
|
10
|
+
// escape hatch for OAuth integrations whose tokens can't live in a repo.
|
|
11
|
+
import { register, resourceId, token } from "../core.js";
|
|
12
|
+
export function defineConnector(slug, spec) {
|
|
13
|
+
const id = resourceId("connector", slug);
|
|
14
|
+
register({
|
|
15
|
+
id,
|
|
16
|
+
kind: "connector",
|
|
17
|
+
slug,
|
|
18
|
+
spec: {
|
|
19
|
+
slug,
|
|
20
|
+
name: spec.name === undefined ? toTitle(slug) : spec.name,
|
|
21
|
+
integrationSlug: spec.integration,
|
|
22
|
+
config: spec.config,
|
|
23
|
+
rateLimit: spec.rateLimit,
|
|
24
|
+
cacheTtlMilliseconds: spec.cacheTtlMilliseconds,
|
|
25
|
+
adopt: spec.adopt === undefined ? false : spec.adopt,
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
return {
|
|
29
|
+
slug,
|
|
30
|
+
integrationSlug: spec.integration,
|
|
31
|
+
uuid: token(id, "uuid"),
|
|
32
|
+
datasetUuid: token(id, "datasetUuid"),
|
|
33
|
+
resource: "connector",
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function toTitle(slug) {
|
|
37
|
+
return slug
|
|
38
|
+
.split(/[-_]/)
|
|
39
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
40
|
+
.join(" ");
|
|
41
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Token } from "../core.js";
|
|
2
|
+
export type ContextSpec = {
|
|
3
|
+
/** A local directory of markdown/MDX files to sync (read recursively). */
|
|
4
|
+
dir?: string;
|
|
5
|
+
/** Inline files (repo-relative POSIX path → content). Merged over `dir`. */
|
|
6
|
+
files?: Record<string, string>;
|
|
7
|
+
};
|
|
8
|
+
export type ContextHandle = {
|
|
9
|
+
/** Discriminator (there is one context repo per workspace). */
|
|
10
|
+
readonly resource: "context";
|
|
11
|
+
/** The context repository's uuid (deferred). */
|
|
12
|
+
readonly uuid: Token;
|
|
13
|
+
};
|
|
14
|
+
export declare function defineContext(spec: ContextSpec): ContextHandle;
|
|
15
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/resources/context.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAwB,KAAK,KAAK,EAAS,MAAM,YAAY,CAAC;AAErE,MAAM,MAAM,WAAW,GAAG;IACxB,0EAA0E;IAC1E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,+DAA+D;IAC/D,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,gDAAgD;IAChD,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;CACtB,CAAC;AAKF,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,aAAa,CAoB9D"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// defineContext — the workspace's context repository (a git-backed GTM knowledge
|
|
2
|
+
// base of markdown/MDX files) as code. A workspace has exactly ONE context repo,
|
|
3
|
+
// so this is a singleton resource; its "spec" is a set of repo-relative files.
|
|
4
|
+
//
|
|
5
|
+
// On deploy the executor writes each changed file into the repo via the runtime
|
|
6
|
+
// (committing). It is ADDITIVE — files removed from code are left in place, since
|
|
7
|
+
// the repo may hold files managed elsewhere (the UI, other tooling).
|
|
8
|
+
//
|
|
9
|
+
// defineContext({
|
|
10
|
+
// dir: "./context", // sync a local folder of .md/.mdx
|
|
11
|
+
// files: { "generated/icp.md": buildIcp() }, // + inline additions/overrides
|
|
12
|
+
// });
|
|
13
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
14
|
+
import { join, relative, sep } from "node:path";
|
|
15
|
+
import { register, resourceId, token } from "../core.js";
|
|
16
|
+
// One context repo per workspace → a fixed singleton slug.
|
|
17
|
+
const CONTEXT_SLUG = "repository";
|
|
18
|
+
export function defineContext(spec) {
|
|
19
|
+
const id = resourceId("context", CONTEXT_SLUG);
|
|
20
|
+
const files = {};
|
|
21
|
+
if (spec.dir !== undefined) {
|
|
22
|
+
for (const [path, content] of readMarkdownDir(spec.dir)) {
|
|
23
|
+
files[path] = content;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (spec.files !== undefined) {
|
|
27
|
+
for (const [path, content] of Object.entries(spec.files)) {
|
|
28
|
+
files[path] = content;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
register({
|
|
32
|
+
id,
|
|
33
|
+
kind: "context",
|
|
34
|
+
slug: CONTEXT_SLUG,
|
|
35
|
+
spec: { slug: CONTEXT_SLUG, files },
|
|
36
|
+
});
|
|
37
|
+
return { resource: "context", uuid: token(id, "uuid") };
|
|
38
|
+
}
|
|
39
|
+
// Recursively read a local directory's `.md` / `.mdx` files, keyed by their
|
|
40
|
+
// repo-relative POSIX path.
|
|
41
|
+
function readMarkdownDir(dir) {
|
|
42
|
+
const out = [];
|
|
43
|
+
const walk = (current) => {
|
|
44
|
+
for (const entry of readdirSync(current, { withFileTypes: true })) {
|
|
45
|
+
const abs = join(current, entry.name);
|
|
46
|
+
if (entry.isDirectory()) {
|
|
47
|
+
walk(abs);
|
|
48
|
+
}
|
|
49
|
+
else if (entry.isFile() && /\.mdx?$/i.test(entry.name)) {
|
|
50
|
+
const rel = relative(dir, abs).split(sep).join("/");
|
|
51
|
+
out.push([rel, readFileSync(abs, "utf8")]);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
walk(dir);
|
|
56
|
+
out.sort(([a], [b]) => a.localeCompare(b));
|
|
57
|
+
return out;
|
|
58
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Token } from "../core.js";
|
|
2
|
+
import { type FolderRef } from "../refs.js";
|
|
3
|
+
import type { FolderHandle } from "./folder.js";
|
|
4
|
+
export type FileSpec = {
|
|
5
|
+
/** Path to the file's content (read + uploaded on deploy). */
|
|
6
|
+
path: string;
|
|
7
|
+
name?: string;
|
|
8
|
+
folder?: FolderHandle | FolderRef;
|
|
9
|
+
};
|
|
10
|
+
export type FileHandle = {
|
|
11
|
+
readonly slug: string;
|
|
12
|
+
readonly uuid: Token;
|
|
13
|
+
};
|
|
14
|
+
export declare function defineFile(slug: string, spec: FileSpec): FileHandle;
|
|
15
|
+
//# sourceMappingURL=file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../../src/resources/file.ts"],"names":[],"mappings":"AAcA,OAAO,EAAwB,KAAK,KAAK,EAAS,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,KAAK,SAAS,EAAW,MAAM,YAAY,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,MAAM,QAAQ,GAAG;IACrB,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;CACtB,CAAC;AAEF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,UAAU,CAoBnE"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// defineFile — a Cargo content file, uploaded from a local path. The file's
|
|
2
|
+
// content is read + hashed at define time; the executor uploads it (multipart)
|
|
3
|
+
// and reconciles the returned uuid by its s3Filename.
|
|
4
|
+
//
|
|
5
|
+
// Identity: a file has no slug (uuid-only, state-tracked). Editing the file's
|
|
6
|
+
// content reconciles on the next deploy: Cargo files are immutable, so the
|
|
7
|
+
// executor uploads a replacement and deletes the old one — the uuid changes, and
|
|
8
|
+
// the state's stored `contentHash` is how a content change is told apart from a
|
|
9
|
+
// name/folder-only change (which is reconciled in place).
|
|
10
|
+
import { createHash } from "node:crypto";
|
|
11
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
12
|
+
import { basename, isAbsolute, resolve } from "node:path";
|
|
13
|
+
import { register, resourceId, token } from "../core.js";
|
|
14
|
+
import { refUuid } from "../refs.js";
|
|
15
|
+
export function defineFile(slug, spec) {
|
|
16
|
+
const id = resourceId("file", slug);
|
|
17
|
+
const abs = isAbsolute(spec.path)
|
|
18
|
+
? spec.path
|
|
19
|
+
: resolve(process.cwd(), spec.path);
|
|
20
|
+
if (!existsSync(abs))
|
|
21
|
+
throw new Error(`file path not found: ${abs}`);
|
|
22
|
+
register({
|
|
23
|
+
id,
|
|
24
|
+
kind: "file",
|
|
25
|
+
slug,
|
|
26
|
+
spec: {
|
|
27
|
+
slug,
|
|
28
|
+
name: spec.name === undefined ? basename(spec.path) : spec.name,
|
|
29
|
+
path: spec.path,
|
|
30
|
+
contentHash: `sha256:${createHash("sha256").update(readFileSync(abs)).digest("hex").slice(0, 16)}`,
|
|
31
|
+
folderUuid: spec.folder === undefined ? undefined : refUuid(spec.folder),
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
return { slug, uuid: token(id, "uuid") };
|
|
35
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { WorkspaceManagementTypes } from "@cargo-ai/types";
|
|
2
|
+
import { type Token } from "../core.js";
|
|
3
|
+
import { type FolderRef } from "../refs.js";
|
|
4
|
+
export type FolderKind = WorkspaceManagementTypes.FolderKind;
|
|
5
|
+
export type FolderHandle = {
|
|
6
|
+
readonly slug: string;
|
|
7
|
+
readonly uuid: Token;
|
|
8
|
+
readonly kind: FolderKind;
|
|
9
|
+
readonly resource: "folder";
|
|
10
|
+
};
|
|
11
|
+
export type FolderSpec = {
|
|
12
|
+
/** Which kind of resource this folder holds (model, agent, play, …). */
|
|
13
|
+
kind: FolderKind;
|
|
14
|
+
name?: string;
|
|
15
|
+
emojiSlug?: string;
|
|
16
|
+
/** Parent folder, for nesting — a folder handle or a `folderRef(uuid)`. */
|
|
17
|
+
parent?: FolderHandle | FolderRef;
|
|
18
|
+
};
|
|
19
|
+
export declare function defineFolder(slug: string, spec: FolderSpec): FolderHandle;
|
|
20
|
+
//# sourceMappingURL=folder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"folder.d.ts","sourceRoot":"","sources":["../../../src/resources/folder.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAEhE,OAAO,EAAwB,KAAK,KAAK,EAAS,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,KAAK,SAAS,EAAW,MAAM,YAAY,CAAC;AAErD,MAAM,MAAM,UAAU,GAAG,wBAAwB,CAAC,UAAU,CAAC;AAE7D,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,wEAAwE;IACxE,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;CACnC,CAAC;AAEF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,YAAY,CAgBzE"}
|