@skrr-ai/cli 0.1.119 → 0.1.120

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 (276) hide show
  1. package/dist/base-command.d.ts +31 -0
  2. package/dist/base-command.js +106 -4
  3. package/dist/commands/commands.js +11 -0
  4. package/dist/commands/commitments/action-proposal.d.ts +13 -0
  5. package/dist/commands/commitments/action-proposal.js +39 -0
  6. package/dist/commands/commitments/action-proposals/decide.js +8 -1
  7. package/dist/commands/commitments/action-proposals/execute.js +11 -1
  8. package/dist/commands/commitments/create.js +2 -2
  9. package/dist/commands/commitments/doctor.d.ts +8 -0
  10. package/dist/commands/commitments/doctor.js +22 -0
  11. package/dist/commands/commitments/execute-remediation.js +12 -1
  12. package/dist/commands/commitments/observations.js +2 -2
  13. package/dist/commands/commitments/pack/bind.d.ts +18 -1
  14. package/dist/commands/commitments/pack/bind.js +66 -8
  15. package/dist/commands/commitments/pack/plan.d.ts +4 -1
  16. package/dist/commands/commitments/pack/plan.js +30 -2
  17. package/dist/commands/commitments/update.js +8 -2
  18. package/dist/commands/completion/index.js +1 -1
  19. package/dist/commands/completion/values.js +1 -1
  20. package/dist/commands/computer-use/audio.d.ts +1 -0
  21. package/dist/commands/computer-use/audio.js +1 -0
  22. package/dist/commands/computer-use/browser.d.ts +1 -0
  23. package/dist/commands/computer-use/browser.js +1 -0
  24. package/dist/commands/computer-use/disable.d.ts +1 -0
  25. package/dist/commands/computer-use/disable.js +1 -0
  26. package/dist/commands/computer-use/enable.d.ts +1 -0
  27. package/dist/commands/computer-use/enable.js +1 -0
  28. package/dist/commands/computer-use/index.d.ts +1 -0
  29. package/dist/commands/computer-use/index.js +1 -0
  30. package/dist/commands/computer-use/install.d.ts +1 -0
  31. package/dist/commands/computer-use/install.js +1 -0
  32. package/dist/commands/computer-use/recover.d.ts +1 -0
  33. package/dist/commands/computer-use/recover.js +1 -0
  34. package/dist/commands/computer-use/status.d.ts +1 -0
  35. package/dist/commands/computer-use/status.js +1 -0
  36. package/dist/commands/computer-use/stop.d.ts +1 -0
  37. package/dist/commands/computer-use/stop.js +1 -0
  38. package/dist/commands/context.js +16 -11
  39. package/dist/commands/convos/recovery.js +1 -1
  40. package/dist/commands/daemon/diagnostics.d.ts +9 -0
  41. package/dist/commands/daemon/diagnostics.js +53 -0
  42. package/dist/commands/daemon/index.js +2 -0
  43. package/dist/commands/daemon/maintenance/attest.d.ts +15 -0
  44. package/dist/commands/daemon/maintenance/attest.js +52 -0
  45. package/dist/commands/daemon/maintenance/hold.d.ts +17 -0
  46. package/dist/commands/daemon/maintenance/hold.js +70 -0
  47. package/dist/commands/daemon/maintenance/index.d.ts +12 -0
  48. package/dist/commands/daemon/maintenance/index.js +30 -0
  49. package/dist/commands/daemon/maintenance/resume.d.ts +13 -0
  50. package/dist/commands/daemon/maintenance/resume.js +36 -0
  51. package/dist/commands/daemon/maintenance/status.d.ts +13 -0
  52. package/dist/commands/daemon/maintenance/status.js +36 -0
  53. package/dist/commands/doctor.d.ts +4 -1
  54. package/dist/commands/doctor.js +50 -6
  55. package/dist/commands/followups/plans/cancel-batch.js +6 -3
  56. package/dist/commands/followups/plans/capacity.js +7 -3
  57. package/dist/commands/followups/plans/observability.js +11 -3
  58. package/dist/commands/followups/plans/preferences/set.js +26 -8
  59. package/dist/commands/followups/plans/preferences.js +1 -1
  60. package/dist/commands/followups/plans/show.js +1 -1
  61. package/dist/commands/goals/key-results/assess.d.ts +36 -0
  62. package/dist/commands/goals/key-results/assess.js +110 -0
  63. package/dist/commands/goals/key-results/history.d.ts +30 -0
  64. package/dist/commands/goals/key-results/history.js +104 -0
  65. package/dist/commands/goals/key-results/list.d.ts +5 -4
  66. package/dist/commands/goals/key-results/list.js +12 -6
  67. package/dist/commands/goals/key-results/show.d.ts +4 -2
  68. package/dist/commands/goals/key-results/show.js +25 -4
  69. package/dist/commands/goals/key-results/update.d.ts +4 -0
  70. package/dist/commands/goals/key-results/update.js +18 -24
  71. package/dist/commands/goals/plan-now.js +12 -1
  72. package/dist/commands/goals/planner-compare.d.ts +30 -0
  73. package/dist/commands/goals/planner-compare.js +136 -0
  74. package/dist/commands/machines/dedicated/service/exec.d.ts +3 -0
  75. package/dist/commands/machines/dedicated/service/exec.js +70 -11
  76. package/dist/commands/machines/hosted/destroy.d.ts +1 -0
  77. package/dist/commands/machines/hosted/destroy.js +11 -1
  78. package/dist/commands/machines/hosted/exec.d.ts +1 -0
  79. package/dist/commands/machines/hosted/exec.js +12 -1
  80. package/dist/commands/machines/hosted/index.js +1 -0
  81. package/dist/commands/machines/hosted/operation.d.ts +14 -0
  82. package/dist/commands/machines/hosted/operation.js +51 -0
  83. package/dist/commands/machines/hosted/pull.js +1 -1
  84. package/dist/commands/machines/hosted/start.js +6 -2
  85. package/dist/commands/spaces/auto-executor/compare.d.ts +18 -0
  86. package/dist/commands/spaces/auto-executor/compare.js +139 -0
  87. package/dist/commands/spaces/auto-executor/runs.d.ts +3 -0
  88. package/dist/commands/spaces/auto-executor/runs.js +13 -1
  89. package/dist/commands/spaces/charter/create-from-description.d.ts +21 -0
  90. package/dist/commands/spaces/charter/create-from-description.js +77 -0
  91. package/dist/commands/spaces/charter/show.d.ts +22 -0
  92. package/dist/commands/spaces/charter/show.js +61 -0
  93. package/dist/commands/spaces/heartbeats/list.d.ts +1 -16
  94. package/dist/commands/spaces/heartbeats/list.js +13 -0
  95. package/dist/commands/spaces/install-template.js +3 -0
  96. package/dist/commands/spaces/loops/migrate.d.ts +32 -0
  97. package/dist/commands/spaces/loops/migrate.js +103 -0
  98. package/dist/commands/spaces/loops/release.d.ts +14 -0
  99. package/dist/commands/spaces/loops/release.js +59 -0
  100. package/dist/commands/spaces/notebook.d.ts +25 -0
  101. package/dist/commands/spaces/notebook.js +75 -0
  102. package/dist/commands/spaces/proposals/discard.d.ts +17 -0
  103. package/dist/commands/spaces/proposals/discard.js +17 -0
  104. package/dist/commands/spaces/proposals/keep.d.ts +17 -0
  105. package/dist/commands/spaces/proposals/keep.js +17 -0
  106. package/dist/commands/spaces/proposals/list.d.ts +24 -0
  107. package/dist/commands/spaces/proposals/list.js +89 -0
  108. package/dist/commands/spaces/skills/propose.d.ts +29 -0
  109. package/dist/commands/spaces/skills/propose.js +82 -0
  110. package/dist/commands/spaces/templates/fork.js +3 -0
  111. package/dist/commands/spaces/triggers/show.js +6 -0
  112. package/dist/commands/spaces/workflows/retry.d.ts +1 -0
  113. package/dist/commands/spaces/workflows/retry.js +8 -1
  114. package/dist/commands/spaces/workflows/triggers/create.js +3 -2
  115. package/dist/commands/spaces/workflows/triggers/fire.js +4 -0
  116. package/dist/commands/spaces/workflows/triggers/update.js +2 -1
  117. package/dist/commands/spaces/write-policy/set.d.ts +22 -0
  118. package/dist/commands/spaces/write-policy/set.js +82 -0
  119. package/dist/commands/spaces/write-policy/show.d.ts +19 -0
  120. package/dist/commands/spaces/write-policy/show.js +49 -0
  121. package/dist/commands/store/artifacts/receipt.d.ts +14 -0
  122. package/dist/commands/store/artifacts/receipt.js +34 -0
  123. package/dist/commands/store/artifacts/release.d.ts +2 -0
  124. package/dist/commands/store/artifacts/release.js +11 -0
  125. package/dist/commands/store/governance/publish-release.d.ts +2 -0
  126. package/dist/commands/store/governance/publish-release.js +30 -1
  127. package/dist/commands/store/governance/release-receipt.d.ts +12 -0
  128. package/dist/commands/store/governance/release-receipt.js +32 -0
  129. package/dist/commands/tasks/approvals/list.d.ts +11 -5
  130. package/dist/commands/tasks/approvals/list.js +13 -6
  131. package/dist/commands/tasks/attachments/facts.d.ts +12 -0
  132. package/dist/commands/tasks/attachments/facts.js +29 -0
  133. package/dist/commands/tasks/attachments/upload.d.ts +1 -0
  134. package/dist/commands/tasks/attachments/upload.js +16 -0
  135. package/dist/commands/tasks/bulk-update.js +35 -1
  136. package/dist/commands/tasks/context.d.ts +15 -0
  137. package/dist/commands/tasks/context.js +69 -0
  138. package/dist/commands/tasks/copy.d.ts +18 -0
  139. package/dist/commands/tasks/copy.js +85 -0
  140. package/dist/commands/tasks/create-tree.js +97 -23
  141. package/dist/commands/tasks/create.js +9 -1
  142. package/dist/commands/tasks/deliverable/add.js +20 -10
  143. package/dist/commands/tasks/move.js +8 -1
  144. package/dist/commands/tasks/operations/show.d.ts +16 -0
  145. package/dist/commands/tasks/operations/show.js +98 -0
  146. package/dist/commands/tasks/operations/wait.d.ts +22 -0
  147. package/dist/commands/tasks/operations/wait.js +114 -0
  148. package/dist/commands/tasks/preflight.d.ts +1 -0
  149. package/dist/commands/tasks/preflight.js +11 -1
  150. package/dist/commands/tasks/rearm-recurrence.js +4 -0
  151. package/dist/commands/tasks/result/show.js +22 -0
  152. package/dist/commands/tasks/result/submit.d.ts +1 -0
  153. package/dist/commands/tasks/result/submit.js +3 -0
  154. package/dist/commands/tasks/retry-receipt.d.ts +15 -0
  155. package/dist/commands/tasks/retry-receipt.js +89 -0
  156. package/dist/commands/tasks/retry-review.d.ts +16 -0
  157. package/dist/commands/tasks/retry-review.js +66 -0
  158. package/dist/commands/tasks/retry.d.ts +4 -8
  159. package/dist/commands/tasks/retry.js +34 -68
  160. package/dist/commands/tasks/runs.d.ts +21 -0
  161. package/dist/commands/tasks/runs.js +95 -0
  162. package/dist/commands/tasks/show.d.ts +2 -0
  163. package/dist/commands/tasks/show.js +15 -1
  164. package/dist/commands/tasks/start-receipt.d.ts +15 -0
  165. package/dist/commands/tasks/start-receipt.js +95 -0
  166. package/dist/commands/tasks/start.d.ts +4 -0
  167. package/dist/commands/tasks/start.js +49 -3
  168. package/dist/commands/tasks/update.js +3 -0
  169. package/dist/commands/tasks/upsert.js +17 -3
  170. package/dist/commands/tasks/watch.d.ts +3 -0
  171. package/dist/commands/tasks/watch.js +85 -20
  172. package/dist/commands/wiki/history.d.ts +33 -0
  173. package/dist/commands/wiki/history.js +134 -0
  174. package/dist/commands/wiki/ls.d.ts +2 -0
  175. package/dist/commands/wiki/ls.js +8 -0
  176. package/dist/commands/wiki/update.d.ts +3 -1
  177. package/dist/commands/wiki/update.js +24 -2
  178. package/dist/commands/wiki/write.d.ts +22 -0
  179. package/dist/commands/wiki/write.js +144 -6
  180. package/dist/generated/agent-guides.json +81 -81
  181. package/dist/generated/managed-instruction-guides.json +1 -1
  182. package/dist/lib/agent-guides.d.ts +9 -0
  183. package/dist/lib/agent-guides.js +23 -1
  184. package/dist/lib/agentic-stream.d.ts +5 -0
  185. package/dist/lib/agentic-stream.js +122 -3
  186. package/dist/lib/auth-diagnostics.d.ts +39 -0
  187. package/dist/lib/auth-diagnostics.js +71 -0
  188. package/dist/lib/cli-client-identity.d.ts +6 -0
  189. package/dist/lib/cli-client-identity.js +16 -0
  190. package/dist/lib/cli-installation-diagnostics.d.ts +52 -0
  191. package/dist/lib/cli-installation-diagnostics.js +254 -0
  192. package/dist/lib/command-hygiene.d.ts +45 -0
  193. package/dist/lib/command-hygiene.js +413 -0
  194. package/dist/lib/commitments.d.ts +64 -3
  195. package/dist/lib/commitments.js +34 -6
  196. package/dist/lib/completion-index.d.ts +16 -4
  197. package/dist/lib/completion-index.js +50 -14
  198. package/dist/lib/config.js +7 -1
  199. package/dist/lib/daemon-maintenance-command.d.ts +22 -0
  200. package/dist/lib/daemon-maintenance-command.js +39 -0
  201. package/dist/lib/daemon-maintenance.d.ts +275 -0
  202. package/dist/lib/daemon-maintenance.js +1035 -0
  203. package/dist/lib/dedicated-service.d.ts +3 -2
  204. package/dist/lib/dedicated-service.js +11 -3
  205. package/dist/lib/governed-store.d.ts +8 -0
  206. package/dist/lib/governed-store.js +5 -0
  207. package/dist/lib/hosted-machines.d.ts +33 -2
  208. package/dist/lib/hosted-machines.js +19 -1
  209. package/dist/lib/json-output.d.ts +1 -1
  210. package/dist/lib/machines.d.ts +9 -1
  211. package/dist/lib/machines.js +15 -1
  212. package/dist/lib/node-adapter.js +13 -0
  213. package/dist/lib/record-output.d.ts +22 -0
  214. package/dist/lib/record-output.js +78 -0
  215. package/dist/lib/roles.d.ts +3 -3
  216. package/dist/lib/scoped-memory-command.d.ts +18 -0
  217. package/dist/lib/scoped-memory-command.js +53 -2
  218. package/dist/lib/space-charter.d.ts +49 -0
  219. package/dist/lib/space-charter.js +78 -0
  220. package/dist/lib/space-loop-migration.d.ts +18 -0
  221. package/dist/lib/space-loop-migration.js +128 -0
  222. package/dist/lib/space-notebook.d.ts +22 -0
  223. package/dist/lib/space-notebook.js +140 -0
  224. package/dist/lib/space-proposal-decision-command.d.ts +36 -0
  225. package/dist/lib/space-proposal-decision-command.js +108 -0
  226. package/dist/lib/space-proposals.d.ts +44 -0
  227. package/dist/lib/space-proposals.js +186 -0
  228. package/dist/lib/space-templates.d.ts +8 -0
  229. package/dist/lib/space-templates.js +17 -0
  230. package/dist/lib/space-write-policy.d.ts +24 -0
  231. package/dist/lib/space-write-policy.js +103 -0
  232. package/dist/lib/task-agent-context-capabilities.d.ts +10 -0
  233. package/dist/lib/task-agent-context-capabilities.js +22 -0
  234. package/dist/lib/task-agent-context-compatibility.d.ts +9 -0
  235. package/dist/lib/task-agent-context-compatibility.js +30 -0
  236. package/dist/lib/task-asset-upload.d.ts +22 -0
  237. package/dist/lib/task-asset-upload.js +257 -29
  238. package/dist/lib/task-batch.d.ts +15 -1
  239. package/dist/lib/task-batch.js +35 -2
  240. package/dist/lib/task-operation-watch.d.ts +66 -0
  241. package/dist/lib/task-operation-watch.js +159 -0
  242. package/dist/lib/task-resolver.d.ts +1 -1
  243. package/dist/lib/task-resolver.js +4 -3
  244. package/dist/lib/task-work.d.ts +1 -1
  245. package/dist/lib/task-work.js +35 -1
  246. package/dist/lib/task-write-attribution.d.ts +14 -0
  247. package/dist/lib/task-write-attribution.js +35 -2
  248. package/dist/lib/triggers.d.ts +11 -0
  249. package/dist/lib/triggers.js +7 -0
  250. package/dist/lib/wiki-update.d.ts +1 -0
  251. package/dist/lib/wiki-update.js +10 -1
  252. package/dist/lib/wiki.js +4 -1
  253. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.d.ts +9 -1
  254. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.js +31 -15
  255. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonToolApproval.js +1 -0
  256. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonWire.js +13 -7
  257. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/guidedUpdate.d.ts +370 -0
  258. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/guidedUpdate.js +315 -0
  259. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/maintenanceReportWire.d.ts +178 -0
  260. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/maintenanceReportWire.js +262 -0
  261. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/toolApprovalSignature.d.ts +51 -0
  262. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/toolApprovalSignature.js +106 -0
  263. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.d.ts +9 -1
  264. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.js +32 -5
  265. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonToolApproval.js +1 -0
  266. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonWire.js +33 -14
  267. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/guidedUpdate.d.ts +370 -0
  268. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/guidedUpdate.js +404 -0
  269. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/maintenanceReportWire.d.ts +178 -0
  270. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/maintenanceReportWire.js +342 -0
  271. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/toolApprovalSignature.d.ts +51 -0
  272. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/toolApprovalSignature.js +138 -0
  273. package/dist/node_modules/@skrr-ai/auth-core/package.json +20 -0
  274. package/dist/node_modules/@skrr-ai/data-provider/index.js +27085 -20250
  275. package/oclif.manifest.json +10566 -7247
  276. package/package.json +20 -2
@@ -252,8 +252,9 @@ export interface DedicatedServiceSocketOptions {
252
252
  export type ServiceVerb = 'list' | 'get' | 'create' | 'update' | 'action' | 'logs' | 'logs:stop' | 'approve' | 'secret' | 'exec';
253
253
  /**
254
254
  * One admitted socket for a run of service verbs. `call` emits
255
- * `dedicated:service:<verb>` with a fresh requestId and resolves on the
256
- * matching `dedicated:service:ack`; push events (`state`, `log`,
255
+ * `dedicated:service:<verb>` with a requestId and resolves on the matching
256
+ * `dedicated:service:ack`; callers normally get a fresh id, while service
257
+ * exec may provide its durable idempotency key. Push events (`state`, `log`,
257
258
  * `log:closed`, `proposed`) are exposed via `on` for the follow loop.
258
259
  */
259
260
  export declare class DedicatedServiceChannel {
@@ -122,6 +122,7 @@ exports.DedicatedServiceError = DedicatedServiceError;
122
122
  function isServiceUnsupportedCode(code) {
123
123
  const c = (code || '').toLowerCase();
124
124
  return (c === 'dedicated_runtime_services_unsupported' ||
125
+ c === 'dedicated_runtime_service_exec_receipts_unsupported' ||
125
126
  c === 'dedicated_runtime_terminal_unsupported' ||
126
127
  c === 'services_unsupported' ||
127
128
  c === 'unsupported' ||
@@ -432,8 +433,9 @@ function socketOptions(token, wsOrigin) {
432
433
  }
433
434
  /**
434
435
  * One admitted socket for a run of service verbs. `call` emits
435
- * `dedicated:service:<verb>` with a fresh requestId and resolves on the
436
- * matching `dedicated:service:ack`; push events (`state`, `log`,
436
+ * `dedicated:service:<verb>` with a requestId and resolves on the matching
437
+ * `dedicated:service:ack`; callers normally get a fresh id, while service
438
+ * exec may provide its durable idempotency key. Push events (`state`, `log`,
437
439
  * `log:closed`, `proposed`) are exposed via `on` for the follow loop.
438
440
  */
439
441
  class DedicatedServiceChannel {
@@ -539,7 +541,13 @@ class DedicatedServiceChannel {
539
541
  }
540
542
  /** The shared request/ack round-trip. */
541
543
  callEvent(event, ackEvent, payload, context, timeoutMs, describe = describeServiceRefusal) {
542
- const requestId = `svc-${(0, node_crypto_1.randomUUID)()}`;
544
+ // `service exec` deliberately supplies its durable request id so a lost
545
+ // socket response can be inspected or replayed without a second effect.
546
+ // Other verbs retain their historical per-call id generation.
547
+ const supplied = payload.requestId;
548
+ const requestId = typeof supplied === 'string' && /^[A-Za-z0-9_.:-]{1,128}$/.test(supplied)
549
+ ? supplied
550
+ : `svc-${(0, node_crypto_1.randomUUID)()}`;
543
551
  return new Promise((resolve, reject) => {
544
552
  if (this.dead) {
545
553
  reject(new DedicatedServiceError('The connection to skrr is closed.', 'disconnected'));
@@ -65,6 +65,14 @@ export declare function resolveGovernedStoreInstallPlan(body: {
65
65
  /** `POST /admin/releases` — publish one artifact release. Admin. */
66
66
  export declare function publishGovernedStoreRelease(body: Record<string, unknown>): Promise<{
67
67
  release: unknown;
68
+ releaseId?: string;
69
+ execution?: unknown;
70
+ }>;
71
+ /** Read the immutable governed-release receipt before retrying a lost response. */
72
+ export declare function getGovernedStoreReleaseReceipt(releaseId: string): Promise<{
73
+ release: unknown;
74
+ releaseId: string;
75
+ execution: unknown;
68
76
  }>;
69
77
  /** `POST /admin/licenses` — mint a bundle license against an acquisition. Admin. */
70
78
  export declare function createGovernedStoreLicense(body: Record<string, unknown>): Promise<{
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.searchGovernedStoreArtifacts = searchGovernedStoreArtifacts;
4
4
  exports.resolveGovernedStoreInstallPlan = resolveGovernedStoreInstallPlan;
5
5
  exports.publishGovernedStoreRelease = publishGovernedStoreRelease;
6
+ exports.getGovernedStoreReleaseReceipt = getGovernedStoreReleaseReceipt;
6
7
  exports.createGovernedStoreLicense = createGovernedStoreLicense;
7
8
  exports.updateOwnLicensePolicy = updateOwnLicensePolicy;
8
9
  exports.updateWorkspaceLicensePolicy = updateWorkspaceLicensePolicy;
@@ -46,6 +47,10 @@ async function publishGovernedStoreRelease(body) {
46
47
  body,
47
48
  });
48
49
  }
50
+ /** Read the immutable governed-release receipt before retrying a lost response. */
51
+ async function getGovernedStoreReleaseReceipt(releaseId) {
52
+ return (0, api_fetch_1.apiFetch)(`/api/store/governance/admin/releases/${encodeURIComponent(releaseId)}/receipt`);
53
+ }
49
54
  /** `POST /admin/licenses` — mint a bundle license against an acquisition. Admin. */
50
55
  async function createGovernedStoreLicense(body) {
51
56
  return (0, api_fetch_1.apiFetch)('/api/store/governance/admin/licenses', {
@@ -44,6 +44,26 @@ export interface HostedMachineSession {
44
44
  }
45
45
  export interface HostedMachineResponse {
46
46
  session?: HostedMachineSession;
47
+ operation?: HostedMachineOperation;
48
+ replayed?: boolean;
49
+ }
50
+ /** A durable request receipt, deliberately separate from the machine state. */
51
+ export interface HostedMachineOperation {
52
+ id: string;
53
+ action: 'start' | 'execute' | 'destroy';
54
+ state: 'accepted' | 'started' | 'completed' | 'failed' | 'unknown';
55
+ acceptedAt?: string | null;
56
+ startedAt?: string | null;
57
+ completedAt?: string | null;
58
+ sessionId?: string;
59
+ result?: Record<string, unknown>;
60
+ error?: {
61
+ code?: string;
62
+ message?: string;
63
+ };
64
+ }
65
+ export interface HostedMachineOperationResponse {
66
+ operation: HostedMachineOperation;
47
67
  }
48
68
  export interface HostedMachineListResponse {
49
69
  data?: HostedMachineSession[];
@@ -77,6 +97,8 @@ export interface HostedMachineExecResponse {
77
97
  executionTime?: number;
78
98
  previewUrl?: string | null;
79
99
  session?: HostedMachineSession;
100
+ operation?: HostedMachineOperation;
101
+ replayed?: boolean;
80
102
  }
81
103
  /**
82
104
  * The curated `machines hosted exec --json` shape (OSK-4870).
@@ -98,6 +120,9 @@ export interface HostedMachineExecJson {
98
120
  id: string;
99
121
  status: string;
100
122
  };
123
+ /** Additive durable receipt metadata for safely recovering a lost response. */
124
+ operation?: HostedMachineOperation;
125
+ replayed?: boolean;
101
126
  }
102
127
  export declare function curateHostedMachineExecResult(response: HostedMachineExecResponse): HostedMachineExecJson;
103
128
  export interface HostedMachineScope {
@@ -155,8 +180,14 @@ export declare function getHostedMachine(id: string, scope?: HostedMachineScope)
155
180
  export declare function attachHostedMachineRepo(id: string, input: AttachHostedMachineRepoInput, scope?: HostedMachineScope): Promise<HostedMachineResponse>;
156
181
  export declare function pauseHostedMachine(id: string, scope?: HostedMachineScope): Promise<HostedMachineResponse>;
157
182
  export declare function resumeHostedMachine(id: string, scope?: HostedMachineScope): Promise<HostedMachineResponse>;
158
- export declare function destroyHostedMachine(id: string, scope?: HostedMachineScope): Promise<HostedMachineResponse>;
159
- export declare function execHostedMachine(id: string, input: HostedMachineExecInput, scope?: HostedMachineScope): Promise<HostedMachineExecResponse>;
183
+ export declare function destroyHostedMachine(id: string, scope?: HostedMachineScope & {
184
+ requestId?: string;
185
+ }): Promise<HostedMachineResponse>;
186
+ export declare function execHostedMachine(id: string, input: HostedMachineExecInput, scope?: HostedMachineScope & {
187
+ requestId?: string;
188
+ }): Promise<HostedMachineExecResponse>;
189
+ /** Read a durable operation receipt without touching the machine or provider. */
190
+ export declare function getHostedMachineOperation(operationId: string, scope?: HostedMachineScope): Promise<HostedMachineOperationResponse>;
160
191
  /**
161
192
  * The CLI gave up watching. The RUNTIME did not give up.
162
193
  *
@@ -23,6 +23,7 @@ exports.pauseHostedMachine = pauseHostedMachine;
23
23
  exports.resumeHostedMachine = resumeHostedMachine;
24
24
  exports.destroyHostedMachine = destroyHostedMachine;
25
25
  exports.execHostedMachine = execHostedMachine;
26
+ exports.getHostedMachineOperation = getHostedMachineOperation;
26
27
  exports.waitForHostedMachineReady = waitForHostedMachineReady;
27
28
  exports.offlineForLabel = offlineForLabel;
28
29
  const api_fetch_1 = require("./api-fetch");
@@ -77,6 +78,10 @@ function curateHostedMachineExecResult(response) {
77
78
  status: hostedMachineStatus(response.session),
78
79
  };
79
80
  }
81
+ if (response.operation)
82
+ out.operation = response.operation;
83
+ if (response.replayed)
84
+ out.replayed = true;
80
85
  return out;
81
86
  }
82
87
  function hostedMachineId(session) {
@@ -201,6 +206,10 @@ async function startHostedMachine(input) {
201
206
  return (0, api_fetch_1.apiFetch)('/api/agentic/sandbox-sessions', {
202
207
  method: 'POST',
203
208
  body: input,
209
+ // apiFetch normally creates a fresh key for each invocation. The key
210
+ // generated (or supplied) by `machines hosted start` instead names this
211
+ // exact operation across a process restart and a lost response.
212
+ headers: { 'Idempotency-Key': input.clientRequestId },
204
213
  });
205
214
  }
206
215
  async function listHostedMachines(scope = {}) {
@@ -228,14 +237,23 @@ async function resumeHostedMachine(id, scope = {}) {
228
237
  async function destroyHostedMachine(id, scope = {}) {
229
238
  return (0, api_fetch_1.apiFetch)(hostedMachinePath(`/${encodeURIComponent(id)}`, scope), {
230
239
  method: 'DELETE',
240
+ ...(scope.requestId ? { headers: { 'Idempotency-Key': scope.requestId } } : {}),
231
241
  });
232
242
  }
233
243
  async function execHostedMachine(id, input, scope = {}) {
234
244
  return (0, api_fetch_1.apiFetch)(hostedMachinePath(`/${encodeURIComponent(id)}/execute`, scope), {
235
245
  method: 'POST',
236
- body: input,
246
+ body: {
247
+ ...input,
248
+ ...(scope.requestId ? { clientRequestId: scope.requestId } : {}),
249
+ },
250
+ ...(scope.requestId ? { headers: { 'Idempotency-Key': scope.requestId } } : {}),
237
251
  });
238
252
  }
253
+ /** Read a durable operation receipt without touching the machine or provider. */
254
+ async function getHostedMachineOperation(operationId, scope = {}) {
255
+ return (0, api_fetch_1.apiFetch)(`/api/agentic/sandbox-sessions/operations/${encodeURIComponent(operationId)}${scope.workspaceId ? `?workspaceId=${encodeURIComponent(scope.workspaceId)}` : ''}`);
256
+ }
239
257
  /**
240
258
  * The CLI gave up watching. The RUNTIME did not give up.
241
259
  *
@@ -53,7 +53,7 @@ export declare function stripStorageFieldsFromText(text: string): string;
53
53
  export declare function withOk<T>(value: T, ok?: boolean): T | ({
54
54
  ok: boolean;
55
55
  } & Record<string, unknown>);
56
- export type CliOperationMode = 'execute' | 'dry_run' | 'verify';
56
+ export type CliOperationMode = 'execute' | 'dry_run' | 'read' | 'verify';
57
57
  export type CliWriteState = 'confirmed' | 'not_attempted' | 'unknown';
58
58
  export type CliResourceIdentity = {
59
59
  kind: string;
@@ -1,4 +1,4 @@
1
- import type { DaemonContactState } from '@skrr-ai/data-provider';
1
+ import type { DaemonContactState, DaemonMaintenanceSummary } from '@skrr-ai/data-provider';
2
2
  /**
3
3
  * machines.ts — request client for `/api/machines`.
4
4
  *
@@ -220,6 +220,14 @@ export interface MachineDaemonSummary {
220
220
  supersededCount: number;
221
221
  /** The profile this CLI is running as. */
222
222
  activeProfile: boolean;
223
+ /**
224
+ * The key a maintenance hold addresses this daemon by (`skrr daemon maintenance`),
225
+ * read from the server's own `daemons` list (D25). Absent on a server older than that
226
+ * list, on a managed machine, and on a daemon with no stable identity.
227
+ */
228
+ runtimeKey?: string;
229
+ /** Present only while this daemon is held. See `DaemonMaintenanceSummary`. */
230
+ maintenance?: DaemonMaintenanceSummary;
223
231
  }
224
232
  export declare function parseDaemonId(daemonId: string): {
225
233
  source: string;
@@ -207,10 +207,24 @@ function machineListView(machine, options) {
207
207
  ? daemons
208
208
  : daemons.filter((daemon) => daemon.harnessCount > daemon.supersededCount);
209
209
  const hidden = rows.length - visibleRows.length;
210
+ // The server's own `daemons` (one per runtimeKey, D25) carries the key a hold is
211
+ // addressed by, and this view REPLACES that list with one per daemon id, so it
212
+ // would drop the key. Carried over by daemon id, and only when the server sent one.
213
+ const serverDaemons = machine.daemons ?? [];
214
+ const keyedDaemons = visibleDaemons.map((daemon) => {
215
+ const named = serverDaemons.find((candidate) => candidate.daemonId === daemon.daemonId);
216
+ if (!named?.runtimeKey)
217
+ return daemon;
218
+ return {
219
+ ...daemon,
220
+ runtimeKey: named.runtimeKey,
221
+ ...(named.maintenance ? { maintenance: named.maintenance } : {}),
222
+ };
223
+ });
210
224
  return {
211
225
  ...machine,
212
226
  thisComputer: isThisComputer(machine, options.hardwareMachineUuid),
213
- daemons: visibleDaemons,
227
+ daemons: keyedDaemons,
214
228
  harnesses: visibleRows,
215
229
  ...(hidden > 0 ? { hiddenHarnessCount: hidden } : {}),
216
230
  };
@@ -98,10 +98,23 @@ function createNodeAdapter(opts = {}) {
98
98
  // the exact attempt session before stamping Commitment provenance.
99
99
  const autonomousRunId = process.env.OVERSKY_AUTONOMOUS_RUN_ID?.trim();
100
100
  const sessionId = process.env.OVERSKY_SESSION_ID?.trim();
101
+ // The same pair for a Task run the AgentWorker executes (OSK-18132). It has
102
+ // no AutonomousRun, so the server names its TaskExecutionRun instead, and
103
+ // the wiki verifies that Run against this session before crediting the
104
+ // agent. A separate header pair, and only when there is no autonomous one:
105
+ // routes that read the session header above treat it as the
106
+ // AutonomousRun's attempt session and refuse it without a Run id beside
107
+ // it. Brand-free like the rest of the public contract (OSK-18267); the
108
+ // server names the pair once, in TaskExecutionRun/sessionRunBinding.js.
109
+ const taskRunId = process.env.OVERSKY_SESSION_TASK_RUN_ID?.trim();
101
110
  if (autonomousRunId && sessionId) {
102
111
  headers['X-Oversky-Autonomous-Run-Id'] = autonomousRunId;
103
112
  headers['X-Oversky-Session-Id'] = sessionId;
104
113
  }
114
+ else if (taskRunId && sessionId) {
115
+ headers['X-Task-Run-Id'] = taskRunId;
116
+ headers['X-Task-Run-Session-Id'] = sessionId;
117
+ }
105
118
  // Which agent this process is running AS, for attribution only — it is
106
119
  // what lets a task record `createdByAgentId` instead of overloading the
107
120
  // assignee list to remember that an agent filed it. Same contract as the
@@ -0,0 +1,22 @@
1
+ export declare const COMPACT_RECORD_FIELDS: {
2
+ readonly task: readonly ["id", "identifier", "ref", "title", "status", "statusType", "priority", "parentId", "spaceId", "projectId", "goalId", "assigneeAgentIds", "assigneeUserIds", "dri", "executionMode", "actionability", "execution", "completion", "currentResultId", "createdAt", "updatedAt", "completedAt", "url"];
3
+ };
4
+ export type RecordResource = keyof typeof COMPACT_RECORD_FIELDS;
5
+ /** JSON-only projection flags for detail reads. */
6
+ export declare const recordOutputFlags: {
7
+ fields: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ compact: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ };
10
+ export type RecordOutputFlags = {
11
+ fields?: string;
12
+ compact?: boolean;
13
+ };
14
+ /**
15
+ * Shape an already-normalized record. `--fields` is an explicit caller
16
+ * selection and therefore wins over `--compact`; no envelope is introduced.
17
+ */
18
+ export declare function shapeRecordResponse(response: unknown, { resource, fields, compact }: RecordOutputFlags & {
19
+ resource: RecordResource;
20
+ }): unknown;
21
+ /** Explain that projection flags are intentionally JSON-only on a detail read. */
22
+ export declare function textModeRecordProjectionNotes(flags: RecordOutputFlags): string[];
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.recordOutputFlags = exports.COMPACT_RECORD_FIELDS = void 0;
4
+ exports.shapeRecordResponse = shapeRecordResponse;
5
+ exports.textModeRecordProjectionNotes = textModeRecordProjectionNotes;
6
+ /**
7
+ * JSON projection for one record, deliberately separate from list output.
8
+ *
9
+ * A list has paging and an envelope; a detail read is one canonical document.
10
+ * Sharing the field selector is useful, but wrapping a detail in `{data:[...]}`
11
+ * merely to reuse list mechanics would give callers two incompatible meanings
12
+ * for the same command. This module owns the record-shaped contract instead.
13
+ */
14
+ const core_1 = require("@oclif/core");
15
+ const list_output_1 = require("./list-output");
16
+ exports.COMPACT_RECORD_FIELDS = {
17
+ task: [
18
+ 'id',
19
+ 'identifier',
20
+ 'ref',
21
+ 'title',
22
+ 'status',
23
+ 'statusType',
24
+ 'priority',
25
+ 'parentId',
26
+ 'spaceId',
27
+ 'projectId',
28
+ 'goalId',
29
+ 'assigneeAgentIds',
30
+ 'assigneeUserIds',
31
+ 'dri',
32
+ 'executionMode',
33
+ 'actionability',
34
+ 'execution',
35
+ 'completion',
36
+ 'currentResultId',
37
+ 'createdAt',
38
+ 'updatedAt',
39
+ 'completedAt',
40
+ 'url',
41
+ ],
42
+ };
43
+ /** JSON-only projection flags for detail reads. */
44
+ exports.recordOutputFlags = {
45
+ fields: core_1.Flags.string({
46
+ description: 'JSON only: comma-separated fields to keep on this record (dotted paths allowed, e.g. id,title,actionability.reason). Wins over --compact.',
47
+ }),
48
+ compact: core_1.Flags.boolean({
49
+ description: 'JSON only: keep the task detail navigation and state fields, omitting description, activity, lifecycle, and other bulk. See docs/cli/SKRR_TASKS.md (Task detail output for agents).',
50
+ }),
51
+ };
52
+ /**
53
+ * Shape an already-normalized record. `--fields` is an explicit caller
54
+ * selection and therefore wins over `--compact`; no envelope is introduced.
55
+ */
56
+ function shapeRecordResponse(response, { resource, fields, compact }) {
57
+ if (!response || typeof response !== 'object' || Array.isArray(response))
58
+ return response;
59
+ const record = response;
60
+ const selected = (0, list_output_1.parseFields)(fields);
61
+ if (selected)
62
+ return (0, list_output_1.projectRow)(record, selected);
63
+ if (!compact)
64
+ return record;
65
+ const compacted = (0, list_output_1.projectRow)(record, exports.COMPACT_RECORD_FIELDS[resource]);
66
+ // Do not turn a future/unknown detail response into an empty object: preserving
67
+ // it is safer than hiding the only information a caller received.
68
+ return Object.keys(compacted).length > 0 ? compacted : record;
69
+ }
70
+ /** Explain that projection flags are intentionally JSON-only on a detail read. */
71
+ function textModeRecordProjectionNotes(flags) {
72
+ const given = [flags.fields ? '--fields' : null, flags.compact ? '--compact' : null].filter(Boolean);
73
+ if (given.length === 0)
74
+ return [];
75
+ return [
76
+ `Note: ${given.join(' and ')} ${given.length > 1 ? 'shape' : 'shapes'} JSON output only; the detail view is unchanged. Add --json to apply ${given.length > 1 ? 'them' : 'it'}.`,
77
+ ];
78
+ }
@@ -53,7 +53,7 @@ export declare const roleApi: {
53
53
  config?: Record<string, unknown> | undefined;
54
54
  }[];
55
55
  sources: {
56
- source: "space" | "tasks" | "memory" | "email" | "goal" | "files" | "local" | "daemon" | "browser" | "conversations" | "slack" | "github" | "messages" | "calendar" | "docs" | "metrics" | "agent_run" | "agent_initiatives" | "documents" | "product_metrics" | "business_metrics" | "state_monitor" | "monitor";
56
+ source: "space" | "tasks" | "memory" | "daemon" | "email" | "goal" | "files" | "local" | "browser" | "conversations" | "slack" | "github" | "messages" | "calendar" | "agent_run" | "docs" | "metrics" | "agent_initiatives" | "documents" | "product_metrics" | "business_metrics" | "state_monitor" | "monitor";
57
57
  enabled: boolean;
58
58
  config?: Record<string, unknown> | undefined;
59
59
  }[];
@@ -135,7 +135,7 @@ export declare const roleApi: {
135
135
  text: string;
136
136
  effect: "append";
137
137
  id: string;
138
- status: "active" | "proposed" | "retired";
138
+ status: "active" | "retired" | "proposed";
139
139
  reason?: string | undefined;
140
140
  source?: {
141
141
  kind: "owner" | "role_spec" | "correction";
@@ -151,7 +151,7 @@ export declare const roleApi: {
151
151
  phrases: string[];
152
152
  effect: "refuse" | "require_approval";
153
153
  id: string;
154
- status: "active" | "proposed" | "retired";
154
+ status: "active" | "retired" | "proposed";
155
155
  reason?: string | undefined;
156
156
  source?: {
157
157
  kind: "owner" | "role_spec" | "correction";
@@ -12,6 +12,24 @@ export type MemoryStoreResolution = {
12
12
  };
13
13
  export declare function parseMemoryStoreResolutions(value: unknown): MemoryStoreResolution[] | undefined;
14
14
  export declare function memoryStoreResolutionLines(resolutions?: MemoryStoreResolution[]): string[];
15
+ /**
16
+ * A Space on a command is context for the request; it is not evidence that
17
+ * this session mounted the Space's Memory Store. Keeping that distinction in
18
+ * one diagnostic prevents every Memory verb from inventing a different (and
19
+ * often unsafe) recovery path.
20
+ *
21
+ * `stores` has already passed the server's mount visibility check. We expose
22
+ * only those scopes, never a guessed Store or an inaccessible Space.
23
+ */
24
+ export declare function memoryNotMountedDiagnostic({ requestedScope, agentId, spaceId, stores, }: {
25
+ requestedScope: string;
26
+ agentId: string;
27
+ spaceId?: string;
28
+ stores: MemoryStore[];
29
+ }): {
30
+ message: string;
31
+ details: Record<string, unknown>;
32
+ };
15
33
  export declare function parseMemoryMount(value: unknown): MemoryMount;
16
34
  export declare function parseMountedMemoryStore(value: unknown): MemoryStore;
17
35
  export declare const scopedMemoryFlags: {
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ScopedMemoryCommand = exports.versionedMutationFlags = exports.mutationFlags = exports.scopedMemoryFlags = void 0;
4
4
  exports.parseMemoryStoreResolutions = parseMemoryStoreResolutions;
5
5
  exports.memoryStoreResolutionLines = memoryStoreResolutionLines;
6
+ exports.memoryNotMountedDiagnostic = memoryNotMountedDiagnostic;
6
7
  exports.parseMemoryMount = parseMemoryMount;
7
8
  exports.parseMountedMemoryStore = parseMountedMemoryStore;
8
9
  exports.parseMemoryApiError = parseMemoryApiError;
@@ -45,6 +46,43 @@ function memoryStoreResolutionLines(resolutions) {
45
46
  };
46
47
  return resolutions.map((resolution) => `${labels[resolution.outcome]}: ${resolution.storeId}`);
47
48
  }
49
+ /**
50
+ * A Space on a command is context for the request; it is not evidence that
51
+ * this session mounted the Space's Memory Store. Keeping that distinction in
52
+ * one diagnostic prevents every Memory verb from inventing a different (and
53
+ * often unsafe) recovery path.
54
+ *
55
+ * `stores` has already passed the server's mount visibility check. We expose
56
+ * only those scopes, never a guessed Store or an inaccessible Space.
57
+ */
58
+ function memoryNotMountedDiagnostic({ requestedScope, agentId, spaceId, stores, }) {
59
+ const availableScopes = [...new Set(stores.map((store) => `${store.owner.kind}:${store.owner.id}`))].sort();
60
+ const agentScope = `agent:${agentId}`;
61
+ const writableAgentStore = stores.some((store) => store.owner.kind === 'agent' &&
62
+ store.owner.id === agentId &&
63
+ store.mount.access === 'read_write');
64
+ const requestedSpaceId = requestedScope.startsWith('space:')
65
+ ? requestedScope.slice('space:'.length)
66
+ : undefined;
67
+ const resolve = `skrr memory mounts resolve --agent ${agentId}${spaceId ? ` --space ${spaceId}` : requestedSpaceId ? ` --space ${requestedSpaceId}` : ''} --json`;
68
+ const remedy = [
69
+ `Run \`${resolve}\` and select a writable mounted Store.`,
70
+ writableAgentStore
71
+ ? `To file Agent-owned Memory, retry with \`--scope ${agentScope}\`; Task or Space placement does not change that ownership.`
72
+ : 'A Space Store can be selected only after the session has mounted it; do not infer a mount from `--space` alone.',
73
+ ].join(' ');
74
+ return {
75
+ message: `MEMORY_NOT_MOUNTED: ${requestedScope} is not mounted for this session. ` +
76
+ '`--space` selects request context; it does not mount Space Memory. ' +
77
+ `→ ${remedy}`,
78
+ details: {
79
+ requestedScope,
80
+ ...(spaceId ? { spaceContext: spaceId } : {}),
81
+ availableScopes,
82
+ remedy,
83
+ },
84
+ };
85
+ }
48
86
  // The public CLI must not load the private data-schemas package at runtime.
49
87
  // The API validates the full wire contract; check the fields used by CLI commands
50
88
  // before treating a response as a mounted Store or mount.
@@ -236,8 +274,21 @@ class ScopedMemoryCommand extends base_command_1.BaseCommand {
236
274
  const response = await this.memoryApi(flags.agent, `/stores${this.query(flags)}`);
237
275
  const stores = response.stores.map(parseMountedMemoryStore);
238
276
  const store = stores.find((candidate) => candidate.owner.kind === kind && candidate.owner.id === id);
239
- if (!store)
240
- this.error(`MEMORY_NOT_MOUNTED: ${flags.scope}`, { exit: 5 });
277
+ if (!store) {
278
+ const diagnostic = memoryNotMountedDiagnostic({
279
+ requestedScope: flags.scope,
280
+ agentId: flags.agent,
281
+ spaceId: flags.space,
282
+ stores,
283
+ });
284
+ this.failWithCliError({
285
+ message: diagnostic.message,
286
+ code: 'MEMORY_NOT_MOUNTED',
287
+ exit: 5,
288
+ retryable: false,
289
+ details: diagnostic.details,
290
+ });
291
+ }
241
292
  if (write && store.mount?.access !== 'read_write') {
242
293
  this.error('MEMORY_STORE_READ_ONLY: selected Store is read-only', { exit: 5 });
243
294
  }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Shared helpers for `skrr spaces charter …` and the wiki commands that can
3
+ * meet the one-charter rule (OSK-17985).
4
+ *
5
+ * A Space's charter is its one live `kind: 'charter'` wiki page. Its LEAD
6
+ * SECTION — everything before the first `##` heading — is what every agent
7
+ * turn in the Space receives; the rest is read on demand. The server computes
8
+ * the lead (`leadSection` on the charter read) with the same function the
9
+ * Space context builder uses, so these helpers print it rather than
10
+ * re-deriving it.
11
+ */
12
+ import type { WikiCharterPage } from '@skrr-ai/data-provider';
13
+ export type CharterConflictHint = {
14
+ message: string;
15
+ details: {
16
+ pageId?: string;
17
+ path?: string;
18
+ };
19
+ };
20
+ /**
21
+ * A `409 WIKI_CHARTER_EXISTS` turned into a message that names the charter
22
+ * already there and the command that frees the slot. `undefined` for anything
23
+ * else, so the caller falls through to its ordinary error handling.
24
+ */
25
+ export declare function charterConflictHint(err: unknown, { binName, spaceId }: {
26
+ binName: string;
27
+ spaceId: string;
28
+ }): CharterConflictHint | undefined;
29
+ /**
30
+ * The lines `charter show` prints: where the charter is, then its lead section
31
+ * marked as what every agent reads, then either the whole page (`full`) or the
32
+ * command that reads it.
33
+ *
34
+ * An EMPTY lead is said in words, because it is the one charter state that
35
+ * changes what agents see without anything looking wrong: a page that opens
36
+ * with a `##` heading gives them no charter lead at all.
37
+ */
38
+ export declare function charterLines(charter: WikiCharterPage & {
39
+ url?: string | null;
40
+ }, { binName, spaceId, full }: {
41
+ binName: string;
42
+ spaceId: string;
43
+ full?: boolean;
44
+ }): string[];
45
+ /** What `charter show` prints for a Space that has no charter page yet. */
46
+ export declare function noCharterLines({ binName, spaceId, }: {
47
+ binName: string;
48
+ spaceId: string;
49
+ }): string[];
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.charterConflictHint = charterConflictHint;
4
+ exports.charterLines = charterLines;
5
+ exports.noCharterLines = noCharterLines;
6
+ const http_error_1 = require("./http-error");
7
+ /**
8
+ * A `409 WIKI_CHARTER_EXISTS` turned into a message that names the charter
9
+ * already there and the command that frees the slot. `undefined` for anything
10
+ * else, so the caller falls through to its ordinary error handling.
11
+ */
12
+ function charterConflictHint(err, { binName, spaceId }) {
13
+ if (!(0, http_error_1.hasHttpStatus)(err, 409))
14
+ return undefined;
15
+ const body = (0, http_error_1.httpBodyOf)(err);
16
+ if (body?.code !== 'WIKI_CHARTER_EXISTS')
17
+ return undefined;
18
+ const pageId = typeof body.pageId === 'string' && body.pageId ? body.pageId : undefined;
19
+ const path = typeof body.path === 'string' && body.path ? body.path : undefined;
20
+ let where = 'another page';
21
+ if (path)
22
+ where = `'${path}'`;
23
+ else if (pageId)
24
+ where = `page ${pageId}`;
25
+ return {
26
+ message: `This Space already has a charter page: ${where}. A Space holds at most one live charter. ` +
27
+ `Change that page to another kind first (\`${binName} wiki update ${spaceId} ${path ?? '<path>'} ` +
28
+ `--kind doc\`) or archive it, then try again. Show it with \`${binName} spaces charter show ${spaceId}\`.`,
29
+ details: { ...(pageId ? { pageId } : {}), ...(path ? { path } : {}) },
30
+ };
31
+ }
32
+ /**
33
+ * The lines `charter show` prints: where the charter is, then its lead section
34
+ * marked as what every agent reads, then either the whole page (`full`) or the
35
+ * command that reads it.
36
+ *
37
+ * An EMPTY lead is said in words, because it is the one charter state that
38
+ * changes what agents see without anything looking wrong: a page that opens
39
+ * with a `##` heading gives them no charter lead at all.
40
+ */
41
+ function charterLines(charter, { binName, spaceId, full = false }) {
42
+ const path = charter.path ?? charter.slug;
43
+ const lines = [`Charter: ${path} (${charter.pageId})`];
44
+ if (charter.title && charter.title !== path)
45
+ lines.push(`Title: ${charter.title}`);
46
+ if (charter.url)
47
+ lines.push(`URL: ${charter.url}`);
48
+ lines.push('');
49
+ lines.push('Lead section (everything before the first ## heading; read by every agent in this Space):');
50
+ const lead = typeof charter.leadSection === 'string' ? charter.leadSection : '';
51
+ if (lead) {
52
+ for (const line of lead.split('\n'))
53
+ lines.push(` ${line}`);
54
+ }
55
+ else {
56
+ lines.push(' (empty: the page opens with a ## heading, so agents receive no charter lead. ' +
57
+ 'Put the essentials before the first ## heading.)');
58
+ }
59
+ lines.push('');
60
+ if (full) {
61
+ lines.push('Full page:');
62
+ for (const line of String(charter.content ?? '').split('\n'))
63
+ lines.push(` ${line}`);
64
+ }
65
+ else {
66
+ lines.push(`The rest of the page is read on demand: \`${binName} spaces charter show ${spaceId} --full\` ` +
67
+ `or \`${binName} wiki cat ${spaceId} ${path}\`.`);
68
+ }
69
+ return lines;
70
+ }
71
+ /** What `charter show` prints for a Space that has no charter page yet. */
72
+ function noCharterLines({ binName, spaceId, }) {
73
+ return [
74
+ 'This Space has no charter page yet.',
75
+ `Create one from the Space description: \`${binName} spaces charter create-from-description ${spaceId}\``,
76
+ `Or make an existing page the charter: \`${binName} wiki update ${spaceId} <path> --kind charter\``,
77
+ ];
78
+ }