@trydreamstate/cli 1.3.13 → 1.3.15

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 (53) hide show
  1. package/README.md +5 -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/diagnostics/SKILL.md +2 -0
  5. package/agent-plugin/skills/first-win/SKILL.md +1 -1
  6. package/agent-plugin/skills/list-building/SKILL.md +4 -0
  7. package/agent-plugin/skills/list-building/column-authoring.md +1 -1
  8. package/agent-plugin/skills/list-building/incoming-people.md +2 -2
  9. package/agent-plugin/skills/outreach/SKILL.md +6 -6
  10. package/agent-plugin/skills/outreach/enrollment.md +3 -3
  11. package/agent-plugin/skills/outreach/message-copy.md +1 -1
  12. package/agent-plugin/skills/social/SKILL.md +6 -2
  13. package/agent-plugin/skills/workflows/lifecycle-and-enrollment.md +1 -1
  14. package/dist/client.d.ts +2 -2
  15. package/dist/client.d.ts.map +1 -1
  16. package/dist/client.js +48 -5
  17. package/dist/commands/engage.d.ts +2 -0
  18. package/dist/commands/engage.d.ts.map +1 -0
  19. package/dist/commands/engage.js +6 -0
  20. package/dist/commands/genericPack.d.ts +1 -1
  21. package/dist/commands/genericPack.d.ts.map +1 -1
  22. package/dist/commands/shared.d.ts +1 -1
  23. package/dist/commands/shared.d.ts.map +1 -1
  24. package/dist/commands/shared.js +14 -4
  25. package/dist/config.d.ts +1 -0
  26. package/dist/config.d.ts.map +1 -1
  27. package/dist/config.js +9 -0
  28. package/dist/errors.d.ts +8 -0
  29. package/dist/errors.d.ts.map +1 -1
  30. package/dist/errors.js +4 -0
  31. package/dist/gatedRun.d.ts +13 -5
  32. package/dist/gatedRun.d.ts.map +1 -1
  33. package/dist/gatedRun.js +46 -11
  34. package/dist/generated/packVerbs.generated.json +1 -5
  35. package/dist/idempotency.d.ts.map +1 -1
  36. package/dist/idempotency.js +47 -17
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +39 -5
  39. package/dist/runEnvelopeStatus.d.ts +53 -0
  40. package/dist/runEnvelopeStatus.d.ts.map +1 -0
  41. package/dist/runEnvelopeStatus.js +83 -0
  42. package/dist/runWait.d.ts.map +1 -1
  43. package/dist/runWait.js +9 -11
  44. package/dist/skillInstaller.d.ts.map +1 -1
  45. package/dist/skillInstaller.js +10 -0
  46. package/dist/tableFilePreview.d.ts.map +1 -1
  47. package/dist/tableFilePreview.js +21 -3
  48. package/dist/tablesImport.d.ts.map +1 -1
  49. package/dist/tablesImport.js +13 -3
  50. package/dist/turnCache.d.ts +12 -1
  51. package/dist/turnCache.d.ts.map +1 -1
  52. package/dist/turnCache.js +104 -25
  53. package/package.json +1 -1
@@ -6,12 +6,20 @@ export declare function capabilityRecord(fetched: unknown): Record<string, unkno
6
6
  /**
7
7
  * Header value, or null when the request must not carry Idempotency-Key.
8
8
  * Any key forces a read onto the durable run path (isInlineReadEligible).
9
- * Send one only for an explicit key, or when the tools get contract says
10
- * mutates or idempotency_required. Missing flags omit the key: a read whose
11
- * contract does not set mutates must not be treated as a write.
9
+ * Send one for an explicit key, when the tools get contract says mutates or
10
+ * idempotency_required, when the body carries approval_id (a root approval is
11
+ * a live write), or when a live body carries tool_turn_token and the contract
12
+ * does not explicitly say the call is a non-mutating read. --turn-token skips
13
+ * tools get, so a live body has a token and no flags. A fetched contract with
14
+ * mutates false and idempotency_required not true still omits the key: its
15
+ * token is transport, and a key would force the read onto the durable path.
16
+ * A turn token without mode live stays keyless: that call has not said it is
17
+ * a write.
12
18
  *
13
- * A write's key is scoped to an attempt (idempotency.ts). A pending interrupted
14
- * attempt reuses its key; a terminal attempt gets a fresh key on a later command.
19
+ * The key is the attempt digest (idempotency.ts). tool_turn_token is not part
20
+ * of that digest, so a fresh token stays the same attempt. A pending
21
+ * interrupted attempt reuses its key; a terminal attempt gets a fresh key on
22
+ * a later command.
15
23
  */
16
24
  export declare function capabilityIdempotencyKey(fetched: unknown, explicit: string | undefined, identity: IdempotencyIdentity): string | null;
17
25
  export declare function parameterIdempotencyKey(body: Record<string, unknown>): string | undefined;
@@ -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;AAqLD,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;CAC/B;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,CAoOvG;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":"AACA,OAAO,EAAE,QAAQ,EAA0B,KAAK,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEnF,OAAO,EAA4F,KAAK,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAqBnJ,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;AAuBD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI,CAWrI;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;AAyLD,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;CAC/B;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,CAwOvG;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"}
package/dist/gatedRun.js CHANGED
@@ -14,6 +14,7 @@ const client_1 = require("./client");
14
14
  const errors_1 = require("./errors");
15
15
  const idempotency_1 = require("./idempotency");
16
16
  const schemaCoercion_1 = require("./schemaCoercion");
17
+ const runEnvelopeStatus_1 = require("./runEnvelopeStatus");
17
18
  const runWait_1 = require("./runWait");
18
19
  const turnCache_1 = require("./turnCache");
19
20
  const capabilityPosture_1 = require("./capabilityPosture");
@@ -64,15 +65,30 @@ function readIdempotencyContract(fetched) {
64
65
  }
65
66
  return null;
66
67
  }
68
+ function requestString(identity, name) {
69
+ const body = identity.body;
70
+ if (!body || typeof body !== 'object' || Array.isArray(body))
71
+ return null;
72
+ const value = body[name];
73
+ return typeof value === 'string' && value.trim().length > 0 ? value : null;
74
+ }
67
75
  /**
68
76
  * Header value, or null when the request must not carry Idempotency-Key.
69
77
  * Any key forces a read onto the durable run path (isInlineReadEligible).
70
- * Send one only for an explicit key, or when the tools get contract says
71
- * mutates or idempotency_required. Missing flags omit the key: a read whose
72
- * contract does not set mutates must not be treated as a write.
78
+ * Send one for an explicit key, when the tools get contract says mutates or
79
+ * idempotency_required, when the body carries approval_id (a root approval is
80
+ * a live write), or when a live body carries tool_turn_token and the contract
81
+ * does not explicitly say the call is a non-mutating read. --turn-token skips
82
+ * tools get, so a live body has a token and no flags. A fetched contract with
83
+ * mutates false and idempotency_required not true still omits the key: its
84
+ * token is transport, and a key would force the read onto the durable path.
85
+ * A turn token without mode live stays keyless: that call has not said it is
86
+ * a write.
73
87
  *
74
- * A write's key is scoped to an attempt (idempotency.ts). A pending interrupted
75
- * attempt reuses its key; a terminal attempt gets a fresh key on a later command.
88
+ * The key is the attempt digest (idempotency.ts). tool_turn_token is not part
89
+ * of that digest, so a fresh token stays the same attempt. A pending
90
+ * interrupted attempt reuses its key; a terminal attempt gets a fresh key on
91
+ * a later command.
76
92
  */
77
93
  function capabilityIdempotencyKey(fetched, explicit, identity) {
78
94
  if (typeof explicit === 'string' && explicit.length > 0)
@@ -80,6 +96,14 @@ function capabilityIdempotencyKey(fetched, explicit, identity) {
80
96
  const contract = readIdempotencyContract(fetched);
81
97
  if (contract?.mutates === true || contract?.idempotency_required === true)
82
98
  return (0, idempotency_1.deterministicIdempotencyKey)(identity);
99
+ if (requestString(identity, 'approval_id'))
100
+ return (0, idempotency_1.deterministicIdempotencyKey)(identity);
101
+ const explicitRead = contract?.mutates === false && contract?.idempotency_required !== true;
102
+ const live = (identity.body && typeof identity.body === 'object' && !Array.isArray(identity.body)
103
+ ? identity.body.mode
104
+ : undefined) === 'live';
105
+ if (live && !explicitRead && requestString(identity, 'tool_turn_token'))
106
+ return (0, idempotency_1.deterministicIdempotencyKey)(identity);
83
107
  return null;
84
108
  }
85
109
  function parameterIdempotencyKey(body) {
@@ -263,18 +287,25 @@ function readinessRefusal(value) {
263
287
  const code = credentials ? 'credentials_required' : codes[0] ?? 'not_ready';
264
288
  return new client_1.CliError(sentence, code, 409, { retryable: false });
265
289
  }
266
- const UNSUCCESSFUL_TERMINAL_RUN_STATUSES = new Set(['failed', 'completed_with_errors', 'partially_completed']);
267
290
  /**
268
291
  * A runs.get HTTP 200 says read succeeded, not that durable work succeeded.
269
292
  * Keep the terminal receipt in error details so callers can inspect or resume
270
293
  * without treating a failed run as a successful CLI command.
294
+ * Refuse only when the shared envelope says the run failed. partially_completed
295
+ * with a null outcome, and cap_reached, are success and keep the continuation
296
+ * on the envelope. Rehearsal receipts are not envelope statuses.
271
297
  */
272
298
  function terminalRunOutcomeRefusal(value) {
273
299
  const root = readinessRecord(value);
274
300
  const data = readinessRecord(root?.data) ?? root;
275
301
  const run = readinessRecord(data?.run);
276
302
  const status = typeof run?.status === 'string' ? run.status : null;
277
- if (!run || !status || !UNSUCCESSFUL_TERMINAL_RUN_STATUSES.has(status))
303
+ if (!run || !status || (0, runEnvelopeStatus_1.isFinishedRehearsalStatus)(status))
304
+ return null;
305
+ // A status this CLI does not know yet is the server's to classify; never crash on it.
306
+ if (!(0, runEnvelopeStatus_1.isRunEnvelopeStatus)(status))
307
+ return null;
308
+ if (!(0, runEnvelopeStatus_1.isFailedRunEnvelope)(status, data?.outcome))
278
309
  return null;
279
310
  const runId = typeof run.run_id === 'string' ? run.run_id : typeof run.id === 'string' ? run.id : null;
280
311
  const stepErrors = Array.isArray(run.steps)
@@ -292,7 +323,7 @@ function terminalRunOutcomeRefusal(value) {
292
323
  ...(runId ? { run_id: runId } : {}),
293
324
  status,
294
325
  };
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, {
326
+ return new client_1.CliError(typeof typedError?.message === 'string' ? typedError.message : `Run${runId ? ` ${runId}` : ''} ended with status ${status}.`, typeof typedError?.code === 'string' ? typedError.code : status === 'cancelled' ? 'run_cancelled' : 'run_failed', typeof typedError?.http_status === 'number' ? typedError.http_status : 409, {
296
327
  details,
297
328
  retryable: typeof typedError?.retryable === 'boolean' ? typedError.retryable : false,
298
329
  ...(typedError?.repair !== undefined ? { repair: typedError.repair } : {}),
@@ -346,9 +377,14 @@ async function runGated(context, input) {
346
377
  // and forgotten once the live run is admitted.
347
378
  const explicitKey = parameterIdempotencyKey(body) ?? input.idempotencyKey;
348
379
  const fingerprint = planFingerprint(body);
380
+ // An explicit quote_hash must travel with the token that dry run stored for
381
+ // THAT hash. A cached token whose fingerprint differs belongs to another input.
382
+ const explicitQuote = typeof body.quote_hash === 'string';
349
383
  const cached = input.turnToken
350
384
  ? null
351
- : await (0, turnCache_1.reusableTurn)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, fingerprint, Date.now(), warnTurnCache);
385
+ : explicitQuote
386
+ ? await (0, turnCache_1.reusableTurnForQuote)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, body.quote_hash, fingerprint, Date.now(), warnTurnCache)
387
+ : await (0, turnCache_1.reusableTurn)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, fingerprint, Date.now(), warnTurnCache);
352
388
  const pending = cached?.token ?? null;
353
389
  const live = body.mode === 'live';
354
390
  // --turn-token is the contract. Do not fetch tools get to invent one.
@@ -367,7 +403,6 @@ async function runGated(context, input) {
367
403
  let turnToken = input.turnToken ?? pending ?? (inlineRead ? undefined : optionalToolTurnToken(fetched));
368
404
  // Only a quote the caller named or a dry run of this exact input returned.
369
405
  // The server's refusal also shows a price, but that one is information, not consent.
370
- const explicitQuote = typeof body.quote_hash === 'string';
371
406
  let quoteHash = explicitQuote
372
407
  ? body.quote_hash
373
408
  : live ? cached?.quote_hash ?? undefined : undefined;
@@ -537,7 +572,7 @@ async function runGated(context, input) {
537
572
  // A timeout still owns the quote and the idempotency key. Forgetting the
538
573
  // turn here made the rerun hash a body with no quote_hash and start a second run.
539
574
  if (!input.turnToken && body.mode !== 'dry_run' && body.mode !== 'smoke_test' && (pending || ranRehearsal) && !timedOut) {
540
- await (0, turnCache_1.forgetTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, warnTurnCache);
575
+ await (0, turnCache_1.forgetTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, warnTurnCache, quoteHash);
541
576
  }
542
577
  // A run still active after waiting has unknown outcome; retain its key for
543
578
  // the read-back/retry rule. A terminal response completes this attempt.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "generated_by": "packages/cli/scripts/generate-pack-verbs.mjs from apps/backend/src/services/v1/capabilityRegistry/catalog.snapshot.json; do not edit by hand",
3
- "registry_hash": "16751d948dd7f0d9dc4edf96af141deaaf4a737f7bea57b45d309b8197517b5a",
3
+ "registry_hash": "ddf314f62331e1fc7a4caa55286415f4204a8a503c3dc8a2c78072620dfe7d95",
4
4
  "verbs": [
5
5
  {
6
6
  "command": "engage accounts list",
@@ -581,10 +581,6 @@
581
581
  ],
582
582
  "capabilityId": "workflow.automations.get"
583
583
  },
584
- {
585
- "command": "sequences import",
586
- "capabilityId": "workflow.automations.import"
587
- },
588
584
  {
589
585
  "command": "workflows import",
590
586
  "capabilityId": "workflow.automations.import"
@@ -1 +1 @@
1
- {"version":3,"file":"idempotency.d.ts","sourceRoot":"","sources":["../src/idempotency.ts"],"names":[],"mappings":"AAIA,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAOjD;AASD,MAAM,WAAW,mBAAmB;IAClC,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAC;IACd,4FAA4F;IAC5F,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,gGAAgG;IAChG,IAAI,EAAE,OAAO,CAAC;CACf;AAED,wBAAgB,sBAAsB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,CAavE;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,CAEjF;AAqBD,mFAAmF;AACnF,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CASxG;AAED,mGAAmG;AACnG,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAMzG"}
1
+ {"version":3,"file":"idempotency.d.ts","sourceRoot":"","sources":["../src/idempotency.ts"],"names":[],"mappings":"AAIA,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAOjD;AASD,MAAM,WAAW,mBAAmB;IAClC,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAC;IACd,4FAA4F;IAC5F,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,gGAAgG;IAChG,IAAI,EAAE,OAAO,CAAC;CACf;AAED,wBAAgB,sBAAsB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,CAavE;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,CAEjF;AAgBD,mFAAmF;AACnF,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CA+BxG;AAED,mGAAmG;AACnG,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAWzG"}
@@ -79,28 +79,58 @@ async function loadPending(path) {
79
79
  throw error;
80
80
  }
81
81
  }
82
- async function savePending(path, attempts) {
83
- await (0, promises_1.mkdir)((0, node_path_1.dirname)(path), { recursive: true, mode: 0o700 });
84
- await (0, promises_1.writeFile)(path, JSON.stringify(attempts), { mode: 0o600 });
85
- }
86
82
  /** Gets a fresh attempt key, or resumes only a pending attempt for this digest. */
87
83
  async function pendingIdempotencyKey(path, identity) {
88
- const attempts = await loadPending(path);
89
84
  const digest = idempotencyDigest(identity);
90
- const existing = attempts[digest];
91
- if (existing)
92
- return existing;
93
- const key = `dscli-${(0, node_crypto_1.randomBytes)(20).toString('hex')}`;
94
- attempts[digest] = key;
95
- await savePending(path, attempts);
96
- return key;
85
+ const directory = `${path}.d`;
86
+ await (0, promises_1.mkdir)(directory, { recursive: true, mode: 0o700 });
87
+ const target = (0, node_path_1.join)(directory, digest);
88
+ try {
89
+ return await (0, promises_1.readFile)(target, 'utf8');
90
+ }
91
+ catch (error) {
92
+ if (error.code !== 'ENOENT')
93
+ throw error;
94
+ }
95
+ let retired = false;
96
+ try {
97
+ await (0, promises_1.readFile)(`${target}.retired`);
98
+ retired = true;
99
+ }
100
+ catch (error) {
101
+ if (error.code !== 'ENOENT')
102
+ throw error;
103
+ }
104
+ const key = (!retired && (await loadPending(path))[digest]) || `dscli-${(0, node_crypto_1.randomBytes)(20).toString('hex')}`;
105
+ const temporary = (0, node_path_1.join)(directory, `.${digest}.${(0, node_crypto_1.randomBytes)(16).toString('hex')}`);
106
+ await (0, promises_1.writeFile)(temporary, key, { mode: 0o600, flag: 'wx' });
107
+ try {
108
+ try {
109
+ await (0, promises_1.link)(temporary, target);
110
+ return key;
111
+ }
112
+ catch (error) {
113
+ if (error.code !== 'EEXIST')
114
+ throw error;
115
+ return await (0, promises_1.readFile)(target, 'utf8');
116
+ }
117
+ }
118
+ finally {
119
+ await (0, promises_1.unlink)(temporary);
120
+ }
97
121
  }
98
122
  /** A success or definitive refusal finishes an attempt; a transient outcome keeps it resumable. */
99
123
  async function finishIdempotencyAttempt(path, identity) {
100
- const attempts = await loadPending(path);
101
124
  const digest = idempotencyDigest(identity);
102
- if (!(digest in attempts))
103
- return;
104
- delete attempts[digest];
105
- await savePending(path, attempts);
125
+ const directory = `${path}.d`;
126
+ await (0, promises_1.mkdir)(directory, { recursive: true, mode: 0o700 });
127
+ const target = (0, node_path_1.join)(directory, digest);
128
+ await (0, promises_1.writeFile)(`${target}.retired`, '', { mode: 0o600 });
129
+ try {
130
+ await (0, promises_1.unlink)(target);
131
+ }
132
+ catch (error) {
133
+ if (error.code !== 'ENOENT')
134
+ throw error;
135
+ }
106
136
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -499,6 +499,9 @@ function workflowsCommands() {
499
499
  function knowledgeCommands() {
500
500
  return require('./commands/knowledge');
501
501
  }
502
+ function engageCommands() {
503
+ return require('./commands/engage');
504
+ }
502
505
  function uniboxCommands() {
503
506
  return require('./commands/unibox');
504
507
  }
@@ -621,6 +624,8 @@ function parseCliArgs(argv) {
621
624
  return workflowsCommands().parseWorkflowsCommand(rest);
622
625
  if (group === 'knowledge')
623
626
  return knowledgeCommands().parseKnowledgeCommand(rest);
627
+ if (group === 'engage')
628
+ return engageCommands().parseEngageCommand(rest);
624
629
  if (group === 'unibox')
625
630
  return uniboxCommands().parseUniboxCommand(rest);
626
631
  throw new errors_1.CliUsageError(`Unknown command: ${group}`);
@@ -1022,12 +1027,31 @@ async function loginWithDeviceAuthorization(runtime, stdout, stderr, profile, no
1022
1027
  const authorization = await (0, client_1.requestDeviceAuthorization)(baseUrl, {
1023
1028
  state,
1024
1029
  client: { os: process.platform, hostname: (0, node_os_1.hostname)(), cli_version: client_1.CLI_VERSION },
1025
- });
1030
+ }, runtime.requestTimeoutMs);
1026
1031
  stderr.write(`Open: ${authorization.verification_uri_complete}\nConfirmation code: ${authorization.user_code}\n`);
1027
1032
  (runtime.openWebUrl ?? openWebUrl)(authorization.verification_uri_complete);
1033
+ const expiresAt = Date.parse(authorization.expires_at);
1034
+ if (!Number.isFinite(expiresAt))
1035
+ throw new client_1.CliError('Invalid device authorization expiry.', 'invalid_response', 0);
1028
1036
  for (;;) {
1029
- const claim = await (0, client_1.claimDeviceAuthorization)(baseUrl, authorization.device_code);
1030
- if (claim.status === 'ready') {
1037
+ const remaining = expiresAt - Date.now();
1038
+ if (remaining <= 0)
1039
+ throw new client_1.CliError('Device authorization expired. Run dreamstate login again.', 'device_authorization_expired', 0);
1040
+ let claim = null;
1041
+ try {
1042
+ claim = await (0, client_1.claimDeviceAuthorization)(baseUrl, authorization.device_code, Math.min(runtime.requestTimeoutMs ?? client_1.DEFAULT_REQUEST_TIMEOUT_MS, remaining));
1043
+ }
1044
+ catch (error) {
1045
+ // A dropped or failed poll is not a refused login: the server keeps a claimed
1046
+ // request redeliverable for a short window, so keep polling until the request expires.
1047
+ const transient = error instanceof client_1.CliError
1048
+ && (error.code === 'network_error' || error.status === 429 || error.status >= 500);
1049
+ if (!transient || !(Date.now() < expiresAt))
1050
+ throw error;
1051
+ }
1052
+ if (Date.now() >= expiresAt)
1053
+ throw new client_1.CliError('Device authorization expired. Run dreamstate login again.', 'device_authorization_expired', 0);
1054
+ if (claim?.status === 'ready') {
1031
1055
  const client = new client_1.DreamstateClient({
1032
1056
  baseUrl,
1033
1057
  apiKey: claim.token,
@@ -1047,7 +1071,7 @@ async function loginWithDeviceAuthorization(runtime, stdout, stderr, profile, no
1047
1071
  print(loginResult(whoami, skills), stdout, jsonOutput);
1048
1072
  return;
1049
1073
  }
1050
- await (runtime.sleep ?? wait)(authorization.interval_seconds * 1_000);
1074
+ await (runtime.sleep ?? wait)(Math.min(authorization.interval_seconds * 1_000, Math.max(0, expiresAt - Date.now())));
1051
1075
  }
1052
1076
  }
1053
1077
  function ignoreBrokenPipe(stdout) {
@@ -1095,7 +1119,10 @@ async function runCli(argv = process.argv.slice(2), runtime = {}) {
1095
1119
  return;
1096
1120
  }
1097
1121
  if (command.command === 'logout') {
1098
- const path = runtimeCredentialsPath(runtime);
1122
+ const basePath = runtimeCredentialsPath(runtime);
1123
+ const environment = runtime.env ?? process.env;
1124
+ const profile = await (0, config_1.currentCredentialProfile)(basePath, environment);
1125
+ const path = await (0, config_1.selectedCredentialsPath)(basePath, environment);
1099
1126
  let removed = true;
1100
1127
  try {
1101
1128
  await (0, promises_1.access)(path);
@@ -1107,6 +1134,10 @@ async function runCli(argv = process.argv.slice(2), runtime = {}) {
1107
1134
  }
1108
1135
  if (removed)
1109
1136
  await (0, promises_1.rm)(path, { force: true });
1137
+ if (profile)
1138
+ await (0, config_1.clearCurrentCredentialProfile)(basePath, profile);
1139
+ if (environment.DREAMSTATE_API_KEY?.trim())
1140
+ stderr.write('DREAMSTATE_API_KEY remains active in the environment.\n');
1110
1141
  const message = removed ? `Removed ${path}` : `Already logged out: no credentials at ${path}`;
1111
1142
  stderr.write(`${message}\n`);
1112
1143
  print({ ok: true, data: { credentials_path: path, removed }, meta: {} }, stdout, Boolean(command.jsonOutput));
@@ -1525,6 +1556,9 @@ async function runCli(argv = process.argv.slice(2), runtime = {}) {
1525
1556
  else if (command.pack === 'knowledge') {
1526
1557
  await knowledgeCommands().runKnowledgeCommand(gatedContext(), command, stdout);
1527
1558
  }
1559
+ else if (command.pack === 'engage') {
1560
+ await engageCommands().runEngageCommand(gatedContext(), command, stdout);
1561
+ }
1528
1562
  else if (command.pack === 'unibox') {
1529
1563
  await uniboxCommands().runUniboxCommand(gatedContext(), command, stdout);
1530
1564
  }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Run envelope status partition for the published CLI.
3
+ *
4
+ * The CLI package does not depend on @dreamstate/types, and its TypeScript
5
+ * build cannot import a JSON file that lives outside this package. This
6
+ * module is the compiled copy. packages/types/src/runStatusPartition.guard.test.ts
7
+ * fails when it drifts from RUN_ENVELOPE_STATUS_PARTITION or from
8
+ * packages/types/src/__fixtures__/runEnvelopeStatusPartition.json, which is
9
+ * the file the Python runtime loads. Do not add a second hand-maintained
10
+ * status list in runWait.ts or gatedRun.ts.
11
+ */
12
+ export declare const RUN_ENVELOPE_STATUS_PARTITION: {
13
+ readonly queued: "in_flight";
14
+ readonly planning: "in_flight";
15
+ readonly running: "in_flight";
16
+ readonly paused: "paused";
17
+ readonly waiting: "waiting";
18
+ readonly succeeded: "success";
19
+ readonly failed: "failure";
20
+ readonly cancelled: "failure";
21
+ readonly timed_out: "failure";
22
+ readonly partially_completed: "success_with_continuation";
23
+ readonly cap_reached: "success_with_continuation";
24
+ readonly reconciling: "in_flight";
25
+ };
26
+ export type RunEnvelopeStatus = keyof typeof RUN_ENVELOPE_STATUS_PARTITION;
27
+ export type RunEnvelopeStatusKind = (typeof RUN_ENVELOPE_STATUS_PARTITION)[RunEnvelopeStatus];
28
+ export declare class UnknownRunEnvelopeStatusError extends Error {
29
+ readonly status: string;
30
+ constructor(status: string);
31
+ }
32
+ export declare function isRunEnvelopeStatus(value: string): value is RunEnvelopeStatus;
33
+ export declare function runEnvelopeStatusKind(status: string): RunEnvelopeStatusKind;
34
+ /**
35
+ * True when polling will not observe a later status by itself.
36
+ * paused is included: the run stays where a person left it. waiting is not
37
+ * included: a provider callback can still move it.
38
+ */
39
+ export declare function isTerminalRunEnvelopeStatus(status: string): boolean;
40
+ /**
41
+ * A continuation is success unless the outcome says the pass failed.
42
+ * partially_completed with a null outcome is that continuation, not a failure.
43
+ */
44
+ export declare function isFailedRunEnvelope(status: string, outcome: unknown): boolean;
45
+ /**
46
+ * Rehearsal receipts. No api_runs row, no table execution job, and no
47
+ * projection emit these words, so they stay out of the partition. A dry run
48
+ * that already returned an id is finished; polling it waits out the command
49
+ * timeout. Equality checks, not a status list, so the partition guard does
50
+ * not treat them as envelope statuses.
51
+ */
52
+ export declare function isFinishedRehearsalStatus(status: string): boolean;
53
+ //# sourceMappingURL=runEnvelopeStatus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runEnvelopeStatus.d.ts","sourceRoot":"","sources":["../src/runEnvelopeStatus.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;CAahC,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,6BAA6B,CAAC;AAE3E,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,6BAA6B,CAAC,CAAC,iBAAiB,CAAC,CAAC;AAI9F,qBAAa,6BAA8B,SAAQ,KAAK;IACtD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,MAAM,EAAE,MAAM;CAK3B;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,iBAAiB,CAE7E;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,qBAAqB,CAG3E;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGnE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAO7E;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEjE"}
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ /**
3
+ * Run envelope status partition for the published CLI.
4
+ *
5
+ * The CLI package does not depend on @dreamstate/types, and its TypeScript
6
+ * build cannot import a JSON file that lives outside this package. This
7
+ * module is the compiled copy. packages/types/src/runStatusPartition.guard.test.ts
8
+ * fails when it drifts from RUN_ENVELOPE_STATUS_PARTITION or from
9
+ * packages/types/src/__fixtures__/runEnvelopeStatusPartition.json, which is
10
+ * the file the Python runtime loads. Do not add a second hand-maintained
11
+ * status list in runWait.ts or gatedRun.ts.
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.UnknownRunEnvelopeStatusError = exports.RUN_ENVELOPE_STATUS_PARTITION = void 0;
15
+ exports.isRunEnvelopeStatus = isRunEnvelopeStatus;
16
+ exports.runEnvelopeStatusKind = runEnvelopeStatusKind;
17
+ exports.isTerminalRunEnvelopeStatus = isTerminalRunEnvelopeStatus;
18
+ exports.isFailedRunEnvelope = isFailedRunEnvelope;
19
+ exports.isFinishedRehearsalStatus = isFinishedRehearsalStatus;
20
+ exports.RUN_ENVELOPE_STATUS_PARTITION = {
21
+ queued: 'in_flight',
22
+ planning: 'in_flight',
23
+ running: 'in_flight',
24
+ paused: 'paused',
25
+ waiting: 'waiting',
26
+ succeeded: 'success',
27
+ failed: 'failure',
28
+ cancelled: 'failure',
29
+ timed_out: 'failure',
30
+ partially_completed: 'success_with_continuation',
31
+ cap_reached: 'success_with_continuation',
32
+ reconciling: 'in_flight',
33
+ };
34
+ const TERMINAL_KINDS = ['success', 'failure', 'success_with_continuation', 'paused'];
35
+ class UnknownRunEnvelopeStatusError extends Error {
36
+ status;
37
+ constructor(status) {
38
+ super(`Unknown run envelope status: ${status}`);
39
+ this.name = 'UnknownRunEnvelopeStatusError';
40
+ this.status = status;
41
+ }
42
+ }
43
+ exports.UnknownRunEnvelopeStatusError = UnknownRunEnvelopeStatusError;
44
+ function isRunEnvelopeStatus(value) {
45
+ return Object.prototype.hasOwnProperty.call(exports.RUN_ENVELOPE_STATUS_PARTITION, value);
46
+ }
47
+ function runEnvelopeStatusKind(status) {
48
+ if (!isRunEnvelopeStatus(status))
49
+ throw new UnknownRunEnvelopeStatusError(status);
50
+ return exports.RUN_ENVELOPE_STATUS_PARTITION[status];
51
+ }
52
+ /**
53
+ * True when polling will not observe a later status by itself.
54
+ * paused is included: the run stays where a person left it. waiting is not
55
+ * included: a provider callback can still move it.
56
+ */
57
+ function isTerminalRunEnvelopeStatus(status) {
58
+ const kind = runEnvelopeStatusKind(status);
59
+ return TERMINAL_KINDS.includes(kind);
60
+ }
61
+ /**
62
+ * A continuation is success unless the outcome says the pass failed.
63
+ * partially_completed with a null outcome is that continuation, not a failure.
64
+ */
65
+ function isFailedRunEnvelope(status, outcome) {
66
+ const kind = runEnvelopeStatusKind(status);
67
+ if (kind === 'failure')
68
+ return true;
69
+ if (kind === 'success_with_continuation') {
70
+ return outcome === 'completed_with_errors' || outcome === 'failed';
71
+ }
72
+ return false;
73
+ }
74
+ /**
75
+ * Rehearsal receipts. No api_runs row, no table execution job, and no
76
+ * projection emit these words, so they stay out of the partition. A dry run
77
+ * that already returned an id is finished; polling it waits out the command
78
+ * timeout. Equality checks, not a status list, so the partition guard does
79
+ * not treat them as envelope statuses.
80
+ */
81
+ function isFinishedRehearsalStatus(status) {
82
+ return status === 'dry_run_rehearsed' || status === 'smoke_test_passed';
83
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"runWait.d.ts","sourceRoot":"","sources":["../src/runWait.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAY3D,sFAAsF;AACtF,eAAO,MAAM,0BAA0B,EAAE,MAAyB,CAAC;AAEnE,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;CACnB;AAuDD,wBAAsB,UAAU,CAC9B,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,aAAa,CAAC,CA4BxB"}
1
+ {"version":3,"file":"runWait.d.ts","sourceRoot":"","sources":["../src/runWait.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAI3D,sFAAsF;AACtF,eAAO,MAAM,0BAA0B,EAAE,MAAyB,CAAC;AAEnE,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;CACnB;AA4DD,wBAAsB,UAAU,CAC9B,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,aAAa,CAAC,CA4BxB"}
package/dist/runWait.js CHANGED
@@ -4,14 +4,7 @@ exports.RUN_WAIT_TIMEOUT_EXIT_CODE = void 0;
4
4
  exports.waitForRun = waitForRun;
5
5
  const client_1 = require("./client");
6
6
  const errors_1 = require("./errors");
7
- const TERMINAL_STATUSES = new Set([
8
- 'succeeded', 'completed', 'completed_with_errors', 'failed', 'cancelled', 'canceled', 'partially_completed',
9
- 'timed_out', 'rejected', 'awaiting_approval', 'awaiting_input', 'waiting', 'waiting_approval', 'approval_required',
10
- // A rehearsal already finished. Polling it as if it were still running times the command out.
11
- 'dry_run_rehearsed', 'smoke_test_passed',
12
- // A credit or row ceiling stopped the run with a continuation; nothing more happens until a new run.
13
- 'cap_reached',
14
- ]);
7
+ const runEnvelopeStatus_1 = require("./runEnvelopeStatus");
15
8
  /** The wait ran out with the run still active; the latest run envelope is printed. */
16
9
  exports.RUN_WAIT_TIMEOUT_EXIT_CODE = errors_1.CLI_EXIT.TIMEOUT;
17
10
  function runFromEnvelope(value) {
@@ -27,9 +20,14 @@ function runFromEnvelope(value) {
27
20
  const resolvedId = typeof id === 'string' ? id : typeof runId === 'string' ? runId : null;
28
21
  if (!resolvedId || typeof status !== 'string')
29
22
  return null;
30
- // The server's own terminal flag wins over the local status list, so a new
31
- // terminal status never makes the CLI wait out its whole timeout.
32
- const terminal = data.terminal === true || TERMINAL_STATUSES.has(status);
23
+ // data.terminal true is the server's own settlement flag and wins even when
24
+ // the status word is newer than this build. Otherwise the shared envelope
25
+ // partition decides. An explicit false still falls through, so waiting stays
26
+ // open. Rehearsal receipts are finished and are not store statuses.
27
+ const serverTerminal = data.terminal === true;
28
+ const terminal = serverTerminal
29
+ || (0, runEnvelopeStatus_1.isFinishedRehearsalStatus)(status)
30
+ || (0, runEnvelopeStatus_1.isTerminalRunEnvelopeStatus)(status);
33
31
  return { id: resolvedId, status, terminal };
34
32
  }
35
33
  function timedOutEnvelope(value, timeoutSeconds) {
@@ -1 +1 @@
1
- {"version":3,"file":"skillInstaller.d.ts","sourceRoot":"","sources":["../src/skillInstaller.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"skillInstaller.d.ts","sourceRoot":"","sources":["../src/skillInstaller.ts"],"names":[],"mappings":"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"}
@@ -175,6 +175,16 @@ async function writeHostedSkill(root, skill, provenance) {
175
175
  async function linkAgentSkill(agentRoot, canonicalDirectory, name, copy) {
176
176
  const targetDirectory = (0, node_path_1.join)(agentRoot, name);
177
177
  await (0, promises_1.mkdir)(agentRoot, { recursive: true, mode: 0o700 });
178
+ const existing = await (0, promises_1.lstat)(targetDirectory).catch((error) => {
179
+ if (error.code === 'ENOENT')
180
+ return null;
181
+ throw error;
182
+ });
183
+ if (existing && !existing.isSymbolicLink()) {
184
+ const owned = existing.isDirectory() && (await (0, promises_1.readFile)((0, node_path_1.join)(targetDirectory, 'SKILL.md'), 'utf8').catch(() => '')).includes(PROVENANCE_MARKER);
185
+ if (!owned)
186
+ throw new errors_1.CliUsageError(`Cannot replace a skill directory not owned by Dreamstate: ${targetDirectory}`);
187
+ }
178
188
  await (0, promises_1.rm)(targetDirectory, { recursive: true, force: true });
179
189
  if (copy) {
180
190
  // The whole skill directory, not only SKILL.md: the supporting pages the skill body
@@ -1 +1 @@
1
- {"version":3,"file":"tableFilePreview.d.ts","sourceRoot":"","sources":["../src/tableFilePreview.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAEnE,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,kBAAkB,CAAC;IAC9B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3C,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,KAAK,CAAC;CACf;AAgBD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAK7F;AAyBD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC;IAAC,UAAU,EAAE,OAAO,CAAC;IAAC,iBAAiB,EAAE,OAAO,CAAA;CAAE,CAwC5G;AA0HD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAsC7G;AAQD,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAgB7G"}
1
+ {"version":3,"file":"tableFilePreview.d.ts","sourceRoot":"","sources":["../src/tableFilePreview.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAEnE,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,kBAAkB,CAAC;IAC9B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3C,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,KAAK,CAAC;CACf;AAgBD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAK7F;AAyBD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC;IAAC,UAAU,EAAE,OAAO,CAAC;IAAC,iBAAiB,EAAE,OAAO,CAAA;CAAE,CAwC5G;AA0HD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAmD7G;AAQD,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAgB7G"}