@skrr-ai/cli 0.1.46 → 0.1.48

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 (305) hide show
  1. package/README.md +1 -1
  2. package/dist/base-command.d.ts +18 -0
  3. package/dist/base-command.js +61 -1
  4. package/dist/commands/agents/chat.d.ts +21 -0
  5. package/dist/commands/agents/chat.js +26 -9
  6. package/dist/commands/balance/usage/breakdown.d.ts +14 -0
  7. package/dist/commands/balance/usage/breakdown.js +68 -0
  8. package/dist/commands/balance/usage.js +24 -0
  9. package/dist/commands/code/handover.d.ts +2 -2
  10. package/dist/commands/code/handover.js +12 -13
  11. package/dist/commands/code/install.js +31 -0
  12. package/dist/commands/code/update.d.ts +46 -0
  13. package/dist/commands/code/update.js +242 -0
  14. package/dist/commands/commerce/entitlements/explain.d.ts +22 -0
  15. package/dist/commands/commerce/entitlements/explain.js +40 -0
  16. package/dist/commands/commerce/incidents/audit.d.ts +20 -0
  17. package/dist/commands/commerce/incidents/audit.js +37 -0
  18. package/dist/commands/commerce/incidents/list.d.ts +22 -0
  19. package/dist/commands/commerce/incidents/list.js +49 -0
  20. package/dist/commands/commerce/incidents/resolve.d.ts +23 -0
  21. package/dist/commands/commerce/incidents/resolve.js +45 -0
  22. package/dist/commands/commerce/incidents/retry.d.ts +22 -0
  23. package/dist/commands/commerce/incidents/retry.js +45 -0
  24. package/dist/commands/commerce/incidents/show.d.ts +13 -0
  25. package/dist/commands/commerce/incidents/show.js +30 -0
  26. package/dist/commands/commerce/offers/approve.d.ts +17 -0
  27. package/dist/commands/commerce/offers/approve.js +33 -0
  28. package/dist/commands/commerce/offers/create.d.ts +18 -0
  29. package/dist/commands/commerce/offers/create.js +34 -0
  30. package/dist/commands/commerce/offers/publish.d.ts +13 -0
  31. package/dist/commands/commerce/offers/publish.js +28 -0
  32. package/dist/commands/commerce/offers/retire.d.ts +17 -0
  33. package/dist/commands/commerce/offers/retire.js +32 -0
  34. package/dist/commands/commerce/offers/validate.d.ts +18 -0
  35. package/dist/commands/commerce/offers/validate.js +33 -0
  36. package/dist/commands/commerce/products/create.d.ts +10 -0
  37. package/dist/commands/commerce/products/create.js +25 -0
  38. package/dist/commands/commerce/promotions/redeem.d.ts +13 -0
  39. package/dist/commands/commerce/promotions/redeem.js +32 -0
  40. package/dist/commands/commerce/terms/accept.d.ts +18 -0
  41. package/dist/commands/commerce/terms/accept.js +39 -0
  42. package/dist/commands/commerce/terms/show.d.ts +10 -0
  43. package/dist/commands/commerce/terms/show.js +34 -0
  44. package/dist/commands/commerce/trials/conversion-preview.d.ts +18 -0
  45. package/dist/commands/commerce/trials/conversion-preview.js +39 -0
  46. package/dist/commands/commerce/trials/start.d.ts +23 -0
  47. package/dist/commands/commerce/trials/start.js +58 -0
  48. package/dist/commands/commitments/accounting.d.ts +39 -0
  49. package/dist/commands/commitments/accounting.js +116 -0
  50. package/dist/commands/commitments/action-history.d.ts +1 -0
  51. package/dist/commands/commitments/action-history.js +8 -1
  52. package/dist/commands/commitments/case.d.ts +1 -0
  53. package/dist/commands/commitments/case.js +19 -3
  54. package/dist/commands/commitments/cases.d.ts +1 -0
  55. package/dist/commands/commitments/cases.js +11 -1
  56. package/dist/commands/commitments/checks.d.ts +1 -0
  57. package/dist/commands/commitments/checks.js +5 -1
  58. package/dist/commands/commitments/cost.d.ts +62 -0
  59. package/dist/commands/commitments/cost.js +130 -0
  60. package/dist/commands/commitments/create.js +1 -1
  61. package/dist/commands/commitments/delete.d.ts +1 -0
  62. package/dist/commands/commitments/delete.js +56 -6
  63. package/dist/commands/commitments/feedback.js +9 -1
  64. package/dist/commands/commitments/handover.js +16 -0
  65. package/dist/commands/commitments/hypotheses.d.ts +1 -0
  66. package/dist/commands/commitments/hypotheses.js +17 -2
  67. package/dist/commands/commitments/links/list.js +4 -1
  68. package/dist/commands/commitments/liveness.d.ts +18 -0
  69. package/dist/commands/commitments/liveness.js +80 -0
  70. package/dist/commands/commitments/metrics.d.ts +1 -0
  71. package/dist/commands/commitments/metrics.js +8 -1
  72. package/dist/commands/commitments/next-tick.d.ts +39 -0
  73. package/dist/commands/commitments/next-tick.js +122 -0
  74. package/dist/commands/commitments/observations.d.ts +1 -0
  75. package/dist/commands/commitments/observations.js +19 -2
  76. package/dist/commands/commitments/pause.js +12 -0
  77. package/dist/commands/commitments/receipt.d.ts +2 -0
  78. package/dist/commands/commitments/receipt.js +16 -2
  79. package/dist/commands/commitments/remediation-proposal.js +6 -2
  80. package/dist/commands/commitments/remediation-proposals.js +5 -1
  81. package/dist/commands/commitments/restore.d.ts +25 -0
  82. package/dist/commands/commitments/restore.js +46 -0
  83. package/dist/commands/commitments/show.js +32 -0
  84. package/dist/commands/commitments/trigger-status.js +33 -0
  85. package/dist/commands/commitments/update.d.ts +1 -0
  86. package/dist/commands/commitments/update.js +31 -5
  87. package/dist/commands/commitments/wake-capabilities.d.ts +0 -1
  88. package/dist/commands/commitments/wake-capabilities.js +8 -4
  89. package/dist/commands/convos/handover.d.ts +1 -0
  90. package/dist/commands/convos/handover.js +4 -0
  91. package/dist/commands/daemon/index.js +2 -0
  92. package/dist/commands/daemon/update.d.ts +19 -0
  93. package/dist/commands/daemon/update.js +48 -0
  94. package/dist/commands/enterprise/budgets/create.d.ts +11 -0
  95. package/dist/commands/enterprise/budgets/create.js +27 -0
  96. package/dist/commands/enterprise/budgets/evaluate.d.ts +17 -0
  97. package/dist/commands/enterprise/budgets/evaluate.js +32 -0
  98. package/dist/commands/enterprise/budgets/publish.d.ts +14 -0
  99. package/dist/commands/enterprise/budgets/publish.js +30 -0
  100. package/dist/commands/enterprise/contracts/activate.d.ts +14 -0
  101. package/dist/commands/enterprise/contracts/activate.js +30 -0
  102. package/dist/commands/enterprise/contracts/create.d.ts +14 -0
  103. package/dist/commands/enterprise/contracts/create.js +32 -0
  104. package/dist/commands/enterprise/contracts/issue.d.ts +18 -0
  105. package/dist/commands/enterprise/contracts/issue.js +34 -0
  106. package/dist/commands/enterprise/domains/begin.d.ts +20 -0
  107. package/dist/commands/enterprise/domains/begin.js +39 -0
  108. package/dist/commands/enterprise/domains/verify.d.ts +14 -0
  109. package/dist/commands/enterprise/domains/verify.js +32 -0
  110. package/dist/commands/enterprise/external-config/activate.d.ts +22 -0
  111. package/dist/commands/enterprise/external-config/activate.js +49 -0
  112. package/dist/commands/enterprise/external-config/set.d.ts +25 -0
  113. package/dist/commands/enterprise/external-config/set.js +123 -0
  114. package/dist/commands/enterprise/external-config/show.d.ts +12 -0
  115. package/dist/commands/enterprise/external-config/show.js +39 -0
  116. package/dist/commands/enterprise/external-config/suspend.d.ts +13 -0
  117. package/dist/commands/enterprise/external-config/suspend.js +41 -0
  118. package/dist/commands/enterprise/finance/close-snapshot.d.ts +11 -0
  119. package/dist/commands/enterprise/finance/close-snapshot.js +28 -0
  120. package/dist/commands/enterprise/finance/record-document.d.ts +18 -0
  121. package/dist/commands/enterprise/finance/record-document.js +35 -0
  122. package/dist/commands/enterprise/profile.d.ts +20 -0
  123. package/dist/commands/enterprise/profile.js +38 -0
  124. package/dist/commands/login.d.ts +13 -0
  125. package/dist/commands/login.js +77 -0
  126. package/dist/commands/machines/dedicated/index.js +3 -0
  127. package/dist/commands/machines/dedicated/service/apply.d.ts +23 -0
  128. package/dist/commands/machines/dedicated/service/apply.js +99 -0
  129. package/dist/commands/machines/dedicated/service/approve.d.ts +23 -0
  130. package/dist/commands/machines/dedicated/service/approve.js +52 -0
  131. package/dist/commands/machines/dedicated/service/create.d.ts +55 -0
  132. package/dist/commands/machines/dedicated/service/create.js +222 -0
  133. package/dist/commands/machines/dedicated/service/edit.d.ts +30 -0
  134. package/dist/commands/machines/dedicated/service/edit.js +146 -0
  135. package/dist/commands/machines/dedicated/service/exec.d.ts +26 -0
  136. package/dist/commands/machines/dedicated/service/exec.js +92 -0
  137. package/dist/commands/machines/dedicated/service/export.d.ts +29 -0
  138. package/dist/commands/machines/dedicated/service/export.js +106 -0
  139. package/dist/commands/machines/dedicated/service/index.d.ts +14 -0
  140. package/dist/commands/machines/dedicated/service/index.js +49 -0
  141. package/dist/commands/machines/dedicated/service/logs.d.ts +33 -0
  142. package/dist/commands/machines/dedicated/service/logs.js +148 -0
  143. package/dist/commands/machines/dedicated/service/ls.d.ts +20 -0
  144. package/dist/commands/machines/dedicated/service/ls.js +80 -0
  145. package/dist/commands/machines/dedicated/service/restart.d.ts +14 -0
  146. package/dist/commands/machines/dedicated/service/restart.js +29 -0
  147. package/dist/commands/machines/dedicated/service/rm.d.ts +20 -0
  148. package/dist/commands/machines/dedicated/service/rm.js +33 -0
  149. package/dist/commands/machines/dedicated/service/secret/index.d.ts +14 -0
  150. package/dist/commands/machines/dedicated/service/secret/index.js +25 -0
  151. package/dist/commands/machines/dedicated/service/secret/rm.d.ts +22 -0
  152. package/dist/commands/machines/dedicated/service/secret/rm.js +54 -0
  153. package/dist/commands/machines/dedicated/service/secret/set.d.ts +22 -0
  154. package/dist/commands/machines/dedicated/service/secret/set.js +93 -0
  155. package/dist/commands/machines/dedicated/service/start.d.ts +14 -0
  156. package/dist/commands/machines/dedicated/service/start.js +29 -0
  157. package/dist/commands/machines/dedicated/service/status.d.ts +21 -0
  158. package/dist/commands/machines/dedicated/service/status.js +85 -0
  159. package/dist/commands/machines/dedicated/service/stop.d.ts +20 -0
  160. package/dist/commands/machines/dedicated/service/stop.js +35 -0
  161. package/dist/commands/machines/dedicated/service/top.d.ts +22 -0
  162. package/dist/commands/machines/dedicated/service/top.js +120 -0
  163. package/dist/commands/machines/dedicated/sign-in-status.d.ts +22 -0
  164. package/dist/commands/machines/dedicated/sign-in-status.js +79 -0
  165. package/dist/commands/machines/dedicated/ssh-config.d.ts +28 -0
  166. package/dist/commands/machines/dedicated/ssh-config.js +66 -0
  167. package/dist/commands/machines/dedicated/ssh-proxy.d.ts +22 -0
  168. package/dist/commands/machines/dedicated/ssh-proxy.js +62 -0
  169. package/dist/commands/machines/dedicated/ssh.d.ts +29 -0
  170. package/dist/commands/machines/dedicated/ssh.js +121 -0
  171. package/dist/commands/native/allow-all.d.ts +14 -0
  172. package/dist/commands/native/allow-all.js +25 -0
  173. package/dist/commands/native/allow.d.ts +24 -0
  174. package/dist/commands/native/allow.js +45 -0
  175. package/dist/commands/native/deny.d.ts +24 -0
  176. package/dist/commands/native/deny.js +43 -0
  177. package/dist/commands/native/disable.d.ts +17 -0
  178. package/dist/commands/native/disable.js +28 -0
  179. package/dist/commands/native/enable.d.ts +12 -0
  180. package/dist/commands/native/enable.js +29 -0
  181. package/dist/commands/native/list-apps.d.ts +19 -0
  182. package/dist/commands/native/list-apps.js +30 -0
  183. package/dist/commands/native/restrict-to.d.ts +22 -0
  184. package/dist/commands/native/restrict-to.js +41 -0
  185. package/dist/commands/native/status.d.ts +19 -0
  186. package/dist/commands/native/status.js +33 -0
  187. package/dist/commands/native.d.ts +39 -0
  188. package/dist/commands/native.js +76 -0
  189. package/dist/commands/service/index.d.ts +14 -0
  190. package/dist/commands/service/index.js +31 -0
  191. package/dist/commands/service/logs.d.ts +18 -0
  192. package/dist/commands/service/logs.js +53 -0
  193. package/dist/commands/service/ls.d.ts +13 -0
  194. package/dist/commands/service/ls.js +48 -0
  195. package/dist/commands/service/propose.d.ts +34 -0
  196. package/dist/commands/service/propose.js +113 -0
  197. package/dist/commands/service/status.d.ts +17 -0
  198. package/dist/commands/service/status.js +56 -0
  199. package/dist/commands/spaces/auto-executor/runs.d.ts +13 -0
  200. package/dist/commands/spaces/auto-executor/runs.js +56 -0
  201. package/dist/commands/spaces/briefs/get.js +8 -0
  202. package/dist/commands/spaces/briefs/list.js +2 -0
  203. package/dist/commands/spaces/briefs/set.d.ts +3 -0
  204. package/dist/commands/spaces/briefs/set.js +78 -13
  205. package/dist/commands/spaces/expertise-suggestions.d.ts +12 -0
  206. package/dist/commands/spaces/expertise-suggestions.js +71 -0
  207. package/dist/commands/spaces/members/add.d.ts +1 -0
  208. package/dist/commands/spaces/members/add.js +11 -3
  209. package/dist/commands/spaces/members/list.js +11 -0
  210. package/dist/commands/store/governance/artifacts.d.ts +25 -0
  211. package/dist/commands/store/governance/artifacts.js +55 -0
  212. package/dist/commands/store/governance/assign.d.ts +16 -0
  213. package/dist/commands/store/governance/assign.js +54 -0
  214. package/dist/commands/store/governance/create-license.d.ts +18 -0
  215. package/dist/commands/store/governance/create-license.js +35 -0
  216. package/dist/commands/store/governance/install-plan.d.ts +25 -0
  217. package/dist/commands/store/governance/install-plan.js +56 -0
  218. package/dist/commands/store/governance/license-policy.d.ts +30 -0
  219. package/dist/commands/store/governance/license-policy.js +69 -0
  220. package/dist/commands/store/governance/policy.d.ts +25 -0
  221. package/dist/commands/store/governance/policy.js +65 -0
  222. package/dist/commands/store/governance/publish-release.d.ts +17 -0
  223. package/dist/commands/store/governance/publish-release.js +34 -0
  224. package/dist/commands/tasks/assign.d.ts +9 -0
  225. package/dist/commands/tasks/assign.js +108 -1
  226. package/dist/commands/tasks/deliverable/add.d.ts +15 -0
  227. package/dist/commands/tasks/deliverable/add.js +174 -0
  228. package/dist/commands/tasks/deliverable/archive.d.ts +35 -0
  229. package/dist/commands/tasks/deliverable/archive.js +205 -0
  230. package/dist/commands/tasks/labels/detach.js +3 -0
  231. package/dist/commands/tasks/labels/suggest.d.ts +24 -0
  232. package/dist/commands/tasks/labels/suggest.js +69 -0
  233. package/dist/commands/tasks/list.d.ts +16 -2
  234. package/dist/commands/tasks/list.js +100 -24
  235. package/dist/commands/tasks/show.d.ts +23 -0
  236. package/dist/commands/tasks/show.js +51 -1
  237. package/dist/commands/wiki/rm.d.ts +22 -1
  238. package/dist/commands/wiki/rm.js +52 -3
  239. package/dist/lib/agentic-stream.js +10 -2
  240. package/dist/lib/assignee-resolver.d.ts +22 -0
  241. package/dist/lib/assignee-resolver.js +26 -0
  242. package/dist/lib/balance.d.ts +6 -1
  243. package/dist/lib/balance.js +15 -0
  244. package/dist/lib/code-handover.d.ts +0 -10
  245. package/dist/lib/code-handover.js +20 -5
  246. package/dist/lib/commerce-command.d.ts +48 -0
  247. package/dist/lib/commerce-command.js +70 -0
  248. package/dist/lib/commerce.d.ts +93 -0
  249. package/dist/lib/commerce.js +129 -0
  250. package/dist/lib/commitment-product.js +1 -1
  251. package/dist/lib/commitments.d.ts +202 -29
  252. package/dist/lib/commitments.js +300 -33
  253. package/dist/lib/dedicated-lease-command.js +10 -0
  254. package/dist/lib/dedicated-machines.d.ts +37 -0
  255. package/dist/lib/dedicated-machines.js +47 -0
  256. package/dist/lib/dedicated-service-command.d.ts +60 -0
  257. package/dist/lib/dedicated-service-command.js +182 -0
  258. package/dist/lib/dedicated-service.d.ts +342 -0
  259. package/dist/lib/dedicated-service.js +741 -0
  260. package/dist/lib/dedicated-ssh.d.ts +136 -0
  261. package/dist/lib/dedicated-ssh.js +387 -0
  262. package/dist/lib/delegated-cli.js +51 -13
  263. package/dist/lib/enterprise-commerce.d.ts +67 -0
  264. package/dist/lib/enterprise-commerce.js +112 -0
  265. package/dist/lib/enterprise-external-configuration.d.ts +60 -0
  266. package/dist/lib/enterprise-external-configuration.js +58 -0
  267. package/dist/lib/first-party-harness.js +17 -3
  268. package/dist/lib/governed-store.d.ts +110 -0
  269. package/dist/lib/governed-store.js +79 -0
  270. package/dist/lib/guest-service-command.d.ts +16 -0
  271. package/dist/lib/guest-service-command.js +32 -0
  272. package/dist/lib/guest-service.d.ts +67 -0
  273. package/dist/lib/guest-service.js +112 -0
  274. package/dist/lib/prompt.d.ts +1 -0
  275. package/dist/lib/prompt.js +1 -0
  276. package/dist/lib/task-asset-upload.d.ts +20 -0
  277. package/dist/lib/task-asset-upload.js +30 -8
  278. package/dist/lib/task-extras.d.ts +23 -0
  279. package/dist/lib/task-extras.js +6 -0
  280. package/dist/lib/update-check.d.ts +80 -7
  281. package/dist/lib/update-check.js +365 -33
  282. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonScopes.d.ts +9 -3
  283. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonScopes.js +10 -3
  284. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.d.ts +9 -1
  285. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.js +8 -0
  286. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +1 -1
  287. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +6 -5
  288. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/messages.d.ts +16 -0
  289. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/messages.js +21 -4
  290. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.d.ts +1 -1
  291. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.js +24 -2
  292. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonScopes.d.ts +9 -3
  293. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonScopes.js +10 -3
  294. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.d.ts +9 -1
  295. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.js +8 -0
  296. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +1 -1
  297. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +1 -1
  298. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/messages.d.ts +16 -0
  299. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/messages.js +20 -4
  300. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.d.ts +1 -1
  301. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.js +24 -2
  302. package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
  303. package/dist/node_modules/@skrr-ai/data-provider/index.js +5067 -4821
  304. package/oclif.manifest.json +34877 -28659
  305. package/package.json +43 -1
package/README.md CHANGED
@@ -53,7 +53,7 @@ observability), and shared links.
53
53
  | **tasks result** | `submit`, `show` (immutable Result versions and exact Review state) |
54
54
  | **tasks resource** | `add`, `list` (versioned inputs, references, evidence, attachments, and Deliverables) |
55
55
  | **tasks deliverable** | `add`, `list`, `confirm` (the user-facing produced-Resource workflow) |
56
- | **tasks labels** | `list`, `create`, `delete` |
56
+ | **tasks labels** | `list`, `create`, `delete`, `attach`, `detach`, `suggest` (label vocabulary + per-task attachment; `suggest` asks the model to pick from the declared vocabulary, advisory only) |
57
57
  | **tasks approvals** | `list`, `create`, `delete`, `resolve` |
58
58
  | **tasks attachments** | `list`, `delete`, `upload`, `download` |
59
59
  | **integrations** | `toolkits`, `search`, `execute`, `tools list`, `tools allow`, `connections connect`, `connections list`, `connections finalize`, `connections disconnect`, `connections reconnect` |
@@ -403,6 +403,24 @@ export declare function describeHarnessUnavailable(body: Record<string, unknown>
403
403
  * Exported for tests.
404
404
  */
405
405
  export declare function describeGitHubUnavailable(): string;
406
+ /**
407
+ * Frame a typed `LABEL_SUGGESTION_UNAVAILABLE` failure as what it is — the
408
+ * suggestion's hosted-inference call found no billing payer — rather than a
409
+ * control-plane outage.
410
+ *
411
+ * `POST /api/tasks/:taskId/labels/suggest` answers 503 with this code when
412
+ * `resolveHostedUtilityBillingContext` cannot resolve a payer. The generic
413
+ * 503 handler would otherwise announce "service outage, retry once it
414
+ * recovers" and record an incident — all false: the platform answered, the
415
+ * task and its labels are untouched, and an immediate retry resolves the
416
+ * same nothing. Lead with the server's `cause`/`remedy` when present (the
417
+ * 5xx redaction boundary lets both through), falling back to the CLI's own
418
+ * sentence keyed on the code — in production the redaction generalizes the
419
+ * message to "An unexpected error occurred."
420
+ *
421
+ * Exported for tests.
422
+ */
423
+ export declare function describeLabelSuggestionUnavailable(body: Record<string, unknown> | null, bin?: string): string;
406
424
  /** A deployment setting cannot recover through a client retry. */
407
425
  export declare function describeGitHubAppNotConfigured(): string;
408
426
  export declare function describeResourceNotFound(serverMessage: string | undefined, bin?: string, baseURL?: string): string | null;
@@ -7,6 +7,7 @@ exports.apiRefusal = apiRefusal;
7
7
  exports.withSubject = withSubject;
8
8
  exports.describeHarnessUnavailable = describeHarnessUnavailable;
9
9
  exports.describeGitHubUnavailable = describeGitHubUnavailable;
10
+ exports.describeLabelSuggestionUnavailable = describeLabelSuggestionUnavailable;
10
11
  exports.describeGitHubAppNotConfigured = describeGitHubAppNotConfigured;
11
12
  exports.describeResourceNotFound = describeResourceNotFound;
12
13
  exports.describeAssigneeNotInSpace = describeAssigneeNotInSpace;
@@ -19,6 +20,7 @@ const core_1 = require("@oclif/core");
19
20
  Object.defineProperty(exports, "Flags", { enumerable: true, get: function () { return core_1.Flags; } });
20
21
  const option_hint_1 = require("./lib/option-hint");
21
22
  const failed_lookup_1 = require("./lib/failed-lookup");
23
+ const http_error_1 = require("./lib/http-error");
22
24
  // Re-exported from its home in `lib/keychain`, beside the other profile
23
25
  // functions. It lived here while `init()` was its only caller; a lib module
24
26
  // needing it would otherwise have to import the command base class, and with
@@ -797,9 +799,27 @@ class BaseCommand extends core_1.Command {
797
799
  if (optionHint) {
798
800
  err.message = `${err.message}\n\n${optionHint}`;
799
801
  }
802
+ // A transport error that reaches here uncaught still carries the server's
803
+ // coded refusal in its body — node adapter `err.body` text, axios-shaped
804
+ // `err.response.data` — but the envelope below reads only `err.code` and
805
+ // the transport line. `commitments import` answered a fingerprint-mismatch
806
+ // 400 as `CLI_PARSE_ERROR` while the body named the mismatch. Lift the
807
+ // body's code and message onto the error so the JSON envelope and the
808
+ // `super.catch` line both report the refusal the API actually sent.
809
+ const httpBody = (0, http_error_1.httpBodyOf)(err);
810
+ const httpStatus = (0, http_error_1.httpStatusOf)(err);
811
+ if (httpBody && httpStatus !== undefined && httpStatus >= 400) {
812
+ const bodyCode = stringProp(httpBody, 'code') || stringProp(httpBody, 'errorType');
813
+ const bodyMessage = stringProp(httpBody, 'message') || stringProp(httpBody, 'error');
814
+ err.code ??= bodyCode || `HTTP_${httpStatus}`;
815
+ if (bodyMessage && !err.message.includes(bodyMessage)) {
816
+ err.message = `${bodyMessage} — ${err.message}`;
817
+ }
818
+ }
800
819
  if (this.wantsJsonOutput()) {
801
820
  const exit = err.exitCode ?? err.oclif?.exit ?? 1;
802
821
  process.exitCode = exit;
822
+ const details = detailsFromCaughtError(err) ?? httpBody;
803
823
  this.log(JSON.stringify({
804
824
  ok: false,
805
825
  error: {
@@ -808,7 +828,7 @@ class BaseCommand extends core_1.Command {
808
828
  retryable: err.retryable ?? false,
809
829
  command: this.id ?? null,
810
830
  server: this.cliConfig?.baseURL ?? null,
811
- ...(detailsFromCaughtError(err) ? { details: detailsFromCaughtError(err) } : {}),
831
+ ...(details ? { details } : {}),
812
832
  },
813
833
  }, null, 2));
814
834
  return;
@@ -931,6 +951,20 @@ class BaseCommand extends core_1.Command {
931
951
  details: body ?? undefined,
932
952
  });
933
953
  }
954
+ else if (bodyCode === 'LABEL_SUGGESTION_UNAVAILABLE') {
955
+ // The label-suggestion route found no inference payer — a per-call
956
+ // condition the API deliberately reported, not a platform outage,
957
+ // even though it answers 503. Intercept before the outage heuristic
958
+ // so the user is not told skrr is down and no incident is recorded.
959
+ this.failWithCliError({
960
+ message: say(describeLabelSuggestionUnavailable(body, this.config.bin)),
961
+ code: bodyCode,
962
+ status: e.status,
963
+ exit: 1,
964
+ retryable: false,
965
+ details: body ?? undefined,
966
+ });
967
+ }
934
968
  else if (bodyCode === 'ASSIGNEE_NOT_IN_SPACE') {
935
969
  // Code-specific enrichment takes precedence over the status heuristic:
936
970
  // the server rejects a non-member assignee by id with no next step, so
@@ -1467,6 +1501,32 @@ function describeGitHubUnavailable() {
1467
1501
  return ('GitHub is temporarily unreachable, so this request could not be completed. ' +
1468
1502
  'skrr itself answered, so this is not a skrr outage — try again shortly.');
1469
1503
  }
1504
+ /**
1505
+ * Frame a typed `LABEL_SUGGESTION_UNAVAILABLE` failure as what it is — the
1506
+ * suggestion's hosted-inference call found no billing payer — rather than a
1507
+ * control-plane outage.
1508
+ *
1509
+ * `POST /api/tasks/:taskId/labels/suggest` answers 503 with this code when
1510
+ * `resolveHostedUtilityBillingContext` cannot resolve a payer. The generic
1511
+ * 503 handler would otherwise announce "service outage, retry once it
1512
+ * recovers" and record an incident — all false: the platform answered, the
1513
+ * task and its labels are untouched, and an immediate retry resolves the
1514
+ * same nothing. Lead with the server's `cause`/`remedy` when present (the
1515
+ * 5xx redaction boundary lets both through), falling back to the CLI's own
1516
+ * sentence keyed on the code — in production the redaction generalizes the
1517
+ * message to "An unexpected error occurred."
1518
+ *
1519
+ * Exported for tests.
1520
+ */
1521
+ function describeLabelSuggestionUnavailable(body, bin = 'skrr') {
1522
+ const cause = stringProp(body, 'cause') ||
1523
+ 'Label suggestion is unavailable — it runs on hosted inference, and no ' +
1524
+ 'billing payer could be resolved for this call.';
1525
+ const remedy = stringProp(body, 'remedy') ||
1526
+ `Attach a label directly with \`${bin} tasks labels attach <task-id> --label <id>\` — ` +
1527
+ 'a suggestion is a convenience, not a requirement.';
1528
+ return `${cause}\n → ${remedy}`;
1529
+ }
1470
1530
  /** A deployment setting cannot recover through a client retry. */
1471
1531
  function describeGitHubAppNotConfigured() {
1472
1532
  return ('The GitHub App is not configured on this deployment. ' +
@@ -120,6 +120,27 @@ export declare function chatStreamHeaderLines(input: {
120
120
  agentUrl?: string | null;
121
121
  threadRootMessageId?: string;
122
122
  }): string[];
123
+ /**
124
+ * The machine-pinning fragment of the chat-start payload. `--local-skill`
125
+ * already pins through the resolved skill daemon; `--daemon` alone pins the
126
+ * turn the same way (OSK-11797 — the flag was previously accepted and
127
+ * dropped). 'local' is the fail-closed pin: the server refuses rather than
128
+ * silently running on another machine when the named daemon is unavailable.
129
+ */
130
+ export declare function daemonPinFields(localSkills: {
131
+ daemonId: string;
132
+ refs: Array<{
133
+ name: string;
134
+ pathHash: string;
135
+ }>;
136
+ } | null, daemonFlag: string | undefined): {
137
+ executionEnvironment: 'local';
138
+ preferredDaemonId: string;
139
+ skillRefs?: Array<{
140
+ name: string;
141
+ pathHash: string;
142
+ }>;
143
+ } | Record<string, never>;
123
144
  export default class AgentsChat extends BaseCommand {
124
145
  static description: string;
125
146
  static examples: string[];
@@ -8,6 +8,7 @@ exports.inspectTurnCommand = inspectTurnCommand;
8
8
  exports.noOutputFailureMessage = noOutputFailureMessage;
9
9
  exports.noStreamJsonPayload = noStreamJsonPayload;
10
10
  exports.chatStreamHeaderLines = chatStreamHeaderLines;
11
+ exports.daemonPinFields = daemonPinFields;
11
12
  const node_fs_1 = require("node:fs");
12
13
  const core_1 = require("@oclif/core");
13
14
  const data_provider_1 = require("@skrr-ai/data-provider");
@@ -190,6 +191,26 @@ function chatStreamHeaderLines(input) {
190
191
  lines.push(`Agent URL: ${agentUrl ?? '-'}`);
191
192
  return lines;
192
193
  }
194
+ /**
195
+ * The machine-pinning fragment of the chat-start payload. `--local-skill`
196
+ * already pins through the resolved skill daemon; `--daemon` alone pins the
197
+ * turn the same way (OSK-11797 — the flag was previously accepted and
198
+ * dropped). 'local' is the fail-closed pin: the server refuses rather than
199
+ * silently running on another machine when the named daemon is unavailable.
200
+ */
201
+ function daemonPinFields(localSkills, daemonFlag) {
202
+ if (localSkills) {
203
+ return {
204
+ skillRefs: localSkills.refs,
205
+ executionEnvironment: 'local',
206
+ preferredDaemonId: localSkills.daemonId,
207
+ };
208
+ }
209
+ if (daemonFlag) {
210
+ return { executionEnvironment: 'local', preferredDaemonId: daemonFlag };
211
+ }
212
+ return {};
213
+ }
193
214
  class AgentsChat extends base_command_1.BaseCommand {
194
215
  static description = 'Run an agent turn with live streaming, tool events, cancellation, and reconnects';
195
216
  static examples = [
@@ -246,8 +267,10 @@ class AgentsChat extends base_command_1.BaseCommand {
246
267
  multiple: true,
247
268
  }),
248
269
  daemon: core_1.Flags.string({
249
- description: 'The machine whose skills --local-skill names. Defaults to your only connected daemon.',
250
- dependsOn: ['local-skill'],
270
+ description: 'Run this turn on this machine — a daemon id from `skrr daemons`. With ' +
271
+ '--local-skill it names the machine whose skills are invoked; without it ' +
272
+ 'the turn itself is pinned to that daemon and fails rather than running ' +
273
+ 'elsewhere if it is unavailable.',
251
274
  }),
252
275
  task: core_1.Flags.string({
253
276
  description: 'Bind this turn to a task (UUID or OSK-####). Injects the canonical task id, ' +
@@ -461,13 +484,7 @@ class AgentsChat extends base_command_1.BaseCommand {
461
484
  // turn is asked to run on the machine that listed them. An agent whose
462
485
  // execution policy places it elsewhere keeps that placement, and the
463
486
  // run fails saying why rather than running without the skill.
464
- ...(localSkills
465
- ? {
466
- skillRefs: localSkills.refs,
467
- executionEnvironment: 'local',
468
- preferredDaemonId: localSkills.daemonId,
469
- }
470
- : {}),
487
+ ...daemonPinFields(localSkills, flags.daemon),
471
488
  });
472
489
  }
473
490
  catch (err) {
@@ -0,0 +1,14 @@
1
+ import type { TSkyCodeUsageBreakdown } from '@skrr-ai/data-provider';
2
+ import { BaseCommand } from '../../../base-command';
3
+ export default class BalanceUsageBreakdown extends BaseCommand {
4
+ static description: string;
5
+ static examples: string[];
6
+ static flags: {
7
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
+ from: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
9
+ to: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
10
+ 'product-family': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
11
+ };
12
+ run(): Promise<void>;
13
+ }
14
+ export declare function renderSkyCodeUsageBreakdown(breakdown: TSkyCodeUsageBreakdown, log: (line: string) => void): void;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderSkyCodeUsageBreakdown = renderSkyCodeUsageBreakdown;
4
+ const core_1 = require("@oclif/core");
5
+ const auth_core_1 = require("@skrr-ai/auth-core");
6
+ const base_command_1 = require("../../../base-command");
7
+ const balance_1 = require("../../../lib/balance");
8
+ class BalanceUsageBreakdown extends base_command_1.BaseCommand {
9
+ static description = `Aggregate settled ${auth_core_1.FIRST_PARTY_HARNESS.displayName} usage by model, surface, agent and member`;
10
+ static examples = [
11
+ '<%= config.bin %> balance usage breakdown',
12
+ '<%= config.bin %> balance usage breakdown --json',
13
+ '<%= config.bin %> balance usage breakdown --workspace <workspace-id>',
14
+ '<%= config.bin %> balance usage breakdown --from 2026-09-01 --to 2026-09-15',
15
+ '<%= config.bin %> balance usage breakdown --product-family sky-code-api',
16
+ ];
17
+ static flags = {
18
+ json: core_1.Flags.boolean({ description: 'Output as JSON' }),
19
+ from: core_1.Flags.string({ description: 'Inclusive ISO start time; defaults to 30 days ago' }),
20
+ to: core_1.Flags.string({ description: 'Inclusive ISO end time; defaults to now' }),
21
+ 'product-family': core_1.Flags.string({
22
+ description: 'Restrict to one product family (e.g. sky-code-api for PAYG spend)',
23
+ }),
24
+ };
25
+ async run() {
26
+ this.requireAuth();
27
+ const { flags } = await this.parse(BalanceUsageBreakdown);
28
+ const workspaceId = flags.workspace;
29
+ let breakdown;
30
+ try {
31
+ breakdown = await (0, balance_1.getSkyCodeUsageBreakdown)(workspaceId, {
32
+ from: flags.from,
33
+ to: flags.to,
34
+ productFamily: flags['product-family'],
35
+ });
36
+ }
37
+ catch (error) {
38
+ this.handleApiError(error);
39
+ }
40
+ if (flags.json) {
41
+ this.log(JSON.stringify(breakdown, null, 2));
42
+ return;
43
+ }
44
+ renderSkyCodeUsageBreakdown(breakdown, (line) => this.log(line));
45
+ }
46
+ }
47
+ exports.default = BalanceUsageBreakdown;
48
+ function renderSkyCodeUsageBreakdown(breakdown, log) {
49
+ log(`${auth_core_1.FIRST_PARTY_HARNESS.displayName} usage breakdown · ${breakdown.ownerType} ${breakdown.ownerId}`);
50
+ log(` Window ${breakdown.from} to ${breakdown.to}`);
51
+ log(` Total ${(0, balance_1.formatCreditsWithUsd)(breakdown.total.usageMicros)} across ${breakdown.total.events} settled authorization${breakdown.total.events === 1 ? '' : 's'}`);
52
+ const section = (title, rows) => {
53
+ if (rows.length === 0)
54
+ return;
55
+ log(` ${title}`);
56
+ for (const row of rows) {
57
+ const balance = row.balanceMicros > 0 ? ` · ${(0, balance_1.formatMicros)(row.balanceMicros)} billed to balance` : '';
58
+ log(` ${row.label} ${(0, balance_1.formatCreditsWithUsd)(row.usageMicros)} · ${row.events} event${row.events === 1 ? '' : 's'}${balance}`);
59
+ }
60
+ };
61
+ section('By model', breakdown.byModel.map((row) => ({
62
+ ...row,
63
+ label: [row.provider, row.model].filter(Boolean).join('/') || 'unknown',
64
+ })));
65
+ section('By surface', breakdown.bySurface.map((row) => ({ ...row, label: row.surface ?? 'unknown' })));
66
+ section('By agent', breakdown.byAgent.map((row) => ({ ...row, label: row.agentId ?? 'unattributed' })));
67
+ section('By member', breakdown.byMember.map((row) => ({ ...row, label: row.memberUserId ?? 'unattributed' })));
68
+ }
@@ -51,8 +51,32 @@ function renderSkyCodeUsage(usage, log) {
51
51
  log(` 5-hour limit ${(0, balance_1.formatCreditsWithUsd)(usage.fiveHour.limitUsageMicros)}`);
52
52
  log(` 5-hour reset ${usage.fiveHour.resetsAt ?? 'unavailable'}`);
53
53
  log(` Concurrent sessions ${usage.fiveHour.activeSessions}/${usage.fiveHour.maxConcurrentSessions}`);
54
+ if (usage.weekly) {
55
+ log(` Weekly used ${(0, balance_1.formatCreditsWithUsd)(usage.weekly.usedUsageMicros)}`);
56
+ log(` Weekly reserved ${(0, balance_1.formatCreditsWithUsd)(usage.weekly.reservedUsageMicros)}`);
57
+ log(` Weekly limit ${(0, balance_1.formatCreditsWithUsd)(usage.weekly.limitUsageMicros)}`);
58
+ log(` Weekly reset ${usage.weekly.resetsAt ?? 'unavailable'}`);
59
+ }
60
+ if (usage.weeklyPremium && usage.weeklyPremium.limitUsageMicros > 0) {
61
+ log(` Premium weekly used ${(0, balance_1.formatCreditsWithUsd)(usage.weeklyPremium.usedUsageMicros)}`);
62
+ log(` Premium weekly reserved ${(0, balance_1.formatCreditsWithUsd)(usage.weeklyPremium.reservedUsageMicros)}`);
63
+ log(` Premium weekly limit ${(0, balance_1.formatCreditsWithUsd)(usage.weeklyPremium.limitUsageMicros)}`);
64
+ log(` Premium weekly reset ${usage.weeklyPremium.resetsAt ?? 'unavailable'}`);
65
+ }
66
+ if (usage.degraded) {
67
+ log(` Economy fallback ${(0, balance_1.formatCreditsWithUsd)(usage.degraded.usedUsageMicros)} used of ${(0, balance_1.formatCreditsWithUsd)(usage.degraded.includedUsageMicros)}`);
68
+ }
54
69
  log(` Available overage ${(0, balance_1.formatCreditsWithUsd)(usage.balance.availableMicros)}`);
55
70
  log(` Overage consent ${usage.overageEnabled ? 'enabled' : 'disabled'}`);
71
+ if (usage.overage) {
72
+ log(` Overage mode ${usage.overage.mode}`);
73
+ if (usage.overage.mode === 'postpaid') {
74
+ log(` Postpaid accrued ${(0, balance_1.formatCreditsWithUsd)(usage.overage.postpaidAccruedMicros ?? 0)}`);
75
+ }
76
+ if (usage.overage.spendCapMicros != null) {
77
+ log(` Overage spend cap ${(0, balance_1.formatCreditsWithUsd)(usage.overage.spendCapMicros)}`);
78
+ }
79
+ }
56
80
  if (usage.dataStatus === 'partial') {
57
81
  if (usage.partialReasons?.includes('missing_entitlement_period')) {
58
82
  log(' Entitlement period unavailable; catalog limits shown');
@@ -25,8 +25,8 @@ import { BaseCommand } from '../../base-command';
25
25
  *
26
26
  * The transcript CAN travel once the engine implements the session-export
27
27
  * contract (docs/architecture/sky-code-session-export-contract-2026-08-21.md):
28
- * `sky-code session export <id> --format json` writes a versioned envelope to
29
- * stdout. This flag runs exactly that contract and folds the export into the
28
+ * `session export <id> --format json` on the engine writes a versioned envelope
29
+ * to stdout. This flag runs exactly that contract and folds the export into the
30
30
  * prompt — the endpoint's only carrier. An engine that predates the contract
31
31
  * is a clean refusal, never a silent fallback to brief-only.
32
32
  *
@@ -4,6 +4,7 @@ const core_1 = require("@oclif/core");
4
4
  const node_child_process_1 = require("node:child_process");
5
5
  const node_crypto_1 = require("node:crypto");
6
6
  const data_provider_1 = require("@skrr-ai/data-provider");
7
+ const auth_core_1 = require("@skrr-ai/auth-core");
7
8
  const base_command_1 = require("../../base-command");
8
9
  const code_handover_1 = require("../../lib/code-handover");
9
10
  const first_party_harness_1 = require("../../lib/first-party-harness");
@@ -33,8 +34,8 @@ const first_party_harness_1 = require("../../lib/first-party-harness");
33
34
  *
34
35
  * The transcript CAN travel once the engine implements the session-export
35
36
  * contract (docs/architecture/sky-code-session-export-contract-2026-08-21.md):
36
- * `sky-code session export <id> --format json` writes a versioned envelope to
37
- * stdout. This flag runs exactly that contract and folds the export into the
37
+ * `session export <id> --format json` on the engine writes a versioned envelope
38
+ * to stdout. This flag runs exactly that contract and folds the export into the
38
39
  * prompt — the endpoint's only carrier. An engine that predates the contract
39
40
  * is a clean refusal, never a silent fallback to brief-only.
40
41
  *
@@ -77,15 +78,15 @@ class CodeHandover extends base_command_1.BaseCommand {
77
78
  description: 'Give the receiving agent a browser. Refused where the deployment has no browser runtime, never run without one.',
78
79
  }),
79
80
  'carry-session': core_1.Flags.boolean({
80
- description: 'Export the engine session transcript (`sky-code session export`) and carry it into the ' +
81
- 'handover. Opt-in because carrying a whole session is a cost the user should choose. ' +
82
- 'Refused outright when the engine predates the export contract — there is no silent ' +
83
- 'fallback to brief-only.',
81
+ description: `Export the engine session transcript (\`${auth_core_1.FIRST_PARTY_HARNESS.provider} session export\`) ` +
82
+ 'and carry it into the handover. Opt-in because carrying a whole session is a cost the ' +
83
+ 'user should choose. Refused outright when the engine predates the export contract — ' +
84
+ 'there is no silent fallback to brief-only.',
84
85
  default: false,
85
86
  }),
86
87
  session: core_1.Flags.string({
87
88
  description: 'Engine session id to export with --carry-session (default: the session id the engine ' +
88
- 'exports to its environment — SKRR_CODE_SESSION_ID or SKY_CODE_SESSION_ID)',
89
+ `exports to its environment — ${(0, auth_core_1.firstPartyHarnessEngineEnvNames)('sessionId').join(' or ')})`,
89
90
  }),
90
91
  json: core_1.Flags.boolean({ description: 'Output the created task as JSON' }),
91
92
  };
@@ -142,12 +143,10 @@ class CodeHandover extends base_command_1.BaseCommand {
142
143
  this.error((0, first_party_harness_1.notInstalledMessage)());
143
144
  // `--session` wins; otherwise the variable the engine stamps into
144
145
  // processes it spawns (current namespace, then the legacy spelling).
145
- const sessionId = flags.session ||
146
- process.env.SKRR_CODE_SESSION_ID?.trim() ||
147
- process.env.SKY_CODE_SESSION_ID?.trim();
146
+ const sessionId = flags.session || (0, auth_core_1.readFirstPartyHarnessEngineEnv)(process.env, 'sessionId').value;
148
147
  if (!sessionId) {
149
148
  this.error('--carry-session needs the engine session to carry. Pass --session <engine-session-id>, ' +
150
- 'or run inside a session that exports SKRR_CODE_SESSION_ID.');
149
+ `or run inside a session that exports ${(0, auth_core_1.firstPartyHarnessEngineEnvNames)('sessionId')[0]}.`);
151
150
  }
152
151
  carriedSessionId = sessionId;
153
152
  let stdout;
@@ -165,8 +164,8 @@ class CodeHandover extends base_command_1.BaseCommand {
165
164
  this.error(`No engine session "${sessionId}" — the engine found nothing to carry.\n` +
166
165
  ` ${failure.detail}`);
167
166
  }
168
- this.error('This engine does not support session export — --carry-session requires a sky-code ' +
169
- 'engine implementing the session-export contract ' +
167
+ this.error(`This engine does not support session export — --carry-session requires a ` +
168
+ `${auth_core_1.FIRST_PARTY_HARNESS_ENGINE.appName} engine implementing the session-export contract ` +
170
169
  '(docs/architecture/sky-code-session-export-contract-2026-08-21.md).\n' +
171
170
  ` ${failure.detail}\n` +
172
171
  ' Re-run without --carry-session to hand over the situation only, or upgrade the engine.');
@@ -57,6 +57,37 @@ class CodeInstall extends base_command_1.BaseCommand {
57
57
  catch (err) {
58
58
  this.handleApiError(err);
59
59
  }
60
+ // The daemon distinguishes three refusals, and only one of them attaches a
61
+ // job worth following:
62
+ //
63
+ // - `alreadyInstalled` carries the LAST job the provider ran — context, not
64
+ // this request's work. Following it replays a stale outcome as though it
65
+ // had just happened: `code install` on an engine one release behind
66
+ // reprinted the previous update's log tail verbatim and reported that job
67
+ // as its result (OSK-10650). The right answer is the daemon's own
68
+ // installDisabledReason plus where the update actually comes from.
69
+ // - `alreadyRunning` carries the LIVE job — following it attaches the user
70
+ // to work that is really in flight, which is what they asked for.
71
+ // - `started` carries the job this request began.
72
+ if (started.alreadyInstalled) {
73
+ if (flags.json) {
74
+ this.log(JSON.stringify({ daemonId, ...started }, null, 2));
75
+ return;
76
+ }
77
+ const state = started.provider;
78
+ const reason = state?.installDisabledReason?.trim();
79
+ const version = state?.version?.trim();
80
+ this.log(`Nothing to do on ${daemonId} — ${reason || 'Already installed.'}${version ? ` (${version})` : ''}`);
81
+ if (state?.updatable === true) {
82
+ this.log(`To update it: ${this.config.bin} code update`);
83
+ }
84
+ else {
85
+ const why = state?.updateDisabledReason?.trim();
86
+ if (why)
87
+ this.log(`Updating: ${why}`);
88
+ }
89
+ return;
90
+ }
60
91
  const jobId = started.job?.id;
61
92
  // A 202 carrying NO job is not a queued install. It is the daemon
62
93
  // acknowledging the call and returning nothing, and the route builds its
@@ -0,0 +1,46 @@
1
+ import { BaseCommand } from '../../base-command';
2
+ /**
3
+ * `skrr code update` — pull the engine's signed release down through the daemon.
4
+ *
5
+ * ── Why this command exists ────────────────────────────────────────────────
6
+ *
7
+ * The update verb has been API-exposed and daemon-implemented since OSK-10096 —
8
+ * `POST /api/daemons/:id/cli-installers/:provider/update` re-fetches the signed
9
+ * manifest and installs whatever the channel points at. But the only CLI that
10
+ * reached it was `skrr harnesses install <provider> --update`: a flag on a
11
+ * command a `code` user has no reason to read. On stable that left no
12
+ * discoverable path at all — `code install` answered "Already installed." with
13
+ * no next step, and the channel moving past the installed build was invisible
14
+ * from the surface that owns the engine (OSK-10650).
15
+ *
16
+ * So this adds a SURFACE and no mechanism. Same route `harnesses install
17
+ * --update` posts, same inventory pre-check, same 504 recovery — one update
18
+ * path, spelled where the engine's users look.
19
+ */
20
+ export default class CodeUpdate extends BaseCommand {
21
+ static description: string;
22
+ static examples: string[];
23
+ static flags: {
24
+ daemon: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
25
+ wait: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
26
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
27
+ };
28
+ run(): Promise<void>;
29
+ /** Which daemon the update targets, by the rule every daemon-picking command shares. */
30
+ private resolveTarget;
31
+ /**
32
+ * The daemon id to update through, or the refusal — identical rules to
33
+ * `code install`: a Dedicated Runtime's own machine is image-managed, several
34
+ * connected daemons get named rather than guessed.
35
+ */
36
+ private updateTarget;
37
+ /**
38
+ * Start the update, and survive a gateway that cut the request off — the same
39
+ * 504 recovery `harnesses install --update` uses: the relay can drop the
40
+ * answer while the daemon runs the job it started, so on a server-side
41
+ * failure we ask the daemon and follow the job it reports.
42
+ */
43
+ private start;
44
+ /** Follow a job to its end, or report why it could not be followed (and return nothing). */
45
+ private follow;
46
+ }