@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
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatAuthor = formatAuthor;
4
+ exports.buildHistoryRows = buildHistoryRows;
5
+ const core_1 = require("@oclif/core");
6
+ const data_provider_1 = require("@skrr-ai/data-provider");
7
+ const base_command_1 = require("../../base-command");
8
+ const format_1 = require("../../lib/format");
9
+ /**
10
+ * `agent <id>` for a write a verified Run proved; otherwise the person whose
11
+ * credential wrote it, with the channel it came through — so an agent working
12
+ * through a delegated CLI credential without Run proof reads as
13
+ * "person <id> (via delegated agent CLI credential)", never as a bare person.
14
+ */
15
+ function formatAuthor(author) {
16
+ if (!author)
17
+ return 'unknown';
18
+ if (author.kind === 'agent')
19
+ return `agent ${author.agentId ?? '?'}`;
20
+ const channel = author.via
21
+ ? (data_provider_1.CREDENTIAL_CHANNEL_LABELS[author.via] ?? author.via)
22
+ : null;
23
+ return channel ? `person ${author.userId} (via ${channel})` : `person ${author.userId}`;
24
+ }
25
+ function sameAuthor(a, b) {
26
+ return (a.kind === b.kind &&
27
+ a.userId === b.userId &&
28
+ a.agentId === b.agentId &&
29
+ a.runId === b.runId &&
30
+ a.via === b.via);
31
+ }
32
+ function buildHistoryRows(revisions) {
33
+ return revisions.map((revision) => {
34
+ const others = (revision.contributors ?? []).filter((contributor) => !revision.author || !sameAuthor(contributor, revision.author));
35
+ const source = revision.source === 'write'
36
+ ? `write${revision.mode ? `/${revision.mode}` : ''}`
37
+ : `editor${revision.open ? ' (open)' : ''}`;
38
+ return {
39
+ rev: String(revision.revisionNumber),
40
+ when: revision.capturedAt ?? revision.createdAt ?? '',
41
+ author: formatAuthor(revision.author),
42
+ also: others.map(formatAuthor).join(', '),
43
+ source,
44
+ chars: String(revision.chars ?? 0),
45
+ };
46
+ });
47
+ }
48
+ class WikiHistory extends base_command_1.BaseCommand {
49
+ static description = "Show a wiki page's revision history: each version, and whether a person or an agent wrote it";
50
+ static examples = [
51
+ '<%= config.bin %> wiki history <space-id> Engineering/Runbooks/deploy',
52
+ '<%= config.bin %> wiki history <space-id> Engineering/Runbooks/deploy --revision 3 > v3.md',
53
+ '<%= config.bin %> wiki history <space-id> --page-id <page-id> --json',
54
+ ];
55
+ static args = {
56
+ space: core_1.Args.string({ description: 'Space ID', required: true, ignoreStdin: true }),
57
+ path: core_1.Args.string({ description: 'Page path', required: false, ignoreStdin: true }),
58
+ };
59
+ static flags = {
60
+ json: core_1.Flags.boolean({ description: 'Output as JSON' }),
61
+ 'page-id': core_1.Flags.string({ description: 'Address the page by id instead of path' }),
62
+ limit: core_1.Flags.integer({ description: 'Revisions per page (max 100)', default: 20 }),
63
+ cursor: core_1.Flags.string({ description: 'Continue from a previous listing (its next_cursor)' }),
64
+ revision: core_1.Flags.integer({
65
+ description: 'Print one revision as Markdown instead of listing them',
66
+ min: 1,
67
+ }),
68
+ };
69
+ async run() {
70
+ this.requireAuth();
71
+ const { args, flags } = await this.parse(WikiHistory);
72
+ if (!args.path && !flags['page-id']) {
73
+ this.failWithCliError({
74
+ message: 'Provide a page path or --page-id.',
75
+ code: 'WIKI_PAGE_ADDRESS_REQUIRED',
76
+ exit: 1,
77
+ retryable: false,
78
+ });
79
+ }
80
+ const pageId = flags['page-id'];
81
+ const path = args.path;
82
+ if (flags.revision !== undefined) {
83
+ let revision;
84
+ try {
85
+ revision = pageId
86
+ ? await data_provider_1.dataService.getSpaceWikiPageRevision(args.space, pageId, flags.revision)
87
+ : await data_provider_1.dataService.getSpaceWikiRevisionByPath(args.space, path, flags.revision);
88
+ }
89
+ catch (err) {
90
+ this.handleApiError(err);
91
+ }
92
+ if (flags.json) {
93
+ this.printJsonResult(revision);
94
+ return;
95
+ }
96
+ // Body only, like `wiki cat`, so `> v3.md` produces a clean file.
97
+ this.log(revision.content ?? '');
98
+ return;
99
+ }
100
+ let response;
101
+ const paging = { limit: flags.limit, cursor: flags.cursor };
102
+ try {
103
+ response = pageId
104
+ ? await data_provider_1.dataService.getSpaceWikiPageHistory(args.space, pageId, paging)
105
+ : await data_provider_1.dataService.getSpaceWikiHistoryByPath(args.space, path, paging);
106
+ }
107
+ catch (err) {
108
+ this.handleApiError(err);
109
+ }
110
+ if (flags.json) {
111
+ this.printJsonResult(response);
112
+ return;
113
+ }
114
+ const revisions = response.data ?? [];
115
+ if (revisions.length === 0) {
116
+ // History starts with the first write recorded after it shipped; an
117
+ // older page has none until it is next edited.
118
+ this.log('No recorded revisions yet.');
119
+ return;
120
+ }
121
+ (0, format_1.renderTable)(buildHistoryRows(revisions), [
122
+ { key: 'rev', header: 'REV' },
123
+ { key: 'when', header: 'WHEN', maxWidth: 24 },
124
+ { key: 'author', header: 'AUTHOR', maxWidth: 60 },
125
+ { key: 'also', header: 'ALSO', maxWidth: 60 },
126
+ { key: 'source', header: 'SOURCE' },
127
+ { key: 'chars', header: 'CHARS' },
128
+ ], (line) => this.log(line));
129
+ if (response.has_more && response.next_cursor) {
130
+ this.log(`More: --cursor ${response.next_cursor}`);
131
+ }
132
+ }
133
+ }
134
+ exports.default = WikiHistory;
@@ -5,6 +5,8 @@ export type WikiLsRow = {
5
5
  kind: string;
6
6
  name: string;
7
7
  title: string;
8
+ /** A page's kind when it is not an ordinary `doc` page (`charter`, ...); '' otherwise. */
9
+ pageKind: string;
8
10
  updated: string;
9
11
  id: string;
10
12
  };
@@ -20,6 +20,7 @@ function buildRows(listing) {
20
20
  // title would just repeat it. The listing carries no folder timestamp, so
21
21
  // it has no date to show either.
22
22
  title: '',
23
+ pageKind: '',
23
24
  updated: '',
24
25
  id: f.folder_id,
25
26
  })),
@@ -32,6 +33,9 @@ function buildRows(listing) {
32
33
  // `tree` has always rendered `slug [title]`; `ls` simply had no column
33
34
  // for it, though `--json` carried it all along.
34
35
  title: p.title && p.title !== p.slug ? p.title : '',
36
+ // Only a page that is not an ordinary doc names its kind (OSK-17985).
37
+ // A server that predates kinds sends none, which reads as `doc`.
38
+ pageKind: p.kind && p.kind !== 'doc' ? p.kind : '',
35
39
  updated: (0, format_1.localStamp)(p.lastEditedAt ?? p.updatedAt) || '',
36
40
  id: p.pageId,
37
41
  })),
@@ -39,6 +43,7 @@ function buildRows(listing) {
39
43
  kind: 'file',
40
44
  name: f.filename,
41
45
  title: '',
46
+ pageKind: '',
42
47
  updated: '',
43
48
  id: f.file_id,
44
49
  })),
@@ -58,6 +63,9 @@ function columnsFor(rows) {
58
63
  ];
59
64
  if (rows.some((r) => r.title))
60
65
  columns.push({ key: 'title', header: 'TITLE', maxWidth: 48 });
66
+ // Elided like TITLE: a wiki of ordinary pages prints exactly what it did.
67
+ if (rows.some((r) => r.pageKind))
68
+ columns.push({ key: 'pageKind', header: 'KIND' });
61
69
  // The thing most worth knowing from a listing is what moved recently, and
62
70
  // `ls` gave a UUID nobody asked for and no date at all.
63
71
  if (rows.some((r) => r.updated))
@@ -1,6 +1,7 @@
1
1
  import { BaseCommand } from '../../base-command';
2
2
  /**
3
- * `skrr wiki update <space> <path>` — a page's METADATA: title, icon, order.
3
+ * `skrr wiki update <space> <path>` — a page's METADATA: title, icon, order,
4
+ * kind.
4
5
  *
5
6
  * Distinct from `mv`, which owns the page's PATH, and from `write`, which owns
6
7
  * its body. That split follows the server: retitling deliberately keeps the
@@ -21,6 +22,7 @@ export default class WikiUpdate extends BaseCommand {
21
22
  icon: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
22
23
  'clear-icon': import("@oclif/core/interfaces").BooleanFlag<boolean>;
23
24
  order: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
25
+ kind: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
24
26
  json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
25
27
  };
26
28
  run(): Promise<void>;
@@ -3,10 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const core_1 = require("@oclif/core");
4
4
  const data_provider_1 = require("@skrr-ai/data-provider");
5
5
  const base_command_1 = require("../../base-command");
6
+ const space_charter_1 = require("../../lib/space-charter");
6
7
  const wiki_1 = require("../../lib/wiki");
7
8
  const wiki_update_1 = require("../../lib/wiki-update");
8
9
  /**
9
- * `skrr wiki update <space> <path>` — a page's METADATA: title, icon, order.
10
+ * `skrr wiki update <space> <path>` — a page's METADATA: title, icon, order,
11
+ * kind.
10
12
  *
11
13
  * Distinct from `mv`, which owns the page's PATH, and from `write`, which owns
12
14
  * its body. That split follows the server: retitling deliberately keeps the
@@ -16,12 +18,16 @@ const wiki_update_1 = require("../../lib/wiki-update");
16
18
  * `mv` is for, and two commands that both rewrite a slug is how they drift.
17
19
  */
18
20
  class WikiUpdate extends base_command_1.BaseCommand {
19
- static description = "Update a wiki page's title, icon, or sort order";
21
+ static description = "Update a wiki page's title, icon, sort order, or kind. A Space holds at most one " +
22
+ 'live charter page: making a second page the charter is refused until the first ' +
23
+ 'is changed to another kind or archived.';
20
24
  static examples = [
21
25
  '<%= config.bin %> wiki update <space-id> Engineering/deploy --title "Deploy Runbook"',
22
26
  '<%= config.bin %> wiki update <space-id> Engineering/deploy --icon 🚀',
23
27
  '<%= config.bin %> wiki update <space-id> Engineering/deploy --clear-icon',
24
28
  '<%= config.bin %> wiki update <space-id> Engineering/deploy --order 0 --json',
29
+ '<%= config.bin %> wiki update <space-id> charter --kind charter',
30
+ '<%= config.bin %> wiki update <space-id> journal/2026-10-22 --kind journal_entry',
25
31
  ];
26
32
  static args = {
27
33
  space: core_1.Args.string({ description: 'Space ID', required: true, ignoreStdin: true }),
@@ -37,6 +43,11 @@ class WikiUpdate extends base_command_1.BaseCommand {
37
43
  exclusive: ['icon'],
38
44
  }),
39
45
  order: core_1.Flags.integer({ description: 'Sort position within its folder (0-based)' }),
46
+ kind: core_1.Flags.string({
47
+ description: "What the page is for. `charter` is the Space's one charter (its lead section, " +
48
+ 'before the first ## heading, is read by every agent in the Space).',
49
+ options: [...data_provider_1.WIKI_PAGE_KINDS],
50
+ }),
40
51
  json: core_1.Flags.boolean({ description: 'Output as JSON' }),
41
52
  };
42
53
  async run() {
@@ -56,6 +67,7 @@ class WikiUpdate extends base_command_1.BaseCommand {
56
67
  icon: flags.icon,
57
68
  clearIcon: flags['clear-icon'],
58
69
  order: flags.order,
70
+ kind: flags.kind,
59
71
  });
60
72
  if (!built.ok) {
61
73
  this.failWithCliError({
@@ -82,6 +94,16 @@ class WikiUpdate extends base_command_1.BaseCommand {
82
94
  });
83
95
  }
84
96
  catch (err) {
97
+ const hint = (0, space_charter_1.charterConflictHint)(err, { binName: this.config.bin, spaceId: args.space });
98
+ if (hint) {
99
+ this.failWithCliError({
100
+ message: hint.message,
101
+ code: 'WIKI_CHARTER_EXISTS',
102
+ exit: 1,
103
+ retryable: false,
104
+ details: hint.details,
105
+ });
106
+ }
85
107
  this.handleApiError(err, { subject: `wiki page ${path}` });
86
108
  }
87
109
  if (flags.json) {
@@ -35,6 +35,23 @@ export declare function slugifyLikeServer(input: string): string;
35
35
  * later reads as "no collision" rather than as a fresh false positive.
36
36
  */
37
37
  export declare function createdSlugCollided(requestedSlug: string, createdSlug?: string): boolean;
38
+ /**
39
+ * The warning for `--kind` on a write that landed in a page that already
40
+ * existed, or `null` when there is nothing to say.
41
+ *
42
+ * `--kind`, like `--title`, describes a page this command CREATES: `write` owns
43
+ * the body, `update` owns metadata. A write into an existing page of another
44
+ * kind therefore changes the body and not the kind, and saying so is the
45
+ * difference between that and a silent no-op. A page an older server returns
46
+ * without a kind reads as `doc`.
47
+ */
48
+ export declare function kindIgnoredWarning(opts: {
49
+ requested?: string;
50
+ existingKind?: string;
51
+ binName: string;
52
+ spaceId: string;
53
+ path: string;
54
+ }): string | null;
38
55
  export default class WikiWrite extends BaseCommand {
39
56
  static description: string;
40
57
  static examples: string[];
@@ -49,7 +66,12 @@ export default class WikiWrite extends BaseCommand {
49
66
  stdin: import("@oclif/core/interfaces").BooleanFlag<boolean>;
50
67
  html: import("@oclif/core/interfaces").BooleanFlag<boolean>;
51
68
  append: import("@oclif/core/interfaces").BooleanFlag<boolean>;
69
+ 'create-only': import("@oclif/core/interfaces").BooleanFlag<boolean>;
52
70
  title: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
71
+ kind: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
72
+ section: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
73
+ lead: import("@oclif/core/interfaces").BooleanFlag<boolean>;
74
+ note: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
53
75
  };
54
76
  run(): Promise<void>;
55
77
  }
@@ -4,10 +4,12 @@ exports.isWikiPageNotFound = isWikiPageNotFound;
4
4
  exports.conflictingPageId = conflictingPageId;
5
5
  exports.slugifyLikeServer = slugifyLikeServer;
6
6
  exports.createdSlugCollided = createdSlugCollided;
7
+ exports.kindIgnoredWarning = kindIgnoredWarning;
7
8
  const core_1 = require("@oclif/core");
8
9
  const data_provider_1 = require("@skrr-ai/data-provider");
9
10
  const base_command_1 = require("../../base-command");
10
11
  const http_error_1 = require("../../lib/http-error");
12
+ const space_charter_1 = require("../../lib/space-charter");
11
13
  const web_url_1 = require("../../lib/web-url");
12
14
  const wiki_1 = require("../../lib/wiki");
13
15
  /**
@@ -90,6 +92,27 @@ function createdSlugCollided(requestedSlug, createdSlug) {
90
92
  // fallback, an 8-char uuid head.
91
93
  return /^\d+$/.test(suffix) || /^[0-9a-f]{8}$/.test(suffix);
92
94
  }
95
+ /**
96
+ * The warning for `--kind` on a write that landed in a page that already
97
+ * existed, or `null` when there is nothing to say.
98
+ *
99
+ * `--kind`, like `--title`, describes a page this command CREATES: `write` owns
100
+ * the body, `update` owns metadata. A write into an existing page of another
101
+ * kind therefore changes the body and not the kind, and saying so is the
102
+ * difference between that and a silent no-op. A page an older server returns
103
+ * without a kind reads as `doc`.
104
+ */
105
+ function kindIgnoredWarning(opts) {
106
+ const { requested, existingKind, binName, spaceId, path } = opts;
107
+ if (requested === undefined)
108
+ return null;
109
+ const actual = (0, data_provider_1.readWikiPageKind)(existingKind);
110
+ if (actual === requested)
111
+ return null;
112
+ return (`--kind was ignored: '${path}' already exists as a ${actual} page, and \`wiki write\` only sets ` +
113
+ `the kind of pages it creates. Change it with \`${binName} wiki update ${spaceId} ${path} ` +
114
+ `--kind ${requested}\`.`);
115
+ }
93
116
  class WikiWrite extends base_command_1.BaseCommand {
94
117
  // The markdown dialect note lives here, not only in SKRR_WIKI.md: --help is the
95
118
  // one place a CLI user (or an agent with no docs) looks before writing, and
@@ -118,6 +141,11 @@ class WikiWrite extends base_command_1.BaseCommand {
118
141
  '<%= config.bin %> wiki write <space-id> Engineering/deploy --file runbook.md',
119
142
  'cat notes.md | <%= config.bin %> wiki write <space-id> notes --stdin',
120
143
  '<%= config.bin %> wiki write <space-id> log --content "Shipped v2" --append',
144
+ '<%= config.bin %> wiki write <space-id> charter --kind charter --file charter.md',
145
+ '<%= config.bin %> wiki write <space-id> journal/2026-10-22 --kind journal_entry --stdin',
146
+ '<%= config.bin %> wiki write <space-id> Reviews/2026-w43 --kind report --create-only --stdin',
147
+ '<%= config.bin %> wiki write <space-id> charter --section "## Goals" --file goals.md --note "Tighter after the KR review"',
148
+ '<%= config.bin %> wiki write <space-id> charter --lead --file lead.md',
121
149
  ];
122
150
  static args = {
123
151
  space: core_1.Args.string({ description: 'Space ID', required: true, ignoreStdin: true }),
@@ -130,9 +158,33 @@ class WikiWrite extends base_command_1.BaseCommand {
130
158
  stdin: core_1.Flags.boolean({ description: 'Read content from stdin' }),
131
159
  html: core_1.Flags.boolean({ description: 'Treat the input as HTML instead of Markdown' }),
132
160
  append: core_1.Flags.boolean({ description: 'Append instead of replacing (>> rather than >)' }),
161
+ 'create-only': core_1.Flags.boolean({
162
+ description: 'Create a new page only. Refuse an existing path or a create race without replacing its content',
163
+ exclusive: ['append', 'section', 'lead'],
164
+ }),
133
165
  title: core_1.Flags.string({
134
166
  description: 'Title for a NEWLY-CREATED page (defaults to the slug). Retitle an existing page with `wiki update --title`',
135
167
  }),
168
+ kind: core_1.Flags.string({
169
+ description: 'Kind for a NEWLY-CREATED page (default doc). A Space holds one live `charter`; its lead ' +
170
+ 'section is read by every agent in the Space. Change an existing page with `wiki update --kind`',
171
+ options: [...data_provider_1.WIKI_PAGE_KINDS],
172
+ }),
173
+ section: core_1.Flags.string({
174
+ description: 'Replace ONE section of an existing page instead of the whole page: a heading line ' +
175
+ '(`## Goals`, which also fixes the level) or its text. The content replaces the heading and ' +
176
+ 'everything under it, up to the next heading of the same or a higher level, so include the heading',
177
+ exclusive: ['lead', 'append'],
178
+ }),
179
+ lead: core_1.Flags.boolean({
180
+ description: 'Replace only the lead of an existing page: everything before its first `##` heading (for a ' +
181
+ 'charter, the part every agent in the Space reads)',
182
+ exclusive: ['section', 'append'],
183
+ }),
184
+ note: core_1.Flags.string({
185
+ description: 'Why you are making the change. When the Space holds the write for approval it becomes a ' +
186
+ 'suggestion on the page, and this is its first comment; otherwise it is not stored',
187
+ }),
136
188
  };
137
189
  async run() {
138
190
  this.requireAuth();
@@ -155,9 +207,10 @@ class WikiWrite extends base_command_1.BaseCommand {
155
207
  }
156
208
  const format = flags.html ? 'html' : 'markdown';
157
209
  const mode = flags.append ? 'append' : 'replace';
158
- // Create-or-write, so an agent never has to branch on existence. Look the
159
- // page up first; a 404 means "create it", which also creates the folder
160
- // chain via `folderPath` (mkdir -p).
210
+ const partial = flags.section !== undefined || flags.lead === true;
211
+ // Create-or-write by default; --create-only refuses the existing branch.
212
+ // A lookup 404 means "create it", which also creates the folder chain via
213
+ // `folderPath` (mkdir -p). The server's conflict check below owns the race.
161
214
  let existing = null;
162
215
  try {
163
216
  existing = await data_provider_1.dataService.getSpaceWikiPageByPath(args.space, args.path);
@@ -167,17 +220,47 @@ class WikiWrite extends base_command_1.BaseCommand {
167
220
  this.handleApiError(err);
168
221
  }
169
222
  }
223
+ if (flags['create-only'] && existing) {
224
+ this.failWithCliError({
225
+ message: `Page '${args.path}' already exists (${existing.pageId}); --create-only changed nothing.`,
226
+ code: 'WIKI_PAGE_EXISTS',
227
+ status: 409,
228
+ exit: 1,
229
+ retryable: false,
230
+ details: { requestedPath: args.path, pageId: existing.pageId },
231
+ });
232
+ }
233
+ // A section or the lead is a part of a page that exists: there is nothing
234
+ // to create it in.
235
+ if (partial && !existing) {
236
+ this.failWithCliError({
237
+ message: `No page at '${args.path}' to replace ${flags.lead ? 'the lead of' : 'a section of'}. ` +
238
+ 'Write the whole page first.',
239
+ code: 'WIKI_PAGE_NOT_FOUND',
240
+ status: 404,
241
+ exit: 1,
242
+ retryable: false,
243
+ });
244
+ }
170
245
  const { dir, name } = (0, wiki_1.splitParentPath)(args.path);
171
246
  const writeInto = (pageId) => data_provider_1.dataService.writeSpaceWikiPageContent({
172
247
  spaceId: args.space,
173
248
  pageId,
174
- data: { content, format, mode },
249
+ data: {
250
+ content,
251
+ format,
252
+ mode,
253
+ ...(flags.section !== undefined ? { section: flags.section } : {}),
254
+ ...(flags.lead ? { lead: true } : {}),
255
+ ...(flags.note ? { note: flags.note } : {}),
256
+ },
175
257
  });
176
258
  let page;
177
259
  // `existing` decides which branch we OPEN with, never which one we end in:
178
260
  // the lookup above can be stale (a CDN-cached 404 is the documented case),
179
261
  // so the create below asks the server to refuse rather than rename, and a
180
- // refusal is resolved by writing into whatever was really there.
262
+ // refusal is normally resolved by writing into whatever was really there.
263
+ // --create-only preserves that refusal instead of changing the winner.
181
264
  let wroteIntoExisting = Boolean(existing);
182
265
  try {
183
266
  if (existing) {
@@ -193,6 +276,7 @@ class WikiWrite extends base_command_1.BaseCommand {
193
276
  folderPath: dir || undefined,
194
277
  content,
195
278
  format,
279
+ ...(flags.kind ? { kind: flags.kind } : {}),
196
280
  // Never let the server rename an EXACTLY addressed path. Without
197
281
  // this it answers 201 having created `x-2` beside `x`, and the
198
282
  // write the user asked for silently did not happen.
@@ -202,7 +286,7 @@ class WikiWrite extends base_command_1.BaseCommand {
202
286
  }
203
287
  catch (err) {
204
288
  const conflictId = conflictingPageId(err);
205
- if (conflictId === undefined) {
289
+ if (conflictId === undefined || flags['create-only']) {
206
290
  throw err;
207
291
  }
208
292
  // The page existed after all. This is the outcome the user asked
@@ -213,11 +297,50 @@ class WikiWrite extends base_command_1.BaseCommand {
213
297
  }
214
298
  }
215
299
  catch (err) {
300
+ const charterConflict = (0, space_charter_1.charterConflictHint)(err, {
301
+ binName: this.config.bin,
302
+ spaceId: args.space,
303
+ });
304
+ if (charterConflict) {
305
+ this.failWithCliError({
306
+ message: charterConflict.message,
307
+ code: 'WIKI_CHARTER_EXISTS',
308
+ status: 409,
309
+ exit: 1,
310
+ retryable: false,
311
+ details: charterConflict.details,
312
+ });
313
+ }
216
314
  this.handleApiError(err);
217
315
  }
316
+ // A write an unattended run makes may be held for approval by the Space's
317
+ // write policy (`202 pending_approval`): a journal entry or report create,
318
+ // or an append to the one it created (`--append`, OSK-17995), in its Run's
319
+ // approval bundle (OSK-17994); an edit of any other page's body as a
320
+ // suggestion on the page (OSK-17997). Nothing was written yet.
321
+ if (this.reportHeldSpaceWrite(page, { json: flags.json }))
322
+ return;
218
323
  // Fallback for a server predating `conflict: 'fail'`, which answers 201
219
324
  // with a renamed slug instead of 409. Unreachable against a current server.
220
325
  if (!wroteIntoExisting && createdSlugCollided(name, page.slug)) {
326
+ if (flags['create-only']) {
327
+ this.failWithCliError({
328
+ message: `The server created '${page.path ?? page.slug}' (${page.pageId}) instead of '${args.path}'. ` +
329
+ 'This server did not honor atomic --create-only. The existing page was not replaced, ' +
330
+ 'and the newly created page has not been removed. Upgrade the server before retrying this operation.',
331
+ code: 'WIKI_CREATE_ONLY_UNSUPPORTED',
332
+ exit: 1,
333
+ retryable: false,
334
+ details: {
335
+ outcome: 'created_different_path',
336
+ requestedPath: args.path,
337
+ requestedSlug: name,
338
+ createdSlug: page.slug,
339
+ createdPath: page.path,
340
+ pageId: page.pageId,
341
+ },
342
+ });
343
+ }
221
344
  this.failWithCliError({
222
345
  message: `Wrote a DUPLICATE page: asked for '${args.path}' but the server already had that slug and created ` +
223
346
  `'${page.path ?? page.slug}' (${page.pageId}) beside it. The content did NOT overwrite the original.\n` +
@@ -249,6 +372,17 @@ class WikiWrite extends base_command_1.BaseCommand {
249
372
  `it creates. Retitle it with \`${this.config.bin} wiki update ${args.space} ${page.path ?? args.path} ` +
250
373
  `--title ${JSON.stringify(flags.title)}\` (the slug is kept, so stored paths stay valid).`);
251
374
  }
375
+ const ignoredKind = wroteIntoExisting
376
+ ? kindIgnoredWarning({
377
+ requested: flags.kind,
378
+ existingKind: page.kind,
379
+ binName: this.config.bin,
380
+ spaceId: args.space,
381
+ path: page.path ?? args.path,
382
+ })
383
+ : null;
384
+ if (ignoredKind)
385
+ this.warn(ignoredKind);
252
386
  const withUrl = (0, web_url_1.withWikiPageUrl)(this.cliConfig.baseURL, page);
253
387
  if (flags.json) {
254
388
  this.log(JSON.stringify(withUrl, null, 2));
@@ -260,6 +394,10 @@ class WikiWrite extends base_command_1.BaseCommand {
260
394
  let verb = 'Created';
261
395
  if (wroteIntoExisting) {
262
396
  verb = flags.append ? 'Appended to' : 'Updated';
397
+ if (flags.lead)
398
+ verb = 'Replaced the lead of';
399
+ if (flags.section !== undefined)
400
+ verb = `Replaced the section ${JSON.stringify(flags.section)} of`;
263
401
  }
264
402
  this.log(`${verb} ${page.path ?? args.path} (${page.pageId}).`);
265
403
  if (withUrl.url)