@skrr-ai/cli 0.1.92 → 0.1.93

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 (267) hide show
  1. package/dist/base-command.d.ts +44 -0
  2. package/dist/base-command.js +96 -0
  3. package/dist/commands/agents/badge.d.ts +41 -0
  4. package/dist/commands/agents/badge.js +158 -0
  5. package/dist/commands/agents/create.d.ts +24 -0
  6. package/dist/commands/agents/create.js +212 -0
  7. package/dist/commands/agents/embed.d.ts +20 -0
  8. package/dist/commands/agents/embed.js +61 -0
  9. package/dist/commands/agents/share.d.ts +27 -0
  10. package/dist/commands/agents/share.js +100 -0
  11. package/dist/commands/agents/vanity.d.ts +21 -0
  12. package/dist/commands/agents/vanity.js +77 -0
  13. package/dist/commands/agents/visibility.d.ts +21 -1
  14. package/dist/commands/agents/visibility.js +112 -0
  15. package/dist/commands/commands.d.ts +1 -0
  16. package/dist/commands/commands.js +22 -9
  17. package/dist/commands/earnings/attributions.d.ts +17 -0
  18. package/dist/commands/earnings/attributions.js +82 -0
  19. package/dist/commands/earnings/index.js +2 -1
  20. package/dist/commands/generate-recovery-code.js +4 -3
  21. package/dist/commands/github/allow-tools.d.ts +1 -0
  22. package/dist/commands/github/app/install.d.ts +1 -0
  23. package/dist/commands/github/app/status.d.ts +1 -0
  24. package/dist/commands/github/connect.d.ts +1 -0
  25. package/dist/commands/github/connections.d.ts +1 -0
  26. package/dist/commands/github/disconnect.d.ts +1 -0
  27. package/dist/commands/github/finalize.d.ts +1 -0
  28. package/dist/commands/github/reconnect.d.ts +1 -0
  29. package/dist/commands/github/run.d.ts +1 -0
  30. package/dist/commands/github/tools.d.ts +1 -0
  31. package/dist/commands/integrations/connections/connect.d.ts +1 -0
  32. package/dist/commands/integrations/connections/disconnect.d.ts +1 -0
  33. package/dist/commands/integrations/connections/finalize.d.ts +1 -0
  34. package/dist/commands/integrations/connections/list.d.ts +1 -0
  35. package/dist/commands/integrations/connections/reconnect.d.ts +1 -0
  36. package/dist/commands/integrations/execute.d.ts +1 -0
  37. package/dist/commands/integrations/search.d.ts +1 -0
  38. package/dist/commands/integrations/toolkits.d.ts +1 -0
  39. package/dist/commands/integrations/tools/allow.d.ts +1 -0
  40. package/dist/commands/integrations/tools/list.d.ts +1 -0
  41. package/dist/commands/login.js +12 -0
  42. package/dist/commands/machines/dedicated/logs.d.ts +19 -0
  43. package/dist/commands/machines/dedicated/logs.js +103 -0
  44. package/dist/commands/machines/dedicated/power/set.js +1 -1
  45. package/dist/commands/open.d.ts +24 -0
  46. package/dist/commands/open.js +74 -0
  47. package/dist/commands/projects/archive.d.ts +1 -0
  48. package/dist/commands/projects/archive.js +23 -0
  49. package/dist/commands/projects/delete.d.ts +1 -0
  50. package/dist/commands/projects/delete.js +23 -0
  51. package/dist/commands/projects/list.d.ts +3 -0
  52. package/dist/commands/projects/list.js +12 -2
  53. package/dist/commands/spaces/actions/add.js +4 -3
  54. package/dist/commands/spaces/actions/available.js +3 -2
  55. package/dist/commands/spaces/actions/list.js +5 -4
  56. package/dist/commands/spaces/actions/replace.js +6 -5
  57. package/dist/commands/spaces/archive.js +3 -2
  58. package/dist/commands/spaces/auto-executor/preview.js +4 -3
  59. package/dist/commands/spaces/auto-executor/run.js +4 -3
  60. package/dist/commands/spaces/auto-executor/runs.js +3 -2
  61. package/dist/commands/spaces/auto-executor/update.js +4 -3
  62. package/dist/commands/spaces/bootstrap.js +3 -2
  63. package/dist/commands/spaces/briefs/delete.js +3 -2
  64. package/dist/commands/spaces/briefs/get.js +3 -2
  65. package/dist/commands/spaces/briefs/list.js +3 -2
  66. package/dist/commands/spaces/briefs/set.js +5 -4
  67. package/dist/commands/spaces/capacity.js +5 -4
  68. package/dist/commands/spaces/conversations.js +3 -2
  69. package/dist/commands/spaces/cycles/create.js +3 -2
  70. package/dist/commands/spaces/cycles/graph.js +2 -1
  71. package/dist/commands/spaces/cycles/list.js +3 -2
  72. package/dist/commands/spaces/cycles/settings.js +4 -3
  73. package/dist/commands/spaces/cycles/show.js +3 -2
  74. package/dist/commands/spaces/cycles/update.js +3 -2
  75. package/dist/commands/spaces/delete.js +4 -3
  76. package/dist/commands/spaces/expertise-suggestions.js +4 -3
  77. package/dist/commands/spaces/files/delete.js +3 -2
  78. package/dist/commands/spaces/files/folders/create.js +3 -2
  79. package/dist/commands/spaces/files/folders/delete.js +3 -2
  80. package/dist/commands/spaces/files/folders/list.js +3 -2
  81. package/dist/commands/spaces/files/folders/update.js +3 -2
  82. package/dist/commands/spaces/files/list.js +3 -2
  83. package/dist/commands/spaces/files/move.js +3 -2
  84. package/dist/commands/spaces/files/rename.js +3 -2
  85. package/dist/commands/spaces/files/upload.js +6 -5
  86. package/dist/commands/spaces/github-automations/set.js +3 -2
  87. package/dist/commands/spaces/github-automations/show.js +3 -2
  88. package/dist/commands/spaces/goals.js +2 -1
  89. package/dist/commands/spaces/heartbeats/create.js +4 -3
  90. package/dist/commands/spaces/heartbeats/delete.js +4 -3
  91. package/dist/commands/spaces/heartbeats/list.js +4 -3
  92. package/dist/commands/spaces/heartbeats/status.js +3 -2
  93. package/dist/commands/spaces/heartbeats/update.js +4 -3
  94. package/dist/commands/spaces/insights.js +5 -4
  95. package/dist/commands/spaces/labels/add.js +4 -3
  96. package/dist/commands/spaces/labels/list.js +2 -1
  97. package/dist/commands/spaces/labels/remove.js +4 -3
  98. package/dist/commands/spaces/list.d.ts +3 -0
  99. package/dist/commands/spaces/list.js +11 -2
  100. package/dist/commands/spaces/live/cards/create.js +3 -2
  101. package/dist/commands/spaces/live/cards/list.js +3 -2
  102. package/dist/commands/spaces/live/cards/reorder.js +7 -2
  103. package/dist/commands/spaces/live/scene.js +4 -3
  104. package/dist/commands/spaces/members/add.js +7 -6
  105. package/dist/commands/spaces/members/list.js +4 -3
  106. package/dist/commands/spaces/members/remove.js +7 -6
  107. package/dist/commands/spaces/move.js +3 -2
  108. package/dist/commands/spaces/pin.js +5 -4
  109. package/dist/commands/spaces/preferences/show.js +4 -3
  110. package/dist/commands/spaces/preferences/tabs.js +4 -3
  111. package/dist/commands/spaces/revisions.js +3 -2
  112. package/dist/commands/spaces/room/ensure.js +5 -4
  113. package/dist/commands/spaces/room/messages.js +3 -2
  114. package/dist/commands/spaces/room/show.js +5 -4
  115. package/dist/commands/spaces/skills/add.js +4 -3
  116. package/dist/commands/spaces/skills/list.js +3 -2
  117. package/dist/commands/spaces/skills/pin.js +4 -3
  118. package/dist/commands/spaces/skills/remove.js +4 -3
  119. package/dist/commands/spaces/snapshot.js +3 -2
  120. package/dist/commands/spaces/states/archive.js +3 -2
  121. package/dist/commands/spaces/states/create.js +3 -2
  122. package/dist/commands/spaces/states/list.js +3 -2
  123. package/dist/commands/spaces/states/reorder.js +2 -1
  124. package/dist/commands/spaces/states/update.js +3 -2
  125. package/dist/commands/spaces/summary.js +4 -3
  126. package/dist/commands/spaces/tasks.d.ts +3 -0
  127. package/dist/commands/spaces/tasks.js +14 -3
  128. package/dist/commands/spaces/triggers/delete.js +5 -4
  129. package/dist/commands/spaces/triggers/set.js +4 -3
  130. package/dist/commands/spaces/triggers/show.js +4 -3
  131. package/dist/commands/spaces/unarchive.js +3 -2
  132. package/dist/commands/spaces/update.js +5 -4
  133. package/dist/commands/spaces/views/create.js +3 -2
  134. package/dist/commands/spaces/views/list.js +3 -2
  135. package/dist/commands/spaces/views/reorder.js +6 -3
  136. package/dist/commands/spaces/views/subscribe.js +2 -1
  137. package/dist/commands/spaces/views/subscriptions.js +1 -0
  138. package/dist/commands/spaces/views/unsubscribe.js +2 -1
  139. package/dist/commands/spaces/widgets/add.js +4 -3
  140. package/dist/commands/spaces/widgets/list.js +3 -2
  141. package/dist/commands/spaces/widgets/remove.js +5 -4
  142. package/dist/commands/spaces/work-graph.js +2 -1
  143. package/dist/commands/store/install.d.ts +1 -1
  144. package/dist/commands/store/install.js +24 -8
  145. package/dist/commands/store/show.d.ts +25 -0
  146. package/dist/commands/store/show.js +203 -0
  147. package/dist/commands/store/stats.d.ts +33 -0
  148. package/dist/commands/store/stats.js +258 -0
  149. package/dist/commands/tasks/actions/attach.js +1 -1
  150. package/dist/commands/tasks/actions/detach.js +4 -3
  151. package/dist/commands/tasks/activity.js +3 -2
  152. package/dist/commands/tasks/ancestors.js +2 -1
  153. package/dist/commands/tasks/approvals/create.js +2 -1
  154. package/dist/commands/tasks/approvals/delete.js +3 -2
  155. package/dist/commands/tasks/approvals/list.js +5 -4
  156. package/dist/commands/tasks/approvals/resolve.js +2 -1
  157. package/dist/commands/tasks/archive.js +3 -2
  158. package/dist/commands/tasks/assign.js +4 -3
  159. package/dist/commands/tasks/attachments/delete.js +3 -2
  160. package/dist/commands/tasks/attachments/download.d.ts +1 -0
  161. package/dist/commands/tasks/attachments/download.js +20 -1
  162. package/dist/commands/tasks/attachments/list.js +2 -1
  163. package/dist/commands/tasks/attachments/set-role.js +2 -1
  164. package/dist/commands/tasks/attachments/upload.js +2 -1
  165. package/dist/commands/tasks/bulk-update.d.ts +1 -0
  166. package/dist/commands/tasks/bulk-update.js +106 -15
  167. package/dist/commands/tasks/cancel-cascade.d.ts +1 -0
  168. package/dist/commands/tasks/cancel-cascade.js +13 -3
  169. package/dist/commands/tasks/cascade-status.js +2 -1
  170. package/dist/commands/tasks/checkout.js +3 -2
  171. package/dist/commands/tasks/children.js +2 -1
  172. package/dist/commands/tasks/comments/add.js +7 -6
  173. package/dist/commands/tasks/comments/anchor.js +8 -7
  174. package/dist/commands/tasks/comments/delete.js +3 -2
  175. package/dist/commands/tasks/comments/list.js +2 -1
  176. package/dist/commands/tasks/comments/reopen.js +3 -2
  177. package/dist/commands/tasks/comments/resolve.js +3 -2
  178. package/dist/commands/tasks/create-tree.d.ts +63 -0
  179. package/dist/commands/tasks/create-tree.js +197 -4
  180. package/dist/commands/tasks/delete.js +5 -4
  181. package/dist/commands/tasks/descendants.js +2 -1
  182. package/dist/commands/tasks/dri-plan.js +3 -2
  183. package/dist/commands/tasks/dri-run.js +3 -2
  184. package/dist/commands/tasks/dri-status.js +2 -1
  185. package/dist/commands/tasks/duplicate-pipeline.js +2 -1
  186. package/dist/commands/tasks/execution-summary.js +2 -1
  187. package/dist/commands/tasks/execution-timeline.js +2 -1
  188. package/dist/commands/tasks/fork.js +1 -0
  189. package/dist/commands/tasks/forward.js +4 -3
  190. package/dist/commands/tasks/handover.js +1 -0
  191. package/dist/commands/tasks/interrupt.js +3 -2
  192. package/dist/commands/tasks/labels/attach.js +4 -3
  193. package/dist/commands/tasks/labels/detach.js +4 -3
  194. package/dist/commands/tasks/labels/suggest.js +5 -4
  195. package/dist/commands/tasks/list.d.ts +27 -1
  196. package/dist/commands/tasks/list.js +101 -3
  197. package/dist/commands/tasks/move.js +4 -3
  198. package/dist/commands/tasks/output.js +6 -5
  199. package/dist/commands/tasks/pause-schedule.js +3 -2
  200. package/dist/commands/tasks/promote.js +1 -0
  201. package/dist/commands/tasks/prompt-log.js +2 -1
  202. package/dist/commands/tasks/release.js +5 -4
  203. package/dist/commands/tasks/remind.js +2 -1
  204. package/dist/commands/tasks/replay.js +3 -2
  205. package/dist/commands/tasks/report.js +1 -0
  206. package/dist/commands/tasks/resume-schedule.js +3 -2
  207. package/dist/commands/tasks/retry-schedule.js +3 -2
  208. package/dist/commands/tasks/retry.js +10 -9
  209. package/dist/commands/tasks/revisions.js +2 -1
  210. package/dist/commands/tasks/runs.js +6 -5
  211. package/dist/commands/tasks/schedule.js +3 -2
  212. package/dist/commands/tasks/self-schedule.js +6 -5
  213. package/dist/commands/tasks/skills/pin.js +3 -2
  214. package/dist/commands/tasks/skills/unpin.js +3 -2
  215. package/dist/commands/tasks/snooze.js +6 -5
  216. package/dist/commands/tasks/start-all.js +5 -4
  217. package/dist/commands/tasks/subscribe.js +1 -0
  218. package/dist/commands/tasks/tags/add.js +4 -3
  219. package/dist/commands/tasks/tags/remove.js +4 -3
  220. package/dist/commands/tasks/timeline.js +3 -2
  221. package/dist/commands/tasks/today.d.ts +4 -1
  222. package/dist/commands/tasks/today.js +12 -2
  223. package/dist/commands/tasks/transcript.js +6 -5
  224. package/dist/commands/tasks/unschedule.js +3 -2
  225. package/dist/commands/tasks/unsnooze.js +3 -2
  226. package/dist/commands/tasks/unsubscribe.js +2 -1
  227. package/dist/commands/tasks/update.js +5 -4
  228. package/dist/commands/tasks/wait.js +5 -4
  229. package/dist/lib/agent-distribution.d.ts +37 -0
  230. package/dist/lib/agent-distribution.js +63 -0
  231. package/dist/lib/agent-ref.d.ts +69 -0
  232. package/dist/lib/agent-ref.js +168 -0
  233. package/dist/lib/api-fetch.d.ts +2 -0
  234. package/dist/lib/api-fetch.js +14 -3
  235. package/dist/lib/command-hygiene.d.ts +13 -0
  236. package/dist/lib/command-hygiene.js +62 -2
  237. package/dist/lib/dedicated-power.d.ts +5 -0
  238. package/dist/lib/dedicated-power.js +30 -2
  239. package/dist/lib/dry-run-plans.d.ts +50 -0
  240. package/dist/lib/dry-run-plans.js +85 -0
  241. package/dist/lib/json-output.d.ts +31 -0
  242. package/dist/lib/json-output.js +78 -0
  243. package/dist/lib/list-output.d.ts +75 -0
  244. package/dist/lib/list-output.js +266 -0
  245. package/dist/lib/machine-daemon-log.d.ts +36 -0
  246. package/dist/lib/machine-daemon-log.js +78 -0
  247. package/dist/lib/node-adapter.js +10 -1
  248. package/dist/lib/open-target.d.ts +12 -0
  249. package/dist/lib/open-target.js +108 -0
  250. package/dist/lib/rate-limit-retry.d.ts +45 -0
  251. package/dist/lib/rate-limit-retry.js +88 -0
  252. package/dist/lib/store-listing.d.ts +45 -0
  253. package/dist/lib/store-listing.js +186 -0
  254. package/dist/lib/task-batch.d.ts +67 -0
  255. package/dist/lib/task-batch.js +227 -0
  256. package/dist/lib/terminal-qr.d.ts +55 -0
  257. package/dist/lib/terminal-qr.js +119 -0
  258. package/dist/lib/web-url.d.ts +11 -0
  259. package/dist/lib/web-url.js +24 -0
  260. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.d.ts +68 -0
  261. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.js +47 -1
  262. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.d.ts +68 -0
  263. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.js +46 -0
  264. package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
  265. package/dist/node_modules/@skrr-ai/data-provider/index.js +6612 -6113
  266. package/oclif.manifest.json +46778 -38019
  267. package/package.json +2 -1
@@ -43,7 +43,15 @@ export declare abstract class BaseCommand extends Command {
43
43
  token: Interfaces.OptionFlag<string | undefined, Interfaces.CustomOptions>;
44
44
  workspace: Interfaces.OptionFlag<string | undefined, Interfaces.CustomOptions>;
45
45
  profile: Interfaces.OptionFlag<string | undefined, Interfaces.CustomOptions>;
46
+ raw: Interfaces.BooleanFlag<boolean>;
46
47
  };
48
+ /**
49
+ * JSON output goes through here, so the storage fields (`_id` beside `id`,
50
+ * `__v`) are dropped in ONE place and only at the CLI serializer (P9).
51
+ * `--raw` / `OVERSKY_CLI_RAW=1` opts out.
52
+ */
53
+ log(message?: string, ...args: unknown[]): void;
54
+ protected wantsRawJson(): boolean;
47
55
  protected cliConfig: CliConfig;
48
56
  /**
49
57
  * Resolved credential for this process. Populated in `init()` and
@@ -146,6 +154,22 @@ export declare abstract class BaseCommand extends Command {
146
154
  * server resolves the latter itself — so existing callers keep their
147
155
  * behavior and their request count. Only a title reaches the search.
148
156
  */
157
+ /**
158
+ * The ONE way a positional ID argument becomes the id a request carries
159
+ * (audit P7). `tasks show` resolved titles and refs while `tasks delete`,
160
+ * `tasks archive` and `spaces update` sent the raw string and relied on the
161
+ * server happening to accept it, so the same `OSK-12` worked on one verb and
162
+ * 404ed on the next. A command that takes a task, space or project reference
163
+ * calls this (or one of the three it delegates to) and nothing else;
164
+ * `entity-ref-resolution.spec.ts` fails on a new command that does not.
165
+ *
166
+ * `project` returns the project ref only: a project is addressed inside a
167
+ * space, so a command that needs the space too calls
168
+ * `resolveProjectReference` directly.
169
+ */
170
+ protected resolveEntityRef(kind: 'task' | 'space' | 'project', value: string, opts?: {
171
+ space?: string;
172
+ }): Promise<string>;
149
173
  protected resolveTaskReference(value: string): Promise<string>;
150
174
  /**
151
175
  * Parse flags, then resolve any `--space` reference to an id.
@@ -344,7 +368,14 @@ export declare abstract class BaseCommand extends Command {
344
368
  * bug (2026-09-18).
345
369
  */
346
370
  private lastApiRequestId?;
371
+ /** E6: the server's `Retry-After` for the refused call, when it was a 429. */
372
+ private lastRetryAfterMs?;
347
373
  private writeJsonCliError;
374
+ /**
375
+ * Write a shaped list (see `lib/list-output.ts`) to stdout, or as NDJSON:
376
+ * rows on stdout, one `{"_meta":...}` line (paging, warnings) on stderr.
377
+ */
378
+ protected printList(shaped: unknown, ndjson: boolean): void;
348
379
  protected wantsJsonOutput(): boolean;
349
380
  }
350
381
  /**
@@ -488,4 +519,17 @@ export declare function isTypedServerRefusal(body: Record<string, unknown> | nul
488
519
  */
489
520
  export declare function isApplicationCodedUnavailable(status: number | undefined, body: Record<string, unknown> | null): boolean;
490
521
  export declare function isRetryableFailure(status: number | undefined, body: Record<string, unknown> | null): boolean;
522
+ /**
523
+ * P6: a parse error used to say what was wrong and drop the remedy that text
524
+ * mode (and every domain error) carries. Adds `fix` (one imperative line an
525
+ * agent can act on) and, for a missing flag, `flag` — beside the unchanged
526
+ * `code`, so nothing that matched CLI_PARSE_ERROR breaks.
527
+ */
528
+ export declare function parseErrorRemedy(err: Error & {
529
+ code?: string;
530
+ suggestions?: unknown;
531
+ }, commandId: string | undefined, bin?: string): {
532
+ fix?: string;
533
+ flag?: string;
534
+ };
491
535
  export { Flags };
@@ -17,10 +17,12 @@ exports.describeDaemonScopedCredential = describeDaemonScopedCredential;
17
17
  exports.isTypedServerRefusal = isTypedServerRefusal;
18
18
  exports.isApplicationCodedUnavailable = isApplicationCodedUnavailable;
19
19
  exports.isRetryableFailure = isRetryableFailure;
20
+ exports.parseErrorRemedy = parseErrorRemedy;
20
21
  const node_fs_1 = require("node:fs");
21
22
  const core_1 = require("@oclif/core");
22
23
  Object.defineProperty(exports, "Flags", { enumerable: true, get: function () { return core_1.Flags; } });
23
24
  const option_hint_1 = require("./lib/option-hint");
25
+ const json_output_1 = require("./lib/json-output");
24
26
  const failed_lookup_1 = require("./lib/failed-lookup");
25
27
  const internal_id_1 = require("./lib/internal-id");
26
28
  const http_error_1 = require("./lib/http-error");
@@ -33,6 +35,7 @@ Object.defineProperty(exports, "resolveProfileFromArgv", { enumerable: true, get
33
35
  const data_provider_1 = require("@skrr-ai/data-provider");
34
36
  const auth_core_1 = require("@skrr-ai/auth-core");
35
37
  const auth_failure_1 = require("./lib/auth-failure");
38
+ const list_output_1 = require("./lib/list-output");
36
39
  const assignee_resolver_1 = require("./lib/assignee-resolver");
37
40
  const task_ref_resolver_1 = require("./lib/task-ref-resolver");
38
41
  const space_resolver_1 = require("./lib/space-resolver");
@@ -148,7 +151,25 @@ class BaseCommand extends core_1.Command {
148
151
  'so signing into one does not sign you out of another. Also OVERSKY_PROFILE. ' +
149
152
  'List them with `profiles list`.',
150
153
  }),
154
+ raw: core_1.Flags.boolean({
155
+ description: 'With --json, keep the Mongo storage fields (_id next to id, __v) that the CLI otherwise strips. Also OVERSKY_CLI_RAW=1.',
156
+ default: false,
157
+ }),
151
158
  };
159
+ /**
160
+ * JSON output goes through here, so the storage fields (`_id` beside `id`,
161
+ * `__v`) are dropped in ONE place and only at the CLI serializer (P9).
162
+ * `--raw` / `OVERSKY_CLI_RAW=1` opts out.
163
+ */
164
+ log(message, ...args) {
165
+ const text = typeof message === 'string' && this.wantsJsonOutput() && !this.wantsRawJson()
166
+ ? (0, json_output_1.stripStorageFieldsFromText)(message)
167
+ : message;
168
+ super.log(text, ...args);
169
+ }
170
+ wantsRawJson() {
171
+ return this.argv.includes('--raw') || process.env.OVERSKY_CLI_RAW === '1';
172
+ }
152
173
  cliConfig;
153
174
  /**
154
175
  * Resolved credential for this process. Populated in `init()` and
@@ -707,6 +728,26 @@ class BaseCommand extends core_1.Command {
707
728
  * server resolves the latter itself — so existing callers keep their
708
729
  * behavior and their request count. Only a title reaches the search.
709
730
  */
731
+ /**
732
+ * The ONE way a positional ID argument becomes the id a request carries
733
+ * (audit P7). `tasks show` resolved titles and refs while `tasks delete`,
734
+ * `tasks archive` and `spaces update` sent the raw string and relied on the
735
+ * server happening to accept it, so the same `OSK-12` worked on one verb and
736
+ * 404ed on the next. A command that takes a task, space or project reference
737
+ * calls this (or one of the three it delegates to) and nothing else;
738
+ * `entity-ref-resolution.spec.ts` fails on a new command that does not.
739
+ *
740
+ * `project` returns the project ref only: a project is addressed inside a
741
+ * space, so a command that needs the space too calls
742
+ * `resolveProjectReference` directly.
743
+ */
744
+ async resolveEntityRef(kind, value, opts = {}) {
745
+ if (kind === 'task')
746
+ return this.resolveTaskReference(value);
747
+ if (kind === 'space')
748
+ return this.resolveSpaceReference(value);
749
+ return (await this.resolveProjectReference(value, opts.space)).projectRef;
750
+ }
710
751
  async resolveTaskReference(value) {
711
752
  const direct = (0, task_ref_resolver_1.directTaskRef)(value);
712
753
  if (direct)
@@ -1066,6 +1107,7 @@ class BaseCommand extends core_1.Command {
1066
1107
  retryable: err.retryable ?? false,
1067
1108
  command: this.id ?? null,
1068
1109
  server: this.cliConfig?.baseURL ?? null,
1110
+ ...parseErrorRemedy(err, this.id, this.config?.bin),
1069
1111
  ...(details ? { details } : {}),
1070
1112
  },
1071
1113
  }, null, 2));
@@ -1131,6 +1173,7 @@ class BaseCommand extends core_1.Command {
1131
1173
  // Remembered once here rather than threaded through every branch below:
1132
1174
  // each one ends in `failWithCliError`, and the id belongs on all of them.
1133
1175
  this.lastApiRequestId = e.requestId;
1176
+ this.lastRetryAfterMs = e.retryAfterMs;
1134
1177
  const body = parseErrorBody(e.body);
1135
1178
  const bodyCode = stringProp(body, 'code') || stringProp(body, 'errorType');
1136
1179
  const bodyMessage = stringProp(body, 'message') || stringProp(body, 'error');
@@ -1715,6 +1758,8 @@ class BaseCommand extends core_1.Command {
1715
1758
  * bug (2026-09-18).
1716
1759
  */
1717
1760
  lastApiRequestId;
1761
+ /** E6: the server's `Retry-After` for the refused call, when it was a 429. */
1762
+ lastRetryAfterMs;
1718
1763
  writeJsonCliError({ message, code, status, exit, retryable, details, requestId, }) {
1719
1764
  this.log(JSON.stringify({
1720
1765
  ok: false,
@@ -1732,13 +1777,26 @@ class BaseCommand extends core_1.Command {
1732
1777
  ...(requestId || this.lastApiRequestId
1733
1778
  ? { requestId: requestId ?? this.lastApiRequestId }
1734
1779
  : {}),
1780
+ ...(this.lastRetryAfterMs !== undefined ? { retryAfterMs: this.lastRetryAfterMs } : {}),
1735
1781
  ...(details ? { details } : {}),
1736
1782
  },
1737
1783
  }, null, 2));
1738
1784
  this.exit(exit);
1739
1785
  }
1786
+ /**
1787
+ * Write a shaped list (see `lib/list-output.ts`) to stdout, or as NDJSON:
1788
+ * rows on stdout, one `{"_meta":...}` line (paging, warnings) on stderr.
1789
+ */
1790
+ printList(shaped, ndjson) {
1791
+ const out = (0, list_output_1.renderListOutput)(shaped, ndjson);
1792
+ for (const line of out.stdout)
1793
+ this.log(line);
1794
+ for (const line of out.stderr)
1795
+ process.stderr.write(`${line}\n`);
1796
+ }
1740
1797
  wantsJsonOutput() {
1741
1798
  return (this.argv.includes('--json') ||
1799
+ this.argv.includes('--ndjson') ||
1742
1800
  process.env.SKY_JSON === '1' ||
1743
1801
  process.env.OVERSKY_CLI_JSON === '1');
1744
1802
  }
@@ -2271,6 +2329,44 @@ function retiredFlagHint(message) {
2271
2329
  return null;
2272
2330
  return hits.map((flag) => ` ${RETIRED_FLAG_REPLACEMENTS[flag]}`).join('\n');
2273
2331
  }
2332
+ /**
2333
+ * P6: a parse error used to say what was wrong and drop the remedy that text
2334
+ * mode (and every domain error) carries. Adds `fix` (one imperative line an
2335
+ * agent can act on) and, for a missing flag, `flag` — beside the unchanged
2336
+ * `code`, so nothing that matched CLI_PARSE_ERROR breaks.
2337
+ */
2338
+ function parseErrorRemedy(err, commandId, bin = 'skrr') {
2339
+ if (err.code)
2340
+ return {};
2341
+ const helpCommand = `${bin} ${(commandId ?? '').replace(/:/g, ' ')} --help`.replace(/\s+/g, ' ');
2342
+ const message = err.message || '';
2343
+ const suggestion = Array.isArray(err.suggestions)
2344
+ ? err.suggestions.find((s) => typeof s === 'string')
2345
+ : undefined;
2346
+ const missingFlag = /Missing required flag[s]?:?\s*(?:\n\s*)?-{0,2}([a-z][\w-]*)/i.exec(message);
2347
+ if (missingFlag) {
2348
+ const flag = missingFlag[1];
2349
+ return {
2350
+ flag,
2351
+ fix: suggestion ??
2352
+ `Pass --${flag} <value>. Run \`${helpCommand}\` for its description and accepted values.`,
2353
+ };
2354
+ }
2355
+ const nonexistent = /Nonexistent flag[s]?:?\s*(-{1,2}[\w-]+)/i.exec(message);
2356
+ if (nonexistent) {
2357
+ return {
2358
+ flag: nonexistent[1].replace(/^-+/, ''),
2359
+ fix: suggestion ??
2360
+ `Remove ${nonexistent[1]}, or run \`${helpCommand}\` for the flags this command takes.`,
2361
+ };
2362
+ }
2363
+ if (/Missing \d+ required arg/i.test(message)) {
2364
+ return {
2365
+ fix: suggestion ?? `Supply the missing argument. Run \`${helpCommand}\` for the usage line.`,
2366
+ };
2367
+ }
2368
+ return { fix: suggestion ?? `Run \`${helpCommand}\` for usage.` };
2369
+ }
2274
2370
  function parseCliErrorCode(err) {
2275
2371
  if (err.name && err.name !== 'Error') {
2276
2372
  return err.name.replace(/([a-z0-9])([A-Z])/g, '$1_$2').toUpperCase();
@@ -0,0 +1,41 @@
1
+ import { BaseCommand } from '../../base-command';
2
+ declare const FORMATS: readonly ["markdown", "html", "rst"];
3
+ type BadgeFormat = (typeof FORMATS)[number];
4
+ export type BadgeSnippetInput = {
5
+ name: string;
6
+ badgeUrl: string;
7
+ listingUrl: string;
8
+ installCommand: string;
9
+ };
10
+ /**
11
+ * The README snippet: the badge, linked to the attributed listing, then the
12
+ * one-line install. Pure, so the three formats are pinned by a test rather
13
+ * than by eye.
14
+ */
15
+ export declare function badgeSnippet(format: BadgeFormat, input: BadgeSnippetInput): string;
16
+ /**
17
+ * `skrr agents badge <agent>` — a README badge and install one-liner for a
18
+ * published agent.
19
+ *
20
+ * The badge IMAGE is served by the API (`/api/public/store/agents/:id/badge.svg`:
21
+ * anonymous, cacheable, public listings only), so it stays current as ratings
22
+ * and installs move and needs nothing committed beside the README. The badge
23
+ * LINK is the attributed listing URL on the `badge` channel, and the install
24
+ * line carries its own code on the `cli` channel, so the publisher's analytics
25
+ * can tell "clicked the badge" from "pasted the command". Both codes are the
26
+ * caller's, minted idempotently, so re-running this prints the same snippet.
27
+ */
28
+ export default class AgentsBadge extends BaseCommand {
29
+ static description: string;
30
+ static examples: string[];
31
+ static args: {
32
+ agent: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
33
+ };
34
+ static flags: {
35
+ format: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
36
+ style: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
37
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
38
+ };
39
+ run(): Promise<void>;
40
+ }
41
+ export {};
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.badgeSnippet = badgeSnippet;
4
+ const core_1 = require("@oclif/core");
5
+ const data_provider_1 = require("@skrr-ai/data-provider");
6
+ const base_command_1 = require("../../base-command");
7
+ const agent_ref_1 = require("../../lib/agent-ref");
8
+ const agent_distribution_1 = require("../../lib/agent-distribution");
9
+ const FORMATS = ['markdown', 'html', 'rst'];
10
+ function escapeHtml(value) {
11
+ return value
12
+ .replace(/&/g, '&amp;')
13
+ .replace(/</g, '&lt;')
14
+ .replace(/>/g, '&gt;')
15
+ .replace(/"/g, '&quot;');
16
+ }
17
+ /** Markdown link text: brackets and backslashes would end or bend the link. */
18
+ function escapeMarkdownText(value) {
19
+ return value.replace(/[\\[\]]/g, (char) => `\\${char}`);
20
+ }
21
+ /**
22
+ * The README snippet: the badge, linked to the attributed listing, then the
23
+ * one-line install. Pure, so the three formats are pinned by a test rather
24
+ * than by eye.
25
+ */
26
+ function badgeSnippet(format, input) {
27
+ const alt = `${data_provider_1.BRAND.displayName}: ${input.name}`;
28
+ switch (format) {
29
+ case 'html':
30
+ return [
31
+ `<a href="${escapeHtml(input.listingUrl)}"><img src="${escapeHtml(input.badgeUrl)}" alt="${escapeHtml(alt)}"></a>`,
32
+ '',
33
+ `<pre><code>${escapeHtml(input.installCommand)}</code></pre>`,
34
+ ].join('\n');
35
+ case 'rst':
36
+ return [
37
+ `.. image:: ${input.badgeUrl}`,
38
+ ` :target: ${input.listingUrl}`,
39
+ ` :alt: ${alt}`,
40
+ '',
41
+ '.. code-block:: sh',
42
+ '',
43
+ ` ${input.installCommand}`,
44
+ ].join('\n');
45
+ case 'markdown':
46
+ default:
47
+ return [
48
+ `[![${escapeMarkdownText(alt)}](${input.badgeUrl})](${input.listingUrl})`,
49
+ '',
50
+ '```sh',
51
+ input.installCommand,
52
+ '```',
53
+ ].join('\n');
54
+ }
55
+ }
56
+ /**
57
+ * `skrr agents badge <agent>` — a README badge and install one-liner for a
58
+ * published agent.
59
+ *
60
+ * The badge IMAGE is served by the API (`/api/public/store/agents/:id/badge.svg`:
61
+ * anonymous, cacheable, public listings only), so it stays current as ratings
62
+ * and installs move and needs nothing committed beside the README. The badge
63
+ * LINK is the attributed listing URL on the `badge` channel, and the install
64
+ * line carries its own code on the `cli` channel, so the publisher's analytics
65
+ * can tell "clicked the badge" from "pasted the command". Both codes are the
66
+ * caller's, minted idempotently, so re-running this prints the same snippet.
67
+ */
68
+ class AgentsBadge extends base_command_1.BaseCommand {
69
+ static description = "Print a README badge (linked to the agent's Store listing) and a one-line install command for a published agent";
70
+ static examples = [
71
+ '<%= config.bin %> agents badge agent_abc123',
72
+ '<%= config.bin %> agents badge agent_abc123 --format html',
73
+ '<%= config.bin %> agents badge agent_abc123 --style flat-square --json',
74
+ ];
75
+ static args = {
76
+ agent: core_1.Args.string({
77
+ description: 'The published agent: its id or a link to it',
78
+ required: true,
79
+ ignoreStdin: true,
80
+ }),
81
+ };
82
+ static flags = {
83
+ format: core_1.Flags.string({
84
+ description: 'Snippet markup',
85
+ options: [...FORMATS],
86
+ default: 'markdown',
87
+ }),
88
+ style: core_1.Flags.string({
89
+ description: 'Badge look',
90
+ options: [...data_provider_1.STORE_BADGE_STYLES],
91
+ default: data_provider_1.STORE_BADGE_STYLES[0],
92
+ }),
93
+ json: core_1.Flags.boolean({
94
+ description: 'Print {agentId, name, badgeUrl, listingUrl, installCommand, snippet} as JSON',
95
+ }),
96
+ };
97
+ async run() {
98
+ this.requireAuth();
99
+ const { args, flags } = await this.parse(AgentsBadge);
100
+ const baseURL = this.cliConfig.baseURL;
101
+ let agentId;
102
+ try {
103
+ ({ agentId } = await (0, agent_ref_1.resolveAgentRef)(args.agent, { baseURL }));
104
+ }
105
+ catch (err) {
106
+ if (err instanceof agent_ref_1.AgentRefError) {
107
+ this.failWithCliError({ message: err.message, code: err.code, exit: 1, retryable: false });
108
+ }
109
+ this.handleApiError(err);
110
+ }
111
+ let listingLink;
112
+ let installLink;
113
+ try {
114
+ [listingLink, installLink] = await Promise.all([
115
+ (0, agent_distribution_1.mintAgentShareLink)({ baseURL, agentId, channel: 'badge' }),
116
+ (0, agent_distribution_1.mintAgentShareLink)({ baseURL, agentId, channel: 'cli' }),
117
+ ]);
118
+ }
119
+ catch (err) {
120
+ if (err instanceof agent_distribution_1.AgentNotShareableError) {
121
+ this.failWithCliError({ message: err.message, code: err.code, exit: 1, retryable: false });
122
+ }
123
+ this.handleApiError(err, { subject: `agent ${agentId}` });
124
+ }
125
+ // The name in the alt text is the public listing's (the released name),
126
+ // the same one the badge image draws. A failed read falls back to the id
127
+ // rather than failing a snippet whose image and links are already correct.
128
+ let name = agentId;
129
+ try {
130
+ name = (await data_provider_1.dataService.getPublicAgentListing(agentId)).name || agentId;
131
+ }
132
+ catch {
133
+ // keep the id
134
+ }
135
+ const badgeUrl = (0, agent_distribution_1.agentBadgeImageUrl)(agentId, flags.style);
136
+ const installCommand = `${this.config.bin} store install ${(0, agent_ref_1.shellQuote)(installLink.url)}`;
137
+ const snippet = badgeSnippet(flags.format, {
138
+ name,
139
+ badgeUrl,
140
+ listingUrl: listingLink.url,
141
+ installCommand,
142
+ });
143
+ if (flags.json) {
144
+ this.log(JSON.stringify({
145
+ agentId,
146
+ name,
147
+ badgeUrl,
148
+ listingUrl: listingLink.url,
149
+ installCommand,
150
+ format: flags.format,
151
+ snippet,
152
+ }, null, 2));
153
+ return;
154
+ }
155
+ this.log(snippet);
156
+ }
157
+ }
158
+ exports.default = AgentsBadge;
@@ -72,12 +72,21 @@ export declare function unappliedPayloadKeys(sent: Record<string, unknown>, crea
72
72
  */
73
73
  export declare function unappliedPayloadKeysWarning(keys: readonly string[]): string;
74
74
  export declare function backgroundLoopLines(agentId: string, relationshipLoopsSkipped: boolean): string[];
75
+ /**
76
+ * The flags `--from-spec` may be combined with: placement and identity for the
77
+ * NEW row, which a spec document deliberately cannot carry (where an agent runs
78
+ * is not portable). Every configuration flag is refused alongside it, because
79
+ * the file is the source — a flag that quietly overrode a line of it would
80
+ * leave git and the agent disagreeing from the first push.
81
+ */
82
+ export declare const FROM_SPEC_COMPATIBLE_FLAGS: readonly string[];
75
83
  export default class AgentsCreate extends BaseCommand {
76
84
  static description: string;
77
85
  static examples: string[];
78
86
  static flags: {
79
87
  json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
80
88
  'from-json': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
89
+ 'from-spec': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
81
90
  name: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
82
91
  description: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
83
92
  provider: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
@@ -124,4 +133,19 @@ export default class AgentsCreate extends BaseCommand {
124
133
  'auto-minor-updates': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
125
134
  };
126
135
  run(): Promise<void>;
136
+ /**
137
+ * `agents create --from-spec <file>`: bootstrap a NEW agent from an
138
+ * agent-as-code document, so a repository can hold an agent before one
139
+ * exists (`agents push` needs an existing id).
140
+ *
141
+ * Two writes, one writer per concern. The create carries only what makes a
142
+ * row — its name, provider, model and placement — and every other field
143
+ * reaches the agent through the push endpoint, so the document is held to
144
+ * exactly the rules `agents push` and `agents validate` apply (portable
145
+ * fields only, no credentials, no withheld references, nothing push may not
146
+ * set). Validation runs first with no network. If the server then refuses
147
+ * the document, the agent just created is deleted again: a refused spec must
148
+ * not leave behind a half-configured agent that looks like it worked.
149
+ */
150
+ private createFromSpec;
127
151
  }