@trydreamstate/cli 1.3.6 → 1.3.8

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 (76) hide show
  1. package/README.md +1 -1
  2. package/agent-plugin/.claude-plugin/plugin.json +1 -1
  3. package/agent-plugin/.codex-plugin/plugin.json +1 -1
  4. package/agent-plugin/skills/crm/SKILL.md +2 -2
  5. package/agent-plugin/skills/diagnostics/SKILL.md +1 -1
  6. package/agent-plugin/skills/dreamstate/SKILL.md +4 -4
  7. package/agent-plugin/skills/facebook-posts/SKILL.md +46 -0
  8. package/agent-plugin/skills/first-win/SKILL.md +6 -6
  9. package/agent-plugin/skills/inbox-replies/SKILL.md +1 -1
  10. package/agent-plugin/skills/instagram-posts/SKILL.md +56 -0
  11. package/agent-plugin/skills/knowledge/SKILL.md +1 -1
  12. package/agent-plugin/skills/linkedin-posts/SKILL.md +1 -1
  13. package/agent-plugin/skills/linkedin-warm-signals/SKILL.md +1 -1
  14. package/agent-plugin/skills/list-building/SKILL.md +5 -2
  15. package/agent-plugin/skills/list-building/column-authoring.md +4 -0
  16. package/agent-plugin/skills/list-building/incoming-people.md +32 -0
  17. package/agent-plugin/skills/list-building/sourcing.md +8 -1
  18. package/agent-plugin/skills/outreach/SKILL.md +2 -1
  19. package/agent-plugin/skills/outreach/channels.md +3 -1
  20. package/agent-plugin/skills/outreach/enrollment.md +2 -0
  21. package/agent-plugin/skills/outreach/replies.md +2 -0
  22. package/agent-plugin/skills/outreach/steps-and-timing.md +5 -1
  23. package/agent-plugin/skills/plays/SKILL.md +1 -1
  24. package/agent-plugin/skills/reddit-posts/SKILL.md +1 -1
  25. package/agent-plugin/skills/skill-authoring/SKILL.md +6 -6
  26. package/agent-plugin/skills/social/SKILL.md +5 -1
  27. package/agent-plugin/skills/tiktok-posts/SKILL.md +51 -0
  28. package/agent-plugin/skills/visibility/SKILL.md +5 -1
  29. package/agent-plugin/skills/workflows/SKILL.md +3 -1
  30. package/agent-plugin/skills/workflows/lifecycle-and-enrollment.md +2 -0
  31. package/agent-plugin/skills/worksheet-tidy/SKILL.md +2 -2
  32. package/agent-plugin/skills/writing/SKILL.md +1 -1
  33. package/agent-plugin/skills/writing/publishing.md +1 -1
  34. package/agent-plugin/skills/writing/revision-and-voice.md +1 -1
  35. package/agent-plugin/skills/x-posts/SKILL.md +1 -1
  36. package/agent-plugin/skills/youtube-posts/SKILL.md +49 -0
  37. package/dist/agentGuidance.generated.json +4 -4
  38. package/dist/client.d.ts +6 -1
  39. package/dist/client.d.ts.map +1 -1
  40. package/dist/client.js +35 -11
  41. package/dist/commandTable.d.ts +2 -2
  42. package/dist/commandTable.d.ts.map +1 -1
  43. package/dist/commandTable.js +5 -2
  44. package/dist/commands/genericPack.d.ts +13 -0
  45. package/dist/commands/genericPack.d.ts.map +1 -0
  46. package/dist/commands/genericPack.js +31 -0
  47. package/dist/commands/knowledge.d.ts +2 -0
  48. package/dist/commands/knowledge.d.ts.map +1 -0
  49. package/dist/commands/knowledge.js +6 -0
  50. package/dist/commands/shared.d.ts +3 -1
  51. package/dist/commands/shared.d.ts.map +1 -1
  52. package/dist/commands/shared.js +14 -5
  53. package/dist/commands/tables.d.ts +2 -0
  54. package/dist/commands/tables.d.ts.map +1 -0
  55. package/dist/commands/tables.js +6 -0
  56. package/dist/commands/unibox.d.ts +2 -0
  57. package/dist/commands/unibox.d.ts.map +1 -0
  58. package/dist/commands/unibox.js +6 -0
  59. package/dist/gatedRun.d.ts.map +1 -1
  60. package/dist/gatedRun.js +145 -54
  61. package/dist/generated/packVerbs.generated.json +332 -4
  62. package/dist/index.d.ts +2 -1
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +31 -3
  65. package/dist/money.d.ts +2 -1
  66. package/dist/money.d.ts.map +1 -1
  67. package/dist/money.js +22 -5
  68. package/dist/runWait.d.ts +1 -1
  69. package/dist/runWait.d.ts.map +1 -1
  70. package/dist/runWait.js +37 -5
  71. package/dist/tablesImport.d.ts.map +1 -1
  72. package/dist/tablesImport.js +15 -1
  73. package/dist/turnCache.d.ts +5 -1
  74. package/dist/turnCache.d.ts.map +1 -1
  75. package/dist/turnCache.js +5 -3
  76. package/package.json +3 -2
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.runKnowledgeCommand = exports.parseKnowledgeCommand = exports.KNOWLEDGE_USAGE = exports.KNOWLEDGE_VERBS = void 0;
5
+ const genericPack_1 = require("./genericPack");
6
+ _a = (0, genericPack_1.packSurface)('knowledge'), exports.KNOWLEDGE_VERBS = _a.verbs, exports.KNOWLEDGE_USAGE = _a.usage, exports.parseKnowledgeCommand = _a.parse, exports.runKnowledgeCommand = _a.run;
@@ -1,5 +1,7 @@
1
1
  import { type CliCommand } from '../index';
2
2
  import { type GatedRunContext } from '../gatedRun';
3
+ /** First-class CLI pack groups. sequences and workflows also carry the shared authoring kind. */
4
+ export type PackName = 'sequences' | 'workflows' | 'knowledge' | 'unibox' | 'tables';
3
5
  export interface PackVerbSpec {
4
6
  verb: string;
5
7
  capabilityId: string;
@@ -18,7 +20,7 @@ export interface PackVerbSpec {
18
20
  /** Local-only route; `init` accepts --name and --file without an API schema. */
19
21
  local?: 'init';
20
22
  }
21
- export declare function buildPackParser(pack: 'sequences' | 'workflows', kind: 'sequence' | 'workflow', specs: PackVerbSpec[], usage: string): (argv: string[]) => CliCommand;
23
+ export declare function buildPackParser(pack: PackName, kind: 'sequence' | 'workflow' | undefined, specs: PackVerbSpec[], usage: string): (argv: string[]) => CliCommand;
22
24
  /**
23
25
  * A starter document written to disk, so authoring can begin from a file the way the
24
26
  * rest of this pack now accepts one. It writes nothing to the workspace and calls no
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/commands/shared.ts"],"names":[],"mappings":"AAKA,OAAO,EAAc,KAAK,UAAU,EAAiC,MAAM,UAAU,CAAC;AAEtF,OAAO,EAA4B,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAS7E,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IACnC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;IAClE,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA4CD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,WAAW,GAAC,WAAW,EAAE,IAAI,EAAE,UAAU,GAAC,UAAU,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,GAC/F,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,UAAU,CAsFhC;AAGD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKjG;AAED,wBAAgB,WAAW,CACzB,IAAI,EAAE,UAAU,GAAG,UAAU,EAC7B,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,MAAM,CAAC,cAAc,GAC5B,IAAI,CAuBN;AAYD,wBAAsB,cAAc,CAClC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,MAAM,CAAC,cAAc,GAC5B,OAAO,CAAC,IAAI,CAAC,CAoDf;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,MAAM,CAK3E"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/commands/shared.ts"],"names":[],"mappings":"AAKA,OAAO,EAAc,KAAK,UAAU,EAAiC,MAAM,UAAU,CAAC;AAEtF,OAAO,EAA4B,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAS7E,iGAAiG;AACjG,MAAM,MAAM,QAAQ,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAErF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IACnC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;IAClE,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA4CD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,GAAC,UAAU,GAAC,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,GAC1F,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,UAAU,CAsFhC;AAGD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKjG;AAED,wBAAgB,WAAW,CACzB,IAAI,EAAE,UAAU,GAAG,UAAU,EAC7B,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,MAAM,CAAC,cAAc,GAC5B,IAAI,CAuBN;AAYD,wBAAsB,cAAc,CAClC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,MAAM,CAAC,cAAc,GAC5B,OAAO,CAAC,IAAI,CAAC,CA6Df;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,MAAM,CAK3E"}
@@ -132,7 +132,7 @@ function buildPackParser(pack, kind, specs, usage) {
132
132
  // family-specific capabilities have strict schemas that do not declare it,
133
133
  // so injecting it everywhere made every one of those verbs fail validation
134
134
  // with an unrecognized key before it reached the server's real work.
135
- if (spec.capabilityId.startsWith('workflow.automations.'))
135
+ if (kind !== undefined && spec.capabilityId.startsWith('workflow.automations.'))
136
136
  input.kind = kind;
137
137
  // No default mode. A mutating verb run with no mode used to be rewritten to dry_run
138
138
  // silently, where `tools run` sends none and lets the server answer mode_required
@@ -238,10 +238,7 @@ async function runPackCommand(context, command, stdout) {
238
238
  const outcome = await (0, gatedRun_1.runGated)(context, {
239
239
  capabilityId: command.capabilityId,
240
240
  body: {
241
- params: {
242
- ...command.input,
243
- ...(command.maxLiveSends === undefined ? {} : { max_live_sends: command.maxLiveSends }),
244
- },
241
+ params: command.input,
245
242
  ...(command.mode ? { mode: command.mode } : {}),
246
243
  ...(maxCredits === undefined ? {} : { max_credits: maxCredits }),
247
244
  ...(command.approved ? { approved: true } : {}),
@@ -254,6 +251,18 @@ async function runPackCommand(context, command, stdout) {
254
251
  waitTimeout: command.waitTimeout,
255
252
  ...(command.noWait ? { noWait: true } : {}),
256
253
  coerceParams: true,
254
+ // max_live_sends is a capability param, not a door control. It belongs in
255
+ // params only where the live schema declares it; sequence lifecycle and
256
+ // enrollment capabilities (for example sequence.sequences.activate_audience)
257
+ // have a strict, cap-free schema, so injecting it there was refused before
258
+ // the request left the CLI.
259
+ ...(command.maxLiveSends === undefined ? {} : { adjustParams: (params, capability) => {
260
+ const schema = capability?.input_json_schema;
261
+ const properties = schema && typeof schema === 'object' ? schema.properties : null;
262
+ return properties && typeof properties === 'object' && Object.prototype.hasOwnProperty.call(properties, 'max_live_sends')
263
+ ? { ...params, max_live_sends: command.maxLiveSends }
264
+ : params;
265
+ } }),
257
266
  });
258
267
  const result = outcome.value;
259
268
  if (outcome.timedOut)
@@ -0,0 +1,2 @@
1
+ export declare const TABLES_VERBS: import("./shared").PackVerbSpec[], TABLES_USAGE: string, parseTablesCommand: (argv: string[]) => import("..").CliCommand, runTablesCommand: (context: import("../gatedRun").GatedRunContext | undefined, command: import("..").CliCommand, stdout: NodeJS.WritableStream) => Promise<void>;
2
+ //# sourceMappingURL=tables.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tables.d.ts","sourceRoot":"","sources":["../../src/commands/tables.ts"],"names":[],"mappings":"AAEA,eAAO,MACE,YAAY,qCACZ,YAAY,UACZ,kBAAkB,+CACpB,gBAAgB,gJACE,CAAC"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.runTablesCommand = exports.parseTablesCommand = exports.TABLES_USAGE = exports.TABLES_VERBS = void 0;
5
+ const genericPack_1 = require("./genericPack");
6
+ _a = (0, genericPack_1.packSurface)('tables'), exports.TABLES_VERBS = _a.verbs, exports.TABLES_USAGE = _a.usage, exports.parseTablesCommand = _a.parse, exports.runTablesCommand = _a.run;
@@ -0,0 +1,2 @@
1
+ export declare const UNIBOX_VERBS: import("./shared").PackVerbSpec[], UNIBOX_USAGE: string, parseUniboxCommand: (argv: string[]) => import("..").CliCommand, runUniboxCommand: (context: import("../gatedRun").GatedRunContext | undefined, command: import("..").CliCommand, stdout: NodeJS.WritableStream) => Promise<void>;
2
+ //# sourceMappingURL=unibox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unibox.d.ts","sourceRoot":"","sources":["../../src/commands/unibox.ts"],"names":[],"mappings":"AAEA,eAAO,MACE,YAAY,qCACZ,YAAY,UACZ,kBAAkB,+CACpB,gBAAgB,gJACE,CAAC"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.runUniboxCommand = exports.parseUniboxCommand = exports.UNIBOX_USAGE = exports.UNIBOX_VERBS = void 0;
5
+ const genericPack_1 = require("./genericPack");
6
+ _a = (0, genericPack_1.packSurface)('unibox'), exports.UNIBOX_VERBS = _a.verbs, exports.UNIBOX_USAGE = _a.usage, exports.parseUniboxCommand = _a.parse, exports.runUniboxCommand = _a.run;
@@ -1 +1 @@
1
- {"version":3,"file":"gatedRun.d.ts","sourceRoot":"","sources":["../src/gatedRun.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAA0B,KAAK,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEnF,OAAO,EAA4F,KAAK,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAoBnJ,wBAAgB,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAIvD;AAUD,4FAA4F;AAC5F,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAKjF;AAgBD;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI,CAKrI;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS,CAKzF;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAazF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAMrE;AA0HD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,gBAAgB,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,mGAAmG;IACnG,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,KAAK,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,sFAAsF;IACtF,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qFAAqF;IACrF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzH;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,4EAA4E;IAC5E,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,qGAAqG;IACrG,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AASD,wBAAsB,QAAQ,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC,CAmMvG;AAED,uFAAuF;AACvF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAEpE;AAED,mGAAmG;AACnG,wBAAsB,cAAc,CAClC,OAAO,EAAE,eAAe,EACxB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC,CAGlB"}
1
+ {"version":3,"file":"gatedRun.d.ts","sourceRoot":"","sources":["../src/gatedRun.ts"],"names":[],"mappings":"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"}
package/dist/gatedRun.js CHANGED
@@ -121,7 +121,19 @@ function planFingerprint(body) {
121
121
  delete params[key];
122
122
  return (0, node_crypto_1.createHash)('sha256').update((0, idempotency_1.stableJson)({ params, max_credits: body.max_credits ?? null })).digest('hex');
123
123
  }
124
- /** The quote a dry run returned, wherever the envelope nests its outputs. */
124
+ function creditsPhrase(estimate) {
125
+ if (!estimate)
126
+ return null;
127
+ const { minimum_credits: minimum, maximum_credits: maximum, expected_credits: expected } = estimate;
128
+ if (typeof minimum === 'number' && typeof maximum === 'number' && minimum !== maximum)
129
+ return `${minimum}..${maximum} credits`;
130
+ if (typeof minimum !== 'number' && typeof maximum === 'number')
131
+ return `up to ${maximum} credits`;
132
+ if (typeof expected === 'number')
133
+ return `${expected} credits`;
134
+ return typeof maximum === 'number' ? `${maximum} credits` : null;
135
+ }
136
+ /** The quote a supported rehearsal returned, wherever the envelope nests its outputs. */
125
137
  function quoteFromResult(value, depth = 0) {
126
138
  if (!value || typeof value !== 'object' || depth > 6)
127
139
  return null;
@@ -135,10 +147,14 @@ function quoteFromResult(value, depth = 0) {
135
147
  }
136
148
  const entry = value;
137
149
  if (typeof entry.quote_hash === 'string' && runContract_1.QUOTE_HASH_PATTERN.test(entry.quote_hash)) {
138
- const estimate = entry.estimate && typeof entry.estimate === 'object' ? entry.estimate : null;
150
+ const estimate = record(entry.credit_estimate) ?? record(entry.estimate);
151
+ const affected = record(entry.affected_count);
152
+ const rows = affected?.rows ?? affected?.row_or_recipient_count;
139
153
  return {
140
154
  quote_hash: entry.quote_hash,
141
155
  maximum_credits: typeof estimate?.maximum_credits === 'number' ? estimate.maximum_credits : null,
156
+ rows: typeof rows === 'number' ? rows : null,
157
+ credits: creditsPhrase(estimate),
142
158
  };
143
159
  }
144
160
  for (const key of ['data', 'run', 'outputs', 'steps']) {
@@ -148,19 +164,20 @@ function quoteFromResult(value, depth = 0) {
148
164
  }
149
165
  return null;
150
166
  }
151
- function quotePriced(capabilityId, body, quote) {
167
+ function quotePriced(capabilityId, body, price, rehearsal = 'dry_run') {
152
168
  const params = body.params && typeof body.params === 'object' ? body.params : {};
153
- const rows = typeof params.max_rows === 'number' ? `${params.max_rows} rows` : 'rows not stated';
154
- const credits = quote.maximum_credits === null ? 'credits not stated' : `up to ${quote.maximum_credits} credits`;
155
- return `Dry run of ${capabilityId} priced: ${rows}, ${credits}.`;
169
+ const rowCount = price.rows ?? (typeof params.max_rows === 'number' ? params.max_rows : null);
170
+ const rows = rowCount === null ? 'rows not stated' : `${rowCount} rows`;
171
+ const credits = price.credits ?? 'credits not stated';
172
+ const name = rehearsal === 'smoke_test' ? 'Smoke test' : rehearsal === 'dry_run' ? 'Dry run' : 'Rehearsal';
173
+ return `${name} of ${capabilityId} priced: ${rows}, ${credits}.`;
156
174
  }
157
- /** A known price of 0 spends nothing. An unknown price or a positive price is sent only after the caller passes the approval flag. */
158
- function spendNeedsApproval(maximum, approved) {
159
- if (approved)
160
- return false;
161
- if (maximum === 0)
162
- return false;
163
- return true;
175
+ function rehearsalMode(fetched) {
176
+ const contract = record(capabilityRecord(fetched)?.execution_mode_contract);
177
+ const supported = Array.isArray(contract?.supported_modes) ? contract.supported_modes : [];
178
+ if (supported.includes('dry_run'))
179
+ return 'dry_run';
180
+ return supported.includes('smoke_test') ? 'smoke_test' : null;
164
181
  }
165
182
  const CREDENTIALS_REQUIRED_SENTENCE = 'A connected credential is required before this run can continue.';
166
183
  function readinessRecord(value) {
@@ -246,6 +263,41 @@ function readinessRefusal(value) {
246
263
  const code = credentials ? 'credentials_required' : codes[0] ?? 'not_ready';
247
264
  return new client_1.CliError(sentence, code, 409, { retryable: false });
248
265
  }
266
+ const UNSUCCESSFUL_TERMINAL_RUN_STATUSES = new Set(['failed', 'completed_with_errors', 'partially_completed']);
267
+ /**
268
+ * A runs.get HTTP 200 says read succeeded, not that durable work succeeded.
269
+ * Keep the terminal receipt in error details so callers can inspect or resume
270
+ * without treating a failed run as a successful CLI command.
271
+ */
272
+ function terminalRunOutcomeRefusal(value) {
273
+ const root = readinessRecord(value);
274
+ const data = readinessRecord(root?.data) ?? root;
275
+ const run = readinessRecord(data?.run);
276
+ const status = typeof run?.status === 'string' ? run.status : null;
277
+ if (!run || !status || !UNSUCCESSFUL_TERMINAL_RUN_STATUSES.has(status))
278
+ return null;
279
+ const runId = typeof run.run_id === 'string' ? run.run_id : typeof run.id === 'string' ? run.id : null;
280
+ const stepErrors = Array.isArray(run.steps)
281
+ ? run.steps.flatMap((step) => {
282
+ const record = readinessRecord(step);
283
+ return [readinessRecord(record?.error), readinessRecord(record?.user_error)];
284
+ })
285
+ : [];
286
+ const typedError = [readinessRecord(run.error), readinessRecord(run.user_error), ...stepErrors]
287
+ .find((error) => typeof error?.code === 'string' && typeof error.message === 'string');
288
+ const typedDetails = readinessRecord(typedError?.details);
289
+ const details = {
290
+ ...(typedDetails ?? {}),
291
+ ...(typedError?.details !== undefined && !typedDetails ? { run_error_details: typedError.details } : {}),
292
+ ...(runId ? { run_id: runId } : {}),
293
+ status,
294
+ };
295
+ return new client_1.CliError(typeof typedError?.message === 'string' ? typedError.message : `Run${runId ? ` ${runId}` : ''} ended with status ${status}.`, typeof typedError?.code === 'string' ? typedError.code : 'run_failed', typeof typedError?.http_status === 'number' ? typedError.http_status : 409, {
296
+ details,
297
+ retryable: typeof typedError?.retryable === 'boolean' ? typedError.retryable : false,
298
+ ...(typedError?.repair !== undefined ? { repair: typedError.repair } : {}),
299
+ });
300
+ }
249
301
  /** Adds the idempotency key to the printed meta, so a user can see which key to re-run with. */
250
302
  function withIdempotencyMeta(value, key) {
251
303
  const envelope = record(value);
@@ -288,10 +340,10 @@ async function runGated(context, input) {
288
340
  if (params)
289
341
  body.params = params;
290
342
  }
291
- // A paid live run needs the quote_hash of a dry run of the same input,
292
- // and a quote is bound to the turn that asked for it. So a turn is reused
293
- // only while a quote is pending, together with the quote its dry run
294
- // returned, and forgotten once the paid run is admitted.
343
+ // A quote-bound live run needs the quote_hash of a supported rehearsal of
344
+ // the same input, and the quote is bound to the turn that asked for it. So a
345
+ // turn is reused only while a quote is pending, together with that quote,
346
+ // and forgotten once the live run is admitted.
295
347
  const explicitKey = parameterIdempotencyKey(body) ?? input.idempotencyKey;
296
348
  const fingerprint = planFingerprint(body);
297
349
  const cached = input.turnToken
@@ -305,7 +357,7 @@ async function runGated(context, input) {
305
357
  const inlineFromCache = !input.turnToken && !pending && !explicitKey && cachedPosture?.inlineRead === true;
306
358
  if (!input.turnToken && !pending && !inlineFromCache)
307
359
  await contract();
308
- const posture = fetched ? (0, capabilityPosture_1.postureFromContract)(fetched) : cachedPosture;
360
+ let posture = fetched ? (0, capabilityPosture_1.postureFromContract)(fetched) : cachedPosture;
309
361
  if (fetched && posture)
310
362
  (0, registryManifest_1.rememberPosture)(capabilityId, posture);
311
363
  const refusal = fetched ? cliSurfaceRefusal(capabilityId, fetched) : null;
@@ -319,11 +371,13 @@ async function runGated(context, input) {
319
371
  let quoteHash = explicitQuote
320
372
  ? body.quote_hash
321
373
  : live ? cached?.quote_hash ?? undefined : undefined;
322
- // null means the price was not stated (or the flag named a hash with no ceiling).
323
- let quotedMaximum = !explicitQuote && cached?.quote_hash ? cached.maximum_credits : undefined;
324
- let ranDryRun = false;
374
+ // The price of the quote in hand. A cached quote prices this input only when it
375
+ // is the quote named (explicit --quote-hash) or the quote this input was dry run for.
376
+ let quotedPrice = cached?.quote_hash && (!explicitQuote || cached.quote_hash === body.quote_hash)
377
+ ? { quote_hash: cached.quote_hash, maximum_credits: cached.maximum_credits, rows: cached.rows ?? null, credits: cached.credits ?? null }
378
+ : null;
379
+ let ranRehearsal = false;
325
380
  let sentKey = null;
326
- const approvalRequired = () => new client_1.CliError('This run spends credits. Rerun the same command with --approved.', 'approval_required', 409, { retryable: false, repair: { kind: 'ask_user', hint: 'Rerun the same command with --approved.' } });
327
381
  const requestBody = () => ({
328
382
  ...body,
329
383
  ...(turnToken ? { tool_turn_token: turnToken } : {}),
@@ -353,23 +407,48 @@ async function runGated(context, input) {
353
407
  sentKey = await keyFor(sent);
354
408
  return client.runCapability(capabilityId, sent, sentKey);
355
409
  };
410
+ let retriedCapabilityDigestStale = false;
411
+ const refreshCapabilityAfterDigestStale = async () => {
412
+ retriedCapabilityDigestStale = true;
413
+ // A stale refusal is terminal for the original logical attempt. A new
414
+ // contract starts a fresh generated key, while a caller-supplied key keeps
415
+ // its explicit replay semantics.
416
+ if (attemptIdentity) {
417
+ await (0, idempotency_1.finishIdempotencyAttempt)(idempotencyPath, attemptIdentity);
418
+ attemptIdentity = null;
419
+ }
420
+ if (!input.turnToken) {
421
+ await (0, turnCache_1.forgetTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, warnTurnCache);
422
+ }
423
+ fetched = await client.getTool(capabilityId);
424
+ posture = (0, capabilityPosture_1.postureFromContract)(fetched);
425
+ (0, registryManifest_1.rememberPosture)(capabilityId, posture);
426
+ const refreshedTurnToken = optionalToolTurnToken(fetched);
427
+ turnToken = refreshedTurnToken;
428
+ // A cached quote is bound to the stale turn. An explicitly supplied quote
429
+ // remains caller intent and the server decides whether it is still valid.
430
+ if (!explicitQuote) {
431
+ quoteHash = undefined;
432
+ quotedPrice = null;
433
+ }
434
+ };
356
435
  let result;
357
436
  try {
358
437
  try {
359
438
  if (live && quoteHash) {
360
- const maximum = explicitQuote ? null : quotedMaximum ?? null;
361
- if (spendNeedsApproval(maximum, body.approved === true)) {
362
- stderr.write(`${quotePriced(capabilityId, body, { quote_hash: quoteHash, maximum_credits: maximum })}\n`);
363
- throw approvalRequired();
364
- }
365
- if (body.approved === true || maximum === 0) {
366
- stderr.write(`${quotePriced(capabilityId, body, { quote_hash: quoteHash, maximum_credits: maximum })}\nRunning live on that quote.\n`);
367
- }
439
+ // The shared gateway owns per-call paid, external-effect and recurring
440
+ // consent. A positive quote alone does not require human approval.
441
+ // Forward only caller-supplied approval; preserve every server refusal.
442
+ stderr.write(`${quotePriced(capabilityId, body, quotedPrice ?? { rows: null, credits: null }, rehearsalMode(fetched))}\nRunning live on that quote.\n`);
368
443
  }
369
444
  result = await run();
370
445
  }
371
446
  catch (error) {
372
- if (!input.turnToken && code(error) === 'capability_not_fetched') {
447
+ if (code(error) === 'capability_digest_stale') {
448
+ await refreshCapabilityAfterDigestStale();
449
+ result = await run();
450
+ }
451
+ else if (!input.turnToken && code(error) === 'capability_not_fetched') {
373
452
  // Capability posture can change between tools get and run. Refresh it
374
453
  // once rather than maintaining a client-side list of token-free reads.
375
454
  fetched = await client.getTool(capabilityId);
@@ -380,17 +459,18 @@ async function runGated(context, input) {
380
459
  result = await run();
381
460
  }
382
461
  else if (live && code(error) === 'quote_required' && !quoteHash && turnToken) {
383
- // A live paid run with no quote behind it. The refusal's own quote is
384
- // only a price and is never replayed, so price the same input with a
385
- // real dry run (free, never calls a paid provider), show the person
386
- // its rows and cost, and run live on that quote. Above the size or
387
- // dollar threshold the server still refuses until --approved.
388
- const dry = await client.runCapability(capabilityId, {
462
+ // A live quote is minted by the capability's advertised rehearsal.
463
+ // Most capabilities use dry_run; activation intentionally has only
464
+ // smoke_test and live, so never invent an unsupported dry_run mode.
465
+ const rehearsal = rehearsalMode(fetched);
466
+ if (!rehearsal)
467
+ throw error;
468
+ const rehearsalResult = await client.runCapability(capabilityId, {
389
469
  ...body,
390
- mode: 'dry_run',
470
+ mode: rehearsal,
391
471
  tool_turn_token: turnToken,
392
472
  }, null);
393
- const quote = quoteFromResult(dry);
473
+ const quote = quoteFromResult(rehearsalResult);
394
474
  if (!quote)
395
475
  throw error;
396
476
  // The no-quote call was definitively refused before execution. Its
@@ -399,13 +479,11 @@ async function runGated(context, input) {
399
479
  await (0, idempotency_1.finishIdempotencyAttempt)(idempotencyPath, attemptIdentity);
400
480
  attemptIdentity = null;
401
481
  }
402
- ranDryRun = true;
482
+ ranRehearsal = true;
403
483
  quoteHash = quote.quote_hash;
404
- quotedMaximum = quote.maximum_credits;
405
- stderr.write(`${quotePriced(capabilityId, body, quote)}\n`);
406
- await (0, turnCache_1.rememberTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, turnToken, Date.now(), warnTurnCache, { quote_hash: quote.quote_hash, fingerprint, maximum_credits: quote.maximum_credits });
407
- if (spendNeedsApproval(quote.maximum_credits, body.approved === true))
408
- throw approvalRequired();
484
+ quotedPrice = quote;
485
+ stderr.write(`${quotePriced(capabilityId, body, quote, rehearsal)}\n`);
486
+ await (0, turnCache_1.rememberTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, turnToken, Date.now(), warnTurnCache, { quote_hash: quote.quote_hash, fingerprint, maximum_credits: quote.maximum_credits, rows: quote.rows, credits: quote.credits });
409
487
  stderr.write('Running live on that quote.\n');
410
488
  result = await run();
411
489
  }
@@ -421,19 +499,22 @@ async function runGated(context, input) {
421
499
  if (code(error) === 'approval_required') {
422
500
  stderr.write('This run needs a person\'s approval. Show them the rows and cost above; when they agree, rerun the same command with --approved.\n');
423
501
  }
424
- await (0, turnCache_1.rememberTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, turnToken, Date.now(), warnTurnCache, quoteHash ? { quote_hash: quoteHash, fingerprint, ...(quotedMaximum !== undefined ? { maximum_credits: quotedMaximum } : {}) } : undefined);
502
+ await (0, turnCache_1.rememberTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, turnToken, Date.now(), warnTurnCache, quoteHash ? { quote_hash: quoteHash, fingerprint, maximum_credits: quotedPrice?.maximum_credits ?? null, rows: quotedPrice?.rows ?? null, credits: quotedPrice?.credits ?? null } : undefined);
425
503
  }
426
504
  // Only an unknown or transient result may resume an attempt. A server
427
505
  // refusal with retryable:false is terminal and must receive a new key.
428
- const transient = error instanceof client_1.CliError && (error.code === 'request_timeout' || error.code === 'network_error' || error.retryable === true || error.status >= 500);
506
+ // A response body that cannot be parsed is an unknown-effect outcome: the
507
+ // server may have admitted the write before its reply was damaged. Keep the
508
+ // generated key so the unchanged retry can replay that exact attempt.
509
+ const transient = error instanceof client_1.CliError && (error.code === 'request_timeout' || error.code === 'network_error' || error.code === 'invalid_response' || error.retryable === true || error.status >= 500);
429
510
  if (attemptIdentity && !transient)
430
511
  await (0, idempotency_1.finishIdempotencyAttempt)(idempotencyPath, attemptIdentity);
431
512
  throw error;
432
513
  }
433
514
  if (!input.turnToken) {
434
- if (body.mode === 'dry_run' && turnToken) {
515
+ if ((body.mode === 'dry_run' || body.mode === 'smoke_test') && turnToken) {
435
516
  const quote = quoteFromResult(result);
436
- await (0, turnCache_1.rememberTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, turnToken, Date.now(), warnTurnCache, quote ? { quote_hash: quote.quote_hash, fingerprint, maximum_credits: quote.maximum_credits } : undefined);
517
+ await (0, turnCache_1.rememberTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, turnToken, Date.now(), warnTurnCache, quote ? { quote_hash: quote.quote_hash, fingerprint, maximum_credits: quote.maximum_credits, rows: quote.rows, credits: quote.credits } : undefined);
437
518
  }
438
519
  }
439
520
  let timedOut = false;
@@ -442,23 +523,33 @@ async function runGated(context, input) {
442
523
  result = waited.value;
443
524
  timedOut = waited.timedOut;
444
525
  }
526
+ let outcomeRefusal = refusalFromRunResult(result);
527
+ if (!retriedCapabilityDigestStale && code(outcomeRefusal) === 'capability_digest_stale') {
528
+ await refreshCapabilityAfterDigestStale();
529
+ result = await run();
530
+ if (!input.noWait && !posture?.returnsRunId) {
531
+ const waited = await (0, runWait_1.waitForRun)(client, result, input.waitTimeout, context.sleep);
532
+ result = waited.value;
533
+ timedOut = waited.timedOut;
534
+ }
535
+ outcomeRefusal = refusalFromRunResult(result);
536
+ }
445
537
  // A timeout still owns the quote and the idempotency key. Forgetting the
446
538
  // turn here made the rerun hash a body with no quote_hash and start a second run.
447
- if (!input.turnToken && body.mode !== 'dry_run' && (pending || ranDryRun) && !timedOut) {
539
+ if (!input.turnToken && body.mode !== 'dry_run' && body.mode !== 'smoke_test' && (pending || ranRehearsal) && !timedOut) {
448
540
  await (0, turnCache_1.forgetTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, warnTurnCache);
449
541
  }
450
542
  // A run still active after waiting has unknown outcome; retain its key for
451
543
  // the read-back/retry rule. A terminal response completes this attempt.
452
544
  if (attemptIdentity && !timedOut)
453
545
  await (0, idempotency_1.finishIdempotencyAttempt)(idempotencyPath, attemptIdentity);
454
- const blocked = readinessRefusal(result);
455
- if (blocked)
456
- throw blocked;
546
+ if (outcomeRefusal)
547
+ throw outcomeRefusal;
457
548
  return { value: withIdempotencyMeta(result, explicitKey ? null : sentKey), timedOut, idempotencyKey: sentKey, turnToken: turnToken ?? null };
458
549
  }
459
550
  /** Blocker refusal for a run envelope that did not go through runGated (runs wait). */
460
551
  function refusalFromRunResult(value) {
461
- return readinessRefusal(value);
552
+ return readinessRefusal(value) ?? terminalRunOutcomeRefusal(value);
462
553
  }
463
554
  /** A read the CLI needs before it can form a write, run through the same gate as any other run. */
464
555
  async function readCapability(context, capabilityId, params, waitTimeout) {