@skrr-ai/cli 0.1.47 → 0.1.49

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 (286) 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/agent-worker.d.ts +12 -0
  5. package/dist/commands/agent-worker.js +140 -0
  6. package/dist/commands/agents/chat.d.ts +21 -0
  7. package/dist/commands/agents/chat.js +26 -9
  8. package/dist/commands/balance/usage/breakdown.d.ts +14 -0
  9. package/dist/commands/balance/usage/breakdown.js +68 -0
  10. package/dist/commands/balance/usage.js +24 -0
  11. package/dist/commands/commerce/entitlements/explain.d.ts +22 -0
  12. package/dist/commands/commerce/entitlements/explain.js +40 -0
  13. package/dist/commands/commerce/incidents/audit.d.ts +20 -0
  14. package/dist/commands/commerce/incidents/audit.js +37 -0
  15. package/dist/commands/commerce/incidents/list.d.ts +22 -0
  16. package/dist/commands/commerce/incidents/list.js +49 -0
  17. package/dist/commands/commerce/incidents/resolve.d.ts +23 -0
  18. package/dist/commands/commerce/incidents/resolve.js +45 -0
  19. package/dist/commands/commerce/incidents/retry.d.ts +22 -0
  20. package/dist/commands/commerce/incidents/retry.js +45 -0
  21. package/dist/commands/commerce/incidents/show.d.ts +13 -0
  22. package/dist/commands/commerce/incidents/show.js +30 -0
  23. package/dist/commands/commerce/offers/approve.d.ts +17 -0
  24. package/dist/commands/commerce/offers/approve.js +33 -0
  25. package/dist/commands/commerce/offers/create.d.ts +18 -0
  26. package/dist/commands/commerce/offers/create.js +34 -0
  27. package/dist/commands/commerce/offers/publish.d.ts +13 -0
  28. package/dist/commands/commerce/offers/publish.js +28 -0
  29. package/dist/commands/commerce/offers/retire.d.ts +17 -0
  30. package/dist/commands/commerce/offers/retire.js +32 -0
  31. package/dist/commands/commerce/offers/validate.d.ts +18 -0
  32. package/dist/commands/commerce/offers/validate.js +33 -0
  33. package/dist/commands/commerce/products/create.d.ts +10 -0
  34. package/dist/commands/commerce/products/create.js +25 -0
  35. package/dist/commands/commerce/promotions/redeem.d.ts +13 -0
  36. package/dist/commands/commerce/promotions/redeem.js +32 -0
  37. package/dist/commands/commerce/terms/accept.d.ts +18 -0
  38. package/dist/commands/commerce/terms/accept.js +39 -0
  39. package/dist/commands/commerce/terms/show.d.ts +10 -0
  40. package/dist/commands/commerce/terms/show.js +34 -0
  41. package/dist/commands/commerce/trials/conversion-preview.d.ts +18 -0
  42. package/dist/commands/commerce/trials/conversion-preview.js +39 -0
  43. package/dist/commands/commerce/trials/start.d.ts +23 -0
  44. package/dist/commands/commerce/trials/start.js +58 -0
  45. package/dist/commands/commitments/accounting.d.ts +39 -0
  46. package/dist/commands/commitments/accounting.js +116 -0
  47. package/dist/commands/commitments/action-history.d.ts +1 -0
  48. package/dist/commands/commitments/action-history.js +8 -1
  49. package/dist/commands/commitments/case.d.ts +1 -0
  50. package/dist/commands/commitments/case.js +19 -3
  51. package/dist/commands/commitments/cases.d.ts +1 -0
  52. package/dist/commands/commitments/cases.js +11 -1
  53. package/dist/commands/commitments/checks.d.ts +1 -0
  54. package/dist/commands/commitments/checks.js +5 -1
  55. package/dist/commands/commitments/cost.d.ts +62 -0
  56. package/dist/commands/commitments/cost.js +130 -0
  57. package/dist/commands/commitments/create.js +1 -1
  58. package/dist/commands/commitments/delete.d.ts +1 -0
  59. package/dist/commands/commitments/delete.js +56 -6
  60. package/dist/commands/commitments/feedback.js +9 -1
  61. package/dist/commands/commitments/handover.js +16 -0
  62. package/dist/commands/commitments/hypotheses.d.ts +1 -0
  63. package/dist/commands/commitments/hypotheses.js +17 -2
  64. package/dist/commands/commitments/links/list.js +4 -1
  65. package/dist/commands/commitments/liveness.d.ts +18 -0
  66. package/dist/commands/commitments/liveness.js +80 -0
  67. package/dist/commands/commitments/metrics.d.ts +1 -0
  68. package/dist/commands/commitments/metrics.js +8 -1
  69. package/dist/commands/commitments/next-tick.d.ts +39 -0
  70. package/dist/commands/commitments/next-tick.js +122 -0
  71. package/dist/commands/commitments/observations.d.ts +1 -0
  72. package/dist/commands/commitments/observations.js +19 -2
  73. package/dist/commands/commitments/pause.js +12 -0
  74. package/dist/commands/commitments/receipt.d.ts +2 -0
  75. package/dist/commands/commitments/receipt.js +16 -2
  76. package/dist/commands/commitments/remediation-proposal.js +6 -2
  77. package/dist/commands/commitments/remediation-proposals.js +5 -1
  78. package/dist/commands/commitments/restore.d.ts +25 -0
  79. package/dist/commands/commitments/restore.js +46 -0
  80. package/dist/commands/commitments/show.js +32 -0
  81. package/dist/commands/commitments/trigger-status.js +33 -0
  82. package/dist/commands/commitments/update.d.ts +1 -0
  83. package/dist/commands/commitments/update.js +31 -5
  84. package/dist/commands/commitments/wake-capabilities.d.ts +0 -1
  85. package/dist/commands/commitments/wake-capabilities.js +8 -4
  86. package/dist/commands/enterprise/budgets/create.d.ts +11 -0
  87. package/dist/commands/enterprise/budgets/create.js +27 -0
  88. package/dist/commands/enterprise/budgets/evaluate.d.ts +17 -0
  89. package/dist/commands/enterprise/budgets/evaluate.js +32 -0
  90. package/dist/commands/enterprise/budgets/publish.d.ts +14 -0
  91. package/dist/commands/enterprise/budgets/publish.js +30 -0
  92. package/dist/commands/enterprise/contracts/activate.d.ts +14 -0
  93. package/dist/commands/enterprise/contracts/activate.js +30 -0
  94. package/dist/commands/enterprise/contracts/create.d.ts +14 -0
  95. package/dist/commands/enterprise/contracts/create.js +32 -0
  96. package/dist/commands/enterprise/contracts/issue.d.ts +18 -0
  97. package/dist/commands/enterprise/contracts/issue.js +34 -0
  98. package/dist/commands/enterprise/domains/begin.d.ts +20 -0
  99. package/dist/commands/enterprise/domains/begin.js +39 -0
  100. package/dist/commands/enterprise/domains/verify.d.ts +14 -0
  101. package/dist/commands/enterprise/domains/verify.js +32 -0
  102. package/dist/commands/enterprise/external-config/activate.d.ts +22 -0
  103. package/dist/commands/enterprise/external-config/activate.js +49 -0
  104. package/dist/commands/enterprise/external-config/set.d.ts +25 -0
  105. package/dist/commands/enterprise/external-config/set.js +123 -0
  106. package/dist/commands/enterprise/external-config/show.d.ts +12 -0
  107. package/dist/commands/enterprise/external-config/show.js +39 -0
  108. package/dist/commands/enterprise/external-config/suspend.d.ts +13 -0
  109. package/dist/commands/enterprise/external-config/suspend.js +41 -0
  110. package/dist/commands/enterprise/finance/close-snapshot.d.ts +11 -0
  111. package/dist/commands/enterprise/finance/close-snapshot.js +28 -0
  112. package/dist/commands/enterprise/finance/record-document.d.ts +18 -0
  113. package/dist/commands/enterprise/finance/record-document.js +35 -0
  114. package/dist/commands/enterprise/profile.d.ts +20 -0
  115. package/dist/commands/enterprise/profile.js +38 -0
  116. package/dist/commands/login.d.ts +13 -0
  117. package/dist/commands/login.js +77 -0
  118. package/dist/commands/machines/dedicated/index.js +3 -0
  119. package/dist/commands/machines/dedicated/service/apply.d.ts +23 -0
  120. package/dist/commands/machines/dedicated/service/apply.js +99 -0
  121. package/dist/commands/machines/dedicated/service/approve.d.ts +23 -0
  122. package/dist/commands/machines/dedicated/service/approve.js +52 -0
  123. package/dist/commands/machines/dedicated/service/create.d.ts +55 -0
  124. package/dist/commands/machines/dedicated/service/create.js +222 -0
  125. package/dist/commands/machines/dedicated/service/edit.d.ts +30 -0
  126. package/dist/commands/machines/dedicated/service/edit.js +146 -0
  127. package/dist/commands/machines/dedicated/service/exec.d.ts +26 -0
  128. package/dist/commands/machines/dedicated/service/exec.js +92 -0
  129. package/dist/commands/machines/dedicated/service/export.d.ts +29 -0
  130. package/dist/commands/machines/dedicated/service/export.js +106 -0
  131. package/dist/commands/machines/dedicated/service/index.d.ts +14 -0
  132. package/dist/commands/machines/dedicated/service/index.js +49 -0
  133. package/dist/commands/machines/dedicated/service/logs.d.ts +33 -0
  134. package/dist/commands/machines/dedicated/service/logs.js +148 -0
  135. package/dist/commands/machines/dedicated/service/ls.d.ts +20 -0
  136. package/dist/commands/machines/dedicated/service/ls.js +80 -0
  137. package/dist/commands/machines/dedicated/service/restart.d.ts +14 -0
  138. package/dist/commands/machines/dedicated/service/restart.js +29 -0
  139. package/dist/commands/machines/dedicated/service/rm.d.ts +20 -0
  140. package/dist/commands/machines/dedicated/service/rm.js +33 -0
  141. package/dist/commands/machines/dedicated/service/secret/index.d.ts +14 -0
  142. package/dist/commands/machines/dedicated/service/secret/index.js +25 -0
  143. package/dist/commands/machines/dedicated/service/secret/rm.d.ts +22 -0
  144. package/dist/commands/machines/dedicated/service/secret/rm.js +54 -0
  145. package/dist/commands/machines/dedicated/service/secret/set.d.ts +22 -0
  146. package/dist/commands/machines/dedicated/service/secret/set.js +93 -0
  147. package/dist/commands/machines/dedicated/service/start.d.ts +14 -0
  148. package/dist/commands/machines/dedicated/service/start.js +29 -0
  149. package/dist/commands/machines/dedicated/service/status.d.ts +21 -0
  150. package/dist/commands/machines/dedicated/service/status.js +85 -0
  151. package/dist/commands/machines/dedicated/service/stop.d.ts +20 -0
  152. package/dist/commands/machines/dedicated/service/stop.js +35 -0
  153. package/dist/commands/machines/dedicated/service/top.d.ts +22 -0
  154. package/dist/commands/machines/dedicated/service/top.js +120 -0
  155. package/dist/commands/machines/dedicated/sign-in-status.d.ts +22 -0
  156. package/dist/commands/machines/dedicated/sign-in-status.js +79 -0
  157. package/dist/commands/machines/dedicated/ssh-config.d.ts +28 -0
  158. package/dist/commands/machines/dedicated/ssh-config.js +66 -0
  159. package/dist/commands/machines/dedicated/ssh-proxy.d.ts +22 -0
  160. package/dist/commands/machines/dedicated/ssh-proxy.js +62 -0
  161. package/dist/commands/machines/dedicated/ssh.d.ts +29 -0
  162. package/dist/commands/machines/dedicated/ssh.js +121 -0
  163. package/dist/commands/native/allow-all.d.ts +14 -0
  164. package/dist/commands/native/allow-all.js +25 -0
  165. package/dist/commands/native/allow.d.ts +24 -0
  166. package/dist/commands/native/allow.js +45 -0
  167. package/dist/commands/native/deny.d.ts +24 -0
  168. package/dist/commands/native/deny.js +43 -0
  169. package/dist/commands/native/disable.d.ts +17 -0
  170. package/dist/commands/native/disable.js +28 -0
  171. package/dist/commands/native/enable.d.ts +12 -0
  172. package/dist/commands/native/enable.js +29 -0
  173. package/dist/commands/native/list-apps.d.ts +19 -0
  174. package/dist/commands/native/list-apps.js +30 -0
  175. package/dist/commands/native/restrict-to.d.ts +22 -0
  176. package/dist/commands/native/restrict-to.js +41 -0
  177. package/dist/commands/native/status.d.ts +19 -0
  178. package/dist/commands/native/status.js +33 -0
  179. package/dist/commands/native.d.ts +39 -0
  180. package/dist/commands/native.js +76 -0
  181. package/dist/commands/service/index.d.ts +14 -0
  182. package/dist/commands/service/index.js +31 -0
  183. package/dist/commands/service/logs.d.ts +18 -0
  184. package/dist/commands/service/logs.js +53 -0
  185. package/dist/commands/service/ls.d.ts +13 -0
  186. package/dist/commands/service/ls.js +48 -0
  187. package/dist/commands/service/propose.d.ts +34 -0
  188. package/dist/commands/service/propose.js +113 -0
  189. package/dist/commands/service/status.d.ts +17 -0
  190. package/dist/commands/service/status.js +56 -0
  191. package/dist/commands/spaces/auto-executor/runs.d.ts +13 -0
  192. package/dist/commands/spaces/auto-executor/runs.js +56 -0
  193. package/dist/commands/store/governance/artifacts.d.ts +25 -0
  194. package/dist/commands/store/governance/artifacts.js +55 -0
  195. package/dist/commands/store/governance/assign.d.ts +16 -0
  196. package/dist/commands/store/governance/assign.js +54 -0
  197. package/dist/commands/store/governance/create-license.d.ts +18 -0
  198. package/dist/commands/store/governance/create-license.js +35 -0
  199. package/dist/commands/store/governance/install-plan.d.ts +25 -0
  200. package/dist/commands/store/governance/install-plan.js +56 -0
  201. package/dist/commands/store/governance/license-policy.d.ts +30 -0
  202. package/dist/commands/store/governance/license-policy.js +69 -0
  203. package/dist/commands/store/governance/policy.d.ts +25 -0
  204. package/dist/commands/store/governance/policy.js +65 -0
  205. package/dist/commands/store/governance/publish-release.d.ts +17 -0
  206. package/dist/commands/store/governance/publish-release.js +34 -0
  207. package/dist/commands/tasks/deliverable/add.d.ts +15 -0
  208. package/dist/commands/tasks/deliverable/add.js +174 -0
  209. package/dist/commands/tasks/deliverable/archive.d.ts +35 -0
  210. package/dist/commands/tasks/deliverable/archive.js +205 -0
  211. package/dist/commands/tasks/labels/detach.js +3 -0
  212. package/dist/commands/tasks/labels/suggest.d.ts +24 -0
  213. package/dist/commands/tasks/labels/suggest.js +69 -0
  214. package/dist/commands/tasks/list.d.ts +16 -2
  215. package/dist/commands/tasks/list.js +100 -24
  216. package/dist/commands/tasks/show.d.ts +23 -0
  217. package/dist/commands/tasks/show.js +51 -1
  218. package/dist/commands/wiki/rm.d.ts +22 -1
  219. package/dist/commands/wiki/rm.js +52 -3
  220. package/dist/lib/agentic-stream.js +10 -2
  221. package/dist/lib/balance.d.ts +6 -1
  222. package/dist/lib/balance.js +15 -0
  223. package/dist/lib/commerce-command.d.ts +48 -0
  224. package/dist/lib/commerce-command.js +70 -0
  225. package/dist/lib/commerce.d.ts +93 -0
  226. package/dist/lib/commerce.js +129 -0
  227. package/dist/lib/commitment-product.js +1 -1
  228. package/dist/lib/commitments.d.ts +202 -29
  229. package/dist/lib/commitments.js +300 -33
  230. package/dist/lib/daemon-installer.d.ts +6 -5
  231. package/dist/lib/daemon-installer.js +4 -17
  232. package/dist/lib/dedicated-lease-command.js +10 -0
  233. package/dist/lib/dedicated-machines.d.ts +37 -0
  234. package/dist/lib/dedicated-machines.js +47 -0
  235. package/dist/lib/dedicated-service-command.d.ts +60 -0
  236. package/dist/lib/dedicated-service-command.js +182 -0
  237. package/dist/lib/dedicated-service.d.ts +342 -0
  238. package/dist/lib/dedicated-service.js +741 -0
  239. package/dist/lib/dedicated-ssh.d.ts +136 -0
  240. package/dist/lib/dedicated-ssh.js +387 -0
  241. package/dist/lib/delegated-cli.js +51 -13
  242. package/dist/lib/enterprise-commerce.d.ts +67 -0
  243. package/dist/lib/enterprise-commerce.js +112 -0
  244. package/dist/lib/enterprise-external-configuration.d.ts +60 -0
  245. package/dist/lib/enterprise-external-configuration.js +58 -0
  246. package/dist/lib/first-party-harness.js +17 -3
  247. package/dist/lib/governed-store.d.ts +110 -0
  248. package/dist/lib/governed-store.js +79 -0
  249. package/dist/lib/guest-service-command.d.ts +16 -0
  250. package/dist/lib/guest-service-command.js +32 -0
  251. package/dist/lib/guest-service.d.ts +67 -0
  252. package/dist/lib/guest-service.js +112 -0
  253. package/dist/lib/prompt.d.ts +1 -0
  254. package/dist/lib/prompt.js +1 -0
  255. package/dist/lib/task-asset-upload.d.ts +20 -0
  256. package/dist/lib/task-asset-upload.js +30 -8
  257. package/dist/lib/task-extras.d.ts +23 -0
  258. package/dist/lib/task-extras.js +6 -0
  259. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonScopes.d.ts +9 -3
  260. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonScopes.js +10 -3
  261. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.d.ts +1 -1
  262. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.js +1 -1
  263. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +2 -2
  264. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +8 -5
  265. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/messages.d.ts +16 -0
  266. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/messages.js +21 -4
  267. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/releaseManifest.d.ts +38 -0
  268. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/releaseManifest.js +66 -1
  269. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.d.ts +1 -1
  270. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.js +24 -2
  271. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonScopes.d.ts +9 -3
  272. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonScopes.js +10 -3
  273. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.d.ts +1 -1
  274. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.js +1 -1
  275. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +2 -2
  276. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +2 -2
  277. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/messages.d.ts +16 -0
  278. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/messages.js +20 -4
  279. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/releaseManifest.d.ts +38 -0
  280. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/releaseManifest.js +64 -0
  281. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.d.ts +1 -1
  282. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.js +24 -2
  283. package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
  284. package/dist/node_modules/@skrr-ai/data-provider/index.js +5060 -4827
  285. package/oclif.manifest.json +35194 -29157
  286. 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. ' +
@@ -0,0 +1,12 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class AgentWorker extends Command {
3
+ static summary: string;
4
+ static description: string;
5
+ static flags: {
6
+ socket: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
7
+ 'heartbeat-ms': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
8
+ };
9
+ run(): Promise<void>;
10
+ /** `revoked`/`invalid_handle` — the binding is gone, not the transport. */
11
+ private bindingRefused;
12
+ }
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const guest_service_1 = require("../lib/guest-service");
5
+ /**
6
+ * `skrr agent-worker` — the long-lived guest agent worker (§10.2).
7
+ *
8
+ * The blessed `agent` service template runs this command inside a Dedicated
9
+ * Runtime guest. The control plane mints the binding at service-create admit
10
+ * and injects it into the spec's env:
11
+ *
12
+ * SKRR_AGENT_ID the agent this worker holds presence for
13
+ * SKRR_AGENT_HANDLE the presence capability — `awh_<id>.aws_<secret>`
14
+ *
15
+ * On start the worker registers with the daemon's broker socket, then
16
+ * heartbeats until it is stopped (SIGTERM → bye) or the binding is revoked —
17
+ * `service remove` deletes the spec, the broker's next answer is `revoked`,
18
+ * and the worker exits. The service lifecycle IS the handle lifecycle.
19
+ *
20
+ * The handle is never logged and never echoed — the daemon's reply names the
21
+ * agent and service it validated, which is everything worth printing.
22
+ */
23
+ const DEFAULT_SOCKET = '/run/skrr-dedicated-runtime/agent-worker/agent-worker.sock';
24
+ const DEFAULT_HEARTBEAT_MS = 30_000;
25
+ /** Register retries cover a service started while the daemon is restarting. */
26
+ const REGISTER_RETRY_MS = 3_000;
27
+ const REGISTER_BUDGET_MS = 120_000;
28
+ /** Consecutive transport failures before the worker gives up and lets the reconciler see the crash. */
29
+ const HEARTBEAT_FAILURE_LIMIT = 10;
30
+ const BYE_TIMEOUT_MS = 5_000;
31
+ const sleep = (ms) => new Promise((done) => setTimeout(done, ms));
32
+ class AgentWorker extends core_1.Command {
33
+ static summary = 'Run the agent-worker presence loop for this machine (launched by the agent service template)';
34
+ static description = 'Reads the server-issued binding from SKRR_AGENT_ID / SKRR_AGENT_HANDLE, registers with ' +
35
+ 'the machine’s daemon over the agent-worker socket, and holds presence with heartbeats ' +
36
+ 'until the service is stopped or the binding is revoked. Not meant to be run by hand — ' +
37
+ 'declare it with `skrr machines dedicated service create --template agent --param agent=<agent-id>` ' +
38
+ 'or the service API.';
39
+ static flags = {
40
+ socket: core_1.Flags.string({
41
+ description: 'Agent-worker socket path (defaults to the machine’s broker socket)',
42
+ env: 'SKRR_AGENT_WORKER_SOCKET',
43
+ }),
44
+ 'heartbeat-ms': core_1.Flags.integer({
45
+ description: 'Heartbeat interval override in milliseconds (the broker’s answer wins)',
46
+ min: 1000,
47
+ }),
48
+ };
49
+ async run() {
50
+ const { flags } = await this.parse(AgentWorker);
51
+ const agentId = (process.env.SKRR_AGENT_ID ?? '').trim();
52
+ const handle = (process.env.SKRR_AGENT_HANDLE ?? '').trim();
53
+ if (!agentId || !handle) {
54
+ this.error('SKRR_AGENT_ID and SKRR_AGENT_HANDLE must both be set — the control plane injects them ' +
55
+ 'when a service is created with an agent binding. This process is not meant to be run ' +
56
+ 'by hand; create the service with `--template agent --param agent=<agent-id>` instead.', { exit: 2 });
57
+ }
58
+ const socketPath = flags.socket ?? DEFAULT_SOCKET;
59
+ const heartbeatOverride = flags['heartbeat-ms'];
60
+ const call = (verb, timeoutMs) => (0, guest_service_1.callGuestServiceSocket)({ verb, handle }, { socketPath, ...(timeoutMs ? { timeoutMs } : {}) });
61
+ // ---- register --------------------------------------------------------
62
+ // The service can start while the daemon is restarting; transport errors
63
+ // retry inside a budget, a refused binding never does.
64
+ const deadline = Date.now() + REGISTER_BUDGET_MS;
65
+ let heartbeatMs = heartbeatOverride ?? DEFAULT_HEARTBEAT_MS;
66
+ for (;;) {
67
+ try {
68
+ const reply = await call('register');
69
+ if (typeof reply.agentId === 'string' && reply.agentId !== agentId) {
70
+ this.error(`The daemon validated this handle for ${reply.agentId}, not ${agentId} — ` +
71
+ 'the service spec is inconsistent. Remove and recreate the service.', { exit: 2 });
72
+ }
73
+ if (typeof reply.heartbeatMs === 'number' && reply.heartbeatMs >= 1000) {
74
+ heartbeatMs = reply.heartbeatMs;
75
+ }
76
+ this.log(`agent-worker registered: agent=${reply.agentId ?? agentId} ` +
77
+ `service=${reply.serviceName ?? '?'} heartbeat=${heartbeatMs}ms`);
78
+ break;
79
+ }
80
+ catch (error) {
81
+ if (this.bindingRefused(error)) {
82
+ this.error(`The daemon refused this worker's binding: ${error.message}. ` +
83
+ 'The service spec predates the handle — remove and recreate the service.', { exit: 1 });
84
+ }
85
+ if (Date.now() >= deadline) {
86
+ this.error(`The agent-worker socket never answered within ${REGISTER_BUDGET_MS / 1000}s ` +
87
+ `(${error.message}) — the machine's daemon is not offering the ` +
88
+ 'agent-worker lane.', { exit: 1 });
89
+ }
90
+ await sleep(REGISTER_RETRY_MS);
91
+ }
92
+ }
93
+ // ---- heartbeat -------------------------------------------------------
94
+ let failures = 0;
95
+ let stopping = false;
96
+ const stop = () => {
97
+ stopping = true;
98
+ };
99
+ process.on('SIGTERM', stop);
100
+ process.on('SIGINT', stop);
101
+ while (!stopping) {
102
+ await sleep(heartbeatMs);
103
+ if (stopping)
104
+ break;
105
+ try {
106
+ await call('heartbeat');
107
+ failures = 0;
108
+ }
109
+ catch (error) {
110
+ if (this.bindingRefused(error)) {
111
+ // The binding is dead — almost always `service remove` having
112
+ // deleted the spec. Exit cleanly: there is nothing to retry, and
113
+ // under an on-failure restart policy a clean exit keeps the
114
+ // reconciler from flapping a corpse.
115
+ this.log('The agent binding was revoked — exiting.');
116
+ process.exit(0);
117
+ }
118
+ failures += 1;
119
+ if (failures >= HEARTBEAT_FAILURE_LIMIT) {
120
+ this.error(`Lost the agent-worker socket ${failures} times in a row ` +
121
+ `(${error.message}) — exiting so the service state is honest.`, { exit: 1 });
122
+ }
123
+ this.warn(`agent-worker heartbeat missed (${failures}/${HEARTBEAT_FAILURE_LIMIT})`);
124
+ }
125
+ }
126
+ // ---- bye ---------------------------------------------------------------
127
+ try {
128
+ await call('bye', BYE_TIMEOUT_MS);
129
+ }
130
+ catch {
131
+ /* a dead socket cannot hear goodbye — the missed heartbeats say it */
132
+ }
133
+ }
134
+ /** `revoked`/`invalid_handle` — the binding is gone, not the transport. */
135
+ bindingRefused(error) {
136
+ const message = error instanceof Error ? error.message : String(error);
137
+ return /revoked|invalid_handle|forbidden/i.test(message);
138
+ }
139
+ }
140
+ exports.default = AgentWorker;
@@ -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');
@@ -0,0 +1,22 @@
1
+ import { BaseCommand } from '../../../base-command';
2
+ /**
3
+ * `skrr commerce entitlements explain` — WHY a subject can or cannot do a thing.
4
+ *
5
+ * The read that pays for this whole topic. "This account says it cannot do X"
6
+ * is a support question, and the answer is a trace through offers, contracts
7
+ * and grants. Tracing it from a terminal — and pasting the JSON into the
8
+ * ticket — is the case a console makes slow.
9
+ *
10
+ * The body is passed through because the question has a real shape (subject,
11
+ * capability, scope type and id) that the server validates. It is a QUESTION,
12
+ * so nothing is mutated by asking it.
13
+ */
14
+ export default class CommerceEntitlementsExplain extends BaseCommand {
15
+ static description: string;
16
+ static examples: string[];
17
+ static flags: {
18
+ file: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
19
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
20
+ };
21
+ run(): Promise<void>;
22
+ }
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const base_command_1 = require("../../../base-command");
4
+ const commerce_1 = require("../../../lib/commerce");
5
+ const commerce_command_1 = require("../../../lib/commerce-command");
6
+ /**
7
+ * `skrr commerce entitlements explain` — WHY a subject can or cannot do a thing.
8
+ *
9
+ * The read that pays for this whole topic. "This account says it cannot do X"
10
+ * is a support question, and the answer is a trace through offers, contracts
11
+ * and grants. Tracing it from a terminal — and pasting the JSON into the
12
+ * ticket — is the case a console makes slow.
13
+ *
14
+ * The body is passed through because the question has a real shape (subject,
15
+ * capability, scope type and id) that the server validates. It is a QUESTION,
16
+ * so nothing is mutated by asking it.
17
+ */
18
+ class CommerceEntitlementsExplain extends base_command_1.BaseCommand {
19
+ static description = 'Explain why a subject does or does not hold a capability at a scope (admin). A question — it changes nothing.';
20
+ static examples = [
21
+ '<%= config.bin %> commerce entitlements explain --file ./question.json',
22
+ 'echo \'{"subject":{...},"capability":"...","scopeType":"workspace","scopeId":"..."}\' | <%= config.bin %> commerce entitlements explain --file -',
23
+ ];
24
+ static flags = { ...commerce_command_1.jsonBodyFlags };
25
+ async run() {
26
+ this.requireAuth();
27
+ const { flags } = await this.parse(CommerceEntitlementsExplain);
28
+ const body = await (0, commerce_command_1.jsonBodyFrom)(this, flags.file);
29
+ let result;
30
+ try {
31
+ result = await (0, commerce_1.explainCommerceEntitlement)(body);
32
+ }
33
+ catch (error) {
34
+ this.handleApiError(error);
35
+ return;
36
+ }
37
+ this.log(JSON.stringify(result, null, 2));
38
+ }
39
+ }
40
+ exports.default = CommerceEntitlementsExplain;
@@ -0,0 +1,20 @@
1
+ import { BaseCommand } from '../../../base-command';
2
+ /**
3
+ * What was DONE to an incident, as opposed to what it is.
4
+ *
5
+ * Kept a separate verb from `show` because the two answer different questions
6
+ * and one of them is the one you need when an incident looks resolved and
7
+ * nobody remembers who resolved it.
8
+ */
9
+ export default class CommerceIncidentsAudit extends BaseCommand {
10
+ static description: string;
11
+ static examples: string[];
12
+ static args: {
13
+ kind: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
14
+ incident: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
15
+ };
16
+ static flags: {
17
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
18
+ };
19
+ run(): Promise<void>;
20
+ }
@@ -0,0 +1,37 @@
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 commerce_1 = require("../../../lib/commerce");
6
+ /**
7
+ * What was DONE to an incident, as opposed to what it is.
8
+ *
9
+ * Kept a separate verb from `show` because the two answer different questions
10
+ * and one of them is the one you need when an incident looks resolved and
11
+ * nobody remembers who resolved it.
12
+ */
13
+ class CommerceIncidentsAudit extends base_command_1.BaseCommand {
14
+ static description = 'Show the audit trail of one marketplace incident — who acted on it and when (admin).';
15
+ static examples = ['<%= config.bin %> commerce incidents audit integrity <incident-id>'];
16
+ static args = {
17
+ kind: core_1.Args.string({ description: 'Incident kind', required: true, ignoreStdin: true }),
18
+ incident: core_1.Args.string({ description: 'Incident id', required: true, ignoreStdin: true }),
19
+ };
20
+ static flags = {
21
+ json: core_1.Flags.boolean({ description: 'Output as JSON' }),
22
+ };
23
+ async run() {
24
+ this.requireAuth();
25
+ const { args } = await this.parse(CommerceIncidentsAudit);
26
+ let result;
27
+ try {
28
+ result = await (0, commerce_1.listMarketplaceIncidentAudit)(args.kind, args.incident);
29
+ }
30
+ catch (error) {
31
+ this.handleApiError(error);
32
+ return;
33
+ }
34
+ this.log(JSON.stringify(result, null, 2));
35
+ }
36
+ }
37
+ exports.default = CommerceIncidentsAudit;