@skrr-ai/cli 0.1.47 → 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 (274) 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/commerce/entitlements/explain.d.ts +22 -0
  10. package/dist/commands/commerce/entitlements/explain.js +40 -0
  11. package/dist/commands/commerce/incidents/audit.d.ts +20 -0
  12. package/dist/commands/commerce/incidents/audit.js +37 -0
  13. package/dist/commands/commerce/incidents/list.d.ts +22 -0
  14. package/dist/commands/commerce/incidents/list.js +49 -0
  15. package/dist/commands/commerce/incidents/resolve.d.ts +23 -0
  16. package/dist/commands/commerce/incidents/resolve.js +45 -0
  17. package/dist/commands/commerce/incidents/retry.d.ts +22 -0
  18. package/dist/commands/commerce/incidents/retry.js +45 -0
  19. package/dist/commands/commerce/incidents/show.d.ts +13 -0
  20. package/dist/commands/commerce/incidents/show.js +30 -0
  21. package/dist/commands/commerce/offers/approve.d.ts +17 -0
  22. package/dist/commands/commerce/offers/approve.js +33 -0
  23. package/dist/commands/commerce/offers/create.d.ts +18 -0
  24. package/dist/commands/commerce/offers/create.js +34 -0
  25. package/dist/commands/commerce/offers/publish.d.ts +13 -0
  26. package/dist/commands/commerce/offers/publish.js +28 -0
  27. package/dist/commands/commerce/offers/retire.d.ts +17 -0
  28. package/dist/commands/commerce/offers/retire.js +32 -0
  29. package/dist/commands/commerce/offers/validate.d.ts +18 -0
  30. package/dist/commands/commerce/offers/validate.js +33 -0
  31. package/dist/commands/commerce/products/create.d.ts +10 -0
  32. package/dist/commands/commerce/products/create.js +25 -0
  33. package/dist/commands/commerce/promotions/redeem.d.ts +13 -0
  34. package/dist/commands/commerce/promotions/redeem.js +32 -0
  35. package/dist/commands/commerce/terms/accept.d.ts +18 -0
  36. package/dist/commands/commerce/terms/accept.js +39 -0
  37. package/dist/commands/commerce/terms/show.d.ts +10 -0
  38. package/dist/commands/commerce/terms/show.js +34 -0
  39. package/dist/commands/commerce/trials/conversion-preview.d.ts +18 -0
  40. package/dist/commands/commerce/trials/conversion-preview.js +39 -0
  41. package/dist/commands/commerce/trials/start.d.ts +23 -0
  42. package/dist/commands/commerce/trials/start.js +58 -0
  43. package/dist/commands/commitments/accounting.d.ts +39 -0
  44. package/dist/commands/commitments/accounting.js +116 -0
  45. package/dist/commands/commitments/action-history.d.ts +1 -0
  46. package/dist/commands/commitments/action-history.js +8 -1
  47. package/dist/commands/commitments/case.d.ts +1 -0
  48. package/dist/commands/commitments/case.js +19 -3
  49. package/dist/commands/commitments/cases.d.ts +1 -0
  50. package/dist/commands/commitments/cases.js +11 -1
  51. package/dist/commands/commitments/checks.d.ts +1 -0
  52. package/dist/commands/commitments/checks.js +5 -1
  53. package/dist/commands/commitments/cost.d.ts +62 -0
  54. package/dist/commands/commitments/cost.js +130 -0
  55. package/dist/commands/commitments/create.js +1 -1
  56. package/dist/commands/commitments/delete.d.ts +1 -0
  57. package/dist/commands/commitments/delete.js +56 -6
  58. package/dist/commands/commitments/feedback.js +9 -1
  59. package/dist/commands/commitments/handover.js +16 -0
  60. package/dist/commands/commitments/hypotheses.d.ts +1 -0
  61. package/dist/commands/commitments/hypotheses.js +17 -2
  62. package/dist/commands/commitments/links/list.js +4 -1
  63. package/dist/commands/commitments/liveness.d.ts +18 -0
  64. package/dist/commands/commitments/liveness.js +80 -0
  65. package/dist/commands/commitments/metrics.d.ts +1 -0
  66. package/dist/commands/commitments/metrics.js +8 -1
  67. package/dist/commands/commitments/next-tick.d.ts +39 -0
  68. package/dist/commands/commitments/next-tick.js +122 -0
  69. package/dist/commands/commitments/observations.d.ts +1 -0
  70. package/dist/commands/commitments/observations.js +19 -2
  71. package/dist/commands/commitments/pause.js +12 -0
  72. package/dist/commands/commitments/receipt.d.ts +2 -0
  73. package/dist/commands/commitments/receipt.js +16 -2
  74. package/dist/commands/commitments/remediation-proposal.js +6 -2
  75. package/dist/commands/commitments/remediation-proposals.js +5 -1
  76. package/dist/commands/commitments/restore.d.ts +25 -0
  77. package/dist/commands/commitments/restore.js +46 -0
  78. package/dist/commands/commitments/show.js +32 -0
  79. package/dist/commands/commitments/trigger-status.js +33 -0
  80. package/dist/commands/commitments/update.d.ts +1 -0
  81. package/dist/commands/commitments/update.js +31 -5
  82. package/dist/commands/commitments/wake-capabilities.d.ts +0 -1
  83. package/dist/commands/commitments/wake-capabilities.js +8 -4
  84. package/dist/commands/enterprise/budgets/create.d.ts +11 -0
  85. package/dist/commands/enterprise/budgets/create.js +27 -0
  86. package/dist/commands/enterprise/budgets/evaluate.d.ts +17 -0
  87. package/dist/commands/enterprise/budgets/evaluate.js +32 -0
  88. package/dist/commands/enterprise/budgets/publish.d.ts +14 -0
  89. package/dist/commands/enterprise/budgets/publish.js +30 -0
  90. package/dist/commands/enterprise/contracts/activate.d.ts +14 -0
  91. package/dist/commands/enterprise/contracts/activate.js +30 -0
  92. package/dist/commands/enterprise/contracts/create.d.ts +14 -0
  93. package/dist/commands/enterprise/contracts/create.js +32 -0
  94. package/dist/commands/enterprise/contracts/issue.d.ts +18 -0
  95. package/dist/commands/enterprise/contracts/issue.js +34 -0
  96. package/dist/commands/enterprise/domains/begin.d.ts +20 -0
  97. package/dist/commands/enterprise/domains/begin.js +39 -0
  98. package/dist/commands/enterprise/domains/verify.d.ts +14 -0
  99. package/dist/commands/enterprise/domains/verify.js +32 -0
  100. package/dist/commands/enterprise/external-config/activate.d.ts +22 -0
  101. package/dist/commands/enterprise/external-config/activate.js +49 -0
  102. package/dist/commands/enterprise/external-config/set.d.ts +25 -0
  103. package/dist/commands/enterprise/external-config/set.js +123 -0
  104. package/dist/commands/enterprise/external-config/show.d.ts +12 -0
  105. package/dist/commands/enterprise/external-config/show.js +39 -0
  106. package/dist/commands/enterprise/external-config/suspend.d.ts +13 -0
  107. package/dist/commands/enterprise/external-config/suspend.js +41 -0
  108. package/dist/commands/enterprise/finance/close-snapshot.d.ts +11 -0
  109. package/dist/commands/enterprise/finance/close-snapshot.js +28 -0
  110. package/dist/commands/enterprise/finance/record-document.d.ts +18 -0
  111. package/dist/commands/enterprise/finance/record-document.js +35 -0
  112. package/dist/commands/enterprise/profile.d.ts +20 -0
  113. package/dist/commands/enterprise/profile.js +38 -0
  114. package/dist/commands/login.d.ts +13 -0
  115. package/dist/commands/login.js +77 -0
  116. package/dist/commands/machines/dedicated/index.js +3 -0
  117. package/dist/commands/machines/dedicated/service/apply.d.ts +23 -0
  118. package/dist/commands/machines/dedicated/service/apply.js +99 -0
  119. package/dist/commands/machines/dedicated/service/approve.d.ts +23 -0
  120. package/dist/commands/machines/dedicated/service/approve.js +52 -0
  121. package/dist/commands/machines/dedicated/service/create.d.ts +55 -0
  122. package/dist/commands/machines/dedicated/service/create.js +222 -0
  123. package/dist/commands/machines/dedicated/service/edit.d.ts +30 -0
  124. package/dist/commands/machines/dedicated/service/edit.js +146 -0
  125. package/dist/commands/machines/dedicated/service/exec.d.ts +26 -0
  126. package/dist/commands/machines/dedicated/service/exec.js +92 -0
  127. package/dist/commands/machines/dedicated/service/export.d.ts +29 -0
  128. package/dist/commands/machines/dedicated/service/export.js +106 -0
  129. package/dist/commands/machines/dedicated/service/index.d.ts +14 -0
  130. package/dist/commands/machines/dedicated/service/index.js +49 -0
  131. package/dist/commands/machines/dedicated/service/logs.d.ts +33 -0
  132. package/dist/commands/machines/dedicated/service/logs.js +148 -0
  133. package/dist/commands/machines/dedicated/service/ls.d.ts +20 -0
  134. package/dist/commands/machines/dedicated/service/ls.js +80 -0
  135. package/dist/commands/machines/dedicated/service/restart.d.ts +14 -0
  136. package/dist/commands/machines/dedicated/service/restart.js +29 -0
  137. package/dist/commands/machines/dedicated/service/rm.d.ts +20 -0
  138. package/dist/commands/machines/dedicated/service/rm.js +33 -0
  139. package/dist/commands/machines/dedicated/service/secret/index.d.ts +14 -0
  140. package/dist/commands/machines/dedicated/service/secret/index.js +25 -0
  141. package/dist/commands/machines/dedicated/service/secret/rm.d.ts +22 -0
  142. package/dist/commands/machines/dedicated/service/secret/rm.js +54 -0
  143. package/dist/commands/machines/dedicated/service/secret/set.d.ts +22 -0
  144. package/dist/commands/machines/dedicated/service/secret/set.js +93 -0
  145. package/dist/commands/machines/dedicated/service/start.d.ts +14 -0
  146. package/dist/commands/machines/dedicated/service/start.js +29 -0
  147. package/dist/commands/machines/dedicated/service/status.d.ts +21 -0
  148. package/dist/commands/machines/dedicated/service/status.js +85 -0
  149. package/dist/commands/machines/dedicated/service/stop.d.ts +20 -0
  150. package/dist/commands/machines/dedicated/service/stop.js +35 -0
  151. package/dist/commands/machines/dedicated/service/top.d.ts +22 -0
  152. package/dist/commands/machines/dedicated/service/top.js +120 -0
  153. package/dist/commands/machines/dedicated/sign-in-status.d.ts +22 -0
  154. package/dist/commands/machines/dedicated/sign-in-status.js +79 -0
  155. package/dist/commands/machines/dedicated/ssh-config.d.ts +28 -0
  156. package/dist/commands/machines/dedicated/ssh-config.js +66 -0
  157. package/dist/commands/machines/dedicated/ssh-proxy.d.ts +22 -0
  158. package/dist/commands/machines/dedicated/ssh-proxy.js +62 -0
  159. package/dist/commands/machines/dedicated/ssh.d.ts +29 -0
  160. package/dist/commands/machines/dedicated/ssh.js +121 -0
  161. package/dist/commands/native/allow-all.d.ts +14 -0
  162. package/dist/commands/native/allow-all.js +25 -0
  163. package/dist/commands/native/allow.d.ts +24 -0
  164. package/dist/commands/native/allow.js +45 -0
  165. package/dist/commands/native/deny.d.ts +24 -0
  166. package/dist/commands/native/deny.js +43 -0
  167. package/dist/commands/native/disable.d.ts +17 -0
  168. package/dist/commands/native/disable.js +28 -0
  169. package/dist/commands/native/enable.d.ts +12 -0
  170. package/dist/commands/native/enable.js +29 -0
  171. package/dist/commands/native/list-apps.d.ts +19 -0
  172. package/dist/commands/native/list-apps.js +30 -0
  173. package/dist/commands/native/restrict-to.d.ts +22 -0
  174. package/dist/commands/native/restrict-to.js +41 -0
  175. package/dist/commands/native/status.d.ts +19 -0
  176. package/dist/commands/native/status.js +33 -0
  177. package/dist/commands/native.d.ts +39 -0
  178. package/dist/commands/native.js +76 -0
  179. package/dist/commands/service/index.d.ts +14 -0
  180. package/dist/commands/service/index.js +31 -0
  181. package/dist/commands/service/logs.d.ts +18 -0
  182. package/dist/commands/service/logs.js +53 -0
  183. package/dist/commands/service/ls.d.ts +13 -0
  184. package/dist/commands/service/ls.js +48 -0
  185. package/dist/commands/service/propose.d.ts +34 -0
  186. package/dist/commands/service/propose.js +113 -0
  187. package/dist/commands/service/status.d.ts +17 -0
  188. package/dist/commands/service/status.js +56 -0
  189. package/dist/commands/spaces/auto-executor/runs.d.ts +13 -0
  190. package/dist/commands/spaces/auto-executor/runs.js +56 -0
  191. package/dist/commands/store/governance/artifacts.d.ts +25 -0
  192. package/dist/commands/store/governance/artifacts.js +55 -0
  193. package/dist/commands/store/governance/assign.d.ts +16 -0
  194. package/dist/commands/store/governance/assign.js +54 -0
  195. package/dist/commands/store/governance/create-license.d.ts +18 -0
  196. package/dist/commands/store/governance/create-license.js +35 -0
  197. package/dist/commands/store/governance/install-plan.d.ts +25 -0
  198. package/dist/commands/store/governance/install-plan.js +56 -0
  199. package/dist/commands/store/governance/license-policy.d.ts +30 -0
  200. package/dist/commands/store/governance/license-policy.js +69 -0
  201. package/dist/commands/store/governance/policy.d.ts +25 -0
  202. package/dist/commands/store/governance/policy.js +65 -0
  203. package/dist/commands/store/governance/publish-release.d.ts +17 -0
  204. package/dist/commands/store/governance/publish-release.js +34 -0
  205. package/dist/commands/tasks/deliverable/add.d.ts +15 -0
  206. package/dist/commands/tasks/deliverable/add.js +174 -0
  207. package/dist/commands/tasks/deliverable/archive.d.ts +35 -0
  208. package/dist/commands/tasks/deliverable/archive.js +205 -0
  209. package/dist/commands/tasks/labels/detach.js +3 -0
  210. package/dist/commands/tasks/labels/suggest.d.ts +24 -0
  211. package/dist/commands/tasks/labels/suggest.js +69 -0
  212. package/dist/commands/tasks/list.d.ts +16 -2
  213. package/dist/commands/tasks/list.js +100 -24
  214. package/dist/commands/tasks/show.d.ts +23 -0
  215. package/dist/commands/tasks/show.js +51 -1
  216. package/dist/commands/wiki/rm.d.ts +22 -1
  217. package/dist/commands/wiki/rm.js +52 -3
  218. package/dist/lib/agentic-stream.js +10 -2
  219. package/dist/lib/balance.d.ts +6 -1
  220. package/dist/lib/balance.js +15 -0
  221. package/dist/lib/commerce-command.d.ts +48 -0
  222. package/dist/lib/commerce-command.js +70 -0
  223. package/dist/lib/commerce.d.ts +93 -0
  224. package/dist/lib/commerce.js +129 -0
  225. package/dist/lib/commitment-product.js +1 -1
  226. package/dist/lib/commitments.d.ts +202 -29
  227. package/dist/lib/commitments.js +300 -33
  228. package/dist/lib/dedicated-lease-command.js +10 -0
  229. package/dist/lib/dedicated-machines.d.ts +37 -0
  230. package/dist/lib/dedicated-machines.js +47 -0
  231. package/dist/lib/dedicated-service-command.d.ts +60 -0
  232. package/dist/lib/dedicated-service-command.js +182 -0
  233. package/dist/lib/dedicated-service.d.ts +342 -0
  234. package/dist/lib/dedicated-service.js +741 -0
  235. package/dist/lib/dedicated-ssh.d.ts +136 -0
  236. package/dist/lib/dedicated-ssh.js +387 -0
  237. package/dist/lib/delegated-cli.js +51 -13
  238. package/dist/lib/enterprise-commerce.d.ts +67 -0
  239. package/dist/lib/enterprise-commerce.js +112 -0
  240. package/dist/lib/enterprise-external-configuration.d.ts +60 -0
  241. package/dist/lib/enterprise-external-configuration.js +58 -0
  242. package/dist/lib/first-party-harness.js +17 -3
  243. package/dist/lib/governed-store.d.ts +110 -0
  244. package/dist/lib/governed-store.js +79 -0
  245. package/dist/lib/guest-service-command.d.ts +16 -0
  246. package/dist/lib/guest-service-command.js +32 -0
  247. package/dist/lib/guest-service.d.ts +67 -0
  248. package/dist/lib/guest-service.js +112 -0
  249. package/dist/lib/prompt.d.ts +1 -0
  250. package/dist/lib/prompt.js +1 -0
  251. package/dist/lib/task-asset-upload.d.ts +20 -0
  252. package/dist/lib/task-asset-upload.js +30 -8
  253. package/dist/lib/task-extras.d.ts +23 -0
  254. package/dist/lib/task-extras.js +6 -0
  255. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonScopes.d.ts +9 -3
  256. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonScopes.js +10 -3
  257. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +1 -1
  258. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +6 -5
  259. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/messages.d.ts +16 -0
  260. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/messages.js +21 -4
  261. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.d.ts +1 -1
  262. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.js +24 -2
  263. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonScopes.d.ts +9 -3
  264. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonScopes.js +10 -3
  265. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +1 -1
  266. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +1 -1
  267. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/messages.d.ts +16 -0
  268. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/messages.js +20 -4
  269. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.d.ts +1 -1
  270. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.js +24 -2
  271. package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
  272. package/dist/node_modules/@skrr-ai/data-provider/index.js +5060 -4827
  273. package/oclif.manifest.json +37416 -31416
  274. package/package.json +43 -1
@@ -0,0 +1,25 @@
1
+ import { BaseCommand } from '../../../base-command';
2
+ /**
3
+ * `skrr store governance policy` — which releases a workspace may run at all.
4
+ *
5
+ * `deny_all` and `allowlist` are the two modes the server accepts, and the
6
+ * command refuses an allowlist with nothing in it: an empty allowlist and
7
+ * `deny_all` have the same effect but say different things, and a workspace
8
+ * that reads "allowlist" while permitting nothing is a policy nobody can
9
+ * explain six months later. If you mean deny everything, say `deny_all`.
10
+ */
11
+ export default class StoreGovernancePolicy extends BaseCommand {
12
+ static description: string;
13
+ static examples: string[];
14
+ static args: {
15
+ workspace: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
16
+ };
17
+ static flags: {
18
+ mode: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
19
+ release: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
20
+ 'policy-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
21
+ 'expect-revision': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
22
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
23
+ };
24
+ run(): Promise<void>;
25
+ }
@@ -0,0 +1,65 @@
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 governed_store_1 = require("../../../lib/governed-store");
6
+ /**
7
+ * `skrr store governance policy` — which releases a workspace may run at all.
8
+ *
9
+ * `deny_all` and `allowlist` are the two modes the server accepts, and the
10
+ * command refuses an allowlist with nothing in it: an empty allowlist and
11
+ * `deny_all` have the same effect but say different things, and a workspace
12
+ * that reads "allowlist" while permitting nothing is a policy nobody can
13
+ * explain six months later. If you mean deny everything, say `deny_all`.
14
+ */
15
+ class StoreGovernancePolicy extends base_command_1.BaseCommand {
16
+ static description = 'Set which governed releases a workspace may run. `deny_all`, or an allowlist of release ids.';
17
+ static examples = [
18
+ '<%= config.bin %> store governance policy <workspace-id> --mode deny_all',
19
+ '<%= config.bin %> store governance policy <workspace-id> --mode allowlist --release <id> --release <id>',
20
+ ];
21
+ static args = {
22
+ workspace: core_1.Args.string({ description: 'Workspace id', required: true, ignoreStdin: true }),
23
+ };
24
+ static flags = {
25
+ mode: core_1.Flags.string({
26
+ description: 'deny_all, or allowlist the releases named by --release',
27
+ options: ['deny_all', 'allowlist'],
28
+ required: true,
29
+ }),
30
+ release: core_1.Flags.string({
31
+ description: 'Release id to allow (repeatable). Required with --mode allowlist.',
32
+ multiple: true,
33
+ }),
34
+ 'policy-id': core_1.Flags.string({ description: 'Policy id, when replacing a specific one' }),
35
+ 'expect-revision': core_1.Flags.integer({
36
+ description: 'The policy revision you are replacing (compare-and-set)',
37
+ }),
38
+ json: core_1.Flags.boolean({ description: 'Output as JSON' }),
39
+ };
40
+ async run() {
41
+ this.requireAuth();
42
+ const { args, flags } = await this.parse(StoreGovernancePolicy);
43
+ const releases = flags.release ?? [];
44
+ if (flags.mode === 'allowlist' && releases.length === 0) {
45
+ this.error('An allowlist with no --release permits nothing, which is what --mode deny_all says plainly. Pass at least one release, or say deny_all.', { exit: 2 });
46
+ }
47
+ let result;
48
+ try {
49
+ result = await (0, governed_store_1.setWorkspaceStorePolicy)(args.workspace, {
50
+ mode: flags.mode,
51
+ allowedReleaseIds: releases,
52
+ ...(flags['policy-id'] ? { policyId: flags['policy-id'] } : {}),
53
+ ...(flags['expect-revision'] !== undefined
54
+ ? { expectedRevision: flags['expect-revision'] }
55
+ : {}),
56
+ });
57
+ }
58
+ catch (error) {
59
+ this.handleApiError(error);
60
+ return;
61
+ }
62
+ this.log(JSON.stringify(result, null, 2));
63
+ }
64
+ }
65
+ exports.default = StoreGovernancePolicy;
@@ -0,0 +1,17 @@
1
+ import { BaseCommand } from '../../../base-command';
2
+ /**
3
+ * Publish one artifact release into the governed catalogue (admin).
4
+ *
5
+ * The body carries verified-outcome evidence, which is why it is a file rather
6
+ * than flags: evidence is a list of records with sources and timestamps, and
7
+ * assembling that from a command line is how a claim loses its provenance.
8
+ */
9
+ export default class StoreGovernancePublishRelease extends BaseCommand {
10
+ static description: string;
11
+ static examples: string[];
12
+ static flags: {
13
+ file: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
14
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
15
+ };
16
+ run(): Promise<void>;
17
+ }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const base_command_1 = require("../../../base-command");
4
+ const governed_store_1 = require("../../../lib/governed-store");
5
+ const commerce_command_1 = require("../../../lib/commerce-command");
6
+ /**
7
+ * Publish one artifact release into the governed catalogue (admin).
8
+ *
9
+ * The body carries verified-outcome evidence, which is why it is a file rather
10
+ * than flags: evidence is a list of records with sources and timestamps, and
11
+ * assembling that from a command line is how a claim loses its provenance.
12
+ */
13
+ class StoreGovernancePublishRelease extends base_command_1.BaseCommand {
14
+ static description = 'Publish an artifact release into the governed store catalogue (admin).';
15
+ static examples = [
16
+ '<%= config.bin %> store governance publish-release --file ./release.json',
17
+ ];
18
+ static flags = { ...commerce_command_1.jsonBodyFlags };
19
+ async run() {
20
+ this.requireAuth();
21
+ const { flags } = await this.parse(StoreGovernancePublishRelease);
22
+ const body = await (0, commerce_command_1.jsonBodyFrom)(this, flags.file);
23
+ let result;
24
+ try {
25
+ result = await (0, governed_store_1.publishGovernedStoreRelease)(body);
26
+ }
27
+ catch (error) {
28
+ this.handleApiError(error);
29
+ return;
30
+ }
31
+ this.log(JSON.stringify(result, null, 2));
32
+ }
33
+ }
34
+ exports.default = StoreGovernancePublishRelease;
@@ -25,7 +25,22 @@ export default class TasksDeliverableAdd extends BaseCommand {
25
25
  expectation: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
26
26
  'run-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
27
27
  'idempotency-key': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
28
+ file: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
29
+ 'no-upload': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
28
30
  json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
29
31
  };
30
32
  run(): Promise<void>;
33
+ /**
34
+ * Archive the bytes and let the upload's own ledger receipt BE the
35
+ * Deliverable record.
36
+ *
37
+ * One record, not two: the receipt is keyed on the same coordinate this
38
+ * command would have recorded, so the archived copy and the citation are one
39
+ * Resource rather than a path nobody can open beside an opaque blob nobody
40
+ * can match to it.
41
+ *
42
+ * Returns false when the file cannot be archived and the caller should fall
43
+ * back to recording the coordinate alone.
44
+ */
45
+ private archive;
31
46
  }
@@ -1,8 +1,44 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ const fs = __importStar(require("node:fs"));
37
+ const path = __importStar(require("node:path"));
3
38
  const core_1 = require("@oclif/core");
4
39
  const data_provider_1 = require("@skrr-ai/data-provider");
5
40
  const base_command_1 = require("../../../base-command");
41
+ const task_asset_upload_1 = require("../../../lib/task-asset-upload");
6
42
  const outbox_1 = require("../../../lib/outbox");
7
43
  const api_fetch_1 = require("../../../lib/api-fetch");
8
44
  const session_task_endpoints_1 = require("../../../lib/session-task-endpoints");
@@ -68,6 +104,15 @@ class TasksDeliverableAdd extends base_command_1.BaseCommand {
68
104
  expectation: core_1.Flags.string({ multiple: true, description: 'Expectation id this satisfies' }),
69
105
  'run-id': core_1.Flags.string({ description: 'Run that produced it' }),
70
106
  'idempotency-key': core_1.Flags.string({ description: 'Stable retry key' }),
107
+ file: core_1.Flags.string({
108
+ description: "Archive THIS file as the Deliverable's exact content, when the bytes are somewhere " +
109
+ 'other than the coordinate. Without it a coordinate that already names a readable ' +
110
+ 'local file is archived automatically.',
111
+ }),
112
+ 'no-upload': core_1.Flags.boolean({
113
+ description: 'Record the coordinate only. The Deliverable stays `locator_only`: nothing pins which ' +
114
+ 'revision it is, and nobody can open it from the web app.',
115
+ }),
71
116
  json: core_1.Flags.boolean({ description: 'Output as JSON' }),
72
117
  };
73
118
  async run() {
@@ -84,6 +129,45 @@ class TasksDeliverableAdd extends base_command_1.BaseCommand {
84
129
  this.error('--status and deprecated --lifecycle cannot disagree', { exit: 1 });
85
130
  }
86
131
  const status = flags.status || flags.lifecycle;
132
+ // A bare path has no global meaning and nothing to open — the CLI's own
133
+ // help says so. Archiving the bytes is what turns it into something a
134
+ // person can click and a digest can pin, so a coordinate that already
135
+ // names a readable local file is archived by default.
136
+ //
137
+ // Not when the caller is pinning an EXTERNAL system's version
138
+ // (--provider/--version/--content-digest): that names a revision in
139
+ // somebody else's namespace, and a local file of the same name is not
140
+ // evidence about it.
141
+ const pinsExternalVersion = Boolean(flags.provider || flags.version || flags['content-digest']);
142
+ const archivePath = flags['no-upload']
143
+ ? null
144
+ : flags.file
145
+ ? flags.file
146
+ : pinsExternalVersion
147
+ ? null
148
+ : localFileFor(parsed.value);
149
+ if (flags.file && flags['no-upload']) {
150
+ this.error('--file and --no-upload cannot both be given', { exit: 1 });
151
+ }
152
+ let archiveRefused = false;
153
+ if (archivePath) {
154
+ const uploaded = await this.archive({
155
+ taskId: args.task,
156
+ filePath: archivePath,
157
+ identity: parsed.value.identity,
158
+ title: flags.title,
159
+ expectationIds: flags.expectation,
160
+ requestedStatus: status,
161
+ json: Boolean(flags.json),
162
+ // `--file` is an instruction; a coordinate that happens to name a file
163
+ // is an inference. Only the inference is size-bounded.
164
+ auto: !flags.file,
165
+ });
166
+ if (uploaded)
167
+ return;
168
+ // It tried and said why; the closing hint below would only repeat it.
169
+ archiveRefused = true;
170
+ }
87
171
  let result;
88
172
  try {
89
173
  const payload = {
@@ -116,6 +200,96 @@ class TasksDeliverableAdd extends base_command_1.BaseCommand {
116
200
  }
117
201
  const where = parsed.value.location ? ` at ${parsed.value.location}` : '';
118
202
  this.log(`Recorded Deliverable ${result.link.id}: ${parsed.value.kind}:${parsed.value.identity}${where} (${status || 'local'}; self reported).`);
203
+ if (!pinsExternalVersion && !flags['no-upload'] && !archiveRefused) {
204
+ this.log('No copy was archived, so nothing pins this version and it cannot be opened from the ' +
205
+ 'web app. Pass --file <path> to archive the bytes.');
206
+ }
207
+ }
208
+ /**
209
+ * Archive the bytes and let the upload's own ledger receipt BE the
210
+ * Deliverable record.
211
+ *
212
+ * One record, not two: the receipt is keyed on the same coordinate this
213
+ * command would have recorded, so the archived copy and the citation are one
214
+ * Resource rather than a path nobody can open beside an opaque blob nobody
215
+ * can match to it.
216
+ *
217
+ * Returns false when the file cannot be archived and the caller should fall
218
+ * back to recording the coordinate alone.
219
+ */
220
+ async archive(opts) {
221
+ let stat;
222
+ try {
223
+ stat = fs.statSync(opts.filePath);
224
+ }
225
+ catch {
226
+ this.error(`File not found: ${opts.filePath}`, { exit: 1 });
227
+ return false;
228
+ }
229
+ if (!stat.isFile()) {
230
+ this.error(`Not a regular file: ${opts.filePath}`, { exit: 1 });
231
+ return false;
232
+ }
233
+ // The platform archives a file of any supported size under its own name.
234
+ // What is bounded is the INFERENCE: `deliverable add code:…@build/out.bin`
235
+ // should not quietly send 400 MB because the coordinate resolved to a
236
+ // path. Naming the file with --file says do it anyway, and the only limit
237
+ // left is the platform's own.
238
+ if (opts.auto && stat.size > data_provider_1.TASK_ATTACHMENT_MAX_BYTES) {
239
+ const mb = Math.floor(data_provider_1.TASK_ATTACHMENT_MAX_BYTES / (1024 * 1024));
240
+ this.warn(`${path.basename(opts.filePath)} is larger than ${mb} MB, so it was not archived ` +
241
+ 'automatically. Pass --file to archive it anyway.');
242
+ return false;
243
+ }
244
+ let asset;
245
+ try {
246
+ asset = await (0, task_asset_upload_1.uploadTaskAssetFile)({
247
+ taskId: opts.taskId,
248
+ filePath: opts.filePath,
249
+ role: 'deliverable',
250
+ ledger: {
251
+ identity: opts.identity,
252
+ title: opts.title,
253
+ expectationIds: opts.expectationIds,
254
+ },
255
+ });
256
+ }
257
+ catch (err) {
258
+ this.handleApiError(err);
259
+ return false;
260
+ }
261
+ if (opts.json) {
262
+ this.log(JSON.stringify({ archived: asset, identity: opts.identity }, null, 2));
263
+ return true;
264
+ }
265
+ this.log(`Recorded Deliverable ${opts.identity} — archived copy ${asset.id} ` +
266
+ `(sha256 pinned; observed available; self reported).`);
267
+ if (opts.requestedStatus && opts.requestedStatus !== 'available') {
268
+ // Not silent: the platform WATCHED these bytes land, which is a stronger
269
+ // and verified statement than the one that was asked for. Who vouched
270
+ // is unchanged — still `self_reported`, still nobody else's word.
271
+ this.log(`--status ${opts.requestedStatus} did not apply: an archived copy is observed available.`);
272
+ }
273
+ return true;
119
274
  }
120
275
  }
121
276
  exports.default = TasksDeliverableAdd;
277
+ /**
278
+ * The local file a coordinate already names, if it names one. `location` is
279
+ * checked first because it is where the thing IS; `identity` is the fallback
280
+ * for the common `file:docs/x.md` with no location.
281
+ */
282
+ function localFileFor(value) {
283
+ for (const candidate of [value.location, value.identity]) {
284
+ if (!candidate)
285
+ continue;
286
+ try {
287
+ if (fs.statSync(candidate).isFile())
288
+ return candidate;
289
+ }
290
+ catch {
291
+ /* not a local file */
292
+ }
293
+ }
294
+ return null;
295
+ }
@@ -0,0 +1,35 @@
1
+ import { BaseCommand } from '../../../base-command';
2
+ /**
3
+ * `skrr tasks deliverable archive <task>`
4
+ *
5
+ * Backfill for Deliverables recorded before archiving existed, or recorded
6
+ * with `--no-upload`. They are bare coordinates: nothing pins which revision
7
+ * they are, and nobody can open them from the web app.
8
+ *
9
+ * This is a CLI command and not a server migration, and that is not a
10
+ * shortcut. A Deliverable recorded as `docs/policies/payout.md` names a file
11
+ * the server has never seen and cannot reach — the bytes exist on the machine
12
+ * that produced them. Only something running THERE can archive them, so the
13
+ * backfill has to be a command someone runs in the working tree, not a job
14
+ * that sweeps a collection.
15
+ *
16
+ * What it will not do: guess. A row is archived only when its own coordinate
17
+ * resolves to a readable regular file relative to the current directory. Every
18
+ * row it skips is reported with the reason, because a backfill that silently
19
+ * covers 3 of 5 is worse than one that covers none.
20
+ */
21
+ export default class TasksDeliverableArchive extends BaseCommand {
22
+ static description: string;
23
+ static examples: string[];
24
+ static args: {
25
+ task: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
26
+ };
27
+ static flags: {
28
+ task: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
29
+ 'dry-run': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
30
+ 'max-bytes': import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
31
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
32
+ };
33
+ run(): Promise<void>;
34
+ private report;
35
+ }
@@ -0,0 +1,205 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const fs = __importStar(require("node:fs"));
37
+ const path = __importStar(require("node:path"));
38
+ const core_1 = require("@oclif/core");
39
+ const data_provider_1 = require("@skrr-ai/data-provider");
40
+ const base_command_1 = require("../../../base-command");
41
+ const task_resolver_1 = require("../../../lib/task-resolver");
42
+ const task_asset_upload_1 = require("../../../lib/task-asset-upload");
43
+ /**
44
+ * `skrr tasks deliverable archive <task>`
45
+ *
46
+ * Backfill for Deliverables recorded before archiving existed, or recorded
47
+ * with `--no-upload`. They are bare coordinates: nothing pins which revision
48
+ * they are, and nobody can open them from the web app.
49
+ *
50
+ * This is a CLI command and not a server migration, and that is not a
51
+ * shortcut. A Deliverable recorded as `docs/policies/payout.md` names a file
52
+ * the server has never seen and cannot reach — the bytes exist on the machine
53
+ * that produced them. Only something running THERE can archive them, so the
54
+ * backfill has to be a command someone runs in the working tree, not a job
55
+ * that sweeps a collection.
56
+ *
57
+ * What it will not do: guess. A row is archived only when its own coordinate
58
+ * resolves to a readable regular file relative to the current directory. Every
59
+ * row it skips is reported with the reason, because a backfill that silently
60
+ * covers 3 of 5 is worse than one that covers none.
61
+ */
62
+ class TasksDeliverableArchive extends base_command_1.BaseCommand {
63
+ static description = 'Archive the bytes of Deliverables that are still bare coordinates.\n' +
64
+ '\n' +
65
+ 'Run it from the directory their paths are relative to — usually the repository root. ' +
66
+ 'Each row whose coordinate resolves to a readable local file is uploaded and recorded ' +
67
+ 'against those exact bytes, converging onto the SAME Deliverable rather than adding a ' +
68
+ 'second one. Rows that already carry an archived copy are left alone.';
69
+ static examples = [
70
+ '<%= config.bin %> tasks deliverable archive <task-id> --dry-run',
71
+ '<%= config.bin %> tasks deliverable archive <task-id>',
72
+ ];
73
+ static args = {
74
+ task: core_1.Args.string({ required: false, ignoreStdin: true, description: 'Task id or ref' }),
75
+ };
76
+ static flags = {
77
+ task: core_1.Flags.string({ description: 'Task id; overrides runtime context' }),
78
+ 'dry-run': core_1.Flags.boolean({
79
+ description: 'Report what would be archived and upload nothing',
80
+ }),
81
+ 'max-bytes': core_1.Flags.integer({
82
+ description: `Skip files larger than this (default ${data_provider_1.TASK_ATTACHMENT_MAX_BYTES})`,
83
+ default: data_provider_1.TASK_ATTACHMENT_MAX_BYTES,
84
+ }),
85
+ json: core_1.Flags.boolean({ description: 'Output as JSON' }),
86
+ };
87
+ async run() {
88
+ this.requireAuth();
89
+ const { args, flags } = await this.parse(TasksDeliverableArchive);
90
+ const task = (0, task_resolver_1.resolveTaskIdentity)({ positionalId: args.task, flagTask: flags.task });
91
+ let listed;
92
+ try {
93
+ listed = await data_provider_1.dataService.listTaskDeliverables(task.id);
94
+ }
95
+ catch (error) {
96
+ this.handleApiError(error);
97
+ return;
98
+ }
99
+ const plan = (listed.data || []).map((row) => classify(row, flags['max-bytes']));
100
+ const actionable = plan.filter((entry) => entry.action === 'archive');
101
+ if (flags['dry-run']) {
102
+ const report = { taskId: task.id, dryRun: true, plan };
103
+ if (flags.json)
104
+ return this.log(JSON.stringify(report, null, 2));
105
+ return this.report(plan, []);
106
+ }
107
+ const results = [];
108
+ for (const entry of actionable) {
109
+ try {
110
+ const asset = await (0, task_asset_upload_1.uploadTaskAssetFile)({
111
+ taskId: task.id,
112
+ filePath: entry.filePath,
113
+ role: 'deliverable',
114
+ ledger: {
115
+ identity: entry.identity,
116
+ title: entry.title,
117
+ expectationIds: entry.expectationIds,
118
+ },
119
+ });
120
+ results.push({ identity: entry.identity, ok: true, attachmentId: asset.id });
121
+ }
122
+ catch (error) {
123
+ results.push({
124
+ identity: entry.identity,
125
+ ok: false,
126
+ reason: error instanceof Error ? error.message : String(error),
127
+ });
128
+ }
129
+ }
130
+ if (flags.json) {
131
+ return this.log(JSON.stringify({ taskId: task.id, plan, results }, null, 2));
132
+ }
133
+ this.report(plan, results);
134
+ if (results.some((entry) => !entry.ok)) {
135
+ this.error(`${results.filter((entry) => !entry.ok).length} Deliverable(s) failed to archive`, {
136
+ exit: 1,
137
+ });
138
+ }
139
+ }
140
+ report(plan, results) {
141
+ const byIdentity = new Map(results.map((entry) => [entry.identity, entry]));
142
+ for (const entry of plan) {
143
+ const outcome = byIdentity.get(entry.identity);
144
+ if (entry.action === 'archive' && !outcome) {
145
+ this.log(`would archive ${entry.identity} (${entry.filePath})`);
146
+ }
147
+ else if (outcome?.ok) {
148
+ this.log(`archived ${entry.identity} → ${outcome.attachmentId}`);
149
+ }
150
+ else if (outcome) {
151
+ this.log(`FAILED ${entry.identity} — ${outcome.reason}`);
152
+ }
153
+ else {
154
+ this.log(`skipped ${entry.identity} — ${entry.reason}`);
155
+ }
156
+ }
157
+ if (!plan.length)
158
+ this.log('No Deliverables recorded.');
159
+ }
160
+ }
161
+ exports.default = TasksDeliverableArchive;
162
+ /**
163
+ * One row's verdict. Every `skip` carries the reason it was skipped — the
164
+ * whole point of the command is that a partial backfill says which part.
165
+ */
166
+ function classify(row, maxBytes) {
167
+ const identity = row.identity || row.location || row.title || '';
168
+ const base = {
169
+ linkId: row.linkId,
170
+ identity,
171
+ title: row.title,
172
+ expectationIds: row.expectationIds,
173
+ action: 'skip',
174
+ };
175
+ if (row.managedContentRef) {
176
+ return { ...base, reason: 'already archived' };
177
+ }
178
+ if (!identity) {
179
+ return { ...base, reason: 'no coordinate to resolve' };
180
+ }
181
+ if (/^[a-z][a-z0-9+.-]*:\/\//i.test(row.location || identity)) {
182
+ return { ...base, reason: 'remote locator — nothing local to archive' };
183
+ }
184
+ for (const candidate of [row.location, identity]) {
185
+ if (!candidate)
186
+ continue;
187
+ let stat;
188
+ try {
189
+ stat = fs.statSync(candidate);
190
+ }
191
+ catch {
192
+ continue;
193
+ }
194
+ if (!stat.isFile())
195
+ continue;
196
+ if (stat.size > maxBytes) {
197
+ return {
198
+ ...base,
199
+ reason: `${path.basename(candidate)} is ${stat.size} bytes, over the ${maxBytes} limit`,
200
+ };
201
+ }
202
+ return { ...base, action: 'archive', filePath: candidate };
203
+ }
204
+ return { ...base, reason: 'no readable local file at this coordinate' };
205
+ }
@@ -21,6 +21,9 @@ class TasksLabelsDetach extends base_command_1.BaseCommand {
21
21
  static flags = {
22
22
  json: core_1.Flags.boolean({ description: 'Output the updated task as JSON' }),
23
23
  'label-id': core_1.Flags.string({
24
+ // Same alias `attach` carries: `--label` is what `spaces labels
25
+ // remove` takes, and the two directions should spell one flag alike.
26
+ aliases: ['label'],
24
27
  description: 'Label to detach — id, or a name from `skrr labels list --applicable-to task` (repeatable)',
25
28
  multiple: true,
26
29
  required: true,
@@ -0,0 +1,24 @@
1
+ import { BaseCommand } from '../../../base-command';
2
+ /**
3
+ * Ask the lightweight model which of the DECLARED labels fit this task —
4
+ * `POST /api/tasks/:taskId/labels/suggest`, the on-demand half of the
5
+ * create-time `_labelGuidance` hint. The server keeps the suggestion off the
6
+ * task-create path (the hottest write in the product); this command is how a
7
+ * caller pays for one suggestion when it actually wants it.
8
+ *
9
+ * Same contract as create: the model may only CHOOSE from the declared
10
+ * vocabulary, a label the task already wears is never suggested, and a
11
+ * suggestion is a proposal, not a write — attach is still the caller's
12
+ * decision (`tasks labels attach --label <id>`).
13
+ */
14
+ export default class TasksLabelsSuggest extends BaseCommand {
15
+ static description: string;
16
+ static examples: string[];
17
+ static args: {
18
+ id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
19
+ };
20
+ static flags: {
21
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
22
+ };
23
+ run(): Promise<void>;
24
+ }