@skrr-ai/cli 0.1.46 → 0.1.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (305) hide show
  1. package/README.md +1 -1
  2. package/dist/base-command.d.ts +18 -0
  3. package/dist/base-command.js +61 -1
  4. package/dist/commands/agents/chat.d.ts +21 -0
  5. package/dist/commands/agents/chat.js +26 -9
  6. package/dist/commands/balance/usage/breakdown.d.ts +14 -0
  7. package/dist/commands/balance/usage/breakdown.js +68 -0
  8. package/dist/commands/balance/usage.js +24 -0
  9. package/dist/commands/code/handover.d.ts +2 -2
  10. package/dist/commands/code/handover.js +12 -13
  11. package/dist/commands/code/install.js +31 -0
  12. package/dist/commands/code/update.d.ts +46 -0
  13. package/dist/commands/code/update.js +242 -0
  14. package/dist/commands/commerce/entitlements/explain.d.ts +22 -0
  15. package/dist/commands/commerce/entitlements/explain.js +40 -0
  16. package/dist/commands/commerce/incidents/audit.d.ts +20 -0
  17. package/dist/commands/commerce/incidents/audit.js +37 -0
  18. package/dist/commands/commerce/incidents/list.d.ts +22 -0
  19. package/dist/commands/commerce/incidents/list.js +49 -0
  20. package/dist/commands/commerce/incidents/resolve.d.ts +23 -0
  21. package/dist/commands/commerce/incidents/resolve.js +45 -0
  22. package/dist/commands/commerce/incidents/retry.d.ts +22 -0
  23. package/dist/commands/commerce/incidents/retry.js +45 -0
  24. package/dist/commands/commerce/incidents/show.d.ts +13 -0
  25. package/dist/commands/commerce/incidents/show.js +30 -0
  26. package/dist/commands/commerce/offers/approve.d.ts +17 -0
  27. package/dist/commands/commerce/offers/approve.js +33 -0
  28. package/dist/commands/commerce/offers/create.d.ts +18 -0
  29. package/dist/commands/commerce/offers/create.js +34 -0
  30. package/dist/commands/commerce/offers/publish.d.ts +13 -0
  31. package/dist/commands/commerce/offers/publish.js +28 -0
  32. package/dist/commands/commerce/offers/retire.d.ts +17 -0
  33. package/dist/commands/commerce/offers/retire.js +32 -0
  34. package/dist/commands/commerce/offers/validate.d.ts +18 -0
  35. package/dist/commands/commerce/offers/validate.js +33 -0
  36. package/dist/commands/commerce/products/create.d.ts +10 -0
  37. package/dist/commands/commerce/products/create.js +25 -0
  38. package/dist/commands/commerce/promotions/redeem.d.ts +13 -0
  39. package/dist/commands/commerce/promotions/redeem.js +32 -0
  40. package/dist/commands/commerce/terms/accept.d.ts +18 -0
  41. package/dist/commands/commerce/terms/accept.js +39 -0
  42. package/dist/commands/commerce/terms/show.d.ts +10 -0
  43. package/dist/commands/commerce/terms/show.js +34 -0
  44. package/dist/commands/commerce/trials/conversion-preview.d.ts +18 -0
  45. package/dist/commands/commerce/trials/conversion-preview.js +39 -0
  46. package/dist/commands/commerce/trials/start.d.ts +23 -0
  47. package/dist/commands/commerce/trials/start.js +58 -0
  48. package/dist/commands/commitments/accounting.d.ts +39 -0
  49. package/dist/commands/commitments/accounting.js +116 -0
  50. package/dist/commands/commitments/action-history.d.ts +1 -0
  51. package/dist/commands/commitments/action-history.js +8 -1
  52. package/dist/commands/commitments/case.d.ts +1 -0
  53. package/dist/commands/commitments/case.js +19 -3
  54. package/dist/commands/commitments/cases.d.ts +1 -0
  55. package/dist/commands/commitments/cases.js +11 -1
  56. package/dist/commands/commitments/checks.d.ts +1 -0
  57. package/dist/commands/commitments/checks.js +5 -1
  58. package/dist/commands/commitments/cost.d.ts +62 -0
  59. package/dist/commands/commitments/cost.js +130 -0
  60. package/dist/commands/commitments/create.js +1 -1
  61. package/dist/commands/commitments/delete.d.ts +1 -0
  62. package/dist/commands/commitments/delete.js +56 -6
  63. package/dist/commands/commitments/feedback.js +9 -1
  64. package/dist/commands/commitments/handover.js +16 -0
  65. package/dist/commands/commitments/hypotheses.d.ts +1 -0
  66. package/dist/commands/commitments/hypotheses.js +17 -2
  67. package/dist/commands/commitments/links/list.js +4 -1
  68. package/dist/commands/commitments/liveness.d.ts +18 -0
  69. package/dist/commands/commitments/liveness.js +80 -0
  70. package/dist/commands/commitments/metrics.d.ts +1 -0
  71. package/dist/commands/commitments/metrics.js +8 -1
  72. package/dist/commands/commitments/next-tick.d.ts +39 -0
  73. package/dist/commands/commitments/next-tick.js +122 -0
  74. package/dist/commands/commitments/observations.d.ts +1 -0
  75. package/dist/commands/commitments/observations.js +19 -2
  76. package/dist/commands/commitments/pause.js +12 -0
  77. package/dist/commands/commitments/receipt.d.ts +2 -0
  78. package/dist/commands/commitments/receipt.js +16 -2
  79. package/dist/commands/commitments/remediation-proposal.js +6 -2
  80. package/dist/commands/commitments/remediation-proposals.js +5 -1
  81. package/dist/commands/commitments/restore.d.ts +25 -0
  82. package/dist/commands/commitments/restore.js +46 -0
  83. package/dist/commands/commitments/show.js +32 -0
  84. package/dist/commands/commitments/trigger-status.js +33 -0
  85. package/dist/commands/commitments/update.d.ts +1 -0
  86. package/dist/commands/commitments/update.js +31 -5
  87. package/dist/commands/commitments/wake-capabilities.d.ts +0 -1
  88. package/dist/commands/commitments/wake-capabilities.js +8 -4
  89. package/dist/commands/convos/handover.d.ts +1 -0
  90. package/dist/commands/convos/handover.js +4 -0
  91. package/dist/commands/daemon/index.js +2 -0
  92. package/dist/commands/daemon/update.d.ts +19 -0
  93. package/dist/commands/daemon/update.js +48 -0
  94. package/dist/commands/enterprise/budgets/create.d.ts +11 -0
  95. package/dist/commands/enterprise/budgets/create.js +27 -0
  96. package/dist/commands/enterprise/budgets/evaluate.d.ts +17 -0
  97. package/dist/commands/enterprise/budgets/evaluate.js +32 -0
  98. package/dist/commands/enterprise/budgets/publish.d.ts +14 -0
  99. package/dist/commands/enterprise/budgets/publish.js +30 -0
  100. package/dist/commands/enterprise/contracts/activate.d.ts +14 -0
  101. package/dist/commands/enterprise/contracts/activate.js +30 -0
  102. package/dist/commands/enterprise/contracts/create.d.ts +14 -0
  103. package/dist/commands/enterprise/contracts/create.js +32 -0
  104. package/dist/commands/enterprise/contracts/issue.d.ts +18 -0
  105. package/dist/commands/enterprise/contracts/issue.js +34 -0
  106. package/dist/commands/enterprise/domains/begin.d.ts +20 -0
  107. package/dist/commands/enterprise/domains/begin.js +39 -0
  108. package/dist/commands/enterprise/domains/verify.d.ts +14 -0
  109. package/dist/commands/enterprise/domains/verify.js +32 -0
  110. package/dist/commands/enterprise/external-config/activate.d.ts +22 -0
  111. package/dist/commands/enterprise/external-config/activate.js +49 -0
  112. package/dist/commands/enterprise/external-config/set.d.ts +25 -0
  113. package/dist/commands/enterprise/external-config/set.js +123 -0
  114. package/dist/commands/enterprise/external-config/show.d.ts +12 -0
  115. package/dist/commands/enterprise/external-config/show.js +39 -0
  116. package/dist/commands/enterprise/external-config/suspend.d.ts +13 -0
  117. package/dist/commands/enterprise/external-config/suspend.js +41 -0
  118. package/dist/commands/enterprise/finance/close-snapshot.d.ts +11 -0
  119. package/dist/commands/enterprise/finance/close-snapshot.js +28 -0
  120. package/dist/commands/enterprise/finance/record-document.d.ts +18 -0
  121. package/dist/commands/enterprise/finance/record-document.js +35 -0
  122. package/dist/commands/enterprise/profile.d.ts +20 -0
  123. package/dist/commands/enterprise/profile.js +38 -0
  124. package/dist/commands/login.d.ts +13 -0
  125. package/dist/commands/login.js +77 -0
  126. package/dist/commands/machines/dedicated/index.js +3 -0
  127. package/dist/commands/machines/dedicated/service/apply.d.ts +23 -0
  128. package/dist/commands/machines/dedicated/service/apply.js +99 -0
  129. package/dist/commands/machines/dedicated/service/approve.d.ts +23 -0
  130. package/dist/commands/machines/dedicated/service/approve.js +52 -0
  131. package/dist/commands/machines/dedicated/service/create.d.ts +55 -0
  132. package/dist/commands/machines/dedicated/service/create.js +222 -0
  133. package/dist/commands/machines/dedicated/service/edit.d.ts +30 -0
  134. package/dist/commands/machines/dedicated/service/edit.js +146 -0
  135. package/dist/commands/machines/dedicated/service/exec.d.ts +26 -0
  136. package/dist/commands/machines/dedicated/service/exec.js +92 -0
  137. package/dist/commands/machines/dedicated/service/export.d.ts +29 -0
  138. package/dist/commands/machines/dedicated/service/export.js +106 -0
  139. package/dist/commands/machines/dedicated/service/index.d.ts +14 -0
  140. package/dist/commands/machines/dedicated/service/index.js +49 -0
  141. package/dist/commands/machines/dedicated/service/logs.d.ts +33 -0
  142. package/dist/commands/machines/dedicated/service/logs.js +148 -0
  143. package/dist/commands/machines/dedicated/service/ls.d.ts +20 -0
  144. package/dist/commands/machines/dedicated/service/ls.js +80 -0
  145. package/dist/commands/machines/dedicated/service/restart.d.ts +14 -0
  146. package/dist/commands/machines/dedicated/service/restart.js +29 -0
  147. package/dist/commands/machines/dedicated/service/rm.d.ts +20 -0
  148. package/dist/commands/machines/dedicated/service/rm.js +33 -0
  149. package/dist/commands/machines/dedicated/service/secret/index.d.ts +14 -0
  150. package/dist/commands/machines/dedicated/service/secret/index.js +25 -0
  151. package/dist/commands/machines/dedicated/service/secret/rm.d.ts +22 -0
  152. package/dist/commands/machines/dedicated/service/secret/rm.js +54 -0
  153. package/dist/commands/machines/dedicated/service/secret/set.d.ts +22 -0
  154. package/dist/commands/machines/dedicated/service/secret/set.js +93 -0
  155. package/dist/commands/machines/dedicated/service/start.d.ts +14 -0
  156. package/dist/commands/machines/dedicated/service/start.js +29 -0
  157. package/dist/commands/machines/dedicated/service/status.d.ts +21 -0
  158. package/dist/commands/machines/dedicated/service/status.js +85 -0
  159. package/dist/commands/machines/dedicated/service/stop.d.ts +20 -0
  160. package/dist/commands/machines/dedicated/service/stop.js +35 -0
  161. package/dist/commands/machines/dedicated/service/top.d.ts +22 -0
  162. package/dist/commands/machines/dedicated/service/top.js +120 -0
  163. package/dist/commands/machines/dedicated/sign-in-status.d.ts +22 -0
  164. package/dist/commands/machines/dedicated/sign-in-status.js +79 -0
  165. package/dist/commands/machines/dedicated/ssh-config.d.ts +28 -0
  166. package/dist/commands/machines/dedicated/ssh-config.js +66 -0
  167. package/dist/commands/machines/dedicated/ssh-proxy.d.ts +22 -0
  168. package/dist/commands/machines/dedicated/ssh-proxy.js +62 -0
  169. package/dist/commands/machines/dedicated/ssh.d.ts +29 -0
  170. package/dist/commands/machines/dedicated/ssh.js +121 -0
  171. package/dist/commands/native/allow-all.d.ts +14 -0
  172. package/dist/commands/native/allow-all.js +25 -0
  173. package/dist/commands/native/allow.d.ts +24 -0
  174. package/dist/commands/native/allow.js +45 -0
  175. package/dist/commands/native/deny.d.ts +24 -0
  176. package/dist/commands/native/deny.js +43 -0
  177. package/dist/commands/native/disable.d.ts +17 -0
  178. package/dist/commands/native/disable.js +28 -0
  179. package/dist/commands/native/enable.d.ts +12 -0
  180. package/dist/commands/native/enable.js +29 -0
  181. package/dist/commands/native/list-apps.d.ts +19 -0
  182. package/dist/commands/native/list-apps.js +30 -0
  183. package/dist/commands/native/restrict-to.d.ts +22 -0
  184. package/dist/commands/native/restrict-to.js +41 -0
  185. package/dist/commands/native/status.d.ts +19 -0
  186. package/dist/commands/native/status.js +33 -0
  187. package/dist/commands/native.d.ts +39 -0
  188. package/dist/commands/native.js +76 -0
  189. package/dist/commands/service/index.d.ts +14 -0
  190. package/dist/commands/service/index.js +31 -0
  191. package/dist/commands/service/logs.d.ts +18 -0
  192. package/dist/commands/service/logs.js +53 -0
  193. package/dist/commands/service/ls.d.ts +13 -0
  194. package/dist/commands/service/ls.js +48 -0
  195. package/dist/commands/service/propose.d.ts +34 -0
  196. package/dist/commands/service/propose.js +113 -0
  197. package/dist/commands/service/status.d.ts +17 -0
  198. package/dist/commands/service/status.js +56 -0
  199. package/dist/commands/spaces/auto-executor/runs.d.ts +13 -0
  200. package/dist/commands/spaces/auto-executor/runs.js +56 -0
  201. package/dist/commands/spaces/briefs/get.js +8 -0
  202. package/dist/commands/spaces/briefs/list.js +2 -0
  203. package/dist/commands/spaces/briefs/set.d.ts +3 -0
  204. package/dist/commands/spaces/briefs/set.js +78 -13
  205. package/dist/commands/spaces/expertise-suggestions.d.ts +12 -0
  206. package/dist/commands/spaces/expertise-suggestions.js +71 -0
  207. package/dist/commands/spaces/members/add.d.ts +1 -0
  208. package/dist/commands/spaces/members/add.js +11 -3
  209. package/dist/commands/spaces/members/list.js +11 -0
  210. package/dist/commands/store/governance/artifacts.d.ts +25 -0
  211. package/dist/commands/store/governance/artifacts.js +55 -0
  212. package/dist/commands/store/governance/assign.d.ts +16 -0
  213. package/dist/commands/store/governance/assign.js +54 -0
  214. package/dist/commands/store/governance/create-license.d.ts +18 -0
  215. package/dist/commands/store/governance/create-license.js +35 -0
  216. package/dist/commands/store/governance/install-plan.d.ts +25 -0
  217. package/dist/commands/store/governance/install-plan.js +56 -0
  218. package/dist/commands/store/governance/license-policy.d.ts +30 -0
  219. package/dist/commands/store/governance/license-policy.js +69 -0
  220. package/dist/commands/store/governance/policy.d.ts +25 -0
  221. package/dist/commands/store/governance/policy.js +65 -0
  222. package/dist/commands/store/governance/publish-release.d.ts +17 -0
  223. package/dist/commands/store/governance/publish-release.js +34 -0
  224. package/dist/commands/tasks/assign.d.ts +9 -0
  225. package/dist/commands/tasks/assign.js +108 -1
  226. package/dist/commands/tasks/deliverable/add.d.ts +15 -0
  227. package/dist/commands/tasks/deliverable/add.js +174 -0
  228. package/dist/commands/tasks/deliverable/archive.d.ts +35 -0
  229. package/dist/commands/tasks/deliverable/archive.js +205 -0
  230. package/dist/commands/tasks/labels/detach.js +3 -0
  231. package/dist/commands/tasks/labels/suggest.d.ts +24 -0
  232. package/dist/commands/tasks/labels/suggest.js +69 -0
  233. package/dist/commands/tasks/list.d.ts +16 -2
  234. package/dist/commands/tasks/list.js +100 -24
  235. package/dist/commands/tasks/show.d.ts +23 -0
  236. package/dist/commands/tasks/show.js +51 -1
  237. package/dist/commands/wiki/rm.d.ts +22 -1
  238. package/dist/commands/wiki/rm.js +52 -3
  239. package/dist/lib/agentic-stream.js +10 -2
  240. package/dist/lib/assignee-resolver.d.ts +22 -0
  241. package/dist/lib/assignee-resolver.js +26 -0
  242. package/dist/lib/balance.d.ts +6 -1
  243. package/dist/lib/balance.js +15 -0
  244. package/dist/lib/code-handover.d.ts +0 -10
  245. package/dist/lib/code-handover.js +20 -5
  246. package/dist/lib/commerce-command.d.ts +48 -0
  247. package/dist/lib/commerce-command.js +70 -0
  248. package/dist/lib/commerce.d.ts +93 -0
  249. package/dist/lib/commerce.js +129 -0
  250. package/dist/lib/commitment-product.js +1 -1
  251. package/dist/lib/commitments.d.ts +202 -29
  252. package/dist/lib/commitments.js +300 -33
  253. package/dist/lib/dedicated-lease-command.js +10 -0
  254. package/dist/lib/dedicated-machines.d.ts +37 -0
  255. package/dist/lib/dedicated-machines.js +47 -0
  256. package/dist/lib/dedicated-service-command.d.ts +60 -0
  257. package/dist/lib/dedicated-service-command.js +182 -0
  258. package/dist/lib/dedicated-service.d.ts +342 -0
  259. package/dist/lib/dedicated-service.js +741 -0
  260. package/dist/lib/dedicated-ssh.d.ts +136 -0
  261. package/dist/lib/dedicated-ssh.js +387 -0
  262. package/dist/lib/delegated-cli.js +51 -13
  263. package/dist/lib/enterprise-commerce.d.ts +67 -0
  264. package/dist/lib/enterprise-commerce.js +112 -0
  265. package/dist/lib/enterprise-external-configuration.d.ts +60 -0
  266. package/dist/lib/enterprise-external-configuration.js +58 -0
  267. package/dist/lib/first-party-harness.js +17 -3
  268. package/dist/lib/governed-store.d.ts +110 -0
  269. package/dist/lib/governed-store.js +79 -0
  270. package/dist/lib/guest-service-command.d.ts +16 -0
  271. package/dist/lib/guest-service-command.js +32 -0
  272. package/dist/lib/guest-service.d.ts +67 -0
  273. package/dist/lib/guest-service.js +112 -0
  274. package/dist/lib/prompt.d.ts +1 -0
  275. package/dist/lib/prompt.js +1 -0
  276. package/dist/lib/task-asset-upload.d.ts +20 -0
  277. package/dist/lib/task-asset-upload.js +30 -8
  278. package/dist/lib/task-extras.d.ts +23 -0
  279. package/dist/lib/task-extras.js +6 -0
  280. package/dist/lib/update-check.d.ts +80 -7
  281. package/dist/lib/update-check.js +365 -33
  282. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonScopes.d.ts +9 -3
  283. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonScopes.js +10 -3
  284. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.d.ts +9 -1
  285. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.js +8 -0
  286. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +1 -1
  287. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +6 -5
  288. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/messages.d.ts +16 -0
  289. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/messages.js +21 -4
  290. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.d.ts +1 -1
  291. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.js +24 -2
  292. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonScopes.d.ts +9 -3
  293. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonScopes.js +10 -3
  294. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.d.ts +9 -1
  295. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.js +8 -0
  296. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +1 -1
  297. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +1 -1
  298. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/messages.d.ts +16 -0
  299. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/messages.js +20 -4
  300. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.d.ts +1 -1
  301. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.js +24 -2
  302. package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
  303. package/dist/node_modules/@skrr-ai/data-provider/index.js +5067 -4821
  304. package/oclif.manifest.json +34877 -28659
  305. package/package.json +43 -1
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const guest_service_command_1 = require("../../lib/guest-service-command");
5
+ const format_1 = require("../../lib/format");
6
+ /**
7
+ * `skrr service ls` — the services declared on this machine, read from the
8
+ * daemon's workload socket (guest-local, read-only).
9
+ */
10
+ class ServiceLs extends guest_service_command_1.GuestServiceCommand {
11
+ static summary = 'List services declared on this machine (guest-local)';
12
+ static examples = [
13
+ '<%= config.bin %> service ls',
14
+ '<%= config.bin %> service ls --json',
15
+ ];
16
+ static flags = {
17
+ json: core_1.Flags.boolean({ description: 'Output as JSON' }),
18
+ };
19
+ async run() {
20
+ this.requireGuest();
21
+ const { flags } = await this.parse(ServiceLs);
22
+ const reply = await this.guestRead('list');
23
+ const result = (reply.result ?? reply);
24
+ if (flags.json) {
25
+ this.log(JSON.stringify(result, null, 2));
26
+ return;
27
+ }
28
+ const services = result.services ?? [];
29
+ if (services.length === 0) {
30
+ this.log('No declared services on this machine.');
31
+ return;
32
+ }
33
+ (0, format_1.renderTable)(services.map((svc) => ({
34
+ // The daemon's list rows name a service only under `spec.name` —
35
+ // without the fallback every NAME cell renders "-".
36
+ name: (0, format_1.formatCell)(svc.name ?? svc.spec?.name),
37
+ status: (0, format_1.formatCell)(svc.status ?? 'unknown'),
38
+ restart: (0, format_1.formatCell)(svc.restart ?? svc.spec?.restart),
39
+ createdBy: (0, format_1.formatCell)(svc.createdBy ?? svc.spec?.createdBy),
40
+ })), [
41
+ { key: 'name', header: 'NAME', verbatim: true },
42
+ { key: 'status', header: 'STATUS' },
43
+ { key: 'restart', header: 'RESTART' },
44
+ { key: 'createdBy', header: 'CREATED BY' },
45
+ ], (line) => this.log(line));
46
+ }
47
+ }
48
+ exports.default = ServiceLs;
@@ -0,0 +1,34 @@
1
+ import { BaseCommand } from '../../base-command';
2
+ /**
3
+ * `skrr service propose` — the agent lane for a service that should keep
4
+ * running.
5
+ *
6
+ * Runs INSIDE a Dedicated Runtime guest: the spec is written to the daemon's
7
+ * workload socket and lands as a proposal the owner approves or rejects —
8
+ * nothing runs on the proposal alone. The daemon derives who proposed it
9
+ * from the calling process, so provenance is real, not a claim in the JSON.
10
+ */
11
+ export default class ServicePropose extends BaseCommand {
12
+ static summary: string;
13
+ static description: string;
14
+ static examples: string[];
15
+ static usage: string;
16
+ static args: {
17
+ command: import("@oclif/core/lib/interfaces").Arg<string[] | undefined, Record<string, unknown>>;
18
+ };
19
+ static flags: {
20
+ file: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
21
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
22
+ name: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
23
+ cwd: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
24
+ env: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
25
+ restart: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
26
+ notify: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
27
+ 'stop-timeout': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
28
+ 'limit-memory': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
29
+ 'limit-cpu': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
30
+ 'limit-pids': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
31
+ };
32
+ run(): Promise<void>;
33
+ private resolveSpec;
34
+ }
@@ -0,0 +1,113 @@
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 dedicated_service_command_1 = require("../../lib/dedicated-service-command");
6
+ const dedicated_service_1 = require("../../lib/dedicated-service");
7
+ const guest_service_1 = require("../../lib/guest-service");
8
+ const exec_1 = require("../machines/hosted/exec");
9
+ /**
10
+ * `skrr service propose` — the agent lane for a service that should keep
11
+ * running.
12
+ *
13
+ * Runs INSIDE a Dedicated Runtime guest: the spec is written to the daemon's
14
+ * workload socket and lands as a proposal the owner approves or rejects —
15
+ * nothing runs on the proposal alone. The daemon derives who proposed it
16
+ * from the calling process, so provenance is real, not a claim in the JSON.
17
+ */
18
+ class ServicePropose extends base_command_1.BaseCommand {
19
+ static summary = 'Propose an always-on service to this machine’s owner (guest-local)';
20
+ static description = 'Writes a service spec to the machine’s daemon, which parks it as a pending proposal. ' +
21
+ 'The owner approves it with `skrr machines dedicated service approve <lease-id> <name>` — ' +
22
+ 'approval is what makes it run. Runs only on a Dedicated Runtime guest.';
23
+ static examples = [
24
+ '<%= config.bin %> service propose --file service.json',
25
+ '<%= config.bin %> service propose --name worker --cwd /workspace/repos/app -- node dist/worker.js',
26
+ ];
27
+ static usage = 'service propose [flags] -- <command...>';
28
+ static args = {
29
+ command: core_1.Args.string({
30
+ description: 'The service command and its arguments, after --',
31
+ multiple: true,
32
+ required: false,
33
+ ignoreStdin: true,
34
+ }),
35
+ };
36
+ static flags = {
37
+ ...dedicated_service_command_1.serviceSpecFlags,
38
+ file: core_1.Flags.string({ description: 'Read the spec from a service.json file instead of flags' }),
39
+ json: core_1.Flags.boolean({ description: 'Output the proposal as JSON' }),
40
+ };
41
+ async run() {
42
+ if (!(0, dedicated_service_1.runningOnDedicatedRuntimeGuest)()) {
43
+ this.error('`skrr service propose` runs inside a Dedicated Runtime guest — this is not one. ' +
44
+ 'To declare a service on your own machine use `skrr machines dedicated service create <lease-id> …`.', { exit: 2 });
45
+ }
46
+ const { head, tail } = (0, exec_1.splitExecArgv)(this.argv);
47
+ const { args, flags } = await this.parse(ServicePropose, head);
48
+ let spec;
49
+ try {
50
+ spec = this.resolveSpec(flags, tail ?? args.command ?? []);
51
+ }
52
+ catch (err) {
53
+ if (err instanceof dedicated_service_1.DedicatedServiceError)
54
+ this.error(err.message, { exit: 2 });
55
+ throw err;
56
+ }
57
+ const errors = (0, dedicated_service_1.validateServiceSpec)(spec);
58
+ if (errors.length > 0) {
59
+ this.error(`The service spec is not valid:\n${errors.map((e) => ` - ${e}`).join('\n')}`, {
60
+ exit: 2,
61
+ });
62
+ }
63
+ let proposalId;
64
+ let reply;
65
+ try {
66
+ ({ proposalId, reply } = await (0, guest_service_1.proposeGuestService)(spec));
67
+ }
68
+ catch (err) {
69
+ if (err instanceof dedicated_service_1.DedicatedServiceError)
70
+ this.error(err.message, { exit: 1 });
71
+ throw err;
72
+ }
73
+ if (flags.json) {
74
+ this.log(JSON.stringify({ proposalId: proposalId || undefined, spec: (0, dedicated_service_1.specPayload)(spec), reply }, null, 2));
75
+ return;
76
+ }
77
+ this.log(`Proposed service ${spec.name}${proposalId ? ` (proposal ${proposalId})` : ''}. ` +
78
+ 'Nothing runs until the owner approves it with ' +
79
+ `\`skrr machines dedicated service approve <lease-id> ${spec.name}\`.`);
80
+ }
81
+ resolveSpec(flags, argv) {
82
+ const file = flags.file;
83
+ const flagSpecUsed = Boolean(flags.name ||
84
+ flags.cwd ||
85
+ flags.env?.length ||
86
+ flags.restart ||
87
+ flags.notify !== undefined ||
88
+ flags['stop-timeout'] !== undefined ||
89
+ flags['limit-memory'] ||
90
+ flags['limit-cpu'] !== undefined ||
91
+ flags['limit-pids'] !== undefined);
92
+ if (file && (flagSpecUsed || argv.length > 0)) {
93
+ throw new dedicated_service_1.DedicatedServiceError('--file is the whole spec — it cannot be combined with spec flags or a command after --.', 'SPEC_INVALID');
94
+ }
95
+ if (file)
96
+ return (0, guest_service_1.readGuestSpecFile)(file);
97
+ return (0, dedicated_service_1.specFromFlags)({
98
+ name: flags.name,
99
+ argv,
100
+ cwd: flags.cwd,
101
+ env: (0, dedicated_service_1.parseEnvEntries)(flags.env),
102
+ restart: flags.restart,
103
+ notify: flags.notify,
104
+ stopTimeoutSeconds: flags['stop-timeout'],
105
+ limits: {
106
+ memoryMax: flags['limit-memory'],
107
+ cpuQuotaPercent: flags['limit-cpu'],
108
+ pidsMax: flags['limit-pids'],
109
+ },
110
+ });
111
+ }
112
+ }
113
+ exports.default = ServicePropose;
@@ -0,0 +1,17 @@
1
+ import { GuestServiceCommand } from '../../lib/guest-service-command';
2
+ /**
3
+ * `skrr service status` — one service's computed state, read on the machine
4
+ * itself (guest-local, read-only). The `systemctl status` of a guest: tenant
5
+ * code sees its own services without a credential or a round-trip to the API.
6
+ */
7
+ export default class ServiceStatus extends GuestServiceCommand {
8
+ static summary: string;
9
+ static examples: string[];
10
+ static args: {
11
+ name: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
12
+ };
13
+ static flags: {
14
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
15
+ };
16
+ run(): Promise<void>;
17
+ }
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const guest_service_command_1 = require("../../lib/guest-service-command");
5
+ const format_1 = require("../../lib/format");
6
+ const dedicated_service_1 = require("../../lib/dedicated-service");
7
+ /**
8
+ * `skrr service status` — one service's computed state, read on the machine
9
+ * itself (guest-local, read-only). The `systemctl status` of a guest: tenant
10
+ * code sees its own services without a credential or a round-trip to the API.
11
+ */
12
+ class ServiceStatus extends guest_service_command_1.GuestServiceCommand {
13
+ static summary = 'One service’s computed state on this machine (guest-local)';
14
+ static examples = [
15
+ '<%= config.bin %> service status <name>',
16
+ '<%= config.bin %> service status <name> --json',
17
+ ];
18
+ static args = {
19
+ name: core_1.Args.string({ description: 'Service name', required: true, ignoreStdin: true }),
20
+ };
21
+ static flags = {
22
+ json: core_1.Flags.boolean({ description: 'Output as JSON' }),
23
+ };
24
+ async run() {
25
+ this.requireGuest();
26
+ const { args, flags } = await this.parse(ServiceStatus);
27
+ const reply = await this.guestRead('status', { name: args.name });
28
+ const result = (reply.result ?? reply);
29
+ if (flags.json) {
30
+ this.log(JSON.stringify(result, null, 2));
31
+ return;
32
+ }
33
+ const spec = result.spec ?? {};
34
+ this.log(`service ${args.name}`);
35
+ const row = (label, value) => {
36
+ const cell = (0, format_1.formatCell)(value);
37
+ if (cell !== '-')
38
+ this.log(` ${label.padEnd(13)}${cell}`);
39
+ };
40
+ // detail arrives as a string or a structured object — render its fields.
41
+ row('status', [result.status, (0, dedicated_service_1.serviceDetailText)(result.detail)].filter(Boolean).join(' — ') || undefined);
42
+ row('restart', spec.restart);
43
+ row('command', Array.isArray(spec.command) ? spec.command.join(' ') : spec.shell);
44
+ row('cwd', spec.cwd);
45
+ row('updated', spec.updatedAt ? (0, format_1.localStamp)(spec.updatedAt) : undefined);
46
+ const exits = result.exits ?? [];
47
+ if (exits.length > 0) {
48
+ this.log('');
49
+ this.log('recent exits:');
50
+ for (const exit of exits.slice(-10)) {
51
+ this.log(` ${(0, format_1.localStamp)(exit.at)} exit ${exit.exitCode ?? '-'}${exit.signal ? ` ${exit.signal}` : ''}`);
52
+ }
53
+ }
54
+ }
55
+ }
56
+ exports.default = ServiceStatus;
@@ -0,0 +1,13 @@
1
+ import { BaseCommand } from '../../../base-command';
2
+ export default class SpacesAutoExecutorRuns extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
+ limit: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
11
+ };
12
+ run(): Promise<void>;
13
+ }
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const data_provider_1 = require("@skrr-ai/data-provider");
5
+ const base_command_1 = require("../../../base-command");
6
+ const space_output_1 = require("../../../lib/space-output");
7
+ class SpacesAutoExecutorRuns extends base_command_1.BaseCommand {
8
+ static description = "List a space's recent auto-orchestration runs and its Lead health";
9
+ static examples = [
10
+ '<%= config.bin %> spaces auto-executor runs <space-id>',
11
+ '<%= config.bin %> spaces auto-executor runs <space-id> --limit 50 --json',
12
+ ];
13
+ static args = {
14
+ id: core_1.Args.string({ description: 'Space ID', required: true, ignoreStdin: true }),
15
+ };
16
+ static flags = {
17
+ json: core_1.Flags.boolean({ description: 'Output as JSON' }),
18
+ limit: core_1.Flags.integer({
19
+ description: 'Maximum runs to return (server clamps to 1..50, default 20)',
20
+ }),
21
+ };
22
+ async run() {
23
+ this.requireAuth();
24
+ const { args, flags } = await this.parse(SpacesAutoExecutorRuns);
25
+ let result;
26
+ try {
27
+ result = await data_provider_1.dataService.getSpaceOrchestrationRuns(args.id, flags.limit);
28
+ }
29
+ catch (err) {
30
+ this.handleApiError(err);
31
+ }
32
+ if (flags.json) {
33
+ this.log(JSON.stringify((0, space_output_1.withSpacePerspectiveUrl)(this.cliConfig.baseURL, args.id, 'execution', { result }), null, 2));
34
+ return;
35
+ }
36
+ this.log(`Orchestration: ${result.enabled ? 'enabled' : 'disabled'}`);
37
+ this.log(`Lead health: ${result.leadHealth}`);
38
+ if (result.consecutiveFailures > 0) {
39
+ this.log(`Failures: ${result.consecutiveFailures} consecutive`);
40
+ }
41
+ if (result.lastFailureReason) {
42
+ this.log(`Last failure: ${result.lastFailureReason}`);
43
+ }
44
+ if (result.runs.length === 0) {
45
+ this.log('No orchestration runs recorded.');
46
+ return;
47
+ }
48
+ this.log('');
49
+ for (const run of result.runs) {
50
+ const when = run.triggeredAt ?? 'unknown-time';
51
+ const failure = run.failureReason ? ` — ${run.failureReason}` : '';
52
+ this.log(`${when} ${run.status}${failure}`);
53
+ }
54
+ }
55
+ }
56
+ exports.default = SpacesAutoExecutorRuns;
@@ -38,9 +38,17 @@ class SpacesBriefsGet extends base_command_1.BaseCommand {
38
38
  return;
39
39
  }
40
40
  const b = result;
41
+ const expertise = Array.isArray(b.expertise) ? b.expertise : [];
42
+ const dismissed = Array.isArray(b.dismissedExpertiseSuggestions)
43
+ ? b.dismissedExpertiseSuggestions
44
+ : [];
41
45
  this.log(`Principal Type: ${b.principalType ?? flags.principal}`);
42
46
  this.log(`Principal ID: ${b.principalId ?? flags.id}`);
43
47
  this.log(`Updated: ${b.updatedAt ? (0, format_1.localTime)(b.updatedAt) : '-'}`);
48
+ this.log(`Expertise: ${expertise.length > 0 ? expertise.join(', ') : '-'}`);
49
+ if (dismissed.length > 0) {
50
+ this.log(`Dismissed: ${dismissed.join(', ')}`);
51
+ }
44
52
  this.log('');
45
53
  this.log('Content:');
46
54
  const content = typeof b.content === 'string' ? b.content : '';
@@ -39,12 +39,14 @@ class SpacesBriefsList extends base_command_1.BaseCommand {
39
39
  const rows = items.map((b) => ({
40
40
  principalType: String(b.principalType ?? '-'),
41
41
  principalId: String(b.principalId ?? '-'),
42
+ expertise: Array.isArray(b.expertise) ? b.expertise.join(', ') : '-',
42
43
  length: String(typeof b.content === 'string' ? b.content.length : 0),
43
44
  updated: b.updatedAt ? (0, format_1.localTime)(b.updatedAt) : '-',
44
45
  }));
45
46
  (0, format_1.renderTable)(rows, [
46
47
  { key: 'principalType', header: 'PRINCIPAL TYPE' },
47
48
  { key: 'principalId', header: 'PRINCIPAL ID' },
49
+ { key: 'expertise', header: 'EXPERTISE', maxWidth: 40 },
48
50
  { key: 'length', header: 'LENGTH' },
49
51
  { key: 'updated', header: 'UPDATED' },
50
52
  ], (line) => this.log(line));
@@ -11,6 +11,9 @@ export default class SpacesBriefsSet extends BaseCommand {
11
11
  id: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
12
12
  content: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
13
13
  'content-file': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
14
+ expertise: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
15
+ 'add-expertise': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
16
+ 'dismiss-expertise': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
14
17
  'from-json': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
15
18
  };
16
19
  run(): Promise<void>;
@@ -44,6 +44,9 @@ class SpacesBriefsSet extends base_command_1.BaseCommand {
44
44
  static examples = [
45
45
  '<%= config.bin %> spaces briefs set <space-id> --principal user --id <user-id> --content "You are..."',
46
46
  '<%= config.bin %> spaces briefs set <space-id> --principal agent --id <agent-id> --content-file brief.md',
47
+ '<%= config.bin %> spaces briefs set <space-id> --principal agent --id <agent-id> --expertise browser --expertise frontend',
48
+ '<%= config.bin %> spaces briefs set <space-id> --principal agent --id <agent-id> --add-expertise reliability',
49
+ '<%= config.bin %> spaces briefs set <space-id> --principal agent --id <agent-id> --dismiss-expertise browser',
47
50
  '<%= config.bin %> spaces briefs set <space-id> --principal user --id <user-id> --from-json brief.json',
48
51
  ];
49
52
  static args = {
@@ -59,15 +62,36 @@ class SpacesBriefsSet extends base_command_1.BaseCommand {
59
62
  id: core_1.Flags.string({ description: 'Principal ID', required: true }),
60
63
  content: core_1.Flags.string({ description: 'Brief content string' }),
61
64
  'content-file': core_1.Flags.string({ description: 'Path to a file whose content becomes the brief' }),
65
+ expertise: core_1.Flags.string({
66
+ description: 'Domain label this member is best suited for in the space (repeatable, ≤20 items, ≤40 chars each). Replaces the full expertise list.',
67
+ multiple: true,
68
+ }),
69
+ 'add-expertise': core_1.Flags.string({
70
+ description: 'Add a domain label to the existing expertise list (repeatable, merged — does not replace)',
71
+ multiple: true,
72
+ }),
73
+ 'dismiss-expertise': core_1.Flags.string({
74
+ description: 'Dismiss an expertise suggestion so it stops appearing (repeatable, merged into the dismissed list)',
75
+ multiple: true,
76
+ }),
62
77
  'from-json': core_1.Flags.string({
63
- description: 'Path to a JSON file (or "-" for stdin) containing { content: string }',
78
+ description: 'Path to a JSON file (or "-" for stdin) containing { content?: string, expertise?: string[], dismissedExpertiseSuggestions?: string[] }',
64
79
  }),
65
80
  };
66
81
  async run() {
67
82
  this.requireAuth();
68
83
  const { args, flags } = await this.parse(SpacesBriefsSet);
69
84
  let content;
85
+ let expertise;
86
+ let dismissed;
87
+ const addExpertise = flags['add-expertise'] ?? [];
88
+ const dismissExpertise = flags['dismiss-expertise'] ?? [];
70
89
  if (flags['from-json']) {
90
+ if (addExpertise.length > 0 || dismissExpertise.length > 0) {
91
+ this.error('--add-expertise / --dismiss-expertise cannot be combined with --from-json.', {
92
+ exit: 1,
93
+ });
94
+ }
71
95
  let body = {};
72
96
  try {
73
97
  body = await (0, prompt_1.readJsonBody)(flags['from-json']);
@@ -75,24 +99,56 @@ class SpacesBriefsSet extends base_command_1.BaseCommand {
75
99
  catch (err) {
76
100
  this.error(err.message, { exit: 1 });
77
101
  }
78
- if (typeof body.content !== 'string') {
79
- this.error('JSON body must contain a "content" string field.', { exit: 1 });
102
+ if (body.content !== undefined && typeof body.content !== 'string') {
103
+ this.error('JSON body "content" must be a string when provided.', { exit: 1 });
104
+ }
105
+ for (const key of ['expertise', 'dismissedExpertiseSuggestions']) {
106
+ if (body[key] !== undefined && !Array.isArray(body[key])) {
107
+ this.error(`JSON body "${key}" must be an array of strings when provided.`, { exit: 1 });
108
+ }
80
109
  }
81
110
  content = body.content;
111
+ expertise = body.expertise;
112
+ dismissed = body.dismissedExpertiseSuggestions;
82
113
  }
83
- else if (flags['content-file']) {
84
- try {
85
- content = fs.readFileSync(flags['content-file'], 'utf8');
114
+ else {
115
+ if (flags['content-file']) {
116
+ try {
117
+ content = fs.readFileSync(flags['content-file'], 'utf8');
118
+ }
119
+ catch (err) {
120
+ this.error(`Could not read content file: ${err.message}`, { exit: 1 });
121
+ }
86
122
  }
87
- catch (err) {
88
- this.error(`Could not read content file: ${err.message}`, { exit: 1 });
123
+ else if (flags.content !== undefined) {
124
+ content = flags.content;
125
+ }
126
+ if (flags.expertise !== undefined) {
127
+ expertise = flags.expertise;
89
128
  }
90
129
  }
91
- else if (flags.content !== undefined) {
92
- content = flags.content;
130
+ const needsMerge = addExpertise.length > 0 || dismissExpertise.length > 0;
131
+ if (needsMerge) {
132
+ let existing = {};
133
+ try {
134
+ existing = (await data_provider_1.dataService.getSpaceBrief(args.id, flags.principal, flags.id));
135
+ }
136
+ catch {
137
+ existing = {};
138
+ }
139
+ if (addExpertise.length > 0) {
140
+ const base = expertise ?? (Array.isArray(existing.expertise) ? existing.expertise : []);
141
+ expertise = [...new Set([...base, ...addExpertise])];
142
+ }
143
+ if (dismissExpertise.length > 0) {
144
+ const current = Array.isArray(existing.dismissedExpertiseSuggestions)
145
+ ? existing.dismissedExpertiseSuggestions
146
+ : [];
147
+ dismissed = [...new Set([...current, ...dismissExpertise])];
148
+ }
93
149
  }
94
- else {
95
- this.error('Provide content via --content, --content-file, or --from-json.', { exit: 1 });
150
+ if (content === undefined && expertise === undefined && dismissed === undefined) {
151
+ this.error('Provide --content, --content-file, --expertise, --add-expertise, --dismiss-expertise, or --from-json.', { exit: 1 });
96
152
  }
97
153
  let result;
98
154
  try {
@@ -101,6 +157,8 @@ class SpacesBriefsSet extends base_command_1.BaseCommand {
101
157
  principalType: flags.principal,
102
158
  principalId: flags.id,
103
159
  content,
160
+ expertise,
161
+ dismissedExpertiseSuggestions: dismissed,
104
162
  });
105
163
  }
106
164
  catch (err) {
@@ -110,7 +168,14 @@ class SpacesBriefsSet extends base_command_1.BaseCommand {
110
168
  this.log(JSON.stringify((0, space_output_1.withSpacePerspectiveUrl)(this.cliConfig.baseURL, args.id, 'members', result), null, 2));
111
169
  return;
112
170
  }
113
- this.log(`Saved brief for ${flags.principal} ${flags.id} in space ${args.id} (${content.length} chars)`);
171
+ const changed = [
172
+ content !== undefined ? `content (${content.length} chars)` : null,
173
+ expertise !== undefined ? `expertise=[${expertise.join(', ')}]` : null,
174
+ dismissed !== undefined ? `dismissed=[${dismissed.join(', ')}]` : null,
175
+ ]
176
+ .filter(Boolean)
177
+ .join(', ');
178
+ this.log(`Saved brief for ${flags.principal} ${flags.id} in space ${args.id}: ${changed}`);
114
179
  }
115
180
  }
116
181
  exports.default = SpacesBriefsSet;
@@ -0,0 +1,12 @@
1
+ import { BaseCommand } from '../../base-command';
2
+ export default class SpacesExpertiseSuggestions extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
+ };
11
+ run(): Promise<void>;
12
+ }
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const data_provider_1 = require("@skrr-ai/data-provider");
5
+ const base_command_1 = require("../../base-command");
6
+ const format_1 = require("../../lib/format");
7
+ const space_output_1 = require("../../lib/space-output");
8
+ class SpacesExpertiseSuggestions extends base_command_1.BaseCommand {
9
+ static description = 'Advisory domain expertise inferred from settled-task history (computed on read, never persisted)';
10
+ static examples = [
11
+ '<%= config.bin %> spaces expertise-suggestions <space-id>',
12
+ '<%= config.bin %> spaces expertise-suggestions <space-id> --json',
13
+ ];
14
+ static args = {
15
+ id: core_1.Args.string({ description: 'Space ID', required: true, ignoreStdin: true }),
16
+ };
17
+ static flags = {
18
+ json: core_1.Flags.boolean({ description: 'Output as JSON' }),
19
+ };
20
+ async run() {
21
+ this.requireAuth();
22
+ const { args, flags } = await this.parse(SpacesExpertiseSuggestions);
23
+ let response;
24
+ let members;
25
+ try {
26
+ response = await data_provider_1.dataService.getSpaceExpertiseSuggestions(args.id);
27
+ members = await data_provider_1.dataService.getSpaceMembers(args.id).catch(() => undefined);
28
+ }
29
+ catch (err) {
30
+ this.handleApiError(err);
31
+ }
32
+ if (flags.json) {
33
+ this.log(JSON.stringify((0, space_output_1.withSpacePerspectiveUrl)(this.cliConfig.baseURL, args.id, 'members', response), null, 2));
34
+ return;
35
+ }
36
+ const suggestions = response.suggestions ?? [];
37
+ if (suggestions.length === 0) {
38
+ this.log('No expertise suggestions.');
39
+ return;
40
+ }
41
+ const nameByAgentId = new Map();
42
+ for (const agent of members?.agents ?? []) {
43
+ if (agent.id)
44
+ nameByAgentId.set(agent.id, agent.name || agent.id);
45
+ if (agent._id)
46
+ nameByAgentId.set(agent._id, agent.name || agent.id);
47
+ }
48
+ const rows = suggestions.map((s) => {
49
+ const evidence = (s.evidence ?? {});
50
+ const agentId = String(s.agentId ?? '-');
51
+ return {
52
+ agent: nameByAgentId.get(agentId) ?? agentId,
53
+ suggested: String(s.suggestedExpertise ?? '-'),
54
+ evidence: evidence.tasks !== undefined && evidence.succeeded !== undefined
55
+ ? `${evidence.succeeded}/${evidence.tasks} succeeded`
56
+ : '-',
57
+ samples: (evidence.sampleIdentifiers ?? []).join(', ') || '-',
58
+ };
59
+ });
60
+ (0, format_1.renderTable)(rows, [
61
+ { key: 'agent', header: 'AGENT', maxWidth: 28 },
62
+ { key: 'suggested', header: 'SUGGESTED EXPERTISE', maxWidth: 32 },
63
+ { key: 'evidence', header: 'EVIDENCE' },
64
+ { key: 'samples', header: 'SAMPLE TASKS', maxWidth: 40 },
65
+ ], (line) => this.log(line));
66
+ this.log('');
67
+ this.log('Accept: skrr spaces briefs set <space-id> --principal agent --id <agent-id> --expertise <value>');
68
+ this.log('Dismiss: skrr spaces briefs set <space-id> --principal agent --id <agent-id> --dismiss-expertise <value>');
69
+ }
70
+ }
71
+ exports.default = SpacesExpertiseSuggestions;
@@ -12,6 +12,7 @@ export default class SpacesMembersAdd extends BaseCommand {
12
12
  role: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
13
13
  brief: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
14
14
  'brief-file': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
15
+ expertise: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
15
16
  };
16
17
  run(): Promise<void>;
17
18
  }