@cargo-ai/cli 1.0.71 → 1.0.73

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.
Files changed (34) hide show
  1. package/build/commands/auth/email.d.ts +24 -0
  2. package/build/commands/auth/email.d.ts.map +1 -1
  3. package/build/commands/auth/email.js +27 -14
  4. package/build/commands/auth/index.d.ts.map +1 -1
  5. package/build/commands/auth/index.js +7 -1
  6. package/build/commands/auth/workspace.d.ts.map +1 -1
  7. package/build/commands/auth/workspace.js +99 -26
  8. package/build/commands/connection/connector.d.ts.map +1 -1
  9. package/build/commands/connection/connector.js +144 -21
  10. package/build/commands/orchestration/action.d.ts.map +1 -1
  11. package/build/commands/orchestration/action.js +68 -3
  12. package/build/commands/orchestration/costTable.d.ts +121 -0
  13. package/build/commands/orchestration/costTable.d.ts.map +1 -0
  14. package/build/commands/orchestration/costTable.js +363 -0
  15. package/build/commands/start/brief.d.ts +107 -0
  16. package/build/commands/start/brief.d.ts.map +1 -0
  17. package/build/commands/start/brief.js +222 -0
  18. package/build/commands/start/index.d.ts +44 -0
  19. package/build/commands/start/index.d.ts.map +1 -0
  20. package/build/commands/start/index.js +431 -0
  21. package/build/commands/start/state.d.ts +50 -0
  22. package/build/commands/start/state.d.ts.map +1 -0
  23. package/build/commands/start/state.js +101 -0
  24. package/build/config.d.ts +1 -0
  25. package/build/config.d.ts.map +1 -1
  26. package/build/config.js +1 -0
  27. package/build/index.js +50 -6
  28. package/build/paletteLayout.d.ts +16 -0
  29. package/build/paletteLayout.d.ts.map +1 -0
  30. package/build/paletteLayout.js +131 -0
  31. package/build/setupIssues.d.ts +4 -16
  32. package/build/setupIssues.d.ts.map +1 -1
  33. package/build/setupIssues.js +3 -52
  34. package/package.json +3 -3
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Renders every credits-based action as a pricing table.
3
+ *
4
+ * The catalog is the only place pricing lives, and it moves — providers get
5
+ * added, actions get repriced, tiers get split. Anything that copies those
6
+ * numbers by hand goes stale silently, so the table is generated rather than
7
+ * maintained.
8
+ *
9
+ * Sourced from `orchestration action list` (without a limit), which spans
10
+ * connector and native actions in a single call. Natives are a small set but
11
+ * not a free one — `sendEmail` is 0.1, `modelAsk` 0.5, `fileSearch` 0.02/1k
12
+ * tokens — and a table built from connectors alone silently omits them while
13
+ * claiming to be complete.
14
+ */
15
+ /**
16
+ * Shape returned by `orchestration action list` for each matching action.
17
+ */
18
+ export type ListActionMatch = {
19
+ name: string;
20
+ description?: string;
21
+ score: number;
22
+ action: {
23
+ kind: string;
24
+ integrationSlug?: string;
25
+ actionSlug?: string;
26
+ };
27
+ integrationName?: string;
28
+ category?: string;
29
+ credits?: CreditsCost[];
30
+ };
31
+ export type CreditsCost = {
32
+ type?: string;
33
+ cost?: number;
34
+ unit?: string;
35
+ unitsCount?: number;
36
+ fixedCost?: number;
37
+ config?: {
38
+ jsonSchema?: JsonSchema;
39
+ };
40
+ };
41
+ type JsonSchema = {
42
+ type?: string;
43
+ const?: unknown;
44
+ enum?: unknown[];
45
+ minItems?: number;
46
+ maxItems?: number;
47
+ properties?: Record<string, JsonSchema>;
48
+ required?: string[];
49
+ };
50
+ export type CatalogAction = {
51
+ name?: string;
52
+ description?: string;
53
+ credits?: {
54
+ costs?: CreditsCost[];
55
+ };
56
+ };
57
+ export type CatalogIntegration = {
58
+ slug: string;
59
+ name: string;
60
+ category?: string;
61
+ actions?: Record<string, CatalogAction>;
62
+ };
63
+ export type CostVariant = {
64
+ /** Config that selects this price, e.g. `model=gpt-5-nano`. */
65
+ when: string;
66
+ /** Rendered price, e.g. `0.4 + 0.006 / 1k token`. */
67
+ price: string;
68
+ };
69
+ export type CostRow = {
70
+ integrationSlug: string;
71
+ integrationName: string;
72
+ category: string | undefined;
73
+ actionSlug: string;
74
+ name: string | undefined;
75
+ description: string | undefined;
76
+ /** Cheapest and dearest per-unit price, in credits. */
77
+ minCost: number;
78
+ maxCost: number;
79
+ /**
80
+ * What one call at the cheapest config costs — per-unit price plus any flat
81
+ * component. The sort key, so a cheap-looking per-item rate with a base
82
+ * charge doesn't outrank a genuinely cheaper flat action.
83
+ */
84
+ sortCost: number;
85
+ /** Single price, or `min–max` when config picks between several. */
86
+ price: string;
87
+ /** Config fields that move the price; empty when there is only one. */
88
+ variesBy: string[];
89
+ variants: CostVariant[];
90
+ };
91
+ export type CostTableSummary = {
92
+ integrations: number;
93
+ integrationsWithActions: number;
94
+ actions: number;
95
+ creditsBasedActions: number;
96
+ freeActions: number;
97
+ };
98
+ /**
99
+ * Natives have no integration of their own. `native` cannot collide with a real
100
+ * integration slug, and it is what `kind` an action object needs to run one:
101
+ * `{"kind":"native","actionSlug":"sendEmail"}`.
102
+ */
103
+ export declare const NATIVE_PROVIDER_SLUG = "native";
104
+ export declare function asNativeCatalogIntegration(actions: Record<string, CatalogAction> | undefined): CatalogIntegration;
105
+ /**
106
+ * Groups the flat action list returned by `orchestration action list` into the
107
+ * integration-grouped shape that `buildCostRows` and `summarize` expect.
108
+ */
109
+ export declare function groupActionsByIntegration(actions: ListActionMatch[]): CatalogIntegration[];
110
+ export declare function buildCostRows(integrations: CatalogIntegration[]): CostRow[];
111
+ export declare function summarize(integrations: CatalogIntegration[]): CostTableSummary;
112
+ export type RenderCostTableOptions = {
113
+ generatedAt: string;
114
+ filter?: {
115
+ category?: string;
116
+ integration?: string;
117
+ };
118
+ };
119
+ export declare function renderCostTable(rows: CostRow[], summary: CostTableSummary, opts: RenderCostTableOptions): string;
120
+ export {};
121
+ //# sourceMappingURL=costTable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"costTable.d.ts","sourceRoot":"","sources":["../../../src/commands/orchestration/costTable.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,363 @@
1
+ /**
2
+ * Renders every credits-based action as a pricing table.
3
+ *
4
+ * The catalog is the only place pricing lives, and it moves — providers get
5
+ * added, actions get repriced, tiers get split. Anything that copies those
6
+ * numbers by hand goes stale silently, so the table is generated rather than
7
+ * maintained.
8
+ *
9
+ * Sourced from `orchestration action list` (without a limit), which spans
10
+ * connector and native actions in a single call. Natives are a small set but
11
+ * not a free one — `sendEmail` is 0.1, `modelAsk` 0.5, `fileSearch` 0.02/1k
12
+ * tokens — and a table built from connectors alone silently omits them while
13
+ * claiming to be complete.
14
+ */
15
+ const DESCRIPTION_MAX_LENGTH = 120;
16
+ /**
17
+ * Natives have no integration of their own. `native` cannot collide with a real
18
+ * integration slug, and it is what `kind` an action object needs to run one:
19
+ * `{"kind":"native","actionSlug":"sendEmail"}`.
20
+ */
21
+ export const NATIVE_PROVIDER_SLUG = "native";
22
+ export function asNativeCatalogIntegration(actions) {
23
+ return {
24
+ slug: NATIVE_PROVIDER_SLUG,
25
+ name: "Cargo native",
26
+ category: "platform",
27
+ actions: actions ?? {},
28
+ };
29
+ }
30
+ /**
31
+ * Groups the flat action list returned by `orchestration action list` into the
32
+ * integration-grouped shape that `buildCostRows` and `summarize` expect.
33
+ */
34
+ export function groupActionsByIntegration(actions) {
35
+ const integrationMap = new Map();
36
+ for (const match of actions) {
37
+ const actionKind = match.action.kind;
38
+ const actionSlug = match.action.actionSlug;
39
+ if (actionSlug === undefined) {
40
+ continue;
41
+ }
42
+ let slug;
43
+ let name;
44
+ let category;
45
+ if (actionKind === "native") {
46
+ slug = NATIVE_PROVIDER_SLUG;
47
+ name = "Cargo native";
48
+ category = "platform";
49
+ }
50
+ else if (actionKind === "connector") {
51
+ slug =
52
+ match.action.integrationSlug !== undefined
53
+ ? match.action.integrationSlug
54
+ : "";
55
+ name = match.integrationName !== undefined ? match.integrationName : slug;
56
+ category = match.category;
57
+ }
58
+ else {
59
+ continue;
60
+ }
61
+ let integration = integrationMap.get(slug);
62
+ if (integration === undefined) {
63
+ integration = { slug, name, category, actions: {} };
64
+ integrationMap.set(slug, integration);
65
+ }
66
+ if (integration.actions === undefined) {
67
+ integration.actions = {};
68
+ }
69
+ integration.actions[actionSlug] = {
70
+ name: match.name,
71
+ description: match.description,
72
+ credits: match.credits !== undefined ? { costs: match.credits } : undefined,
73
+ };
74
+ }
75
+ return Array.from(integrationMap.values());
76
+ }
77
+ export function buildCostRows(integrations) {
78
+ const rows = [];
79
+ for (const integration of integrations) {
80
+ for (const [actionSlug, action] of Object.entries(integration.actions ?? {})) {
81
+ const costs = action.credits?.costs;
82
+ const [first] = costs ?? [];
83
+ if (costs === undefined || first === undefined) {
84
+ continue;
85
+ }
86
+ const amounts = costs.map((cost) => cost.cost ?? 0);
87
+ const effective = costs.map((cost) => (cost.cost ?? 0) + (cost.fixedCost ?? 0));
88
+ const variants = costs.map((cost) => ({
89
+ when: describeSelector(cost.config?.jsonSchema),
90
+ price: renderPrice(cost),
91
+ }));
92
+ const minCost = Math.min(...amounts);
93
+ const maxCost = Math.max(...amounts);
94
+ rows.push({
95
+ integrationSlug: integration.slug,
96
+ integrationName: integration.name,
97
+ category: integration.category,
98
+ actionSlug,
99
+ name: action.name,
100
+ description: truncate(action.description),
101
+ minCost,
102
+ maxCost,
103
+ sortCost: Math.min(...effective),
104
+ price: costs.length === 1
105
+ ? renderPrice(first)
106
+ : renderRange(costs, minCost, maxCost),
107
+ variesBy: costs.length === 1 ? [] : selectorFields(costs),
108
+ variants: costs.length === 1 ? [] : variants,
109
+ });
110
+ }
111
+ }
112
+ return rows.sort((a, b) => a.sortCost - b.sortCost ||
113
+ a.maxCost - b.maxCost ||
114
+ a.integrationSlug.localeCompare(b.integrationSlug) ||
115
+ a.actionSlug.localeCompare(b.actionSlug));
116
+ }
117
+ export function summarize(integrations) {
118
+ let actions = 0;
119
+ let creditsBasedActions = 0;
120
+ let integrationsWithActions = 0;
121
+ for (const integration of integrations) {
122
+ const entries = Object.values(integration.actions ?? {});
123
+ // The native pseudo-integration is a carrier for platform actions, not a
124
+ // 139th integration. Its actions count; it does not.
125
+ const isNative = integration.slug === NATIVE_PROVIDER_SLUG;
126
+ if (entries.length > 0 && isNative === false) {
127
+ integrationsWithActions += 1;
128
+ }
129
+ actions += entries.length;
130
+ for (const action of entries) {
131
+ if ((action.credits?.costs ?? []).length > 0) {
132
+ creditsBasedActions += 1;
133
+ }
134
+ }
135
+ }
136
+ return {
137
+ integrations: integrations.filter((integration) => {
138
+ return integration.slug !== NATIVE_PROVIDER_SLUG;
139
+ }).length,
140
+ integrationsWithActions,
141
+ actions,
142
+ creditsBasedActions,
143
+ freeActions: actions - creditsBasedActions,
144
+ };
145
+ }
146
+ export function renderCostTable(rows, summary, opts) {
147
+ const lines = [];
148
+ const filter = opts.filter;
149
+ const isFiltered = filter !== undefined &&
150
+ (filter.category !== undefined || filter.integration !== undefined);
151
+ lines.push("# Credits cost table");
152
+ lines.push("");
153
+ if (isFiltered) {
154
+ const filterDesc = filter.category !== undefined && filter.integration !== undefined
155
+ ? `category \`${filter.category}\` and integration \`${filter.integration}\``
156
+ : filter.category !== undefined
157
+ ? `category \`${filter.category}\``
158
+ : `integration \`${filter.integration}\``;
159
+ lines.push(`Filtered by ${filterDesc}: ${String(summary.creditsBasedActions)} credits-based actions ` +
160
+ `out of ${String(summary.actions)} total across ${String(summary.integrationsWithActions)} of ` +
161
+ `${String(summary.integrations)} integrations, sorted by cost. ` +
162
+ `The other ${String(summary.freeActions)} actions in this subset cost no credits. ` +
163
+ "Run without filters for the full catalog, including Cargo's native actions.");
164
+ }
165
+ else {
166
+ lines.push(`Every credits-based action Cargo can run — ${String(summary.creditsBasedActions)} of the ` +
167
+ `${String(summary.actions)} actions exposed by ${String(summary.integrationsWithActions)} of the catalog's ` +
168
+ `${String(summary.integrations)} integrations, plus Cargo's own native actions — sorted by cost. The other ${String(summary.freeActions)} actions ` +
169
+ "(CRM writes, sequencer pushes, Slack sends, …) cost no credits; list them with " +
170
+ "`cargo-ai connection integration get <slug>`.");
171
+ }
172
+ lines.push("");
173
+ if (isFiltered === false) {
174
+ lines.push("Rows whose provider is `native` are Cargo's own platform actions, run as " +
175
+ '`{"kind":"native","actionSlug":"<action>"}` with no integration; every other row ' +
176
+ 'runs as `{"kind":"connector","integrationSlug":"<provider>","actionSlug":"<action>"}`.');
177
+ lines.push("");
178
+ }
179
+ lines.push("**Auto-generated. Do not edit by hand** — regenerate with " +
180
+ "`cargo-ai orchestration action cost-table --raw > cargo-gtm/references/credits-cost-table.md`.");
181
+ lines.push("");
182
+ lines.push(`Generated: ${opts.generatedAt}`);
183
+ lines.push("");
184
+ lines.push("| Cost | Provider | Category | Action | Description |");
185
+ lines.push("|---|---|---|---|---|");
186
+ for (const row of rows) {
187
+ lines.push(`| ${row.price} | \`${row.integrationSlug}\` | ${row.category ?? "—"} | ` +
188
+ `\`${row.actionSlug}\` | ${escapeCell(row.description ?? "")} |`);
189
+ }
190
+ const variable = rows.filter((row) => row.variants.length > 0);
191
+ if (variable.length > 0) {
192
+ lines.push("");
193
+ lines.push("## Actions whose price depends on config");
194
+ lines.push("");
195
+ lines.push("These bill differently depending on how the node is configured, so the range above is not a quote. " +
196
+ "Pick the row that matches the config you are about to run.");
197
+ lines.push("");
198
+ for (const row of variable) {
199
+ lines.push(`### \`${row.integrationSlug}.${row.actionSlug}\` — varies by ${row.variesBy
200
+ .map((field) => `\`${field}\``)
201
+ .join(", ")}`);
202
+ lines.push("");
203
+ lines.push("| Config | Cost |");
204
+ lines.push("|---|---|");
205
+ for (const variant of dedupeVariants(row.variants)) {
206
+ lines.push(`| ${escapeCell(variant.when)} | ${variant.price} |`);
207
+ }
208
+ lines.push("");
209
+ }
210
+ }
211
+ return `${lines.join("\n").trimEnd()}\n`;
212
+ }
213
+ /**
214
+ * One cost entry as a price expression.
215
+ *
216
+ * `fixed` bills per call, `unit` bills per unit consumed, and `package` bills
217
+ * per block of units on top of a flat call cost — an LLM step that charges a
218
+ * base plus a rate per 1k tokens is the common case.
219
+ */
220
+ function renderPrice(cost) {
221
+ const amount = formatAmount(cost.cost ?? 0);
222
+ if (cost.type === "unit") {
223
+ const metered = cost.unit === undefined ? amount : `${amount} / ${cost.unit}`;
224
+ // A per-item rate can sit on top of a flat charge per call — dropping that
225
+ // base is how a 0.175 + 0.025/item search gets quoted as 0.025.
226
+ return cost.fixedCost === undefined || cost.fixedCost === 0
227
+ ? metered
228
+ : `${formatAmount(cost.fixedCost)} + ${metered}`;
229
+ }
230
+ if (cost.type === "package") {
231
+ const block = formatUnits(cost.unitsCount, cost.unit);
232
+ const metered = block === undefined ? amount : `${amount} / ${block}`;
233
+ return cost.fixedCost === undefined || cost.fixedCost === 0
234
+ ? metered
235
+ : `${formatAmount(cost.fixedCost)} + ${metered}`;
236
+ }
237
+ return amount;
238
+ }
239
+ function renderRange(costs, minCost, maxCost) {
240
+ const range = minCost === maxCost
241
+ ? formatAmount(minCost)
242
+ : `${formatAmount(minCost)}–${formatAmount(maxCost)}`;
243
+ const first = costs[0];
244
+ const unit = first !== undefined ? first.unit : undefined;
245
+ const unitsCount = first !== undefined ? first.unitsCount : undefined;
246
+ const packageBlock = formatUnits(unitsCount, unit);
247
+ const metered = costs.some((cost) => cost.type === "package")
248
+ ? packageBlock !== undefined
249
+ ? `${range} / ${packageBlock}`
250
+ : range
251
+ : costs.every((cost) => cost.type === "unit") && unit !== undefined
252
+ ? `${range} / ${unit}`
253
+ : range;
254
+ const hasBase = costs.some((cost) => cost.fixedCost !== undefined && cost.fixedCost !== 0);
255
+ return hasBase ? `${metered} + base` : metered;
256
+ }
257
+ /**
258
+ * The config fields a cost entry keys off, as dotted paths — the answer to
259
+ * "what do I change to land on a different price".
260
+ */
261
+ function selectorPaths(schema, prefix = "") {
262
+ if (schema?.properties === undefined) {
263
+ return [];
264
+ }
265
+ const paths = [];
266
+ for (const [key, property] of Object.entries(schema.properties)) {
267
+ const path = prefix === "" ? key : `${prefix}.${key}`;
268
+ const nested = selectorPaths(property, path);
269
+ if (nested.length > 0) {
270
+ paths.push(...nested);
271
+ }
272
+ else {
273
+ paths.push(path);
274
+ }
275
+ }
276
+ return paths;
277
+ }
278
+ function selectorFields(costs) {
279
+ const fields = new Set();
280
+ for (const cost of costs) {
281
+ for (const path of selectorPaths(cost.config?.jsonSchema)) {
282
+ fields.add(path);
283
+ }
284
+ }
285
+ return [...fields];
286
+ }
287
+ /** A cost entry's selector as `field=value` pairs, e.g. `model=gpt-5-nano`. */
288
+ function describeSelector(schema) {
289
+ const pairs = selectorPairs(schema);
290
+ return pairs.length === 0 ? "any config" : pairs.join(", ");
291
+ }
292
+ function selectorPairs(schema, prefix = "") {
293
+ if (schema?.properties === undefined) {
294
+ return [];
295
+ }
296
+ const pairs = [];
297
+ for (const [key, property] of Object.entries(schema.properties)) {
298
+ const path = prefix === "" ? key : `${prefix}.${key}`;
299
+ const nested = selectorPairs(property, path);
300
+ if (nested.length > 0) {
301
+ pairs.push(...nested);
302
+ continue;
303
+ }
304
+ pairs.push(`${path}${describeConstraint(property)}`);
305
+ }
306
+ return pairs;
307
+ }
308
+ function describeConstraint(schema) {
309
+ if (schema.const !== undefined) {
310
+ return `=${String(schema.const)}`;
311
+ }
312
+ if (schema.enum !== undefined) {
313
+ return `∈ ${schema.enum.map((value) => String(value)).join("|")}`;
314
+ }
315
+ if (schema.maxItems === 0) {
316
+ return " empty";
317
+ }
318
+ if (schema.minItems !== undefined && schema.minItems > 0) {
319
+ return " set";
320
+ }
321
+ return " (any)";
322
+ }
323
+ /**
324
+ * Catalogs sometimes carry the same price twice under selectors that differ
325
+ * only in a field the reader cannot act on; collapsing them keeps the variant
326
+ * table readable.
327
+ */
328
+ function dedupeVariants(variants) {
329
+ const seen = new Set();
330
+ const kept = [];
331
+ for (const variant of variants) {
332
+ const key = `${variant.when}|${variant.price}`;
333
+ if (seen.has(key) === true) {
334
+ continue;
335
+ }
336
+ seen.add(key);
337
+ kept.push(variant);
338
+ }
339
+ return kept;
340
+ }
341
+ function formatUnits(unitsCount, unit) {
342
+ if (unit === undefined) {
343
+ return undefined;
344
+ }
345
+ if (unitsCount === undefined || unitsCount === 1) {
346
+ return unit;
347
+ }
348
+ return unitsCount % 1000 === 0
349
+ ? `${String(unitsCount / 1000)}k ${unit}`
350
+ : `${String(unitsCount)} ${unit}`;
351
+ }
352
+ function formatAmount(value) {
353
+ return String(Number(value.toFixed(6)));
354
+ }
355
+ function truncate(value) {
356
+ if (value === undefined || value.length <= DESCRIPTION_MAX_LENGTH) {
357
+ return value;
358
+ }
359
+ return `${value.slice(0, DESCRIPTION_MAX_LENGTH).trimEnd()}…`;
360
+ }
361
+ function escapeCell(value) {
362
+ return value.replace(/\r?\n/g, " ").replace(/\|/g, "\\|");
363
+ }
@@ -0,0 +1,107 @@
1
+ import { CDK_SKILL, type CodingAgent } from "@cargo-ai/cdk/cli";
2
+ /**
3
+ * Where the agent is being opened, which decides what it is told to do.
4
+ *
5
+ * Three cases, because the right first move is different in each: outside a
6
+ * project there is nothing to read and the work starts with a conversation;
7
+ * inside a CDK repo the workspace is already declared in files worth reading
8
+ * before touching; and inside one carrying a cookbook, that cookbook's own
9
+ * procedure is the authority and re-deriving intent is the wrong move.
10
+ *
11
+ * Naming the same skill in all three, which is what this used to do, sent an
12
+ * agent into a repo full of answers and told it to start asking questions.
13
+ */
14
+ export type ProjectContext = {
15
+ kind: "none";
16
+ } | {
17
+ kind: "cdk";
18
+ root: string;
19
+ companyContextPath: string | undefined;
20
+ } | {
21
+ kind: "cookbook";
22
+ root: string;
23
+ companyContextPath: string | undefined;
24
+ cookbooks: readonly string[];
25
+ };
26
+ export type StartFacts = {
27
+ workspace: {
28
+ uuid: string;
29
+ name: string;
30
+ };
31
+ /** Whether the Cargo skills bundle is already installed for a coding agent. */
32
+ skillsInstalled: boolean;
33
+ };
34
+ /**
35
+ * The command group "Explore in the CLI" opens the palette on. The action
36
+ * catalog is the shortest path from a menu to something real: search one, run
37
+ * one, see a result.
38
+ */
39
+ export declare const EXPLORE_PATH: readonly string[];
40
+ /**
41
+ * The skill a handoff loads before the agent's first turn. `cargo` routes; the
42
+ * other two own their task outright.
43
+ *
44
+ * This type is the one place the whole story lives, because everything about
45
+ * the handoff depends on getting it right, and it has been got wrong twice.
46
+ *
47
+ * A skill reaches the agent by two paths at once: the launch passes it as a
48
+ * `/<skill>` command, which only Claude Code expands, and the brief names it in
49
+ * prose, which is all every other agent has. So the two must agree. The first
50
+ * version of the demo brief described its *outcome* instead of naming a skill
51
+ * and let the router choose; the router picked `cargo-gtm`, the general
52
+ * sourcing surface, and the agent spent four of its eight minutes rediscovering
53
+ * action names and dumping integration JSON to find a config schema. The
54
+ * second version named `cargo-quickstart` in the launch but left the brief
55
+ * saying "load `cargo`", which put every non-Claude agent back through the
56
+ * router and made the demo ask for two different skills in two steps.
57
+ *
58
+ * Hence a union rather than `string`: a mistyped or mismatched skill name is
59
+ * not something the CLI can notice at runtime, and the symptom is slow rather
60
+ * than broken, which is the kind of bug that survives.
61
+ */
62
+ export type HandoffSkill = "cargo" | typeof CDK_SKILL | "cargo-quickstart";
63
+ export declare const ROUTER_SKILL: HandoffSkill;
64
+ export declare const DEMO_SKILL: HandoffSkill;
65
+ export { CDK_SKILL };
66
+ export type Destination = {
67
+ kind: "agent";
68
+ agent: CodingAgent;
69
+ } | {
70
+ kind: "code";
71
+ } | {
72
+ kind: "cli";
73
+ } | {
74
+ kind: "demo";
75
+ } | {
76
+ kind: "none";
77
+ };
78
+ /**
79
+ * `--continue <where>` as a destination. Agents are named the way a person
80
+ * refers to them ("cursor"), not the way they are installed ("cursor-agent"),
81
+ * and one that is not on this machine is a usage error rather than a silent
82
+ * fallback to something else.
83
+ */
84
+ export declare function parseDestination(value: string, agents: readonly CodingAgent[]): Destination | undefined;
85
+ /**
86
+ * The brief a coding agent is opened with. An agent launched in a bare
87
+ * directory has to rediscover the workspace, the skills and the cost rules;
88
+ * this is the whole reason the handoff beats telling someone to open Claude
89
+ * Code themselves.
90
+ *
91
+ * What it says depends on `project` — see `ProjectContext` for why all three
92
+ * cases need different words rather than one brief and a different skill name.
93
+ */
94
+ export declare function buildBrief(facts: StartFacts, skill: HandoffSkill, project?: ProjectContext): string;
95
+ /**
96
+ * The brief behind the guided demo.
97
+ *
98
+ * It names `cargo-quickstart` rather than describing the demo, because that
99
+ * skill *is* this demo — a persona, ~25 leads, a cost receipt, then saving the
100
+ * pull as a play. Describing the outcome instead is what cost the first version
101
+ * half its runtime (see `HandoffSkill`), so this brief spends its length on
102
+ * pointing at the procedure and forbidding the detour.
103
+ */
104
+ export declare function buildDemoBrief(facts: StartFacts, icp: string | undefined): string;
105
+ /** The block printed when nobody wanted a handoff. */
106
+ export declare function formatStartNextSteps(facts: StartFacts): string;
107
+ //# sourceMappingURL=brief.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brief.d.ts","sourceRoot":"","sources":["../../../src/commands/start/brief.ts"],"names":[],"mappings":"AAMA,OAAO,EAEL,SAAS,EACT,KAAK,WAAW,EAEjB,MAAM,mBAAmB,CAAC;AAE3B;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACrE;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B,CAAC;AAEN,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,+EAA+E;IAC/E,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,MAAM,EAAgC,CAAC;AAE3E;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,OAAO,SAAS,GAAG,kBAAkB,CAAC;AAE3E,eAAO,MAAM,YAAY,EAAE,YAAsB,CAAC;AAClD,eAAO,MAAM,UAAU,EAAE,YAAiC,CAAC;AAE3D,OAAO,EAAE,SAAS,EAAE,CAAC;AAErB,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,GACf;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErB;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,SAAS,WAAW,EAAE,GAC7B,WAAW,GAAG,SAAS,CA8BzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE,cAAiC,GACzC,MAAM,CAaR;AAyED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,MAAM,GAAG,SAAS,GACtB,MAAM,CA+BR;AAED,sDAAsD;AACtD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAgB9D"}