@skrr-ai/cli 0.1.15 → 0.1.18

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 (64) hide show
  1. package/README.md +10 -4
  2. package/dist/commands/commitments/action-proposals/decide.d.ts +13 -0
  3. package/dist/commands/commitments/action-proposals/decide.js +41 -0
  4. package/dist/commands/commitments/action-proposals/execute.d.ts +12 -0
  5. package/dist/commands/commitments/action-proposals/execute.js +29 -0
  6. package/dist/commands/commitments/action-proposals.d.ts +13 -0
  7. package/dist/commands/commitments/action-proposals.js +56 -0
  8. package/dist/commands/commitments/autonomy.d.ts +7 -11
  9. package/dist/commands/commitments/autonomy.js +16 -17
  10. package/dist/commands/commitments/bundle.d.ts +14 -0
  11. package/dist/commands/commitments/bundle.js +49 -0
  12. package/dist/commands/commitments/create.d.ts +33 -5
  13. package/dist/commands/commitments/create.js +234 -27
  14. package/dist/commands/commitments/delivery.d.ts +16 -0
  15. package/dist/commands/commitments/delivery.js +71 -0
  16. package/dist/commands/commitments/doctor.d.ts +20 -0
  17. package/dist/commands/commitments/doctor.js +88 -0
  18. package/dist/commands/commitments/effective-policy.d.ts +2 -0
  19. package/dist/commands/commitments/effective-policy.js +50 -5
  20. package/dist/commands/commitments/endpoints/connect.d.ts +3 -10
  21. package/dist/commands/commitments/endpoints/connect.js +6 -37
  22. package/dist/commands/commitments/endpoints/create.d.ts +2 -9
  23. package/dist/commands/commitments/endpoints/create.js +10 -23
  24. package/dist/commands/commitments/mode.d.ts +15 -0
  25. package/dist/commands/commitments/mode.js +57 -0
  26. package/dist/commands/commitments/pack/promote.d.ts +1 -1
  27. package/dist/commands/commitments/pack/promote.js +7 -3
  28. package/dist/commands/commitments/pack/shadow.d.ts +3 -2
  29. package/dist/commands/commitments/pack/shadow.js +6 -4
  30. package/dist/commands/commitments/patch.d.ts +14 -0
  31. package/dist/commands/commitments/patch.js +51 -0
  32. package/dist/commands/commitments/preflight.d.ts +5 -2
  33. package/dist/commands/commitments/preflight.js +47 -6
  34. package/dist/commands/commitments/receipt.d.ts +15 -0
  35. package/dist/commands/commitments/receipt.js +34 -0
  36. package/dist/commands/commitments/remediate.d.ts +0 -1
  37. package/dist/commands/commitments/remediate.js +5 -3
  38. package/dist/commands/commitments/reports.js +27 -5
  39. package/dist/commands/commitments/show.d.ts +1 -0
  40. package/dist/commands/commitments/show.js +22 -1
  41. package/dist/commands/commitments/update.d.ts +9 -2
  42. package/dist/commands/commitments/update.js +40 -4
  43. package/dist/commands/commitments/wake-capabilities.d.ts +5 -0
  44. package/dist/commands/commitments/wake-capabilities.js +23 -7
  45. package/dist/commands/spaces/bootstrap.js +1 -1
  46. package/dist/commands/tasks/complete.js +57 -0
  47. package/dist/commands/tasks/create.js +2 -1
  48. package/dist/commands/tasks/deliverable/confirm.d.ts +35 -0
  49. package/dist/commands/tasks/deliverable/confirm.js +77 -0
  50. package/dist/commands/tasks/expectations.js +20 -1
  51. package/dist/commands/tasks/report.js +24 -0
  52. package/dist/commands/tasks/trust.d.ts +35 -0
  53. package/dist/commands/tasks/trust.js +75 -0
  54. package/dist/commands/tasks/waive.js +1 -1
  55. package/dist/lib/commitment-endpoints.d.ts +3 -2
  56. package/dist/lib/commitment-endpoints.js +12 -9
  57. package/dist/lib/commitment-product.d.ts +14 -0
  58. package/dist/lib/commitment-product.js +78 -0
  59. package/dist/lib/commitments.d.ts +67 -20
  60. package/dist/lib/commitments.js +89 -39
  61. package/dist/lib/tasks.js +27 -1
  62. package/dist/node_modules/@skrr-ai/data-provider/index.js +3733 -3570
  63. package/oclif.manifest.json +9291 -8306
  64. package/package.json +1 -1
@@ -1,6 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.COMMITMENT_CLI_EVALUATORS = exports.COMMITMENT_CREATE_KEYS = exports.COMMITMENT_REMEDIATION_ACTIONS = exports.COMMITMENT_FEEDBACK_KINDS = exports.commitmentApi = exports.commitmentPackApi = exports.MAX_COMMITMENT_INTERVAL_MS = exports.MIN_COMMITMENT_INTERVAL_MS = exports.COMMITMENT_AUTONOMY_MODES = exports.COMMITMENT_STATUSES = exports.COMMITMENT_CADENCE_MAX_TIMES = exports.COMMITMENT_CADENCE_TIME_PATTERN = exports.COMMITMENT_CADENCE_MODES = exports.COMMITMENT_TEMPLATE_IDS = exports.COMMITMENT_WATCHED_SOURCES = void 0;
3
+ exports.COMMITMENT_CLI_EVALUATORS = exports.COMMITMENT_CREATE_KEYS = exports.COMMITMENT_REMEDIATION_ACTIONS = exports.COMMITMENT_FEEDBACK_KINDS = exports.commitmentApi = exports.commitmentPackApi = exports.MAX_COMMITMENT_INTERVAL_MS = exports.MIN_COMMITMENT_INTERVAL_MS = exports.COMMITMENT_EXECUTION_ISOLATION_MODES = exports.COMMITMENT_AUTHORABLE_AUTONOMY_MODES = exports.COMMITMENT_AUTONOMY_MODES = exports.COMMITMENT_STATUSES = exports.COMMITMENT_AUTHORABLE_CADENCE_MODES = exports.COMMITMENT_CADENCE_MAX_TIMES = exports.COMMITMENT_CADENCE_TIME_PATTERN = exports.COMMITMENT_CADENCE_MODES = exports.COMMITMENT_TEMPLATE_IDS = exports.COMMITMENT_WATCHED_SOURCES = void 0;
4
+ exports.storedAutonomyModeForAuthoring = storedAutonomyModeForAuthoring;
5
+ exports.authoringAutonomyModeForStored = authoringAutonomyModeForStored;
6
+ exports.commitmentAutonomyLabel = commitmentAutonomyLabel;
7
+ exports.readCommitmentAgentDirective = readCommitmentAgentDirective;
4
8
  exports.normalizeCreateBody = normalizeCreateBody;
5
9
  exports.parseIntervalToMs = parseIntervalToMs;
6
10
  exports.buildWatchedSources = buildWatchedSources;
@@ -45,8 +49,15 @@ Object.defineProperty(exports, "COMMITMENT_TEMPLATE_IDS", { enumerable: true, ge
45
49
  Object.defineProperty(exports, "COMMITMENT_CADENCE_MODES", { enumerable: true, get: function () { return data_provider_1.COMMITMENT_CADENCE_MODES; } });
46
50
  Object.defineProperty(exports, "COMMITMENT_CADENCE_TIME_PATTERN", { enumerable: true, get: function () { return data_provider_1.COMMITMENT_CADENCE_TIME_PATTERN; } });
47
51
  Object.defineProperty(exports, "COMMITMENT_CADENCE_MAX_TIMES", { enumerable: true, get: function () { return data_provider_1.COMMITMENT_CADENCE_MAX_TIMES; } });
52
+ Object.defineProperty(exports, "COMMITMENT_AUTONOMY_MODES", { enumerable: true, get: function () { return data_provider_1.COMMITMENT_AUTONOMY_MODES; } });
53
+ Object.defineProperty(exports, "COMMITMENT_EXECUTION_ISOLATION_MODES", { enumerable: true, get: function () { return data_provider_1.COMMITMENT_EXECUTION_ISOLATION_MODES; } });
54
+ const commitment_product_1 = require("./commitment-product");
55
+ const instruction_input_1 = require("./instruction-input");
48
56
  const format_1 = require("./format");
49
57
  const triggers_1 = require("./triggers");
58
+ /** Derived from the installed compatibility vocabulary so the CLI remains
59
+ * safe even while data-provider and CLI packages roll out separately. */
60
+ exports.COMMITMENT_AUTHORABLE_CADENCE_MODES = data_provider_1.COMMITMENT_CADENCE_MODES.filter((mode) => mode !== 'sampled');
50
61
  /**
51
62
  * oclif's `options:` needs runtime arrays, but data-provider models these two as
52
63
  * union TYPES only. The values live here — and both directions of drift are a
@@ -63,27 +74,43 @@ exports.COMMITMENT_STATUSES = [
63
74
  ];
64
75
  const _statusDriftGuard = true;
65
76
  void _statusDriftGuard;
66
- /** Autonomy ladder how much the commitment may act without asking. */
67
- exports.COMMITMENT_AUTONOMY_MODES = [
68
- 'off',
69
- 'suggestions_only',
70
- 'ask_first',
71
- 'auto_run_limited',
72
- 'auto_run',
73
- ];
74
- const _autonomyDriftGuard = true;
75
- void _autonomyDriftGuard;
77
+ exports.COMMITMENT_AUTHORABLE_AUTONOMY_MODES = ['monitor', 'prepare', 'execute'];
78
+ function storedAutonomyModeForAuthoring(mode) {
79
+ if (mode === 'monitor')
80
+ return 'suggestions_only';
81
+ if (mode === 'prepare')
82
+ return 'ask_first';
83
+ if (mode === 'execute')
84
+ return 'auto_run';
85
+ throw new Error(`Unsupported autonomy mode: ${mode}. Use monitor, prepare, or execute.`);
86
+ }
87
+ function authoringAutonomyModeForStored(mode) {
88
+ if (mode === 'ask_first')
89
+ return 'prepare';
90
+ if (mode === 'auto_run' || mode === 'auto_run_limited')
91
+ return 'execute';
92
+ return 'monitor';
93
+ }
94
+ function commitmentAutonomyLabel(mode) {
95
+ if (mode === 'suggestions_only')
96
+ return 'Monitor';
97
+ if (mode === 'ask_first')
98
+ return 'Prepare';
99
+ if (mode === 'auto_run' || mode === 'auto_run_limited')
100
+ return 'Execute';
101
+ if (mode === 'off')
102
+ return 'Legacy off (pause the Commitment)';
103
+ return mode || '-';
104
+ }
76
105
  /**
77
106
  * Interval bounds for `cadence.intervalMs`.
78
107
  *
79
- * The REST schema permits up to 30d, but the mirrored
80
- * `TriggerDefinition.schedule.intervalMs` is capped at 24h and
81
- * `CommitmentTriggerSync` swallows the resulting validation failure — so a cadence
82
- * over 24h yields a commitment whose control loop NEVER fires while every surface
83
- * reports success. Cap at 24h so that state is unreachable from the CLI.
108
+ * The Trigger schedule and Commitment contract now share the same one-year
109
+ * upper bound. Keep the CLI aligned so a valid long-interval contract does not
110
+ * get rejected only at this surface.
84
111
  */
85
112
  exports.MIN_COMMITMENT_INTERVAL_MS = 60_000;
86
- exports.MAX_COMMITMENT_INTERVAL_MS = 24 * 60 * 60 * 1000;
113
+ exports.MAX_COMMITMENT_INTERVAL_MS = 365 * 24 * 60 * 60 * 1000;
87
114
  function base(id) {
88
115
  return `/api/commitments/${encodeURIComponent(id)}`;
89
116
  }
@@ -116,6 +143,7 @@ exports.commitmentApi = {
116
143
  get: (id) => data_provider_1.request.get(base(id)),
117
144
  create: (body) => data_provider_1.request.post('/api/commitments', body),
118
145
  update: (id, body) => data_provider_1.request.patch(base(id), body),
146
+ draftPreflight: (body) => data_provider_1.request.post('/api/commitments/preflight', body),
119
147
  workLinks: (id, includeInactive = false) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/links`, { ...(includeInactive ? { includeInactive: true } : {}) })),
120
148
  createWorkLink: (id, body) => data_provider_1.request.post(`${base(id)}/links`, body),
121
149
  updateWorkLink: (id, linkId, body) => data_provider_1.request.patch(`${base(id)}/links/${encodeURIComponent(linkId)}`, body),
@@ -124,6 +152,11 @@ exports.commitmentApi = {
124
152
  checkNow: (id) => data_provider_1.request.post(`${base(id)}/check-now`, {}),
125
153
  checks: (id, limit) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/checks`, { limit })),
126
154
  actionHistory: (id, limit) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/action-history`, { limit })),
155
+ actionProposals: (id, query = {}) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/action-proposals`, query)),
156
+ decideActionProposal: (id, proposalId, decision) => data_provider_1.request.post(`${base(id)}/action-proposals/${encodeURIComponent(proposalId)}/decision`, {
157
+ decision,
158
+ }),
159
+ executeActionProposal: (id, proposalId) => data_provider_1.request.post(`${base(id)}/action-proposals/${encodeURIComponent(proposalId)}/execute`, {}),
127
160
  preflight: (id, nextRunCount) => data_provider_1.request.post(`${base(id)}/preflight`, {
128
161
  ...(typeof nextRunCount === 'number' ? { nextRunCount } : {}),
129
162
  }),
@@ -132,6 +165,11 @@ exports.commitmentApi = {
132
165
  resume: (id) => data_provider_1.request.post(`${base(id)}/resume`, {}),
133
166
  complete: (id) => data_provider_1.request.post(`${base(id)}/complete`, {}),
134
167
  autonomy: (id, body) => data_provider_1.request.post(`${base(id)}/autonomy`, body),
168
+ mode: (id, body) => data_provider_1.request.post(`${base(id)}/mode`, body),
169
+ delivery: (id, body) => data_provider_1.request.post(`${base(id)}/delivery`, body),
170
+ receipts: (id, limit = 1) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/receipts`, { limit })),
171
+ deliveryPatch: (id, taskId) => data_provider_1.request.get(`${base(id)}/delivery/${encodeURIComponent(taskId)}/patch`),
172
+ deliveryBundle: (id, taskId) => data_provider_1.request.get(`${base(id)}/delivery/${encodeURIComponent(taskId)}/bundle`),
135
173
  operatingReview: (agentId) => data_provider_1.request.get(`/api/commitments/agents/${encodeURIComponent(agentId)}/operating-review`),
136
174
  reflection: (id) => data_provider_1.request.get(`${base(id)}/reflection`),
137
175
  decideReflectionProposal: (id, proposalKey, decision) => data_provider_1.request.post(`${base(id)}/reflection/proposals/${encodeURIComponent(proposalKey)}/decision`, {
@@ -219,6 +257,7 @@ exports.COMMITMENT_REMEDIATION_ACTIONS = [
219
257
  ];
220
258
  /** The only keys `createBodySchema` (a `z.strictObject`) accepts. */
221
259
  exports.COMMITMENT_CREATE_KEYS = [
260
+ 'mode',
222
261
  'agentId',
223
262
  'kind',
224
263
  'compassId',
@@ -231,6 +270,7 @@ exports.COMMITMENT_CREATE_KEYS = [
231
270
  'target',
232
271
  'watchedSources',
233
272
  'policy',
273
+ 'delivery',
234
274
  'cadence',
235
275
  'subject',
236
276
  'sensors',
@@ -238,6 +278,20 @@ exports.COMMITMENT_CREATE_KEYS = [
238
278
  'reports',
239
279
  'createdVia',
240
280
  ];
281
+ /**
282
+ * Read the per-Commitment domain policy from an inline flag or a text file.
283
+ *
284
+ * This deliberately uses a separate pair of names from Agent-level instruction
285
+ * commands: the result configures one Commitment run, not the Agent's global
286
+ * prompt. The explicit error also keeps shell users from accidentally masking
287
+ * a reviewed file with a short inline experiment.
288
+ */
289
+ async function readCommitmentAgentDirective({ directive, file, }) {
290
+ if (directive !== undefined && file !== undefined) {
291
+ throw new Error('Use either --agent-directive or --agent-directive-file, not both.');
292
+ }
293
+ return (0, instruction_input_1.readInstructionBody)({ body: directive, file });
294
+ }
241
295
  /**
242
296
  * Normalize a `--from-json` body into something the create endpoint accepts.
243
297
  *
@@ -248,8 +302,9 @@ exports.COMMITMENT_CREATE_KEYS = [
248
302
  * contract dumped from `list --json` carries id/version/state/ownerUserId/…
249
303
  * — drop everything the schema does not declare.
250
304
  *
251
- * `status` is additionally narrowed: create only permits `draft|active`, but a
252
- * dumped contract may carry `paused`/`completed`.
305
+ * `status` is additionally narrowed: create only permits `draft`; activation
306
+ * is the separate resume + preflight boundary. A dumped contract may carry an
307
+ * active or terminal state, but importing it must still create a draft.
253
308
  */
254
309
  function normalizeCreateBody(input) {
255
310
  const envelope = input;
@@ -261,7 +316,7 @@ function normalizeCreateBody(input) {
261
316
  if (src[key] !== undefined)
262
317
  out[key] = src[key];
263
318
  }
264
- if (out.status !== 'draft' && out.status !== 'active') {
319
+ if (out.status !== 'draft') {
265
320
  delete out.status;
266
321
  }
267
322
  return out;
@@ -314,7 +369,7 @@ function parseIntervalToMs(input) {
314
369
  // Throw rather than clamp: silently turning a requested 90d cadence into 30d
315
370
  // (or 0 into 1m) hides a real misconfiguration on a live control loop.
316
371
  if (ms < exports.MIN_COMMITMENT_INTERVAL_MS || ms > exports.MAX_COMMITMENT_INTERVAL_MS) {
317
- throw new Error(`Interval "${input}" is out of range — must be between 1m and 24h (got ${describeIntervalMs(ms)}).`);
372
+ throw new Error(`Interval "${input}" is out of range — must be between 1m and 365d (got ${describeIntervalMs(ms)}).`);
318
373
  }
319
374
  return ms;
320
375
  }
@@ -499,14 +554,14 @@ function renderCommitmentList(commitments, log) {
499
554
  status: o.status ?? '-',
500
555
  health: o.state?.health ?? '-',
501
556
  cadence: cadenceLabel(o),
502
- autonomy: o.policy?.autonomyMode ?? '-',
557
+ autonomy: (0, commitment_product_1.productModeLabel)(o.policy?.autonomyMode),
503
558
  agent: o.agentId ?? '-',
504
559
  })), [
505
560
  { key: 'title', header: 'TITLE', maxWidth: 34 },
506
561
  { key: 'status', header: 'STATUS', maxWidth: 10 },
507
562
  { key: 'health', header: 'HEALTH', maxWidth: 16 },
508
563
  { key: 'cadence', header: 'CADENCE', maxWidth: 10 },
509
- { key: 'autonomy', header: 'AUTONOMY', maxWidth: 18 },
564
+ { key: 'autonomy', header: 'MODE', maxWidth: 18 },
510
565
  { key: 'agent', header: 'AGENT', verbatim: true },
511
566
  // Commitment ids are routinely pasted into `check-now`, so this column
512
567
  // is never clipped. Widening the guess (28 → 44) fixed today's
@@ -518,13 +573,11 @@ function renderCommitmentList(commitments, log) {
518
573
  * The autonomy mode a check ACTUALLY ran at, read from its policy trace
519
574
  * (OSK-4881).
520
575
  *
521
- * A commitment's STATED autonomy (`policy.autonomyMode`) is only a ceiling: the
522
- * arbiter clamps it to the stricter of the agent's initiative policy and the
523
- * workspace's governance, then records the mode it settled on in the check's
524
- * `decision.policyTrace`. The arbiter's own decision carries it as
525
- * `autonomyMode`; the workspace-governance entry carries the clamped ceiling as
526
- * `effectiveAutonomyMode`. Either answers "what governed this run". Returns the
527
- * effective mode when the trace carries one, else undefined.
576
+ * A check records the Mode it actually used in `decision.policyTrace`. For the
577
+ * v2 product contract, only an explicit Workspace-admin constraint may lower
578
+ * the declared Mode; legacy checks may still carry older effective-mode traces.
579
+ * Either `autonomyMode` or `effectiveAutonomyMode` answers what governed that
580
+ * particular run. Returns undefined when the trace carries neither.
528
581
  *
529
582
  * Exported for tests.
530
583
  */
@@ -589,14 +642,10 @@ function extractStandstillFromCheck(check) {
589
642
  function describeAutonomyLine(commitment, latestCheck) {
590
643
  const stated = commitment.policy?.autonomyMode ?? '-';
591
644
  const effective = effectiveAutonomyMode(latestCheck);
592
- const envelopeEnabled = commitment.policy?.autonomyEnvelope?.enabled;
593
- const envelope = typeof envelopeEnabled === 'boolean'
594
- ? ` [envelope: ${envelopeEnabled ? 'enabled' : 'disabled'}]`
595
- : '';
596
645
  if (effective && effective !== stated) {
597
- return `${stated} (effective: ${effective} — capped by initiative or workspace policy)${envelope}`;
646
+ return `${(0, commitment_product_1.productModeLabel)(stated)} (effective: ${(0, commitment_product_1.productModeLabel)(effective)} — constrained by configured policy)`;
598
647
  }
599
- return `${stated}${envelope}`;
648
+ return (0, commitment_product_1.productModeLabel)(stated);
600
649
  }
601
650
  function renderCommitmentSummary(commitment, log,
602
651
  /**
@@ -621,7 +670,8 @@ latestCheck) {
621
670
  log(`Cadence: ${cadenceLabel(commitment)}`);
622
671
  if (commitment.cadence?.nextCheckAt)
623
672
  log(`Next check:${` ${commitment.cadence.nextCheckAt}`}`);
624
- log(`Autonomy: ${describeAutonomyLine(commitment, latestCheck)}`);
673
+ log(`Mode: ${describeAutonomyLine(commitment, latestCheck)}`);
674
+ log(`Delivery: ${(0, commitment_product_1.deliveryLabel)(commitment.delivery?.mode)}${commitment.delivery?.repo ? ` · ${commitment.delivery.repo}` : ''}${commitment.delivery?.baseBranch ? ` → ${commitment.delivery.baseBranch}` : ''}`);
625
675
  const criteria = commitment.target?.successCriteria || [];
626
676
  const evidenceHealth = latestCheck?.inputs?.evidenceHealth;
627
677
  const evidenceLine = describeEvidenceHealth(evidenceHealth, criteria.length);
@@ -645,7 +695,7 @@ latestCheck) {
645
695
  if (standstill) {
646
696
  const streak = commitment.state?.consecutiveUnresolvedChecks;
647
697
  const streakClause = typeof streak === 'number' && streak >= 2 ? `${streak} checks in a row: ` : '';
648
- log(`Standstill:${` ${streakClause}${standstill.reason}`}`);
698
+ log(`Standstill:${` ${streakClause}${(0, data_provider_1.describeStandstill)(standstill.reason).title}`}`);
649
699
  if (standstill.fix)
650
700
  log(` Fix: ${standstill.fix}`);
651
701
  if (standstill.alsoConstrained?.length) {
@@ -658,7 +708,7 @@ latestCheck) {
658
708
  })
659
709
  .filter((r) => Boolean(r));
660
710
  if (also.length)
661
- log(` Also constrained: ${also.join(', ')}`);
711
+ log(` Also constrained: ${also.map((reason) => (0, data_provider_1.describeStandstill)(reason).title).join(', ')}`);
662
712
  }
663
713
  }
664
714
  const sources = (commitment.watchedSources || [])
package/dist/lib/tasks.js CHANGED
@@ -170,8 +170,34 @@ function parseDeliverableCoordinate(spec) {
170
170
  }
171
171
  /** Lifecycle values a caller may assert, for flag validation. */
172
172
  exports.DELIVERABLE_LIFECYCLE_VALUES = data_provider_1.DELIVERABLE_LIFECYCLES;
173
+ /**
174
+ * `--from-json` takes stored API field names, while the interactive flags use
175
+ * shorter names such as `--project` and `--spawned-by`. Normalize the obvious
176
+ * camel-case forms before a permissive API route can silently drop them.
177
+ */
178
+ function normalizeTaskCreateJsonAliases(body) {
179
+ const normalized = { ...body };
180
+ const aliases = [
181
+ ['parent', 'parentId'],
182
+ ['space', 'spaceId'],
183
+ ['goal', 'goalId'],
184
+ ['commitment', 'commitmentId'],
185
+ ['project', 'projectId'],
186
+ ['cycle', 'cycleId'],
187
+ ['spawnedBy', 'spawnedByTaskId'],
188
+ ];
189
+ for (const [alias, canonical] of aliases) {
190
+ if (Object.prototype.hasOwnProperty.call(normalized, canonical))
191
+ continue;
192
+ if (!Object.prototype.hasOwnProperty.call(normalized, alias))
193
+ continue;
194
+ normalized[canonical] = normalized[alias];
195
+ delete normalized[alias];
196
+ }
197
+ return normalized;
198
+ }
173
199
  function buildTaskCreatePayload(body, flags = {}) {
174
- const payload = (0, prompt_1.mergeDefined)(body, {
200
+ const payload = (0, prompt_1.mergeDefined)(normalizeTaskCreateJsonAliases(body), {
175
201
  templateId: flags.template,
176
202
  title: flags.title,
177
203
  description: flags.description,