cloving 1.0.1 → 1.2.0

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 (309) hide show
  1. package/README.md +251 -20
  2. package/assets/watch-fonts/fira-code-OFL.md +93 -0
  3. package/assets/watch-fonts/fira-code-latin-400-normal.woff2 +0 -0
  4. package/assets/watch-fonts/fira-code-latin-500-normal.woff2 +0 -0
  5. package/assets/watch-fonts/heebo-OFL.md +93 -0
  6. package/assets/watch-fonts/heebo-latin-500-normal.woff2 +0 -0
  7. package/assets/watch-fonts/heebo-latin-700-normal.woff2 +0 -0
  8. package/assets/watch-fonts/heebo-latin-800-normal.woff2 +0 -0
  9. package/assets/watch-fonts/manifest.json +112 -0
  10. package/assets/watch-fonts/space-grotesk-OFL.md +93 -0
  11. package/assets/watch-fonts/space-grotesk-latin-400-normal.woff2 +0 -0
  12. package/assets/watch-fonts/space-grotesk-latin-500-normal.woff2 +0 -0
  13. package/assets/watch-fonts/space-grotesk-latin-600-normal.woff2 +0 -0
  14. package/assets/watch-fonts/space-grotesk-latin-700-normal.woff2 +0 -0
  15. package/dist/src/authority/commands.d.ts +1 -0
  16. package/dist/src/authority/commands.js +33 -4
  17. package/dist/src/authority/dispatch-decision.d.ts +1 -0
  18. package/dist/src/authority/dispatch-decision.js +7 -4
  19. package/dist/src/authority/events.js +2 -2
  20. package/dist/src/authority/handoff-chain.d.ts +24 -0
  21. package/dist/src/authority/handoff-chain.js +46 -0
  22. package/dist/src/authority/reconciliation.d.ts +3 -0
  23. package/dist/src/authority/reconciliation.js +21 -5
  24. package/dist/src/authority/transitions.d.ts +1 -1
  25. package/dist/src/authority/transitions.js +5 -0
  26. package/dist/src/broker/actor/authority-queries.d.ts +4 -0
  27. package/dist/src/broker/actor/authority-queries.js +51 -2
  28. package/dist/src/broker/actor/authority-session.d.ts +2 -0
  29. package/dist/src/broker/actor/authority-session.js +3 -4
  30. package/dist/src/broker/actor/delivery-intents.d.ts +1 -0
  31. package/dist/src/broker/actor/effect-delivery.js +9 -0
  32. package/dist/src/broker/authority-admission.js +13 -5
  33. package/dist/src/chats/analysis-batches.d.ts +42 -0
  34. package/dist/src/chats/analysis-batches.js +97 -0
  35. package/dist/src/chats/analysis-checkpoint.d.ts +29 -0
  36. package/dist/src/chats/analysis-checkpoint.js +31 -0
  37. package/dist/src/chats/analysis-contract.d.ts +80 -0
  38. package/dist/src/chats/analysis-contract.js +16 -0
  39. package/dist/src/chats/analysis-data.d.ts +3 -0
  40. package/dist/src/chats/analysis-data.js +85 -0
  41. package/dist/src/chats/analysis-input.d.ts +18 -0
  42. package/dist/src/chats/analysis-input.js +97 -0
  43. package/dist/src/chats/analysis-links.d.ts +2 -0
  44. package/dist/src/chats/analysis-links.js +25 -0
  45. package/dist/src/chats/analysis-merge.d.ts +16 -0
  46. package/dist/src/chats/analysis-merge.js +134 -0
  47. package/dist/src/chats/analysis-prompt.d.ts +18 -0
  48. package/dist/src/chats/analysis-prompt.js +42 -0
  49. package/dist/src/chats/analysis-proposal.d.ts +4 -0
  50. package/dist/src/chats/analysis-proposal.js +41 -0
  51. package/dist/src/chats/analysis-provenance.d.ts +4 -0
  52. package/dist/src/chats/analysis-provenance.js +99 -0
  53. package/dist/src/chats/analysis-shape.d.ts +4 -0
  54. package/dist/src/chats/analysis-shape.js +235 -0
  55. package/dist/src/chats/analysis.d.ts +3 -0
  56. package/dist/src/chats/analysis.js +42 -0
  57. package/dist/src/chats/corpus-input.d.ts +5 -0
  58. package/dist/src/chats/corpus-input.js +288 -0
  59. package/dist/src/chats/destination.js +3 -1
  60. package/dist/src/chats/import.d.ts +8 -6
  61. package/dist/src/chats/import.js +195 -23
  62. package/dist/src/chats/input-file.d.ts +3 -0
  63. package/dist/src/chats/input-file.js +32 -0
  64. package/dist/src/chats/normalize.d.ts +11 -2
  65. package/dist/src/chats/normalize.js +18 -2
  66. package/dist/src/chats/previous-import.d.ts +5 -0
  67. package/dist/src/chats/previous-import.js +34 -0
  68. package/dist/src/chats/reader.d.ts +7 -1
  69. package/dist/src/chats/reader.js +46 -15
  70. package/dist/src/chats/redact-import.d.ts +14 -0
  71. package/dist/src/chats/redact-import.js +141 -0
  72. package/dist/src/chats/redaction.d.ts +41 -0
  73. package/dist/src/chats/redaction.js +161 -0
  74. package/dist/src/chats/reference-mapping.d.ts +16 -0
  75. package/dist/src/chats/reference-mapping.js +153 -0
  76. package/dist/src/chats/revision-input.d.ts +3 -0
  77. package/dist/src/chats/revision-input.js +180 -0
  78. package/dist/src/chats/revision.d.ts +48 -0
  79. package/dist/src/chats/revision.js +94 -0
  80. package/dist/src/chats/selection.d.ts +25 -0
  81. package/dist/src/chats/selection.js +109 -0
  82. package/dist/src/chats/source.d.ts +23 -0
  83. package/dist/src/chats/source.js +135 -0
  84. package/dist/src/chats/structure.d.ts +57 -0
  85. package/dist/src/chats/structure.js +216 -0
  86. package/dist/src/chats/workflow-generation-projection.d.ts +8 -0
  87. package/dist/src/chats/workflow-generation-projection.js +75 -0
  88. package/dist/src/chats/workflow-generation-source.d.ts +25 -0
  89. package/dist/src/chats/workflow-generation-source.js +124 -0
  90. package/dist/src/chats/workflow-generation-text.d.ts +23 -0
  91. package/dist/src/chats/workflow-generation-text.js +74 -0
  92. package/dist/src/chats/workflow-generation.d.ts +69 -0
  93. package/dist/src/chats/workflow-generation.js +142 -0
  94. package/dist/src/cli/arguments.d.ts +8 -0
  95. package/dist/src/cli/arguments.js +94 -13
  96. package/dist/src/cli/client.d.ts +1 -0
  97. package/dist/src/cli/client.js +38 -1
  98. package/dist/src/cli/commands.d.ts +3 -0
  99. package/dist/src/cli/commands.js +29 -11
  100. package/dist/src/cli/main.d.ts +2 -1
  101. package/dist/src/cli/main.js +61 -14
  102. package/dist/src/cli/render.d.ts +3 -0
  103. package/dist/src/cli/render.js +122 -7
  104. package/dist/src/cli/usage-render.d.ts +3 -0
  105. package/dist/src/cli/usage-render.js +28 -0
  106. package/dist/src/cli/usage.d.ts +3 -2
  107. package/dist/src/cli/usage.js +42 -7
  108. package/dist/src/cli/watch-actions.d.ts +10 -0
  109. package/dist/src/cli/watch-actions.js +58 -0
  110. package/dist/src/cli/watch-board-view.d.ts +44 -1
  111. package/dist/src/cli/watch-board-view.js +137 -18
  112. package/dist/src/cli/watch-board.d.ts +7 -1
  113. package/dist/src/cli/watch-board.js +48 -11
  114. package/dist/src/cli/watch-card-client.d.ts +1 -0
  115. package/dist/src/cli/watch-card-client.js +44 -0
  116. package/dist/src/cli/watch-card-forms.d.ts +2 -0
  117. package/dist/src/cli/watch-card-forms.js +33 -0
  118. package/dist/src/cli/watch-card-reply.d.ts +5 -0
  119. package/dist/src/cli/watch-card-reply.js +34 -0
  120. package/dist/src/cli/watch-card-view.d.ts +40 -0
  121. package/dist/src/cli/watch-card-view.js +86 -0
  122. package/dist/src/cli/watch-client.d.ts +1 -0
  123. package/dist/src/cli/watch-client.js +122 -0
  124. package/dist/src/cli/watch-model.d.ts +10 -4
  125. package/dist/src/cli/watch-model.js +61 -67
  126. package/dist/src/cli/watch-page.d.ts +1 -1
  127. package/dist/src/cli/watch-page.js +89 -86
  128. package/dist/src/cli/watch-phases.js +3 -3
  129. package/dist/src/cli/watch-pr-board.d.ts +3 -0
  130. package/dist/src/cli/watch-pr-board.js +26 -0
  131. package/dist/src/cli/watch-pr-command.d.ts +18 -0
  132. package/dist/src/cli/watch-pr-command.js +74 -0
  133. package/dist/src/cli/watch-pr-identity.d.ts +32 -0
  134. package/dist/src/cli/watch-pr-identity.js +87 -0
  135. package/dist/src/cli/watch-pr-observer.d.ts +20 -0
  136. package/dist/src/cli/watch-pr-observer.js +150 -0
  137. package/dist/src/cli/watch-pr-settings.d.ts +8 -0
  138. package/dist/src/cli/watch-pr-settings.js +47 -0
  139. package/dist/src/cli/watch-pull-request.d.ts +10 -0
  140. package/dist/src/cli/watch-pull-request.js +130 -0
  141. package/dist/src/cli/watch-reads.d.ts +7 -1
  142. package/dist/src/cli/watch-reads.js +44 -18
  143. package/dist/src/cli/watch-render.d.ts +29 -2
  144. package/dist/src/cli/watch-render.js +11 -3
  145. package/dist/src/cli/watch-run-input.d.ts +14 -0
  146. package/dist/src/cli/watch-run-input.js +49 -0
  147. package/dist/src/cli/watch-server.d.ts +3 -0
  148. package/dist/src/cli/watch-server.js +77 -8
  149. package/dist/src/cli/watch-start-view.d.ts +18 -0
  150. package/dist/src/cli/watch-start-view.js +77 -0
  151. package/dist/src/cli/watch-turn.d.ts +1 -0
  152. package/dist/src/cli/watch-turn.js +8 -3
  153. package/dist/src/cli/watch-usage.d.ts +6 -0
  154. package/dist/src/cli/watch-usage.js +65 -0
  155. package/dist/src/cli/watch-view.d.ts +22 -0
  156. package/dist/src/cli/watch-view.js +111 -19
  157. package/dist/src/cli.js +48 -6
  158. package/dist/src/daemon/analysis-launch.d.ts +5 -0
  159. package/dist/src/daemon/analysis-launch.js +81 -0
  160. package/dist/src/daemon/analysis-token.d.ts +6 -0
  161. package/dist/src/daemon/analysis-token.js +88 -0
  162. package/dist/src/daemon/analysis-worker.d.ts +20 -0
  163. package/dist/src/daemon/analysis-worker.js +271 -0
  164. package/dist/src/daemon/chats-batch-binding.d.ts +23 -0
  165. package/dist/src/daemon/chats-batch-binding.js +99 -0
  166. package/dist/src/daemon/chats-capture.d.ts +18 -0
  167. package/dist/src/daemon/chats-capture.js +194 -0
  168. package/dist/src/daemon/chats-checkpoints.d.ts +41 -0
  169. package/dist/src/daemon/chats-checkpoints.js +186 -0
  170. package/dist/src/daemon/chats-files.d.ts +42 -0
  171. package/dist/src/daemon/chats-files.js +252 -0
  172. package/dist/src/daemon/chats-follow-up.d.ts +38 -0
  173. package/dist/src/daemon/chats-follow-up.js +180 -0
  174. package/dist/src/daemon/chats-question.d.ts +15 -0
  175. package/dist/src/daemon/chats-question.js +93 -0
  176. package/dist/src/daemon/chats-worker.d.ts +13 -0
  177. package/dist/src/daemon/chats-worker.js +201 -0
  178. package/dist/src/daemon/claude-turn.d.ts +11 -0
  179. package/dist/src/daemon/claude-turn.js +96 -15
  180. package/dist/src/daemon/claude-worker.d.ts +2 -1
  181. package/dist/src/daemon/claude-worker.js +92 -45
  182. package/dist/src/daemon/codex-stream.js +16 -0
  183. package/dist/src/daemon/daemon.d.ts +8 -1
  184. package/dist/src/daemon/daemon.js +51 -14
  185. package/dist/src/daemon/delivery-router.js +6 -0
  186. package/dist/src/daemon/github-calls.d.ts +4 -0
  187. package/dist/src/daemon/github-calls.js +16 -7
  188. package/dist/src/daemon/github-ci.d.ts +6 -0
  189. package/dist/src/daemon/github-ci.js +170 -0
  190. package/dist/src/daemon/github-merge-call.d.ts +14 -0
  191. package/dist/src/daemon/github-merge-call.js +73 -0
  192. package/dist/src/daemon/github-merge.d.ts +3 -5
  193. package/dist/src/daemon/github-merge.js +52 -95
  194. package/dist/src/daemon/github-methods.d.ts +28 -0
  195. package/dist/src/daemon/github-methods.js +84 -16
  196. package/dist/src/daemon/github-operation.d.ts +2 -0
  197. package/dist/src/daemon/github-retry.d.ts +6 -0
  198. package/dist/src/daemon/github-retry.js +49 -0
  199. package/dist/src/daemon/github-ticket-status.d.ts +3 -0
  200. package/dist/src/daemon/github-ticket-status.js +294 -0
  201. package/dist/src/daemon/github-worker.js +2 -1
  202. package/dist/src/daemon/handoff-worker.d.ts +10 -0
  203. package/dist/src/daemon/handoff-worker.js +232 -0
  204. package/dist/src/daemon/issue-queue.d.ts +2 -0
  205. package/dist/src/daemon/issue-queue.js +186 -43
  206. package/dist/src/daemon/notify-journal.d.ts +18 -0
  207. package/dist/src/daemon/notify-journal.js +108 -0
  208. package/dist/src/daemon/notify-message.js +2 -1
  209. package/dist/src/daemon/notify.js +176 -37
  210. package/dist/src/daemon/operation-journal.d.ts +1 -0
  211. package/dist/src/daemon/operation-journal.js +4 -2
  212. package/dist/src/daemon/retrying-turn.d.ts +12 -0
  213. package/dist/src/daemon/retrying-turn.js +231 -0
  214. package/dist/src/daemon/ticket-dependency-waits.d.ts +18 -0
  215. package/dist/src/daemon/ticket-dependency-waits.js +60 -0
  216. package/dist/src/daemon/ticket-registration.d.ts +8 -4
  217. package/dist/src/daemon/ticket-registration.js +76 -22
  218. package/dist/src/daemon/ticket-source.d.ts +4 -1
  219. package/dist/src/daemon/ticket-source.js +8 -2
  220. package/dist/src/decision-visibility.d.ts +2 -0
  221. package/dist/src/decision-visibility.js +10 -0
  222. package/dist/src/execution-pin.d.ts +4 -0
  223. package/dist/src/execution-pin.js +23 -2
  224. package/dist/src/host/start-delivery.d.ts +2 -1
  225. package/dist/src/host/start-delivery.js +1 -1
  226. package/dist/src/host/step-bridge-host.d.ts +1 -0
  227. package/dist/src/host/step-bridge-host.js +16 -0
  228. package/dist/src/host/world-reconciliation.d.ts +3 -0
  229. package/dist/src/host/world-reconciliation.js +9 -0
  230. package/dist/src/host/world-runs.js +14 -1
  231. package/dist/src/issue-identity.d.ts +6 -0
  232. package/dist/src/issue-identity.js +23 -0
  233. package/dist/src/service/queue-runs.d.ts +3 -0
  234. package/dist/src/service/queue-runs.js +39 -0
  235. package/dist/src/service/registry.d.ts +8 -2
  236. package/dist/src/service/registry.js +20 -8
  237. package/dist/src/service/replies.d.ts +2 -0
  238. package/dist/src/service/run-handlers.js +54 -30
  239. package/dist/src/service/service.d.ts +3 -0
  240. package/dist/src/service/service.js +3 -1
  241. package/dist/src/service/submission-handler.d.ts +1 -0
  242. package/dist/src/service/submission-handler.js +92 -13
  243. package/dist/src/service/worker-totals.d.ts +3 -0
  244. package/dist/src/service/worker-totals.js +52 -0
  245. package/dist/src/step-bridge.d.ts +9 -0
  246. package/dist/src/steps/handoff.d.ts +2 -0
  247. package/dist/src/steps/handoff.js +13 -0
  248. package/dist/src/ticket-dependencies.d.ts +1 -0
  249. package/dist/src/ticket-dependencies.js +15 -0
  250. package/dist/src/ticket-status.d.ts +8 -0
  251. package/dist/src/ticket-status.js +48 -0
  252. package/dist/src/token-prices.d.ts +21 -0
  253. package/dist/src/token-prices.js +108 -0
  254. package/dist/src/worker-usage.d.ts +31 -0
  255. package/dist/src/worker-usage.js +44 -0
  256. package/dist/src/workflow-admission.d.ts +1 -0
  257. package/dist/src/workflow-candidate.d.ts +29 -0
  258. package/dist/src/workflow-candidate.js +60 -0
  259. package/dist/src/workflow-contracts.d.ts +4 -0
  260. package/dist/src/workflow-contracts.js +32 -5
  261. package/dist/src/workflow-declaration.d.ts +12 -1
  262. package/dist/src/workflow-declaration.js +71 -13
  263. package/dist/src/workflow-discovery.d.ts +18 -0
  264. package/dist/src/workflow-discovery.js +33 -0
  265. package/dist/src/workflow-refusals.d.ts +6 -0
  266. package/dist/src/workflow-refusals.js +39 -0
  267. package/dist/src/workflows.d.ts +3 -1
  268. package/dist/src/workflows.js +2 -0
  269. package/dist/tools/admit-workflow.d.ts +13 -0
  270. package/dist/tools/admit-workflow.js +94 -0
  271. package/dist/tools/self-host-processes.js +7 -2
  272. package/dist/tools/self-host-project.d.ts +17 -0
  273. package/dist/tools/self-host-project.js +177 -0
  274. package/dist/tools/self-host-workflows.d.ts +1 -1
  275. package/dist/tools/self-host-workflows.js +2 -2
  276. package/dist/tools/self-host.js +30 -84
  277. package/dist/tools/self-update-host.d.ts +7 -0
  278. package/dist/tools/self-update-host.js +48 -1
  279. package/dist/tools/self-update.d.ts +1 -0
  280. package/dist/tools/self-update.js +85 -13
  281. package/dist/tools/workflow-bundle-dependencies.d.ts +5 -0
  282. package/dist/tools/workflow-bundle-dependencies.js +93 -0
  283. package/dist/tools/workflow-bundles.d.ts +20 -0
  284. package/dist/tools/workflow-bundles.js +173 -0
  285. package/dist/tools/workflow-candidate-counts.d.ts +8 -0
  286. package/dist/tools/workflow-candidate-counts.js +251 -0
  287. package/dist/tools/workflow-candidate-program.d.ts +11 -0
  288. package/dist/tools/workflow-candidate-program.js +78 -0
  289. package/dist/tools/workflow-candidate-source.d.ts +6 -0
  290. package/dist/tools/workflow-candidate-source.js +107 -0
  291. package/dist/tools/workflow-candidate-syntax.d.ts +15 -0
  292. package/dist/tools/workflow-candidate-syntax.js +219 -0
  293. package/dist/tools/workflow-folder-capture.d.ts +17 -0
  294. package/dist/tools/workflow-folder-capture.js +216 -0
  295. package/dist/tools/workflow-folders.d.ts +33 -0
  296. package/dist/tools/workflow-folders.js +150 -0
  297. package/dist/tools/workflow-source-effects.d.ts +10 -0
  298. package/dist/tools/workflow-source-effects.js +213 -0
  299. package/dist/workflows/analyze-chats.d.ts +15 -0
  300. package/dist/workflows/analyze-chats.declaration.json +22 -0
  301. package/dist/workflows/analyze-chats.js +250 -0
  302. package/dist/workflows/develop-prd.js +71 -3
  303. package/dist/workflows/develop-ticket.d.ts +1 -7
  304. package/dist/workflows/develop-ticket.js +47 -141
  305. package/dist/workflows/issue-labels.d.ts +3 -1
  306. package/dist/workflows/issue-labels.js +34 -0
  307. package/dist/workflows/ticket-prompts.d.ts +35 -0
  308. package/dist/workflows/ticket-prompts.js +143 -0
  309. package/package.json +25 -5
@@ -50,6 +50,8 @@ function textValues(argumentsList) {
50
50
  export function parseInvocation(given) {
51
51
  if (given[0] === "chats" && given[1] === "import")
52
52
  return chatsImport(given.slice(2));
53
+ if (given[0] === "chats" && given[1] === "redact")
54
+ return chatsRedact(given.slice(2));
53
55
  const argumentsList = textValues(given);
54
56
  const json = given.includes("--json");
55
57
  const parsed = parsedArguments(argumentsList);
@@ -70,6 +72,17 @@ export function parseInvocation(given) {
70
72
  return { kind: "usage-error", code: outcome, json };
71
73
  return outcome;
72
74
  }
75
+ function chatsRedact(argumentsList) {
76
+ if (argumentsList.length === 1 &&
77
+ ["--help", "-h"].includes(String(argumentsList[0])))
78
+ return { kind: "chats-redact-help" };
79
+ const importId = argumentsList[0];
80
+ if (argumentsList.length !== 1 ||
81
+ importId === undefined ||
82
+ !/^[a-f\d]{8}-[a-f\d]{4}-4[a-f\d]{3}-[89ab][a-f\d]{3}-[a-f\d]{12}$/.test(importId))
83
+ return { kind: "usage-error", code: "invalid-import-id", json: false };
84
+ return { kind: "chats-redact", importId };
85
+ }
73
86
  function chatsImport(argumentsList) {
74
87
  const error = (code) => ({
75
88
  kind: "usage-error",
@@ -79,21 +92,89 @@ function chatsImport(argumentsList) {
79
92
  if (argumentsList.length === 1 &&
80
93
  ["--help", "-h"].includes(String(argumentsList[0])))
81
94
  return { kind: "chats-import-help" };
82
- const paths = [];
83
- let literal = false;
95
+ const state = {
96
+ paths: [],
97
+ roots: [],
98
+ excludeProjects: [],
99
+ literal: false,
100
+ option: undefined,
101
+ previousImportId: undefined,
102
+ };
84
103
  for (const argument of argumentsList) {
85
- if (!literal && argument === "--")
86
- literal = true;
87
- else if (!literal && argument.startsWith("-"))
88
- return error("unexpected-option");
89
- else if (argument === "")
90
- return error("missing-argument");
91
- else
92
- paths.push(argument);
104
+ const failure = importArgument(state, argument);
105
+ if (failure !== undefined)
106
+ return error(failure);
107
+ }
108
+ if (state.option !== undefined)
109
+ return error("missing-value");
110
+ if (state.excludeProjects.length > 0 && state.roots.length === 0)
111
+ return error("roots-required");
112
+ if (state.paths.length + state.roots.length === 0)
113
+ return error("missing-argument");
114
+ return importInvocation(state);
115
+ }
116
+ function importInvocation(state) {
117
+ const previous = state.previousImportId === undefined
118
+ ? {}
119
+ : { previousImportId: state.previousImportId };
120
+ return state.roots.length === 0
121
+ ? { kind: "chats-import", paths: state.paths, ...previous }
122
+ : {
123
+ kind: "chats-import",
124
+ paths: state.paths,
125
+ ...previous,
126
+ roots: state.roots,
127
+ excludeProjects: state.excludeProjects,
128
+ };
129
+ }
130
+ function importArgument(state, argument) {
131
+ if (state.option !== undefined)
132
+ return importValue(state, argument);
133
+ if (argument === "")
134
+ return "missing-argument";
135
+ if (state.literal) {
136
+ state.paths.push(argument);
137
+ return;
93
138
  }
94
- return paths.length === 0
95
- ? error("missing-argument")
96
- : { kind: "chats-import", paths };
139
+ if (argument === "--previous-import" && state.previousImportId !== undefined)
140
+ return "repeated-previous-import";
141
+ if (["--root", "--exclude-project", "--previous-import"].includes(argument)) {
142
+ state.option = argument;
143
+ return;
144
+ }
145
+ if (argument === "--") {
146
+ state.literal = true;
147
+ return;
148
+ }
149
+ if (argument.startsWith("-"))
150
+ return "unexpected-option";
151
+ state.paths.push(argument);
152
+ return;
153
+ }
154
+ function importValue(state, argument) {
155
+ if (argument === "" || argument.startsWith("-"))
156
+ return "missing-value";
157
+ const option = state.option;
158
+ state.option = undefined;
159
+ if (option === "--root") {
160
+ state.roots.push(argument);
161
+ return;
162
+ }
163
+ if (option === "--exclude-project" && !validProjectName(argument))
164
+ return "invalid-exclusion";
165
+ if (option === "--exclude-project") {
166
+ state.excludeProjects.push(argument);
167
+ return;
168
+ }
169
+ if (!/^[a-f\d]{8}-[a-f\d]{4}-4[a-f\d]{3}-[89ab][a-f\d]{3}-[a-f\d]{12}$/.test(argument))
170
+ return "invalid-import-id";
171
+ state.previousImportId = argument;
172
+ return;
173
+ }
174
+ function validProjectName(name) {
175
+ return (name !== "." &&
176
+ name !== ".." &&
177
+ !["/", "\\", "\0", "*", "?", "[", "]"].some((character) => name.includes(character)));
97
178
  }
98
179
  function parsedArguments(argumentsList) {
99
180
  try {
@@ -4,6 +4,7 @@ export interface Interruption {
4
4
  readonly reply: Reply;
5
5
  }
6
6
  export declare function send(runtimeDirectory: string, request: ServiceRequest): Promise<Reply>;
7
+ export declare function listRuns(runtimeDirectory: string): Promise<Reply>;
7
8
  export declare function mutate(runtimeDirectory: string, mutation: {
8
9
  readonly request: ServiceRequest;
9
10
  readonly signal: Promise<void>;
@@ -1,7 +1,7 @@
1
1
  import net from "node:net";
2
2
  import { join } from "node:path";
3
3
  import { socketAddress } from "../broker/socket-address.js";
4
- import { parseReplyLine, requestLine, } from "../protocol.js";
4
+ import { parseReplyLine, record, requestLine, } from "../protocol.js";
5
5
  const mutations = ["run", "decision", "run-command"];
6
6
  function unavailable(runtimeDirectory) {
7
7
  return {
@@ -89,6 +89,43 @@ const unobserved = () => undefined;
89
89
  export function send(runtimeDirectory, request) {
90
90
  return exchange({ runtimeDirectory, request, onEvent: unobserved });
91
91
  }
92
+ function listedRuns(result) {
93
+ const runs = result["runs"];
94
+ return Array.isArray(runs)
95
+ ? runs.map(record).filter((run) => run !== undefined)
96
+ : [];
97
+ }
98
+ export async function listRuns(runtimeDirectory) {
99
+ const first = await send(runtimeDirectory, {
100
+ operation: "status",
101
+ parameters: { limit: 500 },
102
+ });
103
+ if (first.kind === "error")
104
+ return first;
105
+ const runs = listedRuns(first.result);
106
+ let next = first.result["next"];
107
+ let after = "";
108
+ while (typeof next === "string") {
109
+ if (next <= after)
110
+ return {
111
+ kind: "error",
112
+ error: {
113
+ code: "invalid-run-page",
114
+ detail: "The run-list cursor did not advance.",
115
+ },
116
+ };
117
+ after = next;
118
+ const page = await send(runtimeDirectory, {
119
+ operation: "status",
120
+ parameters: { limit: 500, after },
121
+ });
122
+ if (page.kind === "error")
123
+ return page;
124
+ runs.push(...listedRuns(page.result));
125
+ next = page.result["next"];
126
+ }
127
+ return { kind: "result", result: { ...first.result, runs, next: null } };
128
+ }
92
129
  export function mutate(runtimeDirectory, mutation) {
93
130
  return exchange({
94
131
  runtimeDirectory,
@@ -1,3 +1,4 @@
1
+ import type { WatchPrSettings } from "./watch-pr-settings.ts";
1
2
  import type { RuntimeInvocation } from "./runtime-arguments.ts";
2
3
  export interface Terminal {
3
4
  readonly out: (text: string) => void;
@@ -5,6 +6,8 @@ export interface Terminal {
5
6
  }
6
7
  export interface CommandEnvironment {
7
8
  readonly runtimeDirectory: string | undefined;
9
+ readonly watchActions?: string;
10
+ readonly watchPr?: WatchPrSettings;
8
11
  readonly client?: string;
9
12
  readonly workingDirectory: string;
10
13
  readonly terminal: Terminal;
@@ -1,8 +1,8 @@
1
1
  import { readFile } from "node:fs/promises";
2
2
  import { resolve } from "node:path";
3
3
  import { record, } from "../protocol.js";
4
- import { follow, mutate, send } from "./client.js";
5
- import { errorText, eventText, pendingSummary, rendered } from "./render.js";
4
+ import { follow, listRuns, mutate, send } from "./client.js";
5
+ import { errorText, eventText, pendingSummary, rendered, runOverview, statusJson, } from "./render.js";
6
6
  import { commandUsage } from "./usage.js";
7
7
  import { defaultWatchPort, watchServer } from "./watch-server.js";
8
8
  function errorObject(error, format) {
@@ -39,7 +39,9 @@ function presented(environment, outcome) {
39
39
  const { reply, format } = outcome;
40
40
  if (reply.kind === "error")
41
41
  return failed(environment, { error: reply.error, format });
42
- environment.terminal.out(format.json ? `${JSON.stringify(reply.result)}\n` : rendered(reply.result));
42
+ environment.terminal.out(format.json
43
+ ? `${JSON.stringify(statusJson(reply.result))}\n`
44
+ : rendered(reply.result));
43
45
  return 0;
44
46
  }
45
47
  async function requested(environment, exchange) {
@@ -135,6 +137,15 @@ async function status(environment, invocation) {
135
137
  const { runId, limit, after, json } = invocation;
136
138
  if (!json && runId === null)
137
139
  await summarized(environment);
140
+ if (!json && runId === null && limit === null && after === null) {
141
+ const reply = await listRuns(environment.runtimeDirectory);
142
+ return presented(environment, {
143
+ format: { json },
144
+ reply: reply.kind === "result"
145
+ ? { kind: "result", result: runOverview(reply.result) }
146
+ : reply,
147
+ });
148
+ }
138
149
  return requested(environment, {
139
150
  format: { json },
140
151
  request: {
@@ -235,14 +246,7 @@ function located(invocation, environment) {
235
246
  if (invocation.kind === "events")
236
247
  return events(environment, invocation);
237
248
  if (invocation.kind === "watch")
238
- return watchServer({
239
- runtimeDirectory: environment.runtimeDirectory,
240
- port: invocation.port ?? defaultWatchPort,
241
- client: environment.client ?? "cloving",
242
- announce: environment.terminal.out,
243
- complain: environment.terminal.error,
244
- stopped: environment.interrupted(),
245
- });
249
+ return watch(environment, invocation);
246
250
  return requested(environment, {
247
251
  format: { json: invocation.json },
248
252
  request: {
@@ -251,3 +255,17 @@ function located(invocation, environment) {
251
255
  },
252
256
  });
253
257
  }
258
+ function watch(environment, invocation) {
259
+ return watchServer({
260
+ actions: environment.watchActions ?? "on",
261
+ ...(environment.watchPr === undefined
262
+ ? {}
263
+ : { pullRequests: environment.watchPr }),
264
+ runtimeDirectory: environment.runtimeDirectory,
265
+ port: invocation.port ?? defaultWatchPort,
266
+ client: environment.client ?? "cloving",
267
+ announce: environment.terminal.out,
268
+ complain: environment.terminal.error,
269
+ stopped: environment.interrupted(),
270
+ });
271
+ }
@@ -1 +1,2 @@
1
- export declare function main(argumentsList: readonly string[]): Promise<void>;
1
+ import type { WatchPrSettings } from "./watch-pr-settings.ts";
2
+ export declare function main(argumentsList: readonly string[], watchPr?: WatchPrSettings): Promise<void>;
@@ -1,34 +1,43 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import packageMetadata from "#package" with { type: "json" };
3
+ import { redactImport } from "../chats/redact-import.js";
4
+ import { emptyCounts } from "../chats/redaction.js";
3
5
  import { importChats } from "../chats/import.js";
4
6
  import { parseInvocation } from "./arguments.js";
5
7
  import { runtimeCommand } from "./commands.js";
6
8
  import { clientCommand, runtimeDirectory } from "./runtime-directory.js";
7
- import { chatsImportUsage, usage, validateUsage } from "./usage.js";
9
+ import { chatsRedactUsage, chatsImportUsage, usage, validateUsage, } from "./usage.js";
8
10
  import { validateWorkflow } from "./validate.js";
9
- export async function main(argumentsList) {
11
+ const helpTexts = {
12
+ help: usage,
13
+ version: `${packageMetadata.version}\n`,
14
+ "validate-help": validateUsage,
15
+ "chats-import-help": chatsImportUsage,
16
+ "chats-redact-help": chatsRedactUsage,
17
+ };
18
+ function helpInvocation(invocation) {
19
+ return Object.hasOwn(helpTexts, invocation.kind);
20
+ }
21
+ export async function main(argumentsList, watchPr) {
10
22
  const invocation = parseInvocation(argumentsList);
23
+ if (refuseChatPlatform(invocation))
24
+ return;
25
+ if (helpInvocation(invocation)) {
26
+ process.stdout.write(helpTexts[invocation.kind]);
27
+ return;
28
+ }
11
29
  if (invocation.kind === "usage-error") {
12
30
  presentUsageError(invocation);
13
31
  }
14
32
  else if (invocation.kind === "validate") {
15
33
  await validationCommand(invocation);
16
34
  }
17
- else if (invocation.kind === "version") {
18
- process.stdout.write(`${packageMetadata.version}\n`);
19
- }
20
- else if (invocation.kind === "help") {
21
- process.stdout.write(usage);
22
- }
23
- else if (invocation.kind === "validate-help") {
24
- process.stdout.write(validateUsage);
25
- }
26
- else if (invocation.kind === "chats-import-help") {
27
- process.stdout.write(chatsImportUsage);
35
+ else if (invocation.kind === "chats-redact") {
36
+ await redactionCommand(invocation.importId);
28
37
  }
29
38
  else if (invocation.kind === "chats-import") {
30
39
  const result = await importChats({
31
- paths: invocation.paths,
40
+ ...invocation,
32
41
  workingDirectory: process.cwd(),
33
42
  runtimeDirectory: runtimeDirectory(process.env),
34
43
  });
@@ -38,6 +47,10 @@ export async function main(argumentsList) {
38
47
  else {
39
48
  process.exitCode = await runtimeCommand(invocation, {
40
49
  runtimeDirectory: runtimeDirectory(process.env),
50
+ ...(process.env["CLOVING_WATCH_ACTIONS"] === undefined
51
+ ? {}
52
+ : { watchActions: process.env["CLOVING_WATCH_ACTIONS"] }),
53
+ ...(watchPr === undefined ? {} : { watchPr }),
41
54
  client: clientCommand(process.env),
42
55
  workingDirectory: process.cwd(),
43
56
  terminal: {
@@ -54,6 +67,16 @@ export async function main(argumentsList) {
54
67
  });
55
68
  }
56
69
  }
70
+ function refuseChatPlatform(invocation) {
71
+ if (process.platform === "darwin")
72
+ return false;
73
+ if (invocation.kind !== "chats-import" && invocation.kind !== "chats-redact")
74
+ return false;
75
+ process.stdout.write(`${JSON.stringify({ code: "platform-unsupported" })}\n`);
76
+ process.stderr.write("platform-unsupported: Chat commands require macOS.\n");
77
+ process.exitCode = 1;
78
+ return true;
79
+ }
57
80
  function presentUsageError(invocation) {
58
81
  if (invocation.json)
59
82
  process.stdout.write(`${JSON.stringify({ schemaVersion: 1, kind: "usage-error", code: invocation.code })}\n`);
@@ -78,3 +101,27 @@ function present(report, format) {
78
101
  for (const error of report.errors)
79
102
  process.stderr.write(`${error.code}: ${error.file}: ${error.detail}\n`);
80
103
  }
104
+ async function redactionCommand(importId) {
105
+ let privateTexts = [];
106
+ try {
107
+ const setting = process.env["CLOVING_PRIVATE_TEXTS"];
108
+ if (setting !== undefined)
109
+ privateTexts = JSON.parse(setting);
110
+ if (!Array.isArray(privateTexts) ||
111
+ !privateTexts.every((item) => typeof item === "string" && item.trim() !== ""))
112
+ throw new Error("invalid-settings");
113
+ }
114
+ catch {
115
+ process.stdout.write(`${JSON.stringify({ code: "invalid-settings", importId, recordCount: 0, counts: emptyCounts(), totalCount: 0 })}\n`);
116
+ process.exitCode = 1;
117
+ return;
118
+ }
119
+ const result = await redactImport({
120
+ importId,
121
+ workingDirectory: process.cwd(),
122
+ runtimeDirectory: runtimeDirectory(process.env),
123
+ settings: { home: process.env["HOME"] || null, privateTexts },
124
+ });
125
+ process.stdout.write(`${JSON.stringify(result)}\n`);
126
+ process.exitCode = result.code === "redaction-complete" ? 0 : 1;
127
+ }
@@ -1,5 +1,8 @@
1
1
  import { type Fields } from "../protocol.ts";
2
2
  export declare function errorText(error: Fields): string;
3
+ export declare function runOverview(result: Fields): Fields;
4
+ export declare function queueLines(value: unknown): readonly string[];
5
+ export declare function statusJson(result: Fields): Fields;
3
6
  export declare function runStatus(result: Fields): readonly string[];
4
7
  export declare function decisionLines(decision: unknown): readonly string[];
5
8
  export declare function decisionList(result: Fields): readonly string[];
@@ -1,4 +1,6 @@
1
+ import { priceText, usageText, totalsSuffix } from "./usage-render.js";
1
2
  import { record } from "../protocol.js";
3
+ import { workflowRefusals } from "../workflow-refusals.js";
2
4
  function show(value) {
3
5
  return typeof value === "string" ? value : JSON.stringify(value);
4
6
  }
@@ -56,15 +58,74 @@ function admitted(result) {
56
58
  ];
57
59
  }
58
60
  function runLine(run) {
59
- return ` ${show(part(run, "runId"))} ${show(part(run, "workflowId"))} ${show(part(run, "condition"))} revision ${show(part(run, "revision"))} latest at ${show(part(run, "latestAt") ?? "none")}`;
61
+ const line = ` ${show(part(run, "runId"))} ${show(part(run, "workflowId"))} ${show(part(run, "condition"))} revision ${show(part(run, "revision"))} latest at ${show(part(run, "latestAt") ?? "none")}`;
62
+ return [line, ...chainLines(run).map((link) => ` ${link}`)].join("\n");
63
+ }
64
+ function chainLines(run) {
65
+ return [
66
+ `Parent run: ${visible(part(run, "parentRunId") ?? "none")}`,
67
+ `Chain: ${visible(part(run, "chainId") ?? part(run, "runId") ?? "none")}`,
68
+ `Child runs: ${visible(listing(part(run, "childRunIds")))}`,
69
+ ];
70
+ }
71
+ function ended(run) {
72
+ return ["completed", "failed", "cancelled"].includes(show(run["state"]));
73
+ }
74
+ function newest(first, second) {
75
+ return show(second["latestAt"] ?? "").localeCompare(show(first["latestAt"] ?? ""));
76
+ }
77
+ export function runOverview(result) {
78
+ const listed = result["runs"];
79
+ const runs = Array.isArray(listed)
80
+ ? listed.map(record).filter((run) => run !== undefined)
81
+ : [];
82
+ const active = runs.filter((run) => !ended(run)).toSorted(newest);
83
+ const finished = runs.filter(ended).toSorted(newest);
84
+ return {
85
+ ...result,
86
+ runs: [...active, ...finished.slice(0, 20)],
87
+ hiddenRuns: Math.max(0, finished.length - 20),
88
+ };
60
89
  }
61
90
  function runList(result) {
62
91
  const runs = result["runs"];
63
92
  const lines = Array.isArray(runs) ? runs.map(runLine) : [];
93
+ const hiddenRuns = result["hiddenRuns"];
94
+ const refusals = workflowRefusals(result["workflowRefusals"]);
64
95
  return [
65
96
  `Workflows: ${visible(listing(result["workflows"]))}`,
97
+ ...queueLines(result["queue"]),
98
+ ...(refusals.length === 0
99
+ ? []
100
+ : [
101
+ "Refused workflows:",
102
+ ...refusals.map((entry) => ` ${entry.scope} ${entry.label}: ${entry.codes.join(", ")}`),
103
+ ]),
66
104
  "Runs:",
67
105
  ...(lines.length === 0 ? [" none"] : lines),
106
+ ...(typeof hiddenRuns === "number" && hiddenRuns > 0
107
+ ? [
108
+ `${String(hiddenRuns)} older runs: use --limit and --after to see them`,
109
+ ]
110
+ : []),
111
+ ];
112
+ }
113
+ export function queueLines(value) {
114
+ const queue = record(value);
115
+ if (queue === undefined)
116
+ return [];
117
+ const skipped = queue["skipped"];
118
+ return [
119
+ `Queue: ${visible(queue["busy"])} of ${visible(queue["lanes"])} lanes busy`,
120
+ ...(Array.isArray(skipped)
121
+ ? skipped.map((item) => {
122
+ const dependencies = part(item, "dependencies");
123
+ const needs = Array.isArray(dependencies)
124
+ ? `; needs ${dependencies.map(visible).join(", ")}`
125
+ : "";
126
+ return `Skipped ticket ${visible(part(item, "ticketId"))}: ${visible(part(item, "reason"))}${needs}`;
127
+ })
128
+ : []),
68
129
  ];
69
130
  }
70
131
  function observation(value) {
@@ -75,36 +136,90 @@ function observation(value) {
75
136
  function feedbackLines(value) {
76
137
  return (Array.isArray(value) ? value : []).map((item) => `Feedback of ${show(part(item, "decisionId"))}: ${visible(part(item, "text"))}`);
77
138
  }
78
- function outcome(value) {
139
+ function outcomeLines(value) {
79
140
  if (record(value) === undefined)
80
- return "none";
141
+ return ["Outcome: none"];
81
142
  const reason = part(value, "reason");
82
143
  const kind = visible(part(value, "kind"));
83
- return typeof reason === "string" ? `${kind}: ${visible(reason)}` : kind;
144
+ return [
145
+ `Outcome: ${typeof reason === "string" ? `${kind}: ${visible(reason)}` : kind}`,
146
+ ...(typeof part(value, "promotionId") === "string"
147
+ ? [`Promotion: ${visible(part(value, "promotionId"))}`]
148
+ : []),
149
+ ...(typeof part(value, "ticketStatus") === "string"
150
+ ? [`Ticket status: ${visible(part(value, "ticketStatus"))}`]
151
+ : []),
152
+ ...(part(value, "issueUpdate") === "failed"
153
+ ? ["Issue status update failed; check the GitHub operation."]
154
+ : []),
155
+ ];
156
+ }
157
+ function workerLines(value) {
158
+ return (Array.isArray(value) ? value : []).flatMap((turn) => [
159
+ `Worker turn ${visible(part(turn, "operationId"))}: ${priceText(part(turn, "costUsd"), part(turn, "estimatedCostUsd"))}`,
160
+ ` ${usageText(part(turn, "usage"))}`,
161
+ ]);
162
+ }
163
+ export function statusJson(result) {
164
+ const run = record(result["run"]);
165
+ if (result["kind"] !== "run-status" || run === undefined)
166
+ return result;
167
+ const turns = run["workerTurns"];
168
+ return {
169
+ ...result,
170
+ run: {
171
+ ...run,
172
+ costDisplay: priceText(run["claudeCostUsd"], run["estimatedCostUsd"]),
173
+ ...(Array.isArray(turns)
174
+ ? {
175
+ workerTurns: turns.map((turn) => {
176
+ const fields = record(turn);
177
+ if (fields === undefined)
178
+ return turn;
179
+ return {
180
+ ...fields,
181
+ costDisplay: priceText(fields["costUsd"], fields["estimatedCostUsd"]),
182
+ };
183
+ }),
184
+ }
185
+ : {}),
186
+ },
187
+ };
188
+ }
189
+ function inputText(value) {
190
+ const text = visible(record(value) ?? null);
191
+ const characters = Array.from(text);
192
+ return characters.length > 200
193
+ ? `${characters.slice(0, 200).join("")}…`
194
+ : text;
84
195
  }
85
196
  export function runStatus(result) {
86
197
  const run = result["run"];
87
198
  const reason = part(run, "reason");
88
199
  const recovery = part(run, "recovery");
89
200
  const at = part(run, "nextActionAt") ?? null;
90
- const cost = part(run, "claudeCostUsd");
201
+ const suffix = totalsSuffix(part(run, "state"));
91
202
  return [
92
203
  `Run ${show(part(run, "runId"))} (${show(part(run, "workflowId"))})`,
93
204
  `Title: ${visible(part(run, "title") ?? "none")}`,
94
205
  `State: ${show(part(run, "state"))}`,
95
- `Outcome: ${outcome(part(run, "outcome"))}`,
206
+ ...outcomeLines(part(run, "outcome")),
96
207
  `Condition: ${show(part(run, "condition"))}`,
97
208
  `Reason: ${show(part(reason, "code"))}: ${show(part(reason, "detail"))}`,
209
+ `Input: ${inputText(part(run, "input"))}`,
98
210
  `Revision: ${show(part(run, "revision"))}, latest sequence ${show(part(run, "latestSequence"))}`,
99
211
  `Latest at: ${show(part(run, "latestAt") ?? "none")}`,
100
212
  `Pending decisions: ${listing(part(run, "pendingDecisions"))}`,
101
213
  `Evidence: ${listing(part(run, "evidence"))}`,
102
214
  `Last confirmed observation: ${observation(part(run, "lastConfirmedObservation"))}`,
103
215
  `Recovery: ${show(part(recovery, "attempts"))} of ${show(part(recovery, "limit") ?? "no limit")}`,
104
- `Claude cost: ${(typeof cost === "number" ? cost : 0).toFixed(2)} USD`,
216
+ `Cost${suffix}: ${priceText(part(run, "claudeCostUsd"), part(run, "estimatedCostUsd"))}`,
217
+ `Token usage${suffix}: ${usageText(part(run, "usage"))}`,
218
+ ...workerLines(part(run, "workerTurns")),
105
219
  `Next action: ${show(part(run, "nextAction") ?? "none")}${at === null ? "" : ` at ${show(at)}`}`,
106
220
  `Human input can help: ${part(run, "humanInputCanHelp") === true ? "yes" : "no"}`,
107
221
  ...feedbackLines(part(run, "feedback")),
222
+ ...chainLines(run),
108
223
  ];
109
224
  }
110
225
  function binding(decision) {
@@ -0,0 +1,3 @@
1
+ export declare function priceText(value: unknown, estimate?: unknown): string;
2
+ export declare function usageText(value: unknown): string;
3
+ export declare function totalsSuffix(state: unknown): string;
@@ -0,0 +1,28 @@
1
+ import { priceOf, usageOf } from "../worker-usage.js";
2
+ export function priceText(value, estimate) {
3
+ const price = priceOf(value);
4
+ if (price === null && priceOf(estimate) !== null)
5
+ return `≈ ${priceText(estimate)} (estimate)`;
6
+ if (price === null)
7
+ return "Price not known";
8
+ return `${price.toLocaleString("en-US", {
9
+ useGrouping: false,
10
+ minimumFractionDigits: 2,
11
+ maximumFractionDigits: 2,
12
+ })} USD`;
13
+ }
14
+ export function usageText(value) {
15
+ const usage = usageOf(value);
16
+ return [
17
+ ["Input tokens", usage.input_tokens],
18
+ ["Cache read tokens", usage.cache_read_input_tokens],
19
+ ["Output tokens", usage.output_tokens],
20
+ ]
21
+ .map(([label, count]) => `${String(label)}: ${count === null ? "Token usage not known" : String(count)}`)
22
+ .join(" · ");
23
+ }
24
+ export function totalsSuffix(state) {
25
+ return ["completed", "failed", "cancelled"].includes(String(state))
26
+ ? ""
27
+ : " so far";
28
+ }
@@ -1,4 +1,5 @@
1
1
  export declare const commandUsage: Readonly<Record<string, string>>;
2
- export declare const usage = "Usage: cloving [--help] [--version]\n cloving workflows validate <manifest-path> [--input <json-file>] [--json]\n cloving <command> [--help]\n\nCommands:\n workflows validate Check a compiled workflow manifest, its artifacts and optional runtime input.\n chats import Import explicitly selected Claude Code transcripts into private runtime files.\n run Submit one run of an admitted workflow.\n status List the runs or show one run.\n questions List the pending decisions.\n answer Answer one design question.\n approve Approve one pending approval.\n deny Deny one pending approval.\n pause Stop new dispatch for a run.\n resume Resume a paused run.\n drop Cancel a run and keep its files.\n events Print the committed events.\n watch Serve a page that shows the runs live.\n start Start the service for a repository.\n\nThe runtime commands need a Cloving service. CLOVING_RUNTIME_DIR names its runtime directory.\nUse npm exec -- cloving ... for a project-local installation.\n";
3
- export declare const chatsImportUsage = "Usage: cloving chats import [--] <path> [<path> ...]\n\nImports only the selected Claude Code JSONL files. Relative paths use the current directory.\nThis local command needs no service. It does not expand globs or scan directories.\nThe file limit is 10 MiB (10,485,760 bytes). Links and nonregular files are refused.\nPrivate corpus.jsonl and coverage.json files go into a new import directory under the runtime directory's chats directory.\nThe runtime selection is CLOVING_RUNTIME_DIR, XDG_RUNTIME_DIR, XDG_STATE_HOME, then HOME.\nOutput contains only counts, fixed codes and an opaque import ID. Source paths stay in the private manifest.\nExit codes: 0 for complete coverage, 1 for refused sources or output failure, 2 for invalid usage.\n";
2
+ export declare const usage = "Usage: cloving [--help] [--version]\n cloving workflows validate <manifest-path> [--input <json-file>] [--json]\n cloving <command> [--help]\n\nCommands:\n workflows validate Check a compiled workflow manifest, its artifacts and optional runtime input.\n chats redact Redact one imported chat corpus into private runtime files.\n chats import Import explicitly selected Claude Code transcripts into private runtime files.\n run Submit one run of an admitted workflow.\n status List the runs or show one run.\n questions List the pending decisions.\n answer Answer one design question.\n approve Approve one pending approval.\n deny Deny one pending approval.\n pause Stop new dispatch for a run.\n resume Resume a paused run.\n drop Cancel a run and keep its files.\n events Print the committed events.\n watch Serve a page that shows the runs live.\n start Start the service for a repository.\n\nThe runtime commands need a Cloving service. CLOVING_RUNTIME_DIR names its runtime directory.\nUse npm exec -- cloving ... for a project-local installation.\n";
3
+ export declare const chatsImportUsage = "Usage: cloving chats import [--] <path> [<path> ...]\n cloving chats import --root <projects-folder> [--root <projects-folder> ...] [--exclude-project <name> ...] [-- <path> ...]\n\nImports only the selected Claude Code JSONL files. Relative paths use the current directory.\nThis local command needs no service. It scans only explicitly named roots and does not expand globs or discover configuration.\nPositional files come first, retaining order and repetitions. Roots sort by canonical path, then entries by relative path in JavaScript string order.\nExclusions match direct project folder names exactly and prune their children. Exclusions require a root.\nScans accept lowercase .jsonl filenames, attempt at most 100 eligible files across roots, and stop before entering folders at depth four.\nLater file candidates and depth-limited folders are pending. Select pending files explicitly in a later import.\nLinked components, containment changes and roots in Git repositories are refused. Scan protections require the supported macOS kernel.\nThe file limit is 10 MiB (10,485,760 bytes). Links and nonregular files are refused.\nThe total normalized corpus limit is 50 MiB (52,428,800 UTF-8 bytes), including newlines and repeated selections.\nExceeding that total returns output-failed with exit code 1 and no completed coverage manifest; partial files may remain.\n--previous-import <IMPORT_ID> compares against one explicitly named UUID v4 import before --.\nThe earlier coverage and optional revision must be valid, completed private metadata; otherwise previous-import-refused returns exit 1 with no new import.\nA comparison writes private revision.json with ordered selection evidence and six status counts. Matching uses source path and selected root path; repetitions pair in order.\nByte-verified extensions are extended; shorter sources are truncated. Legacy imports without sizes can establish unchanged digests but cannot prove extension or truncation.\nMissing or truncated evidence makes the import partial. History completeness remains unknown.\nPrivate corpus.jsonl, structure.json and coverage.json files go into a new import directory under the runtime directory's chats directory.\nThe runtime selection is CLOVING_RUNTIME_DIR, XDG_RUNTIME_DIR, XDG_STATE_HOME, then HOME.\nOutput contains only counts, fixed codes and an opaque import ID. Source paths stay in the private manifest.\nStructure preserves branches and marks known copies without removing records. History completeness remains unknown.\nRoot imports write coverage version 2 and add excluded and pending entry counts; positional-only imports retain coverage version 1.\nExit codes: 0 for no refused, pending, missing or truncated entries (exclusions alone permit success without comparison), 1 for partial coverage or processing failure, 2 for invalid usage.\n";
4
4
  export declare const validateUsage = "Usage: cloving workflows validate <manifest-path> [--input <json-file>] [--json]\n\nChecks a Cloving workflow manifest, its compiled SDK artifacts, declared resources and toolchain, and an optional runtime input file. Relative paths resolve against the current directory.\n\nOptions:\n --input <json-file> Validate this runtime input file.\n --json Print one versioned JSON result on stdout.\n\nValidation does not admit a run, dispatch effects, import workflow code or call a model.\n\nExample:\n cloving workflows validate cloving.workflow.json --input input.json\n";
5
+ export declare const chatsRedactUsage = "Usage: cloving chats redact <IMPORT_ID>\n\nRedact one existing import selected by its UUID v4 import ID. No service is required.\nWrite redacted.jsonl and redaction.json beside the original corpus with mode 0600.\nHOME supplies the home folder. CLOVING_PRIVATE_TEXTS is an optional JSON list of nonblank strings.\nOriginals and metadata remain private. Redaction does not authorize model use or guarantee removal of every private value.\nExit codes: 0 complete, 1 processing failure, 2 invalid usage.\n";