@skrr-ai/cli 0.1.22 → 0.1.24

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 (281) hide show
  1. package/README.md +83 -73
  2. package/bin/dev-fallback.js +221 -0
  3. package/bin/run.js +96 -0
  4. package/dist/base-command.d.ts +15 -0
  5. package/dist/base-command.js +145 -11
  6. package/dist/commands/agents/attach-harness.d.ts +37 -0
  7. package/dist/commands/agents/attach-harness.js +102 -3
  8. package/dist/commands/agents/chat.d.ts +69 -1
  9. package/dist/commands/agents/chat.js +202 -22
  10. package/dist/commands/agents/create.d.ts +38 -0
  11. package/dist/commands/agents/create.js +95 -2
  12. package/dist/commands/agents/schedule-trace.js +11 -0
  13. package/dist/commands/agents/show.js +29 -1
  14. package/dist/commands/api-keys/create.d.ts +24 -0
  15. package/dist/commands/api-keys/create.js +80 -0
  16. package/dist/commands/api-keys/list.d.ts +11 -0
  17. package/dist/commands/api-keys/list.js +42 -0
  18. package/dist/commands/api-keys/revoke.d.ts +14 -0
  19. package/dist/commands/api-keys/revoke.js +33 -0
  20. package/dist/commands/api-keys/rotate.d.ts +19 -0
  21. package/dist/commands/api-keys/rotate.js +42 -0
  22. package/dist/commands/balance/index.d.ts +18 -0
  23. package/dist/commands/balance/index.js +29 -0
  24. package/dist/commands/balance/show.d.ts +25 -0
  25. package/dist/commands/balance/show.js +60 -0
  26. package/dist/commands/balance/statement.d.ts +19 -0
  27. package/dist/commands/balance/statement.js +52 -0
  28. package/dist/commands/browser/doctor.d.ts +11 -0
  29. package/dist/commands/browser/doctor.js +11 -0
  30. package/dist/commands/code/jobs/approve.d.ts +25 -0
  31. package/dist/commands/code/jobs/approve.js +52 -0
  32. package/dist/commands/code/jobs/cancel.d.ts +12 -0
  33. package/dist/commands/code/jobs/cancel.js +39 -0
  34. package/dist/commands/code/jobs/index.d.ts +19 -0
  35. package/dist/commands/code/jobs/index.js +38 -0
  36. package/dist/commands/code/jobs/list.d.ts +12 -0
  37. package/dist/commands/code/jobs/list.js +87 -0
  38. package/dist/commands/code/jobs/run.d.ts +32 -0
  39. package/dist/commands/code/jobs/run.js +151 -0
  40. package/dist/commands/code/jobs/show.d.ts +12 -0
  41. package/dist/commands/code/jobs/show.js +86 -0
  42. package/dist/commands/commitments/preflight.js +18 -4
  43. package/dist/commands/commitments/receipt-metrics.d.ts +39 -0
  44. package/dist/commands/commitments/receipt-metrics.js +78 -0
  45. package/dist/commands/convos/search.js +5 -5
  46. package/dist/commands/harnesses/leases/list.d.ts +3 -0
  47. package/dist/commands/harnesses/leases/list.js +59 -12
  48. package/dist/commands/harnesses/leases/show.js +36 -0
  49. package/dist/commands/harnesses/list.d.ts +18 -0
  50. package/dist/commands/harnesses/list.js +30 -0
  51. package/dist/commands/harnesses/products.js +49 -3
  52. package/dist/commands/harnesses/quota.d.ts +16 -0
  53. package/dist/commands/harnesses/quota.js +26 -1
  54. package/dist/commands/harnesses/usage.js +17 -0
  55. package/dist/commands/inbox/index.d.ts +2 -1
  56. package/dist/commands/inbox/index.js +27 -4
  57. package/dist/commands/login.js +4 -1
  58. package/dist/commands/machines/dedicated/create.d.ts +18 -0
  59. package/dist/commands/machines/dedicated/create.js +90 -0
  60. package/dist/commands/machines/dedicated/destroy.d.ts +14 -0
  61. package/dist/commands/machines/dedicated/destroy.js +56 -0
  62. package/dist/commands/machines/dedicated/grow.d.ts +13 -0
  63. package/dist/commands/machines/dedicated/grow.js +46 -0
  64. package/dist/commands/machines/dedicated/health-check.d.ts +12 -0
  65. package/dist/commands/machines/dedicated/health-check.js +42 -0
  66. package/dist/commands/machines/dedicated/incident-close.d.ts +12 -0
  67. package/dist/commands/machines/dedicated/incident-close.js +42 -0
  68. package/dist/commands/machines/dedicated/index.d.ts +6 -0
  69. package/dist/commands/machines/dedicated/index.js +39 -0
  70. package/dist/commands/machines/dedicated/list.d.ts +11 -0
  71. package/dist/commands/machines/dedicated/list.js +58 -0
  72. package/dist/commands/machines/dedicated/restart.d.ts +12 -0
  73. package/dist/commands/machines/dedicated/restart.js +42 -0
  74. package/dist/commands/machines/dedicated/show.d.ts +12 -0
  75. package/dist/commands/machines/dedicated/show.js +58 -0
  76. package/dist/commands/machines/dedicated/snapshot.d.ts +12 -0
  77. package/dist/commands/machines/dedicated/snapshot.js +42 -0
  78. package/dist/commands/machines/dedicated/start.d.ts +12 -0
  79. package/dist/commands/machines/dedicated/start.js +42 -0
  80. package/dist/commands/machines/dedicated/stop.d.ts +12 -0
  81. package/dist/commands/machines/dedicated/stop.js +42 -0
  82. package/dist/commands/machines/hosted/index.js +4 -1
  83. package/dist/commands/machines/list.d.ts +1 -0
  84. package/dist/commands/machines/list.js +33 -5
  85. package/dist/commands/memory/approvals/issue.d.ts +18 -0
  86. package/dist/commands/memory/approvals/issue.js +63 -0
  87. package/dist/commands/memory/commit.js +5 -2
  88. package/dist/commands/memory/context.d.ts +3 -2
  89. package/dist/commands/memory/context.js +9 -11
  90. package/dist/commands/memory/delete.d.ts +1 -1
  91. package/dist/commands/memory/list.d.ts +1 -1
  92. package/dist/commands/memory/list.js +1 -1
  93. package/dist/commands/memory/mounts/resolve.d.ts +10 -0
  94. package/dist/commands/memory/mounts/resolve.js +27 -0
  95. package/dist/commands/memory/proposals/commit.d.ts +18 -0
  96. package/dist/commands/memory/proposals/commit.js +32 -0
  97. package/dist/commands/memory/proposals/create.d.ts +18 -0
  98. package/dist/commands/memory/proposals/create.js +56 -0
  99. package/dist/commands/memory/proposals/list.d.ts +13 -0
  100. package/dist/commands/memory/proposals/list.js +31 -0
  101. package/dist/commands/memory/proposals/promote.d.ts +22 -0
  102. package/dist/commands/memory/proposals/promote.js +33 -0
  103. package/dist/commands/memory/proposals/reject.d.ts +16 -0
  104. package/dist/commands/memory/proposals/reject.js +28 -0
  105. package/dist/commands/memory/rebuild-index.d.ts +20 -0
  106. package/dist/commands/memory/rebuild-index.js +25 -0
  107. package/dist/commands/memory/save.d.ts +1 -1
  108. package/dist/commands/memory/save.js +1 -1
  109. package/dist/commands/memory/search.d.ts +6 -3
  110. package/dist/commands/memory/search.js +27 -3
  111. package/dist/commands/memory/show.d.ts +1 -1
  112. package/dist/commands/memory/stores/archive.d.ts +14 -0
  113. package/dist/commands/memory/stores/archive.js +31 -0
  114. package/dist/commands/memory/stores/create.d.ts +12 -0
  115. package/dist/commands/memory/stores/create.js +30 -0
  116. package/dist/commands/memory/stores/delete.d.ts +15 -0
  117. package/dist/commands/memory/stores/delete.js +38 -0
  118. package/dist/commands/memory/stores/list.d.ts +10 -0
  119. package/dist/commands/memory/stores/list.js +29 -0
  120. package/dist/commands/memory/stores/show.d.ts +12 -0
  121. package/dist/commands/memory/stores/show.js +14 -0
  122. package/dist/commands/memory/stores/update.d.ts +15 -0
  123. package/dist/commands/memory/stores/update.js +39 -0
  124. package/dist/commands/memory/sync/delete.d.ts +13 -0
  125. package/dist/commands/memory/sync/delete.js +35 -0
  126. package/dist/commands/memory/sync/pull.d.ts +19 -0
  127. package/dist/commands/memory/sync/pull.js +52 -0
  128. package/dist/commands/memory/sync/push.d.ts +18 -0
  129. package/dist/commands/memory/sync/push.js +115 -0
  130. package/dist/commands/memory/sync/resolve.d.ts +23 -0
  131. package/dist/commands/memory/sync/resolve.js +27 -0
  132. package/dist/commands/memory/sync/status.d.ts +9 -0
  133. package/dist/commands/memory/sync/status.js +22 -0
  134. package/dist/commands/memory/topics/archive.d.ts +20 -0
  135. package/dist/commands/memory/topics/archive.js +29 -0
  136. package/dist/commands/memory/topics/create.d.ts +23 -0
  137. package/dist/commands/memory/topics/create.js +46 -0
  138. package/dist/commands/memory/topics/delete.d.ts +22 -0
  139. package/dist/commands/memory/topics/delete.js +30 -0
  140. package/dist/commands/memory/topics/forget.d.ts +22 -0
  141. package/dist/commands/memory/topics/forget.js +29 -0
  142. package/dist/commands/memory/topics/list.d.ts +13 -0
  143. package/dist/commands/memory/topics/list.js +22 -0
  144. package/dist/commands/memory/topics/move.d.ts +22 -0
  145. package/dist/commands/memory/topics/move.js +26 -0
  146. package/dist/commands/memory/topics/show.d.ts +17 -0
  147. package/dist/commands/memory/topics/show.js +21 -0
  148. package/dist/commands/memory/topics/update.d.ts +23 -0
  149. package/dist/commands/memory/topics/update.js +27 -0
  150. package/dist/commands/memory/tree.d.ts +5 -2
  151. package/dist/commands/memory/tree.js +20 -2
  152. package/dist/commands/memory/update.d.ts +1 -1
  153. package/dist/commands/memory/versions/list.d.ts +16 -0
  154. package/dist/commands/memory/versions/list.js +22 -0
  155. package/dist/commands/memory/versions/redact.d.ts +21 -0
  156. package/dist/commands/memory/versions/redact.js +22 -0
  157. package/dist/commands/memory/versions/restore.d.ts +20 -0
  158. package/dist/commands/memory/versions/restore.js +16 -0
  159. package/dist/commands/memory/versions/show.d.ts +15 -0
  160. package/dist/commands/memory/versions/show.js +17 -0
  161. package/dist/commands/messages/list.js +25 -8
  162. package/dist/commands/messages/show.js +10 -0
  163. package/dist/commands/spaces/update.js +16 -12
  164. package/dist/commands/spaces/work-sync/reconcile.d.ts +38 -0
  165. package/dist/commands/spaces/work-sync/reconcile.js +90 -0
  166. package/dist/commands/spaces/work-sync/telemetry.d.ts +29 -0
  167. package/dist/commands/spaces/work-sync/telemetry.js +96 -0
  168. package/dist/commands/store/install.js +5 -1
  169. package/dist/commands/store/releases.js +1 -1
  170. package/dist/commands/store/update.js +5 -1
  171. package/dist/commands/subscriptions/cancel.js +5 -1
  172. package/dist/commands/subscriptions/health.js +5 -1
  173. package/dist/commands/subscriptions/status.js +5 -1
  174. package/dist/commands/subscriptions/subscribe.js +5 -1
  175. package/dist/commands/tasks/activity.d.ts +2 -3
  176. package/dist/commands/tasks/activity.js +20 -6
  177. package/dist/commands/tasks/complete.d.ts +22 -150
  178. package/dist/commands/tasks/complete.js +174 -599
  179. package/dist/commands/tasks/create.d.ts +6 -0
  180. package/dist/commands/tasks/create.js +114 -4
  181. package/dist/commands/tasks/deliverable/add.d.ts +8 -0
  182. package/dist/commands/tasks/deliverable/add.js +62 -11
  183. package/dist/commands/tasks/deliverable/confirm.d.ts +5 -5
  184. package/dist/commands/tasks/deliverable/confirm.js +9 -18
  185. package/dist/commands/tasks/deliverable/list.d.ts +12 -0
  186. package/dist/commands/tasks/deliverable/list.js +58 -0
  187. package/dist/commands/tasks/events/append.d.ts +2 -0
  188. package/dist/commands/tasks/events/append.js +41 -6
  189. package/dist/commands/tasks/events/list.d.ts +1 -0
  190. package/dist/commands/tasks/events/list.js +1 -0
  191. package/dist/commands/tasks/events/tail.d.ts +1 -0
  192. package/dist/commands/tasks/events/tail.js +1 -0
  193. package/dist/commands/tasks/expectations/assess.d.ts +21 -0
  194. package/dist/commands/tasks/expectations/assess.js +103 -0
  195. package/dist/commands/tasks/expectations.js +121 -25
  196. package/dist/commands/tasks/judge.d.ts +1 -0
  197. package/dist/commands/tasks/judge.js +2 -1
  198. package/dist/commands/tasks/output.d.ts +1 -11
  199. package/dist/commands/tasks/output.js +80 -141
  200. package/dist/commands/tasks/report.d.ts +3 -3
  201. package/dist/commands/tasks/report.js +66 -41
  202. package/dist/commands/tasks/resource/add.d.ts +23 -0
  203. package/dist/commands/tasks/resource/add.js +76 -0
  204. package/dist/commands/tasks/resource/list.d.ts +13 -0
  205. package/dist/commands/tasks/resource/list.js +41 -0
  206. package/dist/commands/tasks/result/show.d.ts +13 -0
  207. package/dist/commands/tasks/result/show.js +64 -0
  208. package/dist/commands/tasks/result/submit.d.ts +26 -0
  209. package/dist/commands/tasks/result/submit.js +134 -0
  210. package/dist/commands/tasks/resume/save.d.ts +16 -0
  211. package/dist/commands/tasks/resume/save.js +69 -0
  212. package/dist/commands/tasks/resume/show.d.ts +13 -0
  213. package/dist/commands/tasks/resume/show.js +35 -0
  214. package/dist/commands/tasks/review.d.ts +17 -0
  215. package/dist/commands/tasks/review.js +54 -0
  216. package/dist/commands/tasks/runs.js +5 -0
  217. package/dist/commands/tasks/self-schedule.js +7 -4
  218. package/dist/commands/tasks/show.js +19 -0
  219. package/dist/commands/tasks/timeline.d.ts +2 -2
  220. package/dist/commands/tasks/timeline.js +19 -24
  221. package/dist/commands/tasks/updates/add.d.ts +22 -0
  222. package/dist/commands/tasks/updates/add.js +122 -0
  223. package/dist/commands/tasks/updates/list.d.ts +15 -0
  224. package/dist/commands/tasks/updates/list.js +57 -0
  225. package/dist/commands/tasks/waive.d.ts +1 -0
  226. package/dist/commands/tasks/waive.js +2 -1
  227. package/dist/lib/agentic-stream.d.ts +257 -0
  228. package/dist/lib/agentic-stream.js +490 -33
  229. package/dist/lib/balance.d.ts +8 -0
  230. package/dist/lib/commitment-product.d.ts +10 -1
  231. package/dist/lib/commitment-product.js +66 -2
  232. package/dist/lib/commitments.d.ts +2 -1
  233. package/dist/lib/commitments.js +1 -0
  234. package/dist/lib/conversation-search.d.ts +3 -0
  235. package/dist/lib/conversation-search.js +75 -0
  236. package/dist/lib/dedicated-machines.d.ts +66 -0
  237. package/dist/lib/dedicated-machines.js +161 -0
  238. package/dist/lib/execution-target.d.ts +21 -0
  239. package/dist/lib/execution-target.js +22 -6
  240. package/dist/lib/harnesses.d.ts +87 -6
  241. package/dist/lib/harnesses.js +32 -1
  242. package/dist/lib/hosted-machines.js +9 -0
  243. package/dist/lib/inbox.d.ts +2 -1
  244. package/dist/lib/machines.d.ts +17 -0
  245. package/dist/lib/machines.js +29 -0
  246. package/dist/lib/managed-agent-keys.d.ts +104 -0
  247. package/dist/lib/managed-agent-keys.js +50 -0
  248. package/dist/lib/memory-scope.d.ts +4 -3
  249. package/dist/lib/memory-scope.js +9 -9
  250. package/dist/lib/memory-sync.d.ts +114 -0
  251. package/dist/lib/memory-sync.js +730 -0
  252. package/dist/lib/message-provenance.d.ts +42 -0
  253. package/dist/lib/message-provenance.js +89 -0
  254. package/dist/lib/scoped-memory-command.d.ts +68 -0
  255. package/dist/lib/scoped-memory-command.js +183 -0
  256. package/dist/lib/session-task-endpoints.d.ts +1 -1
  257. package/dist/lib/session-task-endpoints.js +7 -0
  258. package/dist/lib/sky-code-broker.d.ts +47 -0
  259. package/dist/lib/sky-code-broker.js +50 -0
  260. package/dist/lib/sky-code-doctor.js +10 -1
  261. package/dist/lib/task-artifact-flags.d.ts +2 -0
  262. package/dist/lib/task-artifact-flags.js +7 -0
  263. package/dist/lib/task-execution.d.ts +4 -5
  264. package/dist/lib/task-execution.js +4 -5
  265. package/dist/lib/task-extras.d.ts +1 -5
  266. package/dist/lib/task-extras.js +1 -5
  267. package/dist/lib/task-legacy.d.ts +24 -0
  268. package/dist/lib/task-legacy.js +48 -0
  269. package/dist/lib/task-transcript.d.ts +5 -7
  270. package/dist/lib/task-transcript.js +8 -16
  271. package/dist/lib/tasks.d.ts +39 -21
  272. package/dist/lib/tasks.js +64 -21
  273. package/dist/lib/triggers.d.ts +39 -1
  274. package/dist/lib/triggers.js +70 -2
  275. package/dist/lib/usage-discovery.d.ts +17 -1
  276. package/dist/lib/usage-discovery.js +17 -1
  277. package/dist/lib/work-sync.d.ts +70 -0
  278. package/dist/lib/work-sync.js +29 -0
  279. package/dist/node_modules/@skrr-ai/data-provider/index.js +3760 -3621
  280. package/oclif.manifest.json +14653 -7813
  281. package/package.json +26 -5
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const base_command_1 = require("../../base-command");
5
+ const managed_agent_keys_1 = require("../../lib/managed-agent-keys");
6
+ /**
7
+ * Mint a Managed Agents API key for a Space.
8
+ *
9
+ * The secret is displayed EXACTLY ONCE. There is no endpoint that reveals it
10
+ * again, so this command says that where the value is printed rather than in a
11
+ * footnote — a caller that scrolls past it has to rotate.
12
+ */
13
+ class ApiKeysCreate extends base_command_1.BaseCommand {
14
+ static description = 'Mint a Managed Agents API key (osk_*) for a Space. The secret is shown once and never again.';
15
+ static examples = [
16
+ '<%= config.bin %> api-keys create --space <space-id> --name "ci"',
17
+ '<%= config.bin %> api-keys create --space <space-id> --name "probe" --env test --scope environments:write',
18
+ ];
19
+ static args = {
20
+ name: core_1.Args.string({
21
+ description: 'Human label for the key (also settable with --name)',
22
+ // A positional that reads stdin would swallow a piped secret or script.
23
+ ignoreStdin: true,
24
+ }),
25
+ };
26
+ static flags = {
27
+ space: core_1.Flags.string({ description: 'Space that owns the key', required: true }),
28
+ name: core_1.Flags.string({ description: 'Human label for the key (≤200 chars)' }),
29
+ env: core_1.Flags.string({ description: 'Key environment', options: ['live', 'test'] }),
30
+ scope: core_1.Flags.string({
31
+ description: 'Scope to grant (repeatable, e.g. environments:write)',
32
+ multiple: true,
33
+ }),
34
+ 'expires-at': core_1.Flags.string({ description: 'ISO 8601 expiry; must be in the future' }),
35
+ json: core_1.Flags.boolean({ description: 'Output as JSON' }),
36
+ };
37
+ async run() {
38
+ this.requireAuth();
39
+ const { args, flags } = await this.parse(ApiKeysCreate);
40
+ const name = flags.name || args.name;
41
+ if (!name) {
42
+ this.error('A name is required — pass it positionally or with --name.', { exit: 1 });
43
+ }
44
+ let minted;
45
+ try {
46
+ minted = await (0, managed_agent_keys_1.createManagedAgentKey)({
47
+ spaceId: flags.space,
48
+ name,
49
+ env: flags.env,
50
+ scopes: flags.scope,
51
+ expiresAt: flags['expires-at'],
52
+ });
53
+ }
54
+ catch (err) {
55
+ // Includes the deployment-configuration case: an unconfigured server
56
+ // answers 503 with a sentence naming MANAGED_AGENTS_KEY_PEPPER, which is
57
+ // addressed to an operator and is worth passing through verbatim rather
58
+ // than flattening into "could not create key".
59
+ this.handleApiError(err);
60
+ return;
61
+ }
62
+ if (flags.json) {
63
+ this.log(JSON.stringify(minted, null, 2));
64
+ return;
65
+ }
66
+ this.log('');
67
+ this.log(` ${minted.secret}`);
68
+ this.log('');
69
+ this.log(minted.secret_warning ||
70
+ 'This is the only time the secret will be displayed. Store it securely.');
71
+ this.log('');
72
+ this.log(` id ${minted.id}`);
73
+ this.log(` name ${minted.name}`);
74
+ // No `env` field exists — the environment lives in the prefix, which is
75
+ // also the only part of a secret any later read will ever show.
76
+ this.log(` prefix ${minted.prefix ?? '(none)'}`);
77
+ this.log(` scopes ${minted.scopes?.length ? minted.scopes.join(', ') : '(none)'}`);
78
+ }
79
+ }
80
+ exports.default = ApiKeysCreate;
@@ -0,0 +1,11 @@
1
+ import { BaseCommand } from '../../base-command';
2
+ /** Every Managed Agents API key on a Space, including revoked ones. */
3
+ export default class ApiKeysList extends BaseCommand {
4
+ static description: string;
5
+ static examples: string[];
6
+ static flags: {
7
+ space: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
8
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
+ };
10
+ run(): Promise<void>;
11
+ }
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const base_command_1 = require("../../base-command");
5
+ const managed_agent_keys_1 = require("../../lib/managed-agent-keys");
6
+ /** Every Managed Agents API key on a Space, including revoked ones. */
7
+ class ApiKeysList extends base_command_1.BaseCommand {
8
+ static description = "List a Space's Managed Agents API keys. Secrets are never shown — only prefixes.";
9
+ static examples = ['<%= config.bin %> api-keys list --space <space-id>'];
10
+ static flags = {
11
+ space: core_1.Flags.string({ description: 'Space that owns the keys', required: true }),
12
+ json: core_1.Flags.boolean({ description: 'Output as JSON' }),
13
+ };
14
+ async run() {
15
+ this.requireAuth();
16
+ const { flags } = await this.parse(ApiKeysList);
17
+ let keys;
18
+ try {
19
+ keys = await (0, managed_agent_keys_1.listManagedAgentKeys)(flags.space);
20
+ }
21
+ catch (err) {
22
+ this.handleApiError(err);
23
+ return;
24
+ }
25
+ if (flags.json) {
26
+ this.log(JSON.stringify(keys, null, 2));
27
+ return;
28
+ }
29
+ if (keys.length === 0) {
30
+ this.log('No API keys on this space.');
31
+ return;
32
+ }
33
+ for (const k of keys) {
34
+ // A revoked key is listed rather than hidden: "this key was revoked" and
35
+ // "this key never existed" want different next actions.
36
+ const state = k.revoked_at ? 'revoked' : k.expires_at ? `expires ${k.expires_at}` : 'active';
37
+ // The prefix carries the environment; there is no separate field.
38
+ this.log(`${k.id} ${(k.prefix ?? '').padEnd(12)} ${state.padEnd(28)} ${k.name}`);
39
+ }
40
+ }
41
+ }
42
+ exports.default = ApiKeysList;
@@ -0,0 +1,14 @@
1
+ import { BaseCommand } from '../../base-command';
2
+ /** Revoke a key. Irreversible — a revoked key is replaced, never re-enabled. */
3
+ export default class ApiKeysRevoke extends BaseCommand {
4
+ static description: string;
5
+ static examples: string[];
6
+ static args: {
7
+ id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
8
+ };
9
+ static flags: {
10
+ space: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
11
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
12
+ };
13
+ run(): Promise<void>;
14
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const base_command_1 = require("../../base-command");
5
+ const managed_agent_keys_1 = require("../../lib/managed-agent-keys");
6
+ /** Revoke a key. Irreversible — a revoked key is replaced, never re-enabled. */
7
+ class ApiKeysRevoke extends base_command_1.BaseCommand {
8
+ static description = 'Revoke a Managed Agents API key. Irreversible — mint a replacement rather than expecting to undo this.';
9
+ static examples = ['<%= config.bin %> api-keys revoke <key-id> --space <space-id>'];
10
+ static args = {
11
+ id: core_1.Args.string({ description: 'Key id', required: true, ignoreStdin: true }),
12
+ };
13
+ static flags = {
14
+ space: core_1.Flags.string({ description: 'Space that owns the key', required: true }),
15
+ json: core_1.Flags.boolean({ description: 'Output as JSON' }),
16
+ };
17
+ async run() {
18
+ this.requireAuth();
19
+ const { args, flags } = await this.parse(ApiKeysRevoke);
20
+ try {
21
+ const res = await (0, managed_agent_keys_1.revokeManagedAgentKey)(args.id, flags.space);
22
+ if (flags.json) {
23
+ this.log(JSON.stringify(res, null, 2));
24
+ return;
25
+ }
26
+ this.log(`Revoked ${args.id}. Anything still presenting it will now be refused.`);
27
+ }
28
+ catch (err) {
29
+ this.handleApiError(err);
30
+ }
31
+ }
32
+ }
33
+ exports.default = ApiKeysRevoke;
@@ -0,0 +1,19 @@
1
+ import { BaseCommand } from '../../base-command';
2
+ /**
3
+ * Mint a replacement secret for an existing key row.
4
+ *
5
+ * Same once-only rule as `create`: the new secret is displayed here and nowhere
6
+ * else, and the previous one stops working.
7
+ */
8
+ export default class ApiKeysRotate extends BaseCommand {
9
+ static description: string;
10
+ static examples: string[];
11
+ static args: {
12
+ id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
13
+ };
14
+ static flags: {
15
+ space: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
16
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
17
+ };
18
+ run(): Promise<void>;
19
+ }
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const base_command_1 = require("../../base-command");
5
+ const managed_agent_keys_1 = require("../../lib/managed-agent-keys");
6
+ /**
7
+ * Mint a replacement secret for an existing key row.
8
+ *
9
+ * Same once-only rule as `create`: the new secret is displayed here and nowhere
10
+ * else, and the previous one stops working.
11
+ */
12
+ class ApiKeysRotate extends base_command_1.BaseCommand {
13
+ static description = 'Rotate a Managed Agents API key. The new secret is shown once; the old one stops working.';
14
+ static examples = ['<%= config.bin %> api-keys rotate <key-id> --space <space-id>'];
15
+ static args = {
16
+ id: core_1.Args.string({ description: 'Key id', required: true, ignoreStdin: true }),
17
+ };
18
+ static flags = {
19
+ space: core_1.Flags.string({ description: 'Space that owns the key', required: true }),
20
+ json: core_1.Flags.boolean({ description: 'Output as JSON' }),
21
+ };
22
+ async run() {
23
+ this.requireAuth();
24
+ const { args, flags } = await this.parse(ApiKeysRotate);
25
+ try {
26
+ const minted = await (0, managed_agent_keys_1.rotateManagedAgentKey)(args.id, flags.space);
27
+ if (flags.json) {
28
+ this.log(JSON.stringify(minted, null, 2));
29
+ return;
30
+ }
31
+ this.log('');
32
+ this.log(` ${minted.secret}`);
33
+ this.log('');
34
+ this.log(minted.secret_warning ||
35
+ 'This is the only time the secret will be displayed. The previous secret no longer works.');
36
+ }
37
+ catch (err) {
38
+ this.handleApiError(err);
39
+ }
40
+ }
41
+ }
42
+ exports.default = ApiKeysRotate;
@@ -0,0 +1,18 @@
1
+ import BalanceShow from './show';
2
+ /**
3
+ * `skrr balance` — the balance, not a table of contents.
4
+ *
5
+ * The bare topic printed its tagline ("Your hosted usage balance — the ceiling
6
+ * that refuses a turn") and then a list of four subcommands, with no number
7
+ * anywhere. The tagline names the value and then does not show it, and three of
8
+ * the four subcommands are plausible answers to "what is my balance"
9
+ * (`show`, `usage`, `statement`) — so the reader who typed the noun they wanted
10
+ * has to disambiguate a menu to get it (OSK-7637).
11
+ *
12
+ * Running `show` is what the command's own first line promises. `--help` still
13
+ * lists every subcommand, which is where a menu belongs.
14
+ */
15
+ export default class Balance extends BalanceShow {
16
+ static description: string;
17
+ static examples: string[];
18
+ }
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const show_1 = __importDefault(require("./show"));
7
+ /**
8
+ * `skrr balance` — the balance, not a table of contents.
9
+ *
10
+ * The bare topic printed its tagline ("Your hosted usage balance — the ceiling
11
+ * that refuses a turn") and then a list of four subcommands, with no number
12
+ * anywhere. The tagline names the value and then does not show it, and three of
13
+ * the four subcommands are plausible answers to "what is my balance"
14
+ * (`show`, `usage`, `statement`) — so the reader who typed the noun they wanted
15
+ * has to disambiguate a menu to get it (OSK-7637).
16
+ *
17
+ * Running `show` is what the command's own first line promises. `--help` still
18
+ * lists every subcommand, which is where a menu belongs.
19
+ */
20
+ class Balance extends show_1.default {
21
+ static description = 'Show your hosted usage balance — the ceiling that refuses a turn (not the x402 wallet). ' +
22
+ 'See `balance usage`, `balance statement` and `balance history` for the detail behind it.';
23
+ static examples = [
24
+ '<%= config.bin %> balance',
25
+ '<%= config.bin %> balance --json',
26
+ '<%= config.bin %> balance statement --desc',
27
+ ];
28
+ }
29
+ exports.default = Balance;
@@ -1,4 +1,13 @@
1
1
  import { BaseCommand } from '../../base-command';
2
+ import { type RuntimeMonthlySpend } from '../../lib/harnesses';
3
+ /**
4
+ * The hosted-runtime monthly cap rows, as lines.
5
+ *
6
+ * Pure so it can be tested the way `renderUsageSummary` is: this screen's job
7
+ * is to stop a user reading headroom off the wrong cap, and the wording is the
8
+ * fix, so the wording is what gets pinned.
9
+ */
10
+ export declare function renderRuntimeSpend(spend: RuntimeMonthlySpend[], log: (line: string) => void): void;
2
11
  /**
3
12
  * YOUR hosted usage balance — the personal account, and only that one.
4
13
  *
@@ -33,6 +42,22 @@ export default class BalanceShow extends BaseCommand {
33
42
  json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
34
43
  };
35
44
  run(): Promise<void>;
45
+ /**
46
+ * The OTHER cap — the one that actually refuses a Hosted Machine.
47
+ *
48
+ * Everything above is the credits account and its per-period rate limit. A
49
+ * hosted runtime is additionally bounded by a MONTHLY spend cap that this
50
+ * screen never mentioned, so a user could read `Spend cap: $10.00 per day`
51
+ * and `Cap remaining: $10.00` — headroom on every visible number — while
52
+ * every agent turn on a Hosted Machine was being refused by a limit with no
53
+ * surface at all. They could only discover it by being turned away
54
+ * (OSK-7920, split out of OSK-7900 / OSK-7909).
55
+ *
56
+ * Best-effort by design. This is a second call on a screen whose primary
57
+ * answer is the balance, so a failure here prints a short line and leaves
58
+ * that answer intact rather than failing the command.
59
+ */
60
+ private renderRuntimeSpend;
36
61
  /**
37
62
  * The workspace account, which is the one a workspace-carrying session is
38
63
  * funded from. Rendered in the SAME credits-plus-dollars unit and row labels
@@ -1,9 +1,41 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderRuntimeSpend = renderRuntimeSpend;
3
4
  const core_1 = require("@oclif/core");
4
5
  const base_command_1 = require("../../base-command");
5
6
  const balance_1 = require("../../lib/balance");
6
7
  const workspaces_1 = require("../../lib/workspaces");
8
+ const harnesses_1 = require("../../lib/harnesses");
9
+ const usd = (cents) => (typeof cents === 'number' ? `$${(cents / 100).toFixed(2)}` : '—');
10
+ /**
11
+ * The hosted-runtime monthly cap rows, as lines.
12
+ *
13
+ * Pure so it can be tested the way `renderUsageSummary` is: this screen's job
14
+ * is to stop a user reading headroom off the wrong cap, and the wording is the
15
+ * fix, so the wording is what gets pinned.
16
+ */
17
+ function renderRuntimeSpend(spend, log) {
18
+ const capped = spend.filter((row) => row.hasLimit);
19
+ if (capped.length === 0) {
20
+ // A product with no cap prints nothing rather than a reassuring "no limit"
21
+ // line: this section exists to warn, and an absent cap is not news.
22
+ return;
23
+ }
24
+ log('');
25
+ log('Hosted runtime — a SEPARATE monthly cap from the spend cap above:');
26
+ for (const row of capped) {
27
+ // `projected`, not `spent`: admission compares the cap against spend PLUS
28
+ // the estimated cost of everything still open. Showing only spend would
29
+ // read as headroom right up to the moment of refusal.
30
+ const flag = row.exceeded ? ' <- at the cap; turns are being refused' : '';
31
+ log(` ${row.machineProduct.padEnd(18)} ${usd(row.projectedCents)} of ` +
32
+ `${usd(row.limitCents)} projected${flag}`);
33
+ if (typeof row.openUsageEstimateCents === 'number' && row.openUsageEstimateCents > 0) {
34
+ log(` ${''.padEnd(18)} (${usd(row.currentSpendCents)} billed + ` +
35
+ `${usd(row.openUsageEstimateCents)} estimated for machines still open)`);
36
+ }
37
+ }
38
+ }
7
39
  /**
8
40
  * YOUR hosted usage balance — the personal account, and only that one.
9
41
  *
@@ -140,6 +172,7 @@ class BalanceShow extends base_command_1.BaseCommand {
140
172
  else {
141
173
  this.log(' Auto-refill: off');
142
174
  }
175
+ await this.renderRuntimeSpend();
143
176
  this.log('');
144
177
  this.log('A credit is a micro-dollar: 1,000,000 credits = $1.00. The spend cap');
145
178
  this.log('is a per-period ceiling, not a second balance. `skrr balance statement`');
@@ -150,6 +183,33 @@ class BalanceShow extends base_command_1.BaseCommand {
150
183
  this.log('see `skrr balance show --workspace <id>`. `skrr payments wallet` is the');
151
184
  this.log('separate x402 crypto wallet, in USDC — not this balance.');
152
185
  }
186
+ /**
187
+ * The OTHER cap — the one that actually refuses a Hosted Machine.
188
+ *
189
+ * Everything above is the credits account and its per-period rate limit. A
190
+ * hosted runtime is additionally bounded by a MONTHLY spend cap that this
191
+ * screen never mentioned, so a user could read `Spend cap: $10.00 per day`
192
+ * and `Cap remaining: $10.00` — headroom on every visible number — while
193
+ * every agent turn on a Hosted Machine was being refused by a limit with no
194
+ * surface at all. They could only discover it by being turned away
195
+ * (OSK-7920, split out of OSK-7900 / OSK-7909).
196
+ *
197
+ * Best-effort by design. This is a second call on a screen whose primary
198
+ * answer is the balance, so a failure here prints a short line and leaves
199
+ * that answer intact rather than failing the command.
200
+ */
201
+ async renderRuntimeSpend() {
202
+ let spend;
203
+ try {
204
+ ({ spend } = await (0, harnesses_1.getRuntimeMonthlySpend)());
205
+ }
206
+ catch {
207
+ this.log('');
208
+ this.log(' Hosted runtime: monthly cap unavailable (`skrr harnesses products` to retry)');
209
+ return;
210
+ }
211
+ renderRuntimeSpend(spend, (line) => this.log(line));
212
+ }
153
213
  /**
154
214
  * The workspace account, which is the one a workspace-carrying session is
155
215
  * funded from. Rendered in the SAME credits-plus-dollars unit and row labels
@@ -39,6 +39,25 @@ export default class BalanceStatement extends BaseCommand {
39
39
  };
40
40
  run(): Promise<void>;
41
41
  }
42
+ /**
43
+ * OSK-7641 — the ledger's default page is the OLDEST one, and nothing said so.
44
+ *
45
+ * With no flags the command returned 50 entries spanning three and a half
46
+ * WEEKS before today, opening with the account's legacy-balance-opening credit.
47
+ * A reader filtering for "entries since 06:45" got zero and concluded nothing
48
+ * had been billed at all. That conclusion was wrong, and the output gave them
49
+ * no way to know it: no range, no order, no "page 1 of many".
50
+ *
51
+ * `--desc` already existed (OSK-4823/OSK-4907) and is the fix — but only for
52
+ * someone who already suspected the default was wrong. So the page states what
53
+ * it is. The order word comes first because it is what changes the reading.
54
+ */
55
+ export declare function statementWindowLine(args: {
56
+ wantNewestFirst: boolean;
57
+ firstCreatedAt: string | null;
58
+ lastCreatedAt: string | null;
59
+ hasMore: boolean;
60
+ }): string;
42
61
  /**
43
62
  * The "More rows" footer, pointing at the cursor that matches the direction the
44
63
  * reader asked for: `--before` continues a newest-first page back through older
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.statementWindowLine = statementWindowLine;
3
4
  exports.statementMoreRowsHint = statementMoreRowsHint;
4
5
  exports.statementAmount = statementAmount;
5
6
  exports.statementAccountHeading = statementAccountHeading;
@@ -130,6 +131,15 @@ class BalanceStatement extends base_command_1.BaseCommand {
130
131
  this.log('No ledger entries.');
131
132
  return;
132
133
  }
134
+ // WHICH rows these are, before the reader starts drawing conclusions from
135
+ // them (OSK-7641).
136
+ this.log(statementWindowLine({
137
+ wantNewestFirst,
138
+ firstCreatedAt: entries[0]?.createdAt ?? null,
139
+ lastCreatedAt: entries[entries.length - 1]?.createdAt ?? null,
140
+ hasMore: Boolean(wantNewestFirst ? statement.nextBeforeEntryId : statement.nextAfterEntryId),
141
+ }));
142
+ this.log('');
133
143
  (0, format_1.renderTable)(entries.map((entry) => ({
134
144
  when: entry.createdAt ? String(entry.createdAt).slice(0, 19).replace('T', ' ') : '-',
135
145
  event: (0, format_1.formatCell)(entry.eventType),
@@ -139,6 +149,11 @@ class BalanceStatement extends base_command_1.BaseCommand {
139
149
  // in --json but never printed, so a human could not tell a code session
140
150
  // from a hosted run (OSK-4825).
141
151
  provider: (0, format_1.formatCell)(entry.provider),
152
+ // OSK-7641 — the command promises "what incurred it", and a bare
153
+ // session UUID does not answer that for anyone running more than one
154
+ // agent. Blank rather than '-' when the producer did not record one, so
155
+ // an unattributed row does not look like an attributed one.
156
+ agent: entry.agentId ? String(entry.agentId) : '',
142
157
  // The answer to "which session was this?" — the thing the legacy view
143
158
  // could never name, and the reason that view read as unexplainable. The
144
159
  // compound sourceId already encodes the source type in its first
@@ -152,9 +167,18 @@ class BalanceStatement extends base_command_1.BaseCommand {
152
167
  { key: 'service', header: 'SERVICE', maxWidth: 20 },
153
168
  { key: 'model', header: 'MODEL', maxWidth: 26 },
154
169
  { key: 'provider', header: 'PROVIDER', maxWidth: 16 },
170
+ { key: 'agent', header: 'AGENT', maxWidth: 26 },
155
171
  { key: 'source', header: 'SOURCE' },
156
172
  { key: 'amount', header: 'AMOUNT' },
157
173
  ], (line) => this.log(line));
174
+ // The reader's actual question is "what did my last few turns cost", and on
175
+ // page 1 of an oldest-first ledger the honest answer is "these are not
176
+ // those rows". Said next to the cursor hint, where a reader who has just
177
+ // seen three-week-old dates is looking (OSK-7641).
178
+ if (!wantNewestFirst && statement.nextAfterEntryId) {
179
+ this.log('');
180
+ this.log(`Looking for your most recent charges? \`${this.config.bin} balance statement --desc\``);
181
+ }
158
182
  const hint = statementMoreRowsHint({
159
183
  bin: this.config.bin,
160
184
  workspaceId,
@@ -169,6 +193,34 @@ class BalanceStatement extends base_command_1.BaseCommand {
169
193
  }
170
194
  }
171
195
  exports.default = BalanceStatement;
196
+ /**
197
+ * OSK-7641 — the ledger's default page is the OLDEST one, and nothing said so.
198
+ *
199
+ * With no flags the command returned 50 entries spanning three and a half
200
+ * WEEKS before today, opening with the account's legacy-balance-opening credit.
201
+ * A reader filtering for "entries since 06:45" got zero and concluded nothing
202
+ * had been billed at all. That conclusion was wrong, and the output gave them
203
+ * no way to know it: no range, no order, no "page 1 of many".
204
+ *
205
+ * `--desc` already existed (OSK-4823/OSK-4907) and is the fix — but only for
206
+ * someone who already suspected the default was wrong. So the page states what
207
+ * it is. The order word comes first because it is what changes the reading.
208
+ */
209
+ function statementWindowLine(args) {
210
+ const order = args.wantNewestFirst ? 'Newest first' : 'Oldest first';
211
+ const from = statementDay(args.firstCreatedAt);
212
+ const to = statementDay(args.lastCreatedAt);
213
+ const range = from && to ? (from === to ? from : `${from} → ${to}`) : 'no dated rows';
214
+ // "more" is the load-bearing half: a page that does not say it is one reads
215
+ // as the whole ledger.
216
+ return `${order} · ${range}${args.hasMore ? ' · more rows follow' : ' · complete'}`;
217
+ }
218
+ function statementDay(value) {
219
+ if (!value)
220
+ return null;
221
+ const text = String(value);
222
+ return text.length >= 10 ? text.slice(0, 10) : text;
223
+ }
172
224
  /**
173
225
  * The "More rows" footer, pointing at the cursor that matches the direction the
174
226
  * reader asked for: `--before` continues a newest-first page back through older
@@ -1,6 +1,17 @@
1
1
  import { Command } from '@oclif/core';
2
2
  export default class BrowserDoctor extends Command {
3
3
  static description: string;
4
+ /**
5
+ * `browser diagnose` reaches the same command.
6
+ *
7
+ * The group's own first line is "Install, diagnose, and configure
8
+ * capability-scoped skrr Browser access" — so a reader types the verb the
9
+ * product used to describe itself and gets `error: unknown command
10
+ * 'diagnose'`, one line, suggesting nothing and not even pointing at
11
+ * `--help`, which is how every other error surface in this CLI ends
12
+ * (OSK-7644). Two names for one command is cheaper than the round trip.
13
+ */
14
+ static aliases: string[];
4
15
  static flags: {
5
16
  json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
6
17
  };
@@ -4,6 +4,17 @@ const core_1 = require("@oclif/core");
4
4
  const browser_1 = require("../browser");
5
5
  class BrowserDoctor extends core_1.Command {
6
6
  static description = 'Diagnose browser runtime selection, relay, image, and MCP bridge';
7
+ /**
8
+ * `browser diagnose` reaches the same command.
9
+ *
10
+ * The group's own first line is "Install, diagnose, and configure
11
+ * capability-scoped skrr Browser access" — so a reader types the verb the
12
+ * product used to describe itself and gets `error: unknown command
13
+ * 'diagnose'`, one line, suggesting nothing and not even pointing at
14
+ * `--help`, which is how every other error surface in this CLI ends
15
+ * (OSK-7644). Two names for one command is cheaper than the round trip.
16
+ */
17
+ static aliases = ['browser:diagnose'];
7
18
  static flags = {
8
19
  json: core_1.Flags.boolean({ description: 'Output JSON' }),
9
20
  };
@@ -0,0 +1,25 @@
1
+ import { BaseCommand } from '../../../base-command';
2
+ /**
3
+ * `skrr code jobs approve` — land the pull request a job opened.
4
+ *
5
+ * OSK-7789 listed six verbs on `/api/cloud-coding` and one CLI binding. Four of
6
+ * the missing five are now bound; this is the last, and it is the one that
7
+ * FINISHES the work. Without it a headless operator could start a job, watch
8
+ * it, and stop it — and still had to open a browser to get the result merged,
9
+ * which is the same shape as the create-only path the finding was about.
10
+ *
11
+ * Only a repository-backed job has a pull request. `code jobs run` is bare
12
+ * compute with no repo, so there is nothing here to approve, and the refusal
13
+ * says which command produces one rather than reporting a bare 4xx.
14
+ */
15
+ export default class CodeJobsApprove extends BaseCommand {
16
+ static description: string;
17
+ static examples: string[];
18
+ static args: {
19
+ job: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
20
+ };
21
+ static flags: {
22
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
23
+ };
24
+ run(): Promise<void>;
25
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const data_provider_1 = require("@skrr-ai/data-provider");
5
+ const base_command_1 = require("../../../base-command");
6
+ /**
7
+ * `skrr code jobs approve` — land the pull request a job opened.
8
+ *
9
+ * OSK-7789 listed six verbs on `/api/cloud-coding` and one CLI binding. Four of
10
+ * the missing five are now bound; this is the last, and it is the one that
11
+ * FINISHES the work. Without it a headless operator could start a job, watch
12
+ * it, and stop it — and still had to open a browser to get the result merged,
13
+ * which is the same shape as the create-only path the finding was about.
14
+ *
15
+ * Only a repository-backed job has a pull request. `code jobs run` is bare
16
+ * compute with no repo, so there is nothing here to approve, and the refusal
17
+ * says which command produces one rather than reporting a bare 4xx.
18
+ */
19
+ class CodeJobsApprove extends base_command_1.BaseCommand {
20
+ static description = 'Approve and merge the pull request a Hosted Job Machine job opened';
21
+ static examples = [
22
+ '<%= config.bin %> code jobs approve <job-id>',
23
+ '<%= config.bin %> code jobs approve <job-id> --json',
24
+ ];
25
+ static args = {
26
+ job: core_1.Args.string({ description: 'Job id', required: true, ignoreStdin: true }),
27
+ };
28
+ static flags = { json: core_1.Flags.boolean({ description: 'Output as JSON' }) };
29
+ async run() {
30
+ this.requireAuth();
31
+ const { args, flags } = await this.parse(CodeJobsApprove);
32
+ let task;
33
+ try {
34
+ const res = await data_provider_1.dataService.approveCloudCodingPullRequest(args.job);
35
+ task = res?.task;
36
+ }
37
+ catch (err) {
38
+ this.handleApiError(err);
39
+ }
40
+ if (flags.json) {
41
+ this.log(JSON.stringify(task, null, 2));
42
+ return;
43
+ }
44
+ // The SERVER's status, never the one we asked for — approving races a
45
+ // branch someone merged by hand, and printing an outcome we did not observe
46
+ // is how a CLI starts inventing them.
47
+ this.log(`Job ${task?.id ?? args.job} is now ${task?.status ?? 'unknown'}.`);
48
+ if (task?.prUrl)
49
+ this.log(` ${String(task.prUrl)}`);
50
+ }
51
+ }
52
+ exports.default = CodeJobsApprove;