@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,273 @@
|
|
|
1
|
+
// Live readers — bind the refresh engine's `LiveReaders` to @cargo-ai/api. Each
|
|
2
|
+
// reader fetches a deployed resource by its state uuid and projects its
|
|
3
|
+
// user-editable config into a fingerprint, so `refresh` can compare it against
|
|
4
|
+
// the fingerprint captured at the last apply and flag out-of-band changes.
|
|
5
|
+
//
|
|
6
|
+
// A reader returns { exists:false } ONLY on a confirmed not-found; any other
|
|
7
|
+
// error propagates so detectDrift records "unknown" rather than a false deletion.
|
|
8
|
+
import { fingerprint } from "./refresh.js";
|
|
9
|
+
const GONE = { exists: false };
|
|
10
|
+
// Keys stripped anywhere in a projection before hashing: per-resource volatile
|
|
11
|
+
// ids and canvas coordinates that change without being user edits.
|
|
12
|
+
const VOLATILE = new Set([
|
|
13
|
+
"temporalScheduleWorkflowId",
|
|
14
|
+
"temporalWorkflowId",
|
|
15
|
+
"position",
|
|
16
|
+
"createdAt",
|
|
17
|
+
"updatedAt",
|
|
18
|
+
"deletedAt",
|
|
19
|
+
]);
|
|
20
|
+
function deepOmit(value) {
|
|
21
|
+
if (Array.isArray(value))
|
|
22
|
+
return value.map(deepOmit);
|
|
23
|
+
if (value !== null && typeof value === "object") {
|
|
24
|
+
const out = {};
|
|
25
|
+
for (const [key, inner] of Object.entries(value)) {
|
|
26
|
+
if (VOLATILE.has(key))
|
|
27
|
+
continue;
|
|
28
|
+
out[key] = deepOmit(inner);
|
|
29
|
+
}
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
function present(config) {
|
|
35
|
+
return { exists: true, fingerprint: fingerprint(deepOmit(config)) };
|
|
36
|
+
}
|
|
37
|
+
function isNotFound(error) {
|
|
38
|
+
const reason = error.reason;
|
|
39
|
+
if (typeof reason === "string" && /notfound/i.test(reason))
|
|
40
|
+
return true;
|
|
41
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
42
|
+
return /not found/i.test(message);
|
|
43
|
+
}
|
|
44
|
+
// Re-throw unless it's a not-found, in which case the caller treats it as gone.
|
|
45
|
+
function goneOrThrow(error) {
|
|
46
|
+
if (isNotFound(error))
|
|
47
|
+
return GONE;
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
const pick = (o, keys) => {
|
|
51
|
+
const out = {};
|
|
52
|
+
for (const key of keys)
|
|
53
|
+
out[key] = o[key];
|
|
54
|
+
return out;
|
|
55
|
+
};
|
|
56
|
+
export function liveReaders(api) {
|
|
57
|
+
// The deployed AI release holds an agent's behaviour config; returns null when
|
|
58
|
+
// nothing is deployed yet.
|
|
59
|
+
async function agentRelease(agentUuid) {
|
|
60
|
+
try {
|
|
61
|
+
const { release } = await api.ai.release.getDeployed({ agentUuid });
|
|
62
|
+
return pick(release, [
|
|
63
|
+
"systemPrompt",
|
|
64
|
+
"languageModelSlug",
|
|
65
|
+
"integrationSlug",
|
|
66
|
+
"connectorUuid",
|
|
67
|
+
"withReasoning",
|
|
68
|
+
"temperature",
|
|
69
|
+
"maxSteps",
|
|
70
|
+
"actions",
|
|
71
|
+
"resources",
|
|
72
|
+
"capabilities",
|
|
73
|
+
"mcpClients",
|
|
74
|
+
"output",
|
|
75
|
+
"heartbeat",
|
|
76
|
+
"evaluator",
|
|
77
|
+
]);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
if (isNotFound(error))
|
|
81
|
+
return null;
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// The deployed orchestration release holds a play/tool's workflow graph.
|
|
86
|
+
async function workflowNodes(workflowUuid) {
|
|
87
|
+
if (workflowUuid === undefined)
|
|
88
|
+
return null;
|
|
89
|
+
try {
|
|
90
|
+
const { release } = await api.orchestration.release.getDeployed({
|
|
91
|
+
workflowUuid,
|
|
92
|
+
});
|
|
93
|
+
return {
|
|
94
|
+
nodes: release["nodes"],
|
|
95
|
+
formFields: release["formFields"],
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
if (isNotFound(error))
|
|
100
|
+
return null;
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
async connector(entry) {
|
|
106
|
+
try {
|
|
107
|
+
const { connector } = await api.connection.connector.get({
|
|
108
|
+
uuid: entry.uuid,
|
|
109
|
+
});
|
|
110
|
+
return present(pick(connector, [
|
|
111
|
+
"name",
|
|
112
|
+
"slug",
|
|
113
|
+
"integrationSlug",
|
|
114
|
+
"config",
|
|
115
|
+
"useCredits",
|
|
116
|
+
"rateLimit",
|
|
117
|
+
"cacheTtlMilliseconds",
|
|
118
|
+
]));
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
return goneOrThrow(error);
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
async model(entry) {
|
|
125
|
+
try {
|
|
126
|
+
const { model } = await api.storage.model.get(entry.uuid);
|
|
127
|
+
return present(pick(model, [
|
|
128
|
+
"name",
|
|
129
|
+
"slug",
|
|
130
|
+
"description",
|
|
131
|
+
"extractorSlug",
|
|
132
|
+
"config",
|
|
133
|
+
"schedule",
|
|
134
|
+
"unification",
|
|
135
|
+
"folderUuid",
|
|
136
|
+
"kind",
|
|
137
|
+
"connectorUuid",
|
|
138
|
+
]));
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
return goneOrThrow(error);
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
async agent(entry) {
|
|
145
|
+
let row;
|
|
146
|
+
try {
|
|
147
|
+
const { agent } = await api.ai.agent.get(entry.uuid);
|
|
148
|
+
row = pick(agent, [
|
|
149
|
+
"name",
|
|
150
|
+
"icon",
|
|
151
|
+
"description",
|
|
152
|
+
"triggers",
|
|
153
|
+
"folderUuid",
|
|
154
|
+
]);
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
return goneOrThrow(error);
|
|
158
|
+
}
|
|
159
|
+
return present({ row, release: await agentRelease(entry.uuid) });
|
|
160
|
+
},
|
|
161
|
+
async play(entry) {
|
|
162
|
+
const { plays } = await api.orchestration.play.list();
|
|
163
|
+
const play = plays.find((p) => p["uuid"] === entry.uuid);
|
|
164
|
+
if (play === undefined)
|
|
165
|
+
return GONE;
|
|
166
|
+
const row = pick(play, [
|
|
167
|
+
"name",
|
|
168
|
+
"description",
|
|
169
|
+
"isEnabled",
|
|
170
|
+
"modelUuid",
|
|
171
|
+
"changeKinds",
|
|
172
|
+
"runCreationRule",
|
|
173
|
+
"schedule",
|
|
174
|
+
"folderUuid",
|
|
175
|
+
]);
|
|
176
|
+
const wf = entry.outputs["workflowUuid"];
|
|
177
|
+
return present({ row, workflow: await workflowNodes(wf) });
|
|
178
|
+
},
|
|
179
|
+
async tool(entry) {
|
|
180
|
+
const { tools } = await api.orchestration.tool.all();
|
|
181
|
+
const tool = tools.find((t) => t["uuid"] === entry.uuid);
|
|
182
|
+
if (tool === undefined)
|
|
183
|
+
return GONE;
|
|
184
|
+
const row = pick(tool, [
|
|
185
|
+
"name",
|
|
186
|
+
"icon",
|
|
187
|
+
"description",
|
|
188
|
+
"triggers",
|
|
189
|
+
"publicForm",
|
|
190
|
+
"folderUuid",
|
|
191
|
+
]);
|
|
192
|
+
const wf = entry.outputs["workflowUuid"];
|
|
193
|
+
return present({ row, workflow: await workflowNodes(wf) });
|
|
194
|
+
},
|
|
195
|
+
async mcpServer(entry) {
|
|
196
|
+
try {
|
|
197
|
+
const { mcpServer } = await api.ai.mcpServer.get(entry.uuid);
|
|
198
|
+
return present(pick(mcpServer, [
|
|
199
|
+
"name",
|
|
200
|
+
"description",
|
|
201
|
+
"actions",
|
|
202
|
+
"resources",
|
|
203
|
+
"folderUuid",
|
|
204
|
+
]));
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
return goneOrThrow(error);
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
async folder(entry) {
|
|
211
|
+
try {
|
|
212
|
+
const { folder } = await api.workspaceManagement.folder.get(entry.uuid);
|
|
213
|
+
// Only fingerprint what the folder executor can actually reconcile
|
|
214
|
+
// (name + emojiSlug); kind/parentUuid aren't updatable from the CDK, so
|
|
215
|
+
// including them would flag drift that can never converge.
|
|
216
|
+
return present(pick(folder, ["name", "emojiSlug"]));
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
return goneOrThrow(error);
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
async file(entry) {
|
|
223
|
+
try {
|
|
224
|
+
const { file } = await api.content.file.get(entry.uuid);
|
|
225
|
+
return present(pick(file, ["name", "folderUuid"]));
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
return goneOrThrow(error);
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
async worker(entry) {
|
|
232
|
+
try {
|
|
233
|
+
const { worker } = await api.hosting.worker.get(entry.uuid);
|
|
234
|
+
const w = worker;
|
|
235
|
+
const promoted = w["promotedDeployment"];
|
|
236
|
+
const meta = promoted === null || promoted === undefined
|
|
237
|
+
? undefined
|
|
238
|
+
: promoted["meta"];
|
|
239
|
+
return present({
|
|
240
|
+
...pick(w, ["name", "description", "slug", "folderUuid"]),
|
|
241
|
+
bundle: meta === undefined ? undefined : meta["bundleSha256"],
|
|
242
|
+
outboundAllowlist: meta === undefined ? undefined : meta["outboundAllowlist"],
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
return goneOrThrow(error);
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
async app(entry) {
|
|
250
|
+
try {
|
|
251
|
+
const { app } = await api.hosting.app.get(entry.uuid);
|
|
252
|
+
const a = app;
|
|
253
|
+
const promoted = a["promotedDeployment"];
|
|
254
|
+
return present({
|
|
255
|
+
...pick(a, ["name", "description", "slug", "folderUuid"]),
|
|
256
|
+
// app deployments carry no bundle hash — the promoted deployment uuid
|
|
257
|
+
// is the only "what's deployed" marker.
|
|
258
|
+
promoted: promoted === null || promoted === undefined
|
|
259
|
+
? undefined
|
|
260
|
+
: promoted["uuid"],
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
catch (error) {
|
|
264
|
+
return goneOrThrow(error);
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
// Context is a repo of files (not a uuid resource) — no live fingerprint, so
|
|
268
|
+
// refresh reports it "unknown" rather than fabricating drift.
|
|
269
|
+
async context(_entry) {
|
|
270
|
+
return present({});
|
|
271
|
+
},
|
|
272
|
+
};
|
|
273
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ResourceKind } from "../core.js";
|
|
2
|
+
import type { State, StateEntry } from "./compile.js";
|
|
3
|
+
export type LiveRead = {
|
|
4
|
+
exists: boolean;
|
|
5
|
+
fingerprint?: string;
|
|
6
|
+
};
|
|
7
|
+
export type LiveReader = (entry: StateEntry) => Promise<LiveRead>;
|
|
8
|
+
export type LiveReaders = Record<ResourceKind, LiveReader>;
|
|
9
|
+
export type DriftStatus = "unchanged" | "modified" | "deleted" | "unknown";
|
|
10
|
+
export type DriftEntry = {
|
|
11
|
+
id: string;
|
|
12
|
+
kind: ResourceKind;
|
|
13
|
+
status: DriftStatus;
|
|
14
|
+
};
|
|
15
|
+
/** Hash an arbitrary projection of a resource into a comparable fingerprint. */
|
|
16
|
+
export declare function fingerprint(value: unknown): string;
|
|
17
|
+
/**
|
|
18
|
+
* Read every state-tracked resource live and classify drift:
|
|
19
|
+
* - deleted — gone from the workspace (re-deploy would recreate it)
|
|
20
|
+
* - modified — its live fingerprint differs from the one captured at apply
|
|
21
|
+
* - unchanged — live matches the last apply
|
|
22
|
+
* - unknown — no baseline fingerprint, or the kind has no live reader
|
|
23
|
+
*/
|
|
24
|
+
export declare function detectDrift(state: State, readers: LiveReaders): Promise<DriftEntry[]>;
|
|
25
|
+
/**
|
|
26
|
+
* Return a copy of `state` adjusted so the next compile re-applies drifted
|
|
27
|
+
* resources: a `modified` resource gets its code-hash invalidated (→ update,
|
|
28
|
+
* overwriting the out-of-band edit); a `deleted` one is dropped (→ create).
|
|
29
|
+
* `unchanged`/`unknown` are left as-is.
|
|
30
|
+
*/
|
|
31
|
+
export declare function reconcileDrift(state: State, drift: DriftEntry[]): State;
|
|
32
|
+
//# sourceMappingURL=refresh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../../../src/deploy/refresh.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAKtD,MAAM,MAAM,QAAQ,GAAG;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAKjE,MAAM,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAClE,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;AAE3D,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;AAE3E,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;CACrB,CAAC;AAEF,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQlD;AAMD;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,EAAE,CAAC,CA4BvB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,KAAK,CAavE"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Out-of-band drift detection. The deploy engine only compares code against the
|
|
2
|
+
// committed state, so a resource edited or deleted directly in the Cargo UI goes
|
|
3
|
+
// unnoticed. `refresh` re-reads each state-tracked resource through a per-kind
|
|
4
|
+
// LiveReader and compares a fingerprint of its live config against the one
|
|
5
|
+
// captured at the last apply (StateEntry.live) — surfacing changes the CDK
|
|
6
|
+
// didn't make.
|
|
7
|
+
import { createHash } from "node:crypto";
|
|
8
|
+
/** Hash an arbitrary projection of a resource into a comparable fingerprint. */
|
|
9
|
+
export function fingerprint(value) {
|
|
10
|
+
return ("fp:" +
|
|
11
|
+
createHash("sha256")
|
|
12
|
+
.update(JSON.stringify(value))
|
|
13
|
+
.digest("hex")
|
|
14
|
+
.slice(0, 16));
|
|
15
|
+
}
|
|
16
|
+
function kindOf(id) {
|
|
17
|
+
return id.slice(0, id.indexOf(":"));
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Read every state-tracked resource live and classify drift:
|
|
21
|
+
* - deleted — gone from the workspace (re-deploy would recreate it)
|
|
22
|
+
* - modified — its live fingerprint differs from the one captured at apply
|
|
23
|
+
* - unchanged — live matches the last apply
|
|
24
|
+
* - unknown — no baseline fingerprint, or the kind has no live reader
|
|
25
|
+
*/
|
|
26
|
+
export async function detectDrift(state, readers) {
|
|
27
|
+
const drift = [];
|
|
28
|
+
for (const [id, entry] of Object.entries(state.resources)) {
|
|
29
|
+
const kind = kindOf(id);
|
|
30
|
+
const reader = readers[kind];
|
|
31
|
+
// A read error (network, auth, unexpected) must NOT look like a deletion —
|
|
32
|
+
// record it as "unknown" so `deploy --refresh` never mass-recreates on a
|
|
33
|
+
// transient failure.
|
|
34
|
+
let live;
|
|
35
|
+
try {
|
|
36
|
+
live = reader === undefined ? { exists: true } : await reader(entry);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
drift.push({ id, kind, status: "unknown" });
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
let status;
|
|
43
|
+
if (!live.exists) {
|
|
44
|
+
status = "deleted";
|
|
45
|
+
}
|
|
46
|
+
else if (entry.live === undefined || live.fingerprint === undefined) {
|
|
47
|
+
status = "unknown";
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
status = live.fingerprint === entry.live ? "unchanged" : "modified";
|
|
51
|
+
}
|
|
52
|
+
drift.push({ id, kind, status });
|
|
53
|
+
}
|
|
54
|
+
return drift;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Return a copy of `state` adjusted so the next compile re-applies drifted
|
|
58
|
+
* resources: a `modified` resource gets its code-hash invalidated (→ update,
|
|
59
|
+
* overwriting the out-of-band edit); a `deleted` one is dropped (→ create).
|
|
60
|
+
* `unchanged`/`unknown` are left as-is.
|
|
61
|
+
*/
|
|
62
|
+
export function reconcileDrift(state, drift) {
|
|
63
|
+
const resources = { ...state.resources };
|
|
64
|
+
for (const entry of drift) {
|
|
65
|
+
if (entry.status === "deleted") {
|
|
66
|
+
delete resources[entry.id];
|
|
67
|
+
}
|
|
68
|
+
else if (entry.status === "modified") {
|
|
69
|
+
const prior = resources[entry.id];
|
|
70
|
+
if (prior !== undefined) {
|
|
71
|
+
resources[entry.id] = { ...prior, hash: "drifted" };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return { ...state, resources };
|
|
76
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { State } from "./compile.js";
|
|
2
|
+
/**
|
|
3
|
+
* Snapshot the current cargo.state.json to cargo.state.bak.json before a
|
|
4
|
+
* mutating command, so `cdk rollback` can restore the prior state. No-op when no
|
|
5
|
+
* state exists yet (first deploy). Returns whether a snapshot was taken.
|
|
6
|
+
*/
|
|
7
|
+
export declare function snapshotState(root: string): boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Restore the snapshot taken before the last mutating command. Returns whether a
|
|
10
|
+
* backup existed to restore.
|
|
11
|
+
*/
|
|
12
|
+
export declare function restoreSnapshot(root: string): boolean;
|
|
13
|
+
/** Read a repo's cargo.state.json, or undefined on the first deploy. */
|
|
14
|
+
export declare function readState(root: string): State | undefined;
|
|
15
|
+
/** Write cargo.state.json — pretty-printed + trailing newline (it's committed).
|
|
16
|
+
* Writes to a per-process temp file, fsyncs it, then atomically renames over the
|
|
17
|
+
* target and fsyncs the directory — so a crash or power loss mid-write can't
|
|
18
|
+
* truncate the committed state (which would orphan every uuid-only resource),
|
|
19
|
+
* and two concurrent writers can't clobber a shared temp file. */
|
|
20
|
+
export declare function writeState(root: string, state: State): void;
|
|
21
|
+
/** A fresh, empty state bound to a workspace (used on the first deploy). */
|
|
22
|
+
export declare function emptyState(workspaceUuid: string): State;
|
|
23
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/deploy/state.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAgB1C;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAKnD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAKrD;AAED,wEAAwE;AACxE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAIzD;AAED;;;;kEAIkE;AAClE,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAuB3D;AAkBD,4EAA4E;AAC5E,wBAAgB,UAAU,CAAC,aAAa,EAAE,MAAM,GAAG,KAAK,CAEvD"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// Deploy state — the committed `cargo.state.json`. It maps each code resource
|
|
2
|
+
// ("kind:slug") to the real uuid Cargo assigned it, plus that resource's outputs
|
|
3
|
+
// and the content hash of the spec that produced it.
|
|
4
|
+
//
|
|
5
|
+
// State is the authoritative link from code to deployed infra. For connector and
|
|
6
|
+
// model it is rebuildable (their slug is addressable via exists-by-slug + list);
|
|
7
|
+
// for play and agent — which have NO slug and non-unique names — the stored uuid
|
|
8
|
+
// is the ONLY way to re-find the resource, so a lost entry orphans it. The file
|
|
9
|
+
// is committed, so it is written pretty-printed for clean diffs, and it stores
|
|
10
|
+
// only uuids/hashes/outputs — never secret values.
|
|
11
|
+
import { randomBytes } from "node:crypto";
|
|
12
|
+
import { closeSync, copyFileSync, existsSync, fsyncSync, openSync, readFileSync, renameSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
13
|
+
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
14
|
+
const STATE_VERSION = 1;
|
|
15
|
+
const STATE_FILE = "cargo.state.json";
|
|
16
|
+
const BACKUP_FILE = "cargo.state.bak.json";
|
|
17
|
+
function statePath(root) {
|
|
18
|
+
const rootDir = isAbsolute(root) ? root : resolve(process.cwd(), root);
|
|
19
|
+
return join(rootDir, STATE_FILE);
|
|
20
|
+
}
|
|
21
|
+
function backupPath(root) {
|
|
22
|
+
const rootDir = isAbsolute(root) ? root : resolve(process.cwd(), root);
|
|
23
|
+
return join(rootDir, BACKUP_FILE);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Snapshot the current cargo.state.json to cargo.state.bak.json before a
|
|
27
|
+
* mutating command, so `cdk rollback` can restore the prior state. No-op when no
|
|
28
|
+
* state exists yet (first deploy). Returns whether a snapshot was taken.
|
|
29
|
+
*/
|
|
30
|
+
export function snapshotState(root) {
|
|
31
|
+
const path = statePath(root);
|
|
32
|
+
if (!existsSync(path))
|
|
33
|
+
return false;
|
|
34
|
+
copyFileSync(path, backupPath(root));
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Restore the snapshot taken before the last mutating command. Returns whether a
|
|
39
|
+
* backup existed to restore.
|
|
40
|
+
*/
|
|
41
|
+
export function restoreSnapshot(root) {
|
|
42
|
+
const backup = backupPath(root);
|
|
43
|
+
if (!existsSync(backup))
|
|
44
|
+
return false;
|
|
45
|
+
copyFileSync(backup, statePath(root));
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
/** Read a repo's cargo.state.json, or undefined on the first deploy. */
|
|
49
|
+
export function readState(root) {
|
|
50
|
+
const path = statePath(root);
|
|
51
|
+
if (!existsSync(path))
|
|
52
|
+
return undefined;
|
|
53
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
54
|
+
}
|
|
55
|
+
/** Write cargo.state.json — pretty-printed + trailing newline (it's committed).
|
|
56
|
+
* Writes to a per-process temp file, fsyncs it, then atomically renames over the
|
|
57
|
+
* target and fsyncs the directory — so a crash or power loss mid-write can't
|
|
58
|
+
* truncate the committed state (which would orphan every uuid-only resource),
|
|
59
|
+
* and two concurrent writers can't clobber a shared temp file. */
|
|
60
|
+
export function writeState(root, state) {
|
|
61
|
+
const path = statePath(root);
|
|
62
|
+
// Unique per process (+ random) so a racing writer never shares this temp.
|
|
63
|
+
const tmp = `${path}.${String(process.pid)}.${randomBytes(4).toString("hex")}.tmp`;
|
|
64
|
+
const data = `${JSON.stringify(state, null, 2)}\n`;
|
|
65
|
+
try {
|
|
66
|
+
const fd = openSync(tmp, "w");
|
|
67
|
+
try {
|
|
68
|
+
writeFileSync(fd, data);
|
|
69
|
+
fsyncSync(fd); // flush file data before the rename makes it visible
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
closeSync(fd);
|
|
73
|
+
}
|
|
74
|
+
renameSync(tmp, path);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
try {
|
|
78
|
+
unlinkSync(tmp);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// temp may not exist if openSync failed — nothing to clean up
|
|
82
|
+
}
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
fsyncDir(dirname(path)); // make the rename itself durable
|
|
86
|
+
}
|
|
87
|
+
// Best-effort directory fsync — durably commits the rename. Some platforms
|
|
88
|
+
// (notably Windows) don't permit fsync on a directory handle; there the data
|
|
89
|
+
// fsync + atomic rename already prevent a truncated/partial state file.
|
|
90
|
+
function fsyncDir(dir) {
|
|
91
|
+
try {
|
|
92
|
+
const fd = openSync(dir, "r");
|
|
93
|
+
try {
|
|
94
|
+
fsyncSync(fd);
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
closeSync(fd);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// directory fsync unsupported — acceptable
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/** A fresh, empty state bound to a workspace (used on the first deploy). */
|
|
105
|
+
export function emptyState(workspaceUuid) {
|
|
106
|
+
return { version: STATE_VERSION, workspaceUuid, resources: {} };
|
|
107
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type { ActionOptions, AgentHandle, AgentSpec, AgentUse, ConnectorActionSpec, ModelOptions, ModelUse, ToolUse, } from "./resources/agent.js";
|
|
2
|
+
export { defineAgent } from "./resources/agent.js";
|
|
3
|
+
export type { AppHandle, AppSpec } from "./resources/app.js";
|
|
4
|
+
export { defineApp } from "./resources/app.js";
|
|
5
|
+
export type { ConnectorConfigs, ConnectorHandle, ConnectorSpec, } from "./resources/connector.js";
|
|
6
|
+
export { defineConnector } from "./resources/connector.js";
|
|
7
|
+
export type { ContextHandle, ContextSpec } from "./resources/context.js";
|
|
8
|
+
export { defineContext } from "./resources/context.js";
|
|
9
|
+
export type { FileHandle, FileSpec } from "./resources/file.js";
|
|
10
|
+
export { defineFile } from "./resources/file.js";
|
|
11
|
+
export type { FolderHandle, FolderKind, FolderSpec, } from "./resources/folder.js";
|
|
12
|
+
export { defineFolder } from "./resources/folder.js";
|
|
13
|
+
export type { McpServerHandle, McpServerSpec } from "./resources/mcpServer.js";
|
|
14
|
+
export { defineMcpServer } from "./resources/mcpServer.js";
|
|
15
|
+
export type { ExtractorConfigs, ModelHandle, ModelSpec, } from "./resources/model.js";
|
|
16
|
+
export { defineModel } from "./resources/model.js";
|
|
17
|
+
export type { PlayHandle, PlaySpec } from "./resources/play.js";
|
|
18
|
+
export { definePlay } from "./resources/play.js";
|
|
19
|
+
export type { ToolHandle, ToolSpec, ToolTriggerSpec, WorkflowDefinition, } from "./resources/tool.js";
|
|
20
|
+
export { defineTool } from "./resources/tool.js";
|
|
21
|
+
export type { WorkerHandle, WorkerSpec } from "./resources/worker.js";
|
|
22
|
+
export { defineWorker } from "./resources/worker.js";
|
|
23
|
+
export { createWorker, OpenAPIRoute } from "@cargo-ai/worker-sdk";
|
|
24
|
+
export { agentRef, defineWorkflow, toolRef, type WorkflowResourceRef, } from "@cargo-ai/workflow-sdk";
|
|
25
|
+
export type { EncryptionRef, ResourceKind, ResourceNode, SecretRef, Token, } from "./core.js";
|
|
26
|
+
export { env, isSecret, isToken, resolveSecrets, secret, token, } from "./core.js";
|
|
27
|
+
export type { AgentRef, ConnectorRef, DatasetRef, FolderRef, ModelRef, PlayRef, ResourceRef, ToolRef, } from "./refs.js";
|
|
28
|
+
export { connectorRef, datasetRef, folderRef, modelRef, playRef, refUuid, } from "./refs.js";
|
|
29
|
+
export * from "./deploy/index.js";
|
|
30
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAUA,YAAY,EACV,aAAa,EACb,WAAW,EACX,SAAS,EACT,QAAQ,EACR,mBAAmB,EACnB,YAAY,EACZ,QAAQ,EACR,OAAO,GACR,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,YAAY,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,aAAa,GACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,YAAY,EACV,YAAY,EACZ,UAAU,EACV,UAAU,GACX,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,YAAY,EACV,gBAAgB,EAChB,WAAW,EACX,SAAS,GACV,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,YAAY,EACV,UAAU,EACV,QAAQ,EACR,eAAe,EACf,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAMlE,OAAO,EACL,QAAQ,EACR,cAAc,EACd,OAAO,EACP,KAAK,mBAAmB,GACzB,MAAM,wBAAwB,CAAC;AAGhC,YAAY,EACV,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,KAAK,GACN,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,GAAG,EACH,QAAQ,EACR,OAAO,EACP,cAAc,EACd,MAAM,EACN,KAAK,GACN,MAAM,WAAW,CAAC;AAGnB,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,SAAS,EACT,QAAQ,EACR,OAAO,EACP,WAAW,EACX,OAAO,GACR,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,YAAY,EACZ,UAAU,EACV,SAAS,EACT,QAAQ,EACR,OAAO,EACP,OAAO,GACR,MAAM,WAAW,CAAC;AAGnB,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// @cargo-ai/cdk
|
|
2
|
+
//
|
|
3
|
+
// The Cargo framework: one package, one import, to DEFINE every Cargo resource
|
|
4
|
+
// and to DEPLOY it. `define*` registers a resource and returns a handle whose
|
|
5
|
+
// outputs are deferred tokens; wire resources by passing handles (`defineModel(
|
|
6
|
+
// "c", { datasetUuid: connector.datasetUuid })`). `plan`/`apply`/`deploy`
|
|
7
|
+
// reconcile the graph. The heavier, independently-published workflow + worker
|
|
8
|
+
// SDKs are re-exported so they're reachable from the same import.
|
|
9
|
+
export { defineAgent } from "./resources/agent.js";
|
|
10
|
+
export { defineApp } from "./resources/app.js";
|
|
11
|
+
export { defineConnector } from "./resources/connector.js";
|
|
12
|
+
export { defineContext } from "./resources/context.js";
|
|
13
|
+
export { defineFile } from "./resources/file.js";
|
|
14
|
+
export { defineFolder } from "./resources/folder.js";
|
|
15
|
+
export { defineMcpServer } from "./resources/mcpServer.js";
|
|
16
|
+
export { defineModel } from "./resources/model.js";
|
|
17
|
+
export { definePlay } from "./resources/play.js";
|
|
18
|
+
export { defineTool } from "./resources/tool.js";
|
|
19
|
+
export { defineWorker } from "./resources/worker.js";
|
|
20
|
+
export { createWorker, OpenAPIRoute } from "@cargo-ai/worker-sdk";
|
|
21
|
+
// The workflow-authoring surface a CDK user needs, re-exported so `@cargo-ai/cdk`
|
|
22
|
+
// is the only import: `defineWorkflow` for tool/play bodies, and `toolRef` /
|
|
23
|
+
// `agentRef` (+ their `WorkflowResourceRef` type) to reference a tool or agent by
|
|
24
|
+
// literal uuid inside a body's `uses` map. The lower-level wire-format/codegen
|
|
25
|
+
// types stay in `@cargo-ai/workflow-sdk`.
|
|
26
|
+
export { agentRef, defineWorkflow, toolRef, } from "@cargo-ai/workflow-sdk";
|
|
27
|
+
export { env, isSecret, isToken, resolveSecrets, secret, token, } from "./core.js";
|
|
28
|
+
export { connectorRef, datasetRef, folderRef, modelRef, playRef, refUuid, } from "./refs.js";
|
|
29
|
+
// ── deployment: plan + apply ─────────────────────────────────────────────────
|
|
30
|
+
export * from "./deploy/index.js";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Token } from "./core.js";
|
|
2
|
+
export type ResourceKindRef = "connector" | "dataset" | "model" | "folder" | "play" | "tool" | "agent";
|
|
3
|
+
export type ResourceRef<K extends ResourceKindRef = ResourceKindRef> = {
|
|
4
|
+
readonly uuid: Token | string;
|
|
5
|
+
readonly resource: K;
|
|
6
|
+
};
|
|
7
|
+
export type ConnectorRef = ResourceRef<"connector">;
|
|
8
|
+
export type DatasetRef = ResourceRef<"dataset">;
|
|
9
|
+
export type ModelRef = ResourceRef<"model">;
|
|
10
|
+
export type FolderRef = ResourceRef<"folder">;
|
|
11
|
+
export type PlayRef = ResourceRef<"play">;
|
|
12
|
+
export type ToolRef = ResourceRef<"tool">;
|
|
13
|
+
export type AgentRef = ResourceRef<"agent">;
|
|
14
|
+
/** Reference a connector by uuid (e.g. an adopted OAuth connector). */
|
|
15
|
+
export declare const connectorRef: (uuid: string) => ConnectorRef;
|
|
16
|
+
/** Reference a connector's auto-created dataset by uuid, for `defineModel`. */
|
|
17
|
+
export declare const datasetRef: (uuid: string) => DatasetRef;
|
|
18
|
+
/** Reference a data model by uuid. */
|
|
19
|
+
export declare const modelRef: (uuid: string) => ModelRef;
|
|
20
|
+
/** Reference a folder by uuid. */
|
|
21
|
+
export declare const folderRef: (uuid: string) => FolderRef;
|
|
22
|
+
/** Reference a play by uuid (e.g. a `dependency` schedule's upstream play). */
|
|
23
|
+
export declare const playRef: (uuid: string) => PlayRef;
|
|
24
|
+
/** Extract the uuid from a handle or ref (both carry `uuid`). */
|
|
25
|
+
export declare const refUuid: (ref: {
|
|
26
|
+
uuid: Token | string;
|
|
27
|
+
}) => Token | string;
|
|
28
|
+
//# sourceMappingURL=refs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refs.d.ts","sourceRoot":"","sources":["../../src/refs.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAEvC,MAAM,MAAM,eAAe,GACvB,WAAW,GACX,SAAS,GACT,OAAO,GACP,QAAQ,GACR,MAAM,GACN,MAAM,GACN,OAAO,CAAC;AAEZ,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,eAAe,GAAG,eAAe,IAAI;IACrE,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;AACpD,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;AAChD,MAAM,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;AAC5C,MAAM,MAAM,SAAS,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;AAC9C,MAAM,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;AAC1C,MAAM,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;AAC1C,MAAM,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;AAE5C,uEAAuE;AACvE,eAAO,MAAM,YAAY,SAAU,MAAM,KAAG,YAG1C,CAAC;AACH,+EAA+E;AAC/E,eAAO,MAAM,UAAU,SAAU,MAAM,KAAG,UAGxC,CAAC;AACH,sCAAsC;AACtC,eAAO,MAAM,QAAQ,SAAU,MAAM,KAAG,QAGtC,CAAC;AACH,kCAAkC;AAClC,eAAO,MAAM,SAAS,SAAU,MAAM,KAAG,SAGvC,CAAC;AACH,+EAA+E;AAC/E,eAAO,MAAM,OAAO,SAAU,MAAM,KAAG,OAAuC,CAAC;AAK/E,iEAAiE;AACjE,eAAO,MAAM,OAAO,QAAS;IAAE,IAAI,EAAE,KAAK,GAAG,MAAM,CAAA;CAAE,KAAG,KAAK,GAAG,MACtD,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Resource references — how one resource points at another.
|
|
2
|
+
//
|
|
3
|
+
// Every `define*` handle carries `{ uuid, resource }`, and each `xxRef("uuid")`
|
|
4
|
+
// helper produces the same shape for a resource you didn't define in code (a
|
|
5
|
+
// literal uuid). Builders accept a handle OR a ref anywhere they reference
|
|
6
|
+
// another resource — mirroring `defineWorkflow`'s `uses`, so you never write
|
|
7
|
+
// `.uuid` at the call site. `resource` brands the kind, so a model can't be
|
|
8
|
+
// passed where a connector is expected.
|
|
9
|
+
/** Reference a connector by uuid (e.g. an adopted OAuth connector). */
|
|
10
|
+
export const connectorRef = (uuid) => ({
|
|
11
|
+
uuid,
|
|
12
|
+
resource: "connector",
|
|
13
|
+
});
|
|
14
|
+
/** Reference a connector's auto-created dataset by uuid, for `defineModel`. */
|
|
15
|
+
export const datasetRef = (uuid) => ({
|
|
16
|
+
uuid,
|
|
17
|
+
resource: "dataset",
|
|
18
|
+
});
|
|
19
|
+
/** Reference a data model by uuid. */
|
|
20
|
+
export const modelRef = (uuid) => ({
|
|
21
|
+
uuid,
|
|
22
|
+
resource: "model",
|
|
23
|
+
});
|
|
24
|
+
/** Reference a folder by uuid. */
|
|
25
|
+
export const folderRef = (uuid) => ({
|
|
26
|
+
uuid,
|
|
27
|
+
resource: "folder",
|
|
28
|
+
});
|
|
29
|
+
/** Reference a play by uuid (e.g. a `dependency` schedule's upstream play). */
|
|
30
|
+
export const playRef = (uuid) => ({ uuid, resource: "play" });
|
|
31
|
+
// `toolRef` / `agentRef` are re-exported from `@cargo-ai/workflow-sdk` — their
|
|
32
|
+
// `WorkflowResourceRef` is structurally a `ResourceRef<"tool" | "agent">`.
|
|
33
|
+
/** Extract the uuid from a handle or ref (both carry `uuid`). */
|
|
34
|
+
export const refUuid = (ref) => ref.uuid;
|