@skrr-ai/cli 0.1.116 → 0.1.118

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 (94) hide show
  1. package/dist/base-command.d.ts +21 -0
  2. package/dist/base-command.js +95 -8
  3. package/dist/commands/actions/browse.js +2 -1
  4. package/dist/commands/actions/install.d.ts +2 -0
  5. package/dist/commands/actions/install.js +67 -2
  6. package/dist/commands/actions/list.js +2 -1
  7. package/dist/commands/actions/show.js +2 -1
  8. package/dist/commands/commitments/create.d.ts +21 -2
  9. package/dist/commands/commitments/create.js +74 -4
  10. package/dist/commands/convos/recovery.js +12 -4
  11. package/dist/commands/followups/plans/list.js +1 -1
  12. package/dist/commands/guide.d.ts +21 -0
  13. package/dist/commands/guide.js +46 -0
  14. package/dist/commands/instructions/guide.js +34 -52
  15. package/dist/commands/memory/maintain.js +1 -1
  16. package/dist/commands/skills/browse.js +2 -1
  17. package/dist/commands/skills/details.js +4 -2
  18. package/dist/commands/skills/featured.js +2 -1
  19. package/dist/commands/skills/install.d.ts +2 -0
  20. package/dist/commands/skills/install.js +62 -3
  21. package/dist/commands/skills/search.js +2 -1
  22. package/dist/commands/slack/send-as-agent.js +3 -3
  23. package/dist/commands/spaces/create.js +8 -2
  24. package/dist/commands/spaces/guide.d.ts +21 -0
  25. package/dist/commands/spaces/guide.js +40 -0
  26. package/dist/commands/spaces/index.d.ts +0 -1
  27. package/dist/commands/spaces/index.js +1 -6
  28. package/dist/commands/store/acquisitions/list.js +2 -1
  29. package/dist/commands/store/acquisitions/show.js +2 -1
  30. package/dist/commands/store/browse.js +4 -2
  31. package/dist/commands/store/install.d.ts +1 -0
  32. package/dist/commands/store/install.js +26 -2
  33. package/dist/commands/store/releases.js +4 -2
  34. package/dist/commands/store/show.js +3 -2
  35. package/dist/commands/store/tip.js +2 -2
  36. package/dist/commands/tasks/checkout.js +2 -3
  37. package/dist/commands/tasks/comments/add.js +3 -5
  38. package/dist/commands/tasks/complete.js +2 -3
  39. package/dist/commands/tasks/deliverable/add.d.ts +1 -1
  40. package/dist/commands/tasks/deliverable/add.js +4 -7
  41. package/dist/commands/tasks/expectations/assess.js +2 -2
  42. package/dist/commands/tasks/guide.d.ts +8 -0
  43. package/dist/commands/tasks/guide.js +23 -10
  44. package/dist/commands/tasks/report.js +9 -5
  45. package/dist/commands/tasks/resource/add.js +2 -3
  46. package/dist/commands/tasks/result/submit.js +2 -3
  47. package/dist/commands/tasks/resume/save.js +2 -3
  48. package/dist/commands/tasks/review.js +2 -3
  49. package/dist/commands/tasks/triage.js +2 -1
  50. package/dist/commands/tasks/updates/add.js +2 -3
  51. package/dist/generated/agent-guides.json +8312 -0
  52. package/dist/generated/managed-instruction-guides.json +1 -1
  53. package/dist/help.js +4 -3
  54. package/dist/hooks/command-not-found.js +1 -1
  55. package/dist/lib/action-listings.js +2 -1
  56. package/dist/lib/agent-guide-reference-gate.d.ts +28 -0
  57. package/dist/lib/agent-guide-reference-gate.js +186 -0
  58. package/dist/lib/agent-guides.d.ts +51 -0
  59. package/dist/lib/agent-guides.js +170 -0
  60. package/dist/lib/api-fetch.js +3 -1
  61. package/dist/lib/command-miss.d.ts +13 -2
  62. package/dist/lib/command-miss.js +134 -8
  63. package/dist/lib/guide-pointer.d.ts +15 -0
  64. package/dist/lib/guide-pointer.js +51 -0
  65. package/dist/lib/lookbackPlans.d.ts +3 -1
  66. package/dist/lib/lookbackPlans.js +9 -0
  67. package/dist/lib/node-adapter.js +4 -3
  68. package/dist/lib/outbox.d.ts +0 -14
  69. package/dist/lib/outbox.js +0 -21
  70. package/dist/lib/roles.d.ts +1 -1
  71. package/dist/lib/store-listing.d.ts +6 -1
  72. package/dist/lib/store-listing.js +6 -1
  73. package/dist/lib/task-admission.js +27 -5
  74. package/dist/lib/task-batch.d.ts +10 -7
  75. package/dist/lib/task-batch.js +5 -20
  76. package/dist/lib/task-operations.d.ts +8 -20
  77. package/dist/lib/task-operations.js +9 -94
  78. package/dist/lib/task-preflight.js +70 -33
  79. package/dist/lib/task-runtime-headers.d.ts +11 -0
  80. package/dist/lib/task-runtime-headers.js +73 -0
  81. package/dist/lib/task-write-attribution.js +1 -1
  82. package/dist/lib/usage-discovery.d.ts +4 -0
  83. package/dist/lib/usage-discovery.js +5 -0
  84. package/dist/lib/usd-micros.d.ts +27 -0
  85. package/dist/lib/usd-micros.js +67 -2
  86. package/dist/lib/voice-call-intent.js +3 -1
  87. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/harnessPermissionControls.d.ts +17 -0
  88. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/harnessPermissionControls.js +35 -2
  89. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/harnessPermissionControls.d.ts +17 -0
  90. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/harnessPermissionControls.js +44 -0
  91. package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
  92. package/dist/node_modules/@skrr-ai/data-provider/index.js +11927 -11678
  93. package/oclif.manifest.json +251 -14
  94. package/package.json +4 -2
@@ -5,6 +5,7 @@ const data_provider_1 = require("@skrr-ai/data-provider");
5
5
  const base_command_1 = require("../../base-command");
6
6
  const agent_ref_1 = require("../../lib/agent-ref");
7
7
  const prompt_1 = require("../../lib/prompt");
8
+ const usd_micros_1 = require("../../lib/usd-micros");
8
9
  /**
9
10
  * One line per placement, said the same way the web install rail says it: the
10
11
  * difference is whether a stranger's instructions may reach a connected
@@ -23,6 +24,7 @@ class StoreInstall extends base_command_1.BaseCommand {
23
24
  '<%= config.bin %> store install agent_abc123 --run-on local',
24
25
  '<%= config.bin %> store install agent_abc123 --share-outcomes',
25
26
  '<%= config.bin %> store install agent_abc123 --yes --json',
27
+ '<%= config.bin %> store install agent_abc123 --yes --expected-price 4',
26
28
  ];
27
29
  static args = {
28
30
  agent: core_1.Args.string({
@@ -45,6 +47,10 @@ class StoreInstall extends base_command_1.BaseCommand {
45
47
  char: 'y',
46
48
  description: 'Confirm a paid purchase without prompting. The price and refund terms are still printed.',
47
49
  }),
50
+ 'expected-price': core_1.Flags.string({
51
+ description: 'Refuse unless the purchase would charge exactly this USD amount (e.g. 4 or 2.50; 0 pins free). ' +
52
+ 'Use it to pin the price the person named, not just the one read now.',
53
+ }),
48
54
  'run-on': core_1.Flags.string({
49
55
  description: 'Where its tools may run. cloud (the default) keeps tools off connected machines; ' +
50
56
  'local lets tools use an available connected machine in your account, selected at run time. The agent runs in the cloud either way',
@@ -121,6 +127,21 @@ class StoreInstall extends base_command_1.BaseCommand {
121
127
  });
122
128
  }
123
129
  const charge = Number(quote.charge) || 0;
130
+ // A caller-pinned price binds the purchase to what the PERSON named, not
131
+ // just to what this command read: a listing that moved, or a pin that
132
+ // never matched, refuses here before anything is charged (OSK-18256).
133
+ const expectedMicros = (0, usd_micros_1.expectedPriceFlagMicros)(flags['expected-price']);
134
+ if (expectedMicros === null) {
135
+ this.error(`--expected-price must be a USD amount with at most 2 decimals, e.g. 4 or 2.50 (got "${flags['expected-price']}")`, { exit: 2 });
136
+ }
137
+ if (expectedMicros !== undefined && expectedMicros !== charge) {
138
+ this.failWithCliError({
139
+ message: (0, usd_micros_1.expectedPriceMismatchMessage)(expectedMicros, charge),
140
+ code: 'EXPECTED_PRICE_MISMATCH',
141
+ exit: 1,
142
+ retryable: false,
143
+ });
144
+ }
124
145
  if (charge > 0) {
125
146
  const name = quote.listingName || agentId;
126
147
  const version = quote.versionLabel ? ` v${quote.versionLabel}` : '';
@@ -134,8 +155,11 @@ class StoreInstall extends base_command_1.BaseCommand {
134
155
  this.logToStderr(` Buyer terms: ${quote.buyerTerms
135
156
  ? `${quote.buyerTerms.termsVersion} — ${quote.buyerTerms.artifactUri}`
136
157
  : 'not configured'}`);
158
+ // This path records no acceptance — answering yes buys only. Without a
159
+ // prior acceptance the server refuses MARKETPLACE_TERMS_ACCEPTANCE_REQUIRED.
160
+ this.logToStderr(' Buying requires those terms already accepted; a yes here does not accept them.');
137
161
  this.logToStderr(` Offer: ${quote.offerVersionId}`);
138
- const confirmed = await (0, prompt_1.confirmDestructive)(`Buy ${name} for ${(0, data_provider_1.formatStoreAcquisitionPrice)(charge)} and accept the buyer terms?`, flags.yes).catch((err) => this.error(err.message, { exit: err.exit ?? 1 }));
162
+ const confirmed = await (0, prompt_1.confirmDestructive)(`Buy ${name} for ${(0, data_provider_1.formatStoreAcquisitionPrice)(charge)}?`, flags.yes).catch((err) => this.error(err.message, { exit: err.exit ?? 1 }));
139
163
  if (!confirmed) {
140
164
  this.log('Cancelled. Nothing was bought.');
141
165
  return;
@@ -168,7 +192,7 @@ class StoreInstall extends base_command_1.BaseCommand {
168
192
  this.handleApiError(err);
169
193
  }
170
194
  if (flags.json) {
171
- this.log(JSON.stringify(response, null, 2));
195
+ this.log(JSON.stringify((0, usd_micros_1.withUsdPrices)(response), null, 2));
172
196
  return;
173
197
  }
174
198
  const installedId = response?.installedAgentId;
@@ -4,6 +4,8 @@ const core_1 = require("@oclif/core");
4
4
  const data_provider_1 = require("@skrr-ai/data-provider");
5
5
  const base_command_1 = require("../../base-command");
6
6
  const format_1 = require("../../lib/format");
7
+ const store_listing_1 = require("../../lib/store-listing");
8
+ const usd_micros_1 = require("../../lib/usd-micros");
7
9
  /**
8
10
  * What versions of a published agent exist.
9
11
  *
@@ -34,7 +36,7 @@ class StoreReleases extends base_command_1.BaseCommand {
34
36
  this.handleApiError(err);
35
37
  }
36
38
  if (flags.json) {
37
- this.log(JSON.stringify(response, null, 2));
39
+ this.log(JSON.stringify((0, usd_micros_1.withUsdPrices)(response), null, 2));
38
40
  return;
39
41
  }
40
42
  const items = response?.data ?? [];
@@ -45,7 +47,7 @@ class StoreReleases extends base_command_1.BaseCommand {
45
47
  (0, format_1.renderTable)(items.map((r) => ({
46
48
  id: String(r.id ?? '-'),
47
49
  version: String(r.versionLabel ?? '-'),
48
- price: r.price ? String(r.price) : 'free',
50
+ price: (0, store_listing_1.formatListingPrice)(typeof r.price === 'number' ? r.price : null),
49
51
  published: r.publishedAt ? String(r.publishedAt).slice(0, 10) : '-',
50
52
  changelog: String(r.changelog ?? ''),
51
53
  })), [
@@ -6,6 +6,7 @@ const base_command_1 = require("../../base-command");
6
6
  const agent_ref_1 = require("../../lib/agent-ref");
7
7
  const format_1 = require("../../lib/format");
8
8
  const store_listing_1 = require("../../lib/store-listing");
9
+ const usd_micros_1 = require("../../lib/usd-micros");
9
10
  const web_url_1 = require("../../lib/web-url");
10
11
  /** How many releases the detail view lists; `store releases` lists them all. */
11
12
  const RECENT_RELEASES = 5;
@@ -88,7 +89,7 @@ class StoreShow extends base_command_1.BaseCommand {
88
89
  const listingUrl = (0, web_url_1.webUrl)(this.cliConfig.baseURL, { kind: 'storeListing', agentId });
89
90
  const releaseRows = (releases.value?.data ?? []).slice(0, RECENT_RELEASES);
90
91
  if (flags.json) {
91
- this.log(JSON.stringify({
92
+ this.log(JSON.stringify((0, usd_micros_1.withUsdPrices)({
92
93
  agent: listing,
93
94
  publisher: {
94
95
  handle,
@@ -102,7 +103,7 @@ class StoreShow extends base_command_1.BaseCommand {
102
103
  ...(releases.error ? { releasesError: releases.error } : {}),
103
104
  url: listingUrl,
104
105
  installCommand,
105
- }, null, 2));
106
+ }), null, 2));
106
107
  return;
107
108
  }
108
109
  const version = listing.versionLabel ? `v${listing.versionLabel}` : 'no version label';
@@ -42,12 +42,12 @@ class StoreTip extends base_command_1.BaseCommand {
42
42
  try {
43
43
  const result = await data_provider_1.dataService.tipStoreAgent(args.agentId, { amountMicros, tipId });
44
44
  if (flags.json) {
45
- this.log(JSON.stringify(result, null, 2));
45
+ this.log(JSON.stringify((0, usd_micros_1.withUsdPrices)(result), null, 2));
46
46
  return;
47
47
  }
48
48
  this.log(result.replayed
49
49
  ? `Already tipped under ${tipId}; nothing new was charged.`
50
- : `Tipped $${(result.amountMicros / 1_000_000).toFixed(2)} (tip ${tipId}).`);
50
+ : `Tipped ${(0, data_provider_1.formatStoreAcquisitionPrice)(result.amountMicros)} (tip ${tipId}).`);
51
51
  }
52
52
  catch (err) {
53
53
  this.handleApiError(err);
@@ -61,11 +61,10 @@ class TasksCheckout extends base_command_1.BaseCommand {
61
61
  result = await data_provider_1.dataService.checkoutTask({ taskId: taskRef, runId });
62
62
  }
63
63
  catch (err) {
64
- const e = err;
65
- if (e.status === 409) {
64
+ if ((0, base_command_1.apiRefusal)(err).code === 'TASK_ALREADY_CHECKED_OUT') {
66
65
  // Dedicated exit code for "conflict" so scripts can distinguish
67
66
  // "already checked out" from other failures without string-matching
68
- // the message.
67
+ // the message. Other 409s have their own server-provided reason.
69
68
  this.error('Task is already checked out by another run.', { exit: 9 });
70
69
  }
71
70
  this.handleApiError(err);
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const node_crypto_1 = require("node:crypto");
4
4
  const core_1 = require("@oclif/core");
5
5
  const base_command_1 = require("../../../base-command");
6
- const outbox_1 = require("../../../lib/outbox");
7
6
  const api_fetch_1 = require("../../../lib/api-fetch");
8
7
  const credential_resolver_1 = require("../../../lib/credential-resolver");
9
8
  const unsupported_managed_task_write_1 = require("../../../lib/unsupported-managed-task-write");
@@ -188,7 +187,7 @@ class TasksCommentsAdd extends base_command_1.BaseCommand {
188
187
  // ONE key for the original attempt and any later replay — see the comment
189
188
  // in `spaces create`. A key sent only on the replay would post a second
190
189
  // comment whenever the original landed and its response was lost.
191
- const idempotencyKey = (0, outbox_1.idempotencyKeyFor)('task-comment', taskRef, JSON.stringify(data));
190
+ const idempotencyKey = `task-comment_${(0, node_crypto_1.randomUUID)()}`;
192
191
  let result;
193
192
  try {
194
193
  // apiFetch rather than `dataService.addTaskComment`: the shared transport
@@ -225,9 +224,8 @@ class TasksCommentsAdd extends base_command_1.BaseCommand {
225
224
  }
226
225
  // A comment body is authored content: losing it to a 503 costs the
227
226
  // writing, not just a retry. Queue it durably instead (OSK-2806). The
228
- // key is derived from the task + body so replaying the SAME comment
229
- // collapses server-side rather than posting it twice; a genuinely
230
- // different comment on the same task hashes differently and still posts.
227
+ // key is kept from the original attempt, so replaying this queued intent
228
+ // collapses server-side rather than posting it twice.
231
229
  this.queueWriteOrFail(err, {
232
230
  command: 'tasks comments add',
233
231
  summary: `comment on task ${taskRef}`,
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.describePendingReview = describePendingReview;
4
+ const node_crypto_1 = require("node:crypto");
4
5
  const core_1 = require("@oclif/core");
5
6
  const base_command_1 = require("../../base-command");
6
7
  const task_closure_1 = require("../../lib/task-closure");
7
8
  const api_fetch_1 = require("../../lib/api-fetch");
8
9
  const task_recurrence_outcome_1 = require("../../lib/task-recurrence-outcome");
9
- const outbox_1 = require("../../lib/outbox");
10
10
  const prompt_1 = require("../../lib/prompt");
11
11
  const session_task_write_1 = require("../../lib/session-task-write");
12
12
  const task_resolver_1 = require("../../lib/task-resolver");
@@ -278,8 +278,7 @@ class TasksComplete extends base_command_1.BaseCommand {
278
278
  expectedSpecVersion: typeof input.expectedSpecVersion === 'number' ? input.expectedSpecVersion : undefined,
279
279
  ...(input.force === true ? { force: true } : {}),
280
280
  };
281
- const idempotencyKey = optionalString(input.idempotencyKey) ||
282
- (0, outbox_1.idempotencyKeyFor)('task-complete', identity.id, JSON.stringify(payload));
281
+ const idempotencyKey = optionalString(input.idempotencyKey) || `task-complete_${(0, node_crypto_1.randomUUID)()}`;
283
282
  const sessionWrite = await (0, session_task_write_1.sessionTaskWrite)('completion', identity.id);
284
283
  let taskId = identity.id;
285
284
  if (sessionWrite)
@@ -1,5 +1,5 @@
1
1
  import { BaseCommand } from '../../../base-command';
2
- export declare function defaultDeliverableIdempotencyKey(task: string, payload: Record<string, unknown>): string;
2
+ export declare function defaultDeliverableIdempotencyKey(): string;
3
3
  /**
4
4
  * `skrr tasks deliverable add <task> <kind>:<identity>[@<location>]`
5
5
  *
@@ -37,18 +37,16 @@ exports.defaultDeliverableIdempotencyKey = defaultDeliverableIdempotencyKey;
37
37
  exports.statusNotApplied = statusNotApplied;
38
38
  const fs = __importStar(require("node:fs"));
39
39
  const path = __importStar(require("node:path"));
40
+ const node_crypto_1 = require("node:crypto");
40
41
  const core_1 = require("@oclif/core");
41
42
  const data_provider_1 = require("@skrr-ai/data-provider");
42
43
  const base_command_1 = require("../../../base-command");
43
44
  const task_asset_upload_1 = require("../../../lib/task-asset-upload");
44
- const outbox_1 = require("../../../lib/outbox");
45
45
  const api_fetch_1 = require("../../../lib/api-fetch");
46
46
  const session_task_write_1 = require("../../../lib/session-task-write");
47
47
  const tasks_1 = require("../../../lib/tasks");
48
- function defaultDeliverableIdempotencyKey(task, payload) {
49
- // A retry of one exact observation keeps its key. A new version, provider,
50
- // digest, or expectation binding is a different observation.
51
- return (0, outbox_1.idempotencyKeyFor)('task-deliverable', task, JSON.stringify(payload));
48
+ function defaultDeliverableIdempotencyKey() {
49
+ return `task-deliverable_${(0, node_crypto_1.randomUUID)()}`;
52
50
  }
53
51
  /**
54
52
  * `skrr tasks deliverable add <task> <kind>:<identity>[@<location>]`
@@ -192,8 +190,7 @@ class TasksDeliverableAdd extends base_command_1.BaseCommand {
192
190
  };
193
191
  const payload = {
194
192
  ...observation,
195
- idempotencyKey: flags['idempotency-key'] ||
196
- defaultDeliverableIdempotencyKey(args.task, observation),
193
+ idempotencyKey: flags['idempotency-key'] || defaultDeliverableIdempotencyKey(),
197
194
  };
198
195
  const sessionWrite = await (0, session_task_write_1.sessionTaskWrite)('deliverable', args.task);
199
196
  result = sessionWrite
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_crypto_1 = require("node:crypto");
3
4
  const core_1 = require("@oclif/core");
4
5
  const data_provider_1 = require("@skrr-ai/data-provider");
5
6
  const base_command_1 = require("../../../base-command");
6
- const outbox_1 = require("../../../lib/outbox");
7
7
  const task_resolver_1 = require("../../../lib/task-resolver");
8
8
  const api_fetch_1 = require("../../../lib/api-fetch");
9
9
  const session_task_write_1 = require("../../../lib/session-task-write");
@@ -135,7 +135,7 @@ class TasksExpectationsAssess extends base_command_1.BaseCommand {
135
135
  // settling exactly one Expectation while reporting several.
136
136
  idempotencyKey: reuseCallerKey
137
137
  ? flags['idempotency-key']
138
- : (0, outbox_1.idempotencyKeyFor)('task-expectation-assessment', task.id, JSON.stringify({ expectationId: id, ...payload })),
138
+ : `task-expectation-assessment_${(0, node_crypto_1.randomUUID)()}`,
139
139
  };
140
140
  const sessionWrite = await (0, session_task_write_1.sessionTaskWrite)('assessment', task.id);
141
141
  return sessionWrite
@@ -1,10 +1,18 @@
1
1
  import { Command } from '@oclif/core';
2
2
  /** Local documentation must remain readable without credentials or a daemon. */
3
3
  export default class TasksGuide extends Command {
4
+ static baseFlags: {
5
+ bare: import("@oclif/core/interfaces").BooleanFlag<boolean>;
6
+ token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ workspace: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ raw: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ };
4
11
  static description: string;
5
12
  static examples: string[];
6
13
  static flags: {
7
14
  json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
+ offline: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
16
  };
9
17
  run(): Promise<void>;
10
18
  }
@@ -1,20 +1,33 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const core_1 = require("@oclif/core");
4
- const task_operations_1 = require("../../lib/task-operations");
5
- const json_output_1 = require("../../lib/json-output");
4
+ const data_provider_1 = require("@skrr-ai/data-provider");
5
+ const base_command_1 = require("../../base-command");
6
+ const agent_guides_1 = require("../../lib/agent-guides");
6
7
  /** Local documentation must remain readable without credentials or a daemon. */
7
8
  class TasksGuide extends core_1.Command {
8
- static description = 'Find the commands for Task planning, dependencies, preflight, execution, and results';
9
- static examples = ['<%= config.bin %> tasks guide', '<%= config.bin %> tasks guide --json'];
10
- static flags = { json: core_1.Flags.boolean({ description: 'Output the local operations guide as JSON' }) };
9
+ static baseFlags = base_command_1.BaseCommand.baseFlags;
10
+ static description = 'Alias of `skrr guide tasks commands` — the Task command map. `skrr guide tasks` reads the whole guide.';
11
+ static examples = [
12
+ '<%= config.bin %> tasks guide',
13
+ '<%= config.bin %> tasks guide --json',
14
+ ];
15
+ static flags = {
16
+ json: core_1.Flags.boolean({ description: 'Output the guide and source provenance as JSON' }),
17
+ offline: core_1.Flags.boolean({
18
+ description: 'Read the bundled release guides without checking credentials or the server',
19
+ }),
20
+ };
11
21
  async run() {
12
22
  const { flags } = await this.parse(TasksGuide);
13
- if (flags.json)
14
- this.log(JSON.stringify((0, json_output_1.withOk)((0, task_operations_1.taskOperationsGuide)(this.config.bin)), null, 2));
15
- else
16
- for (const line of (0, task_operations_1.taskOperationsGuideLines)(this.config.bin))
17
- this.log(line);
23
+ const read = await (0, agent_guides_1.readAgentGuide)({ id: 'tasks', section: 'commands' }, flags);
24
+ if (!read.found)
25
+ return (0, agent_guides_1.writeAgentGuideMiss)(this, read.miss, flags.json);
26
+ if (flags.json) {
27
+ process.stdout.write((0, agent_guides_1.agentGuideJson)(read));
28
+ return;
29
+ }
30
+ process.stdout.write((0, data_provider_1.renderAgentGuideText)(read.response));
18
31
  }
19
32
  }
20
33
  exports.default = TasksGuide;
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_crypto_1 = require("node:crypto");
3
4
  const core_1 = require("@oclif/core");
4
5
  const data_provider_1 = require("@skrr-ai/data-provider");
5
6
  const base_command_1 = require("../../base-command");
6
- const outbox_1 = require("../../lib/outbox");
7
7
  const task_report_1 = require("../../lib/task-report");
8
8
  const task_resolver_1 = require("../../lib/task-resolver");
9
9
  const tasks_1 = require("../../lib/tasks");
@@ -110,11 +110,13 @@ class TasksReport extends base_command_1.BaseCommand {
110
110
  continue;
111
111
  }
112
112
  try {
113
- const data = { ...parsed.value, idempotencyKey: (0, outbox_1.idempotencyKeyFor)('task-deliverable', task.id, ref) };
113
+ const data = { ...parsed.value, idempotencyKey: `task-deliverable_${(0, node_crypto_1.randomUUID)()}` };
114
114
  const sessionWrite = await (0, session_task_write_1.sessionTaskWrite)('deliverable', task.id);
115
115
  const recorded = sessionWrite
116
116
  ? await (0, api_fetch_1.apiFetch)(sessionWrite.path, {
117
- method: 'POST', body: data, credential: sessionWrite.credential,
117
+ method: 'POST',
118
+ body: data,
119
+ credential: sessionWrite.credential,
118
120
  })
119
121
  : await data_provider_1.dataService.addTaskDeliverable(task.id, data);
120
122
  resourceLinkIds.push(recorded.link.id);
@@ -153,12 +155,14 @@ class TasksReport extends base_command_1.BaseCommand {
153
155
  try {
154
156
  const data = {
155
157
  ...payload,
156
- idempotencyKey: (0, outbox_1.idempotencyKeyFor)('task-result', task.id, JSON.stringify(payload)),
158
+ idempotencyKey: `task-result_${(0, node_crypto_1.randomUUID)()}`,
157
159
  };
158
160
  const sessionWrite = await (0, session_task_write_1.sessionTaskWrite)('result', task.id);
159
161
  result = sessionWrite
160
162
  ? await (0, api_fetch_1.apiFetch)(sessionWrite.path, {
161
- method: 'POST', body: data, credential: sessionWrite.credential,
163
+ method: 'POST',
164
+ body: data,
165
+ credential: sessionWrite.credential,
162
166
  })
163
167
  : await data_provider_1.dataService.submitTaskResult({ taskId: task.id, data });
164
168
  }
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_crypto_1 = require("node:crypto");
3
4
  const core_1 = require("@oclif/core");
4
5
  const data_provider_1 = require("@skrr-ai/data-provider");
5
6
  const base_command_1 = require("../../../base-command");
6
- const outbox_1 = require("../../../lib/outbox");
7
7
  const tasks_1 = require("../../../lib/tasks");
8
8
  const RESOURCE_ROLES = ['input', 'reference', 'evidence', 'attachment', 'deliverable'];
9
9
  class TasksResourceAdd extends base_command_1.BaseCommand {
@@ -58,8 +58,7 @@ class TasksResourceAdd extends base_command_1.BaseCommand {
58
58
  expectationIds: flags.expectation,
59
59
  resultId: flags['result-id'],
60
60
  runId: flags['run-id'],
61
- idempotencyKey: flags['idempotency-key'] ||
62
- (0, outbox_1.idempotencyKeyFor)('task-resource', args.task, JSON.stringify({ role: args.role, coordinate: parsed.value, status: flags.status })),
61
+ idempotencyKey: flags['idempotency-key'] || `task-resource_${(0, node_crypto_1.randomUUID)()}`,
63
62
  };
64
63
  let result;
65
64
  try {
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_crypto_1 = require("node:crypto");
3
4
  const core_1 = require("@oclif/core");
4
5
  const data_provider_1 = require("@skrr-ai/data-provider");
5
6
  const base_command_1 = require("../../../base-command");
6
- const outbox_1 = require("../../../lib/outbox");
7
7
  const task_resolver_1 = require("../../../lib/task-resolver");
8
8
  const web_url_1 = require("../../../lib/web-url");
9
9
  const api_fetch_1 = require("../../../lib/api-fetch");
@@ -148,8 +148,7 @@ class TasksResultSubmit extends base_command_1.BaseCommand {
148
148
  try {
149
149
  const data = {
150
150
  ...payload,
151
- idempotencyKey: flags['idempotency-key'] ||
152
- (0, outbox_1.idempotencyKeyFor)('task-result', task.id, JSON.stringify(payload)),
151
+ idempotencyKey: flags['idempotency-key'] || `task-result_${(0, node_crypto_1.randomUUID)()}`,
153
152
  };
154
153
  const sessionWrite = await (0, session_task_write_1.sessionTaskWrite)('result', task.id);
155
154
  result = sessionWrite
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_crypto_1 = require("node:crypto");
3
4
  const core_1 = require("@oclif/core");
4
5
  const data_provider_1 = require("@skrr-ai/data-provider");
5
6
  const base_command_1 = require("../../../base-command");
6
- const outbox_1 = require("../../../lib/outbox");
7
7
  const task_resolver_1 = require("../../../lib/task-resolver");
8
8
  const api_fetch_1 = require("../../../lib/api-fetch");
9
9
  const session_task_write_1 = require("../../../lib/session-task-write");
@@ -51,8 +51,7 @@ class TasksResumeSave extends base_command_1.BaseCommand {
51
51
  runId: flags['run-id'],
52
52
  expectedSpecVersion: flags['spec-version'],
53
53
  resume: resume,
54
- idempotencyKey: flags['idempotency-key'] ||
55
- (0, outbox_1.idempotencyKeyFor)('task-resume', task.id, JSON.stringify(resume)),
54
+ idempotencyKey: flags['idempotency-key'] || `task-resume_${(0, node_crypto_1.randomUUID)()}`,
56
55
  };
57
56
  const sessionWrite = await (0, session_task_write_1.sessionTaskWrite)('resume', task.id);
58
57
  result = sessionWrite
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_crypto_1 = require("node:crypto");
3
4
  const core_1 = require("@oclif/core");
4
5
  const data_provider_1 = require("@skrr-ai/data-provider");
5
6
  const base_command_1 = require("../../base-command");
6
- const outbox_1 = require("../../lib/outbox");
7
7
  const task_resolver_1 = require("../../lib/task-resolver");
8
8
  const api_fetch_1 = require("../../lib/api-fetch");
9
9
  const session_task_write_1 = require("../../lib/session-task-write");
@@ -36,8 +36,7 @@ class TasksReview extends base_command_1.BaseCommand {
36
36
  try {
37
37
  const data = {
38
38
  ...payload,
39
- idempotencyKey: flags['idempotency-key'] ||
40
- (0, outbox_1.idempotencyKeyFor)('task-review', task.id, JSON.stringify(payload)),
39
+ idempotencyKey: flags['idempotency-key'] || `task-review_${(0, node_crypto_1.randomUUID)()}`,
41
40
  };
42
41
  const sessionWrite = await (0, session_task_write_1.sessionTaskWrite)('review', task.id);
43
42
  result = sessionWrite
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_crypto_1 = require("node:crypto");
3
4
  const core_1 = require("@oclif/core");
4
5
  const data_provider_1 = require("@skrr-ai/data-provider");
5
6
  const base_command_1 = require("../../base-command");
@@ -123,7 +124,7 @@ class TasksTriage extends base_command_1.BaseCommand {
123
124
  await data_provider_1.dataService.appendTaskWorkEvent({
124
125
  taskId: task.id,
125
126
  data: {
126
- idempotencyKey: `triage:${action}:${task.id}`,
127
+ idempotencyKey: `task-triage_${(0, node_crypto_1.randomUUID)()}`,
127
128
  kind: 'decision',
128
129
  summary,
129
130
  data: { action, ...(flags.reason ? { reason: flags.reason } : {}) },
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_crypto_1 = require("node:crypto");
3
4
  const core_1 = require("@oclif/core");
4
5
  const data_provider_1 = require("@skrr-ai/data-provider");
5
6
  const base_command_1 = require("../../../base-command");
6
- const outbox_1 = require("../../../lib/outbox");
7
7
  const task_resolver_1 = require("../../../lib/task-resolver");
8
8
  const api_fetch_1 = require("../../../lib/api-fetch");
9
9
  const session_task_write_1 = require("../../../lib/session-task-write");
@@ -130,8 +130,7 @@ class TasksUpdatesAdd extends base_command_1.BaseCommand {
130
130
  references.push(...refs);
131
131
  }
132
132
  }
133
- const idempotencyKey = flags['idempotency-key'] ||
134
- (0, outbox_1.idempotencyKeyFor)('task-update', task.id, JSON.stringify({ type: flags.type, summary: flags.summary, data, resume }));
133
+ const idempotencyKey = flags['idempotency-key'] || `task-update_${(0, node_crypto_1.randomUUID)()}`;
135
134
  let result;
136
135
  try {
137
136
  const payload = {