@united-workforce/cli 0.1.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 (310) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +221 -0
  3. package/dist/__tests__/adapter-json-roundtrip.test.d.ts +2 -0
  4. package/dist/__tests__/adapter-json-roundtrip.test.d.ts.map +1 -0
  5. package/dist/__tests__/adapter-json-roundtrip.test.js +147 -0
  6. package/dist/__tests__/adapter-json-roundtrip.test.js.map +1 -0
  7. package/dist/__tests__/config.test.d.ts +2 -0
  8. package/dist/__tests__/config.test.d.ts.map +1 -0
  9. package/dist/__tests__/config.test.js +685 -0
  10. package/dist/__tests__/config.test.js.map +1 -0
  11. package/dist/__tests__/current-role.test.d.ts +2 -0
  12. package/dist/__tests__/current-role.test.d.ts.map +1 -0
  13. package/dist/__tests__/current-role.test.js +401 -0
  14. package/dist/__tests__/current-role.test.js.map +1 -0
  15. package/dist/__tests__/e2e-mock-agent.test.d.ts +2 -0
  16. package/dist/__tests__/e2e-mock-agent.test.d.ts.map +1 -0
  17. package/dist/__tests__/e2e-mock-agent.test.js +401 -0
  18. package/dist/__tests__/e2e-mock-agent.test.js.map +1 -0
  19. package/dist/__tests__/include-tag.test.d.ts +2 -0
  20. package/dist/__tests__/include-tag.test.d.ts.map +1 -0
  21. package/dist/__tests__/include-tag.test.js +69 -0
  22. package/dist/__tests__/include-tag.test.js.map +1 -0
  23. package/dist/__tests__/log.test.d.ts +2 -0
  24. package/dist/__tests__/log.test.d.ts.map +1 -0
  25. package/dist/__tests__/log.test.js +161 -0
  26. package/dist/__tests__/log.test.js.map +1 -0
  27. package/dist/__tests__/moderator-evaluate.test.d.ts +2 -0
  28. package/dist/__tests__/moderator-evaluate.test.d.ts.map +1 -0
  29. package/dist/__tests__/moderator-evaluate.test.js +170 -0
  30. package/dist/__tests__/moderator-evaluate.test.js.map +1 -0
  31. package/dist/__tests__/preload.d.ts +3 -0
  32. package/dist/__tests__/preload.d.ts.map +1 -0
  33. package/dist/__tests__/preload.js +6 -0
  34. package/dist/__tests__/preload.js.map +1 -0
  35. package/dist/__tests__/prompt.test.d.ts +2 -0
  36. package/dist/__tests__/prompt.test.d.ts.map +1 -0
  37. package/dist/__tests__/prompt.test.js +111 -0
  38. package/dist/__tests__/prompt.test.js.map +1 -0
  39. package/dist/__tests__/resolve-head-hash.test.d.ts +2 -0
  40. package/dist/__tests__/resolve-head-hash.test.d.ts.map +1 -0
  41. package/dist/__tests__/resolve-head-hash.test.js +66 -0
  42. package/dist/__tests__/resolve-head-hash.test.js.map +1 -0
  43. package/dist/__tests__/setup-agent-discovery.test.d.ts +2 -0
  44. package/dist/__tests__/setup-agent-discovery.test.d.ts.map +1 -0
  45. package/dist/__tests__/setup-agent-discovery.test.js +119 -0
  46. package/dist/__tests__/setup-agent-discovery.test.js.map +1 -0
  47. package/dist/__tests__/setup-complexity.test.d.ts +2 -0
  48. package/dist/__tests__/setup-complexity.test.d.ts.map +1 -0
  49. package/dist/__tests__/setup-complexity.test.js +314 -0
  50. package/dist/__tests__/setup-complexity.test.js.map +1 -0
  51. package/dist/__tests__/setup-validate.test.d.ts +2 -0
  52. package/dist/__tests__/setup-validate.test.d.ts.map +1 -0
  53. package/dist/__tests__/setup-validate.test.js +108 -0
  54. package/dist/__tests__/setup-validate.test.js.map +1 -0
  55. package/dist/__tests__/solve-issue-tea-worktree.test.d.ts +2 -0
  56. package/dist/__tests__/solve-issue-tea-worktree.test.d.ts.map +1 -0
  57. package/dist/__tests__/solve-issue-tea-worktree.test.js +107 -0
  58. package/dist/__tests__/solve-issue-tea-worktree.test.js.map +1 -0
  59. package/dist/__tests__/spawn-agent-json.test.d.ts +2 -0
  60. package/dist/__tests__/spawn-agent-json.test.d.ts.map +1 -0
  61. package/dist/__tests__/spawn-agent-json.test.js +79 -0
  62. package/dist/__tests__/spawn-agent-json.test.js.map +1 -0
  63. package/dist/__tests__/step-read.test.d.ts +2 -0
  64. package/dist/__tests__/step-read.test.d.ts.map +1 -0
  65. package/dist/__tests__/step-read.test.js +561 -0
  66. package/dist/__tests__/step-read.test.js.map +1 -0
  67. package/dist/__tests__/step-show-json.test.d.ts +2 -0
  68. package/dist/__tests__/step-show-json.test.d.ts.map +1 -0
  69. package/dist/__tests__/step-show-json.test.js +311 -0
  70. package/dist/__tests__/step-show-json.test.js.map +1 -0
  71. package/dist/__tests__/step-timing.test.d.ts +2 -0
  72. package/dist/__tests__/step-timing.test.d.ts.map +1 -0
  73. package/dist/__tests__/step-timing.test.js +345 -0
  74. package/dist/__tests__/step-timing.test.js.map +1 -0
  75. package/dist/__tests__/store-global-cas.test.d.ts +2 -0
  76. package/dist/__tests__/store-global-cas.test.d.ts.map +1 -0
  77. package/dist/__tests__/store-global-cas.test.js +235 -0
  78. package/dist/__tests__/store-global-cas.test.js.map +1 -0
  79. package/dist/__tests__/store-storage-root.test.d.ts +2 -0
  80. package/dist/__tests__/store-storage-root.test.d.ts.map +1 -0
  81. package/dist/__tests__/store-storage-root.test.js +43 -0
  82. package/dist/__tests__/store-storage-root.test.js.map +1 -0
  83. package/dist/__tests__/store-unified-threads.test.d.ts +2 -0
  84. package/dist/__tests__/store-unified-threads.test.d.ts.map +1 -0
  85. package/dist/__tests__/store-unified-threads.test.js +189 -0
  86. package/dist/__tests__/store-unified-threads.test.js.map +1 -0
  87. package/dist/__tests__/thread-cancel-status.test.d.ts +2 -0
  88. package/dist/__tests__/thread-cancel-status.test.d.ts.map +1 -0
  89. package/dist/__tests__/thread-cancel-status.test.js +111 -0
  90. package/dist/__tests__/thread-cancel-status.test.js.map +1 -0
  91. package/dist/__tests__/thread-list-filters.test.d.ts +2 -0
  92. package/dist/__tests__/thread-list-filters.test.d.ts.map +1 -0
  93. package/dist/__tests__/thread-list-filters.test.js +442 -0
  94. package/dist/__tests__/thread-list-filters.test.js.map +1 -0
  95. package/dist/__tests__/thread-location.test.d.ts +2 -0
  96. package/dist/__tests__/thread-location.test.d.ts.map +1 -0
  97. package/dist/__tests__/thread-location.test.js +159 -0
  98. package/dist/__tests__/thread-location.test.js.map +1 -0
  99. package/dist/__tests__/thread-read-quota.test.d.ts +2 -0
  100. package/dist/__tests__/thread-read-quota.test.d.ts.map +1 -0
  101. package/dist/__tests__/thread-read-quota.test.js +546 -0
  102. package/dist/__tests__/thread-read-quota.test.js.map +1 -0
  103. package/dist/__tests__/thread-read-xml-tags.test.d.ts +2 -0
  104. package/dist/__tests__/thread-read-xml-tags.test.d.ts.map +1 -0
  105. package/dist/__tests__/thread-read-xml-tags.test.js +610 -0
  106. package/dist/__tests__/thread-read-xml-tags.test.js.map +1 -0
  107. package/dist/__tests__/thread-resume.test.d.ts +2 -0
  108. package/dist/__tests__/thread-resume.test.d.ts.map +1 -0
  109. package/dist/__tests__/thread-resume.test.js +592 -0
  110. package/dist/__tests__/thread-resume.test.js.map +1 -0
  111. package/dist/__tests__/thread-show-status.test.d.ts +2 -0
  112. package/dist/__tests__/thread-show-status.test.d.ts.map +1 -0
  113. package/dist/__tests__/thread-show-status.test.js +267 -0
  114. package/dist/__tests__/thread-show-status.test.js.map +1 -0
  115. package/dist/__tests__/thread-start-cwd-cli.test.d.ts +2 -0
  116. package/dist/__tests__/thread-start-cwd-cli.test.d.ts.map +1 -0
  117. package/dist/__tests__/thread-start-cwd-cli.test.js +130 -0
  118. package/dist/__tests__/thread-start-cwd-cli.test.js.map +1 -0
  119. package/dist/__tests__/thread-step-count.test.d.ts +2 -0
  120. package/dist/__tests__/thread-step-count.test.d.ts.map +1 -0
  121. package/dist/__tests__/thread-step-count.test.js +55 -0
  122. package/dist/__tests__/thread-step-count.test.js.map +1 -0
  123. package/dist/__tests__/thread-suspend-step.test.d.ts +2 -0
  124. package/dist/__tests__/thread-suspend-step.test.d.ts.map +1 -0
  125. package/dist/__tests__/thread-suspend-step.test.js +155 -0
  126. package/dist/__tests__/thread-suspend-step.test.js.map +1 -0
  127. package/dist/__tests__/thread-suspended-display.test.d.ts +2 -0
  128. package/dist/__tests__/thread-suspended-display.test.d.ts.map +1 -0
  129. package/dist/__tests__/thread-suspended-display.test.js +247 -0
  130. package/dist/__tests__/thread-suspended-display.test.js.map +1 -0
  131. package/dist/__tests__/thread-test-helpers.d.ts +4 -0
  132. package/dist/__tests__/thread-test-helpers.d.ts.map +1 -0
  133. package/dist/__tests__/thread-test-helpers.js +23 -0
  134. package/dist/__tests__/thread-test-helpers.js.map +1 -0
  135. package/dist/__tests__/thread.test.d.ts +2 -0
  136. package/dist/__tests__/thread.test.d.ts.map +1 -0
  137. package/dist/__tests__/thread.test.js +883 -0
  138. package/dist/__tests__/thread.test.js.map +1 -0
  139. package/dist/__tests__/validate-semantic.test.d.ts +2 -0
  140. package/dist/__tests__/validate-semantic.test.d.ts.map +1 -0
  141. package/dist/__tests__/validate-semantic.test.js +408 -0
  142. package/dist/__tests__/validate-semantic.test.js.map +1 -0
  143. package/dist/__tests__/workflow-resolution.test.d.ts +2 -0
  144. package/dist/__tests__/workflow-resolution.test.d.ts.map +1 -0
  145. package/dist/__tests__/workflow-resolution.test.js +308 -0
  146. package/dist/__tests__/workflow-resolution.test.js.map +1 -0
  147. package/dist/background/background.d.ts +38 -0
  148. package/dist/background/background.d.ts.map +1 -0
  149. package/dist/background/background.js +123 -0
  150. package/dist/background/background.js.map +1 -0
  151. package/dist/background/index.d.ts +3 -0
  152. package/dist/background/index.d.ts.map +1 -0
  153. package/dist/background/index.js +2 -0
  154. package/dist/background/index.js.map +1 -0
  155. package/dist/background/types.d.ts +9 -0
  156. package/dist/background/types.d.ts.map +1 -0
  157. package/dist/background/types.js +2 -0
  158. package/dist/background/types.js.map +1 -0
  159. package/dist/cli.d.ts +3 -0
  160. package/dist/cli.d.ts.map +1 -0
  161. package/dist/cli.js +535 -0
  162. package/dist/cli.js.map +1 -0
  163. package/dist/commands/config.d.ts +41 -0
  164. package/dist/commands/config.d.ts.map +1 -0
  165. package/dist/commands/config.js +252 -0
  166. package/dist/commands/config.js.map +1 -0
  167. package/dist/commands/log.d.ts +26 -0
  168. package/dist/commands/log.d.ts.map +1 -0
  169. package/dist/commands/log.js +79 -0
  170. package/dist/commands/log.js.map +1 -0
  171. package/dist/commands/prompt.d.ts +6 -0
  172. package/dist/commands/prompt.d.ts.map +1 -0
  173. package/dist/commands/prompt.js +67 -0
  174. package/dist/commands/prompt.js.map +1 -0
  175. package/dist/commands/setup.d.ts +73 -0
  176. package/dist/commands/setup.d.ts.map +1 -0
  177. package/dist/commands/setup.js +522 -0
  178. package/dist/commands/setup.js.map +1 -0
  179. package/dist/commands/shared.d.ts +31 -0
  180. package/dist/commands/shared.d.ts.map +1 -0
  181. package/dist/commands/shared.js +154 -0
  182. package/dist/commands/shared.js.map +1 -0
  183. package/dist/commands/step.d.ts +18 -0
  184. package/dist/commands/step.d.ts.map +1 -0
  185. package/dist/commands/step.js +257 -0
  186. package/dist/commands/step.js.map +1 -0
  187. package/dist/commands/thread-time-parser.d.ts +6 -0
  188. package/dist/commands/thread-time-parser.d.ts.map +1 -0
  189. package/dist/commands/thread-time-parser.js +22 -0
  190. package/dist/commands/thread-time-parser.js.map +1 -0
  191. package/dist/commands/thread.d.ts +38 -0
  192. package/dist/commands/thread.d.ts.map +1 -0
  193. package/dist/commands/thread.js +1087 -0
  194. package/dist/commands/thread.js.map +1 -0
  195. package/dist/commands/workflow.d.ts +24 -0
  196. package/dist/commands/workflow.d.ts.map +1 -0
  197. package/dist/commands/workflow.js +138 -0
  198. package/dist/commands/workflow.js.map +1 -0
  199. package/dist/format.d.ts +3 -0
  200. package/dist/format.d.ts.map +1 -0
  201. package/dist/format.js +10 -0
  202. package/dist/format.js.map +1 -0
  203. package/dist/include.d.ts +12 -0
  204. package/dist/include.d.ts.map +1 -0
  205. package/dist/include.js +35 -0
  206. package/dist/include.js.map +1 -0
  207. package/dist/moderator/__tests__/evaluate.test.d.ts +2 -0
  208. package/dist/moderator/__tests__/evaluate.test.d.ts.map +1 -0
  209. package/dist/moderator/__tests__/evaluate.test.js +167 -0
  210. package/dist/moderator/__tests__/evaluate.test.js.map +1 -0
  211. package/dist/moderator/evaluate.d.ts +6 -0
  212. package/dist/moderator/evaluate.d.ts.map +1 -0
  213. package/dist/moderator/evaluate.js +65 -0
  214. package/dist/moderator/evaluate.js.map +1 -0
  215. package/dist/moderator/index.d.ts +4 -0
  216. package/dist/moderator/index.d.ts.map +1 -0
  217. package/dist/moderator/index.js +3 -0
  218. package/dist/moderator/index.js.map +1 -0
  219. package/dist/moderator/types.d.ts +25 -0
  220. package/dist/moderator/types.d.ts.map +1 -0
  221. package/dist/moderator/types.js +4 -0
  222. package/dist/moderator/types.js.map +1 -0
  223. package/dist/schemas.d.ts +16 -0
  224. package/dist/schemas.d.ts.map +1 -0
  225. package/dist/schemas.js +17 -0
  226. package/dist/schemas.js.map +1 -0
  227. package/dist/store.d.ts +77 -0
  228. package/dist/store.d.ts.map +1 -0
  229. package/dist/store.js +392 -0
  230. package/dist/store.js.map +1 -0
  231. package/dist/validate-semantic.d.ts +7 -0
  232. package/dist/validate-semantic.d.ts.map +1 -0
  233. package/dist/validate-semantic.js +263 -0
  234. package/dist/validate-semantic.js.map +1 -0
  235. package/dist/validate.d.ts +16 -0
  236. package/dist/validate.d.ts.map +1 -0
  237. package/dist/validate.js +115 -0
  238. package/dist/validate.js.map +1 -0
  239. package/package.json +44 -0
  240. package/src/__tests__/adapter-json-roundtrip.test.ts +181 -0
  241. package/src/__tests__/config.test.ts +740 -0
  242. package/src/__tests__/current-role.test.ts +438 -0
  243. package/src/__tests__/e2e-mock-agent.test.ts +498 -0
  244. package/src/__tests__/fixtures/e2e-completed-resume.mock.yaml +15 -0
  245. package/src/__tests__/fixtures/e2e-count.mock.yaml +19 -0
  246. package/src/__tests__/fixtures/e2e-count.workflow.yaml +45 -0
  247. package/src/__tests__/fixtures/e2e-linear.mock.yaml +13 -0
  248. package/src/__tests__/fixtures/e2e-linear.workflow.yaml +32 -0
  249. package/src/__tests__/fixtures/e2e-loop.mock.yaml +25 -0
  250. package/src/__tests__/fixtures/e2e-loop.workflow.yaml +36 -0
  251. package/src/__tests__/fixtures/e2e-mismatch.mock.yaml +16 -0
  252. package/src/__tests__/fixtures/e2e-mustache.mock.yaml +15 -0
  253. package/src/__tests__/fixtures/e2e-mustache.workflow.yaml +34 -0
  254. package/src/__tests__/fixtures/e2e-suspend.mock.yaml +14 -0
  255. package/src/__tests__/fixtures/e2e-suspend.workflow.yaml +24 -0
  256. package/src/__tests__/include-tag.test.ts +84 -0
  257. package/src/__tests__/log.test.ts +181 -0
  258. package/src/__tests__/moderator-evaluate.test.ts +186 -0
  259. package/src/__tests__/preload.ts +7 -0
  260. package/src/__tests__/prompt.test.ts +129 -0
  261. package/src/__tests__/resolve-head-hash.test.ts +86 -0
  262. package/src/__tests__/setup-agent-discovery.test.ts +167 -0
  263. package/src/__tests__/setup-complexity.test.ts +381 -0
  264. package/src/__tests__/setup-validate.test.ts +148 -0
  265. package/src/__tests__/solve-issue-tea-worktree.test.ts +144 -0
  266. package/src/__tests__/spawn-agent-json.test.ts +100 -0
  267. package/src/__tests__/step-read.test.ts +632 -0
  268. package/src/__tests__/step-show-json.test.ts +373 -0
  269. package/src/__tests__/step-timing.test.ts +392 -0
  270. package/src/__tests__/store-global-cas.test.ts +308 -0
  271. package/src/__tests__/store-storage-root.test.ts +49 -0
  272. package/src/__tests__/store-unified-threads.test.ts +235 -0
  273. package/src/__tests__/thread-cancel-status.test.ts +138 -0
  274. package/src/__tests__/thread-list-filters.test.ts +572 -0
  275. package/src/__tests__/thread-location.test.ts +186 -0
  276. package/src/__tests__/thread-read-quota.test.ts +613 -0
  277. package/src/__tests__/thread-read-xml-tags.test.ts +717 -0
  278. package/src/__tests__/thread-resume.test.ts +710 -0
  279. package/src/__tests__/thread-show-status.test.ts +317 -0
  280. package/src/__tests__/thread-start-cwd-cli.test.ts +164 -0
  281. package/src/__tests__/thread-step-count.test.ts +70 -0
  282. package/src/__tests__/thread-suspend-step.test.ts +181 -0
  283. package/src/__tests__/thread-suspended-display.test.ts +287 -0
  284. package/src/__tests__/thread-test-helpers.ts +37 -0
  285. package/src/__tests__/thread.test.ts +1025 -0
  286. package/src/__tests__/validate-semantic.test.ts +474 -0
  287. package/src/__tests__/workflow-resolution.test.ts +421 -0
  288. package/src/background/background.ts +147 -0
  289. package/src/background/index.ts +11 -0
  290. package/src/background/types.ts +9 -0
  291. package/src/cli.ts +692 -0
  292. package/src/commands/config.ts +304 -0
  293. package/src/commands/log.ts +116 -0
  294. package/src/commands/prompt.ts +81 -0
  295. package/src/commands/setup.ts +603 -0
  296. package/src/commands/shared.ts +227 -0
  297. package/src/commands/step.ts +343 -0
  298. package/src/commands/thread-time-parser.ts +23 -0
  299. package/src/commands/thread.ts +1575 -0
  300. package/src/commands/workflow.ts +213 -0
  301. package/src/format.ts +12 -0
  302. package/src/include.ts +37 -0
  303. package/src/moderator/__tests__/evaluate.test.ts +199 -0
  304. package/src/moderator/evaluate.ts +80 -0
  305. package/src/moderator/index.ts +7 -0
  306. package/src/moderator/types.ts +24 -0
  307. package/src/schemas.ts +26 -0
  308. package/src/store.ts +479 -0
  309. package/src/validate-semantic.ts +304 -0
  310. package/src/validate.ts +137 -0
package/src/cli.ts ADDED
@@ -0,0 +1,692 @@
1
+ #!/usr/bin/env node
2
+
3
+ import type { CasRef, ThreadId, ThreadStatus } from "@united-workforce/protocol";
4
+ import { Command } from "commander";
5
+ import { cmdConfigGet, cmdConfigList, cmdConfigSet } from "./commands/config.js";
6
+ import { cmdLogClean, cmdLogList, cmdLogShow } from "./commands/log.js";
7
+ import {
8
+ cmdPromptAdapterDeveloping,
9
+ cmdPromptBootstrap,
10
+ cmdPromptList,
11
+ cmdPromptSetup,
12
+ cmdPromptUsage,
13
+ cmdPromptUsageReference,
14
+ cmdPromptWorkflowAuthoring,
15
+ } from "./commands/prompt.js";
16
+ import { cmdSetup, cmdSetupInteractive } from "./commands/setup.js";
17
+ import { cmdStepFork, cmdStepList, cmdStepRead, cmdStepShow } from "./commands/step.js";
18
+ import {
19
+ cmdThreadCancel,
20
+ cmdThreadExec,
21
+ cmdThreadList,
22
+ cmdThreadRead,
23
+ cmdThreadResume,
24
+ cmdThreadShow,
25
+ cmdThreadStart,
26
+ cmdThreadStop,
27
+ THREAD_READ_DEFAULT_QUOTA,
28
+ } from "./commands/thread.js";
29
+ import { parseTimeInput } from "./commands/thread-time-parser.js";
30
+ import { cmdWorkflowAdd, cmdWorkflowList, cmdWorkflowShow } from "./commands/workflow.js";
31
+ import { formatOutput, type OutputFormat } from "./format.js";
32
+ import { resolveStorageRoot } from "./store.js";
33
+
34
+ function writeOutput(data: unknown): void {
35
+ const fmt = program.opts().format as OutputFormat;
36
+ process.stdout.write(`${formatOutput(data, fmt)}\n`);
37
+ }
38
+
39
+ function runAction(action: () => Promise<void>): void {
40
+ action().catch((e: unknown) => {
41
+ const message = e instanceof Error ? e.message : String(e);
42
+ process.stderr.write(`${message}\n`);
43
+ process.exit(1);
44
+ });
45
+ }
46
+
47
+ const program = new Command();
48
+
49
+ // eslint-disable-next-line -- dynamic import for version
50
+ const pkg = await import("../package.json", { with: { type: "json" } });
51
+ program
52
+ .name("uwf")
53
+ .description(
54
+ "Stateless workflow CLI\n\n" +
55
+ "Four-layer architecture:\n" +
56
+ " workflow → thread → step → turn",
57
+ )
58
+ .version(pkg.default.version, "-V, --version");
59
+ program.option("--format <fmt>", "Output format: json or yaml", "json");
60
+
61
+ const workflow = program
62
+ .command("workflow")
63
+ .description("Workflow definitions (layer 1: templates)");
64
+
65
+ workflow
66
+ .command("add")
67
+ .description("Register a workflow from YAML")
68
+ .argument("<file>", "Workflow YAML file")
69
+ .action((file: string) => {
70
+ const storageRoot = resolveStorageRoot();
71
+ runAction(async () => {
72
+ const result = await cmdWorkflowAdd(storageRoot, file);
73
+ writeOutput(result);
74
+ });
75
+ });
76
+
77
+ workflow
78
+ .command("show")
79
+ .description("Show a workflow by name or CAS hash")
80
+ .argument("<id>", "Workflow name or hash")
81
+ .action((id: string) => {
82
+ const storageRoot = resolveStorageRoot();
83
+ runAction(async () => {
84
+ const result = await cmdWorkflowShow(storageRoot, id);
85
+ writeOutput(result);
86
+ });
87
+ });
88
+
89
+ workflow
90
+ .command("list")
91
+ .description("List registered workflows")
92
+ .action(() => {
93
+ const storageRoot = resolveStorageRoot();
94
+ runAction(async () => {
95
+ const result = await cmdWorkflowList(storageRoot, process.cwd());
96
+ writeOutput(result);
97
+ });
98
+ });
99
+
100
+ const thread = program.command("thread").description("Thread execution (layer 2: instances)");
101
+
102
+ thread
103
+ .command("start")
104
+ .description("Create a thread without executing")
105
+ .argument("<workflow>", "Workflow name or hash")
106
+ .requiredOption("-p, --prompt <text>", "User prompt")
107
+ .option("--cwd <path>", "Working directory for thread execution (default: process.cwd())")
108
+ .action((workflow: string, opts: { prompt: string; cwd: string | undefined }) => {
109
+ const storageRoot = resolveStorageRoot();
110
+ runAction(async () => {
111
+ const result = await cmdThreadStart(
112
+ storageRoot,
113
+ workflow,
114
+ opts.prompt,
115
+ process.cwd(),
116
+ opts.cwd ?? process.cwd(),
117
+ );
118
+ writeOutput(result);
119
+ });
120
+ });
121
+
122
+ thread
123
+ .command("exec")
124
+ .description("Execute one or more steps")
125
+ .argument("<thread-id>", "Thread ULID")
126
+ .option("--agent <cmd>", "Override agent command")
127
+ .option("-c, --count <number>", "Number of steps to run (default: 1)")
128
+ .option("--background", "Run in background and return immediately")
129
+ .option("--_background-worker", "Internal flag for background worker process", false)
130
+ .action(
131
+ (
132
+ threadId: string,
133
+ opts: {
134
+ agent: string | undefined;
135
+ count: string | undefined;
136
+ background: boolean;
137
+ _backgroundWorker: boolean;
138
+ },
139
+ ) => {
140
+ const storageRoot = resolveStorageRoot();
141
+ runAction(async () => {
142
+ const agentOverride = opts.agent ?? null;
143
+ const count = opts.count !== undefined ? Number(opts.count) : 1;
144
+ const background = opts.background ?? false;
145
+ const backgroundWorker = opts._backgroundWorker ?? false;
146
+
147
+ const results = await cmdThreadExec(
148
+ storageRoot,
149
+ threadId,
150
+ agentOverride,
151
+ count,
152
+ background,
153
+ backgroundWorker,
154
+ );
155
+ if (results.length === 1) {
156
+ writeOutput(results[0]);
157
+ } else {
158
+ writeOutput(results);
159
+ }
160
+ });
161
+ },
162
+ );
163
+
164
+ thread
165
+ .command("show")
166
+ .description("Show thread head pointer")
167
+ .argument("<thread-id>", "Thread ULID")
168
+ .action((threadId: string) => {
169
+ const storageRoot = resolveStorageRoot();
170
+ runAction(async () => {
171
+ const result = await cmdThreadShow(storageRoot, threadId);
172
+ writeOutput(result);
173
+ });
174
+ });
175
+
176
+ // Helper functions for thread list command parsing
177
+ function parseStatusFilter(status: string | undefined): ThreadStatus[] | null {
178
+ if (status === undefined) return null;
179
+ const raw = status.trim();
180
+ if (raw === "active") return ["idle", "running"];
181
+
182
+ const parts = raw.split(",").map((s) => s.trim());
183
+ const validStatuses: ThreadStatus[] = ["idle", "running", "suspended", "completed", "cancelled"];
184
+ for (const part of parts) {
185
+ if (!validStatuses.includes(part as ThreadStatus)) {
186
+ process.stderr.write(
187
+ `Invalid status: ${part}. Must be one of: idle, running, suspended, completed, cancelled, active\n`,
188
+ );
189
+ process.exit(1);
190
+ }
191
+ }
192
+ return parts as ThreadStatus[];
193
+ }
194
+
195
+ function parseTimeFilters(
196
+ after: string | undefined,
197
+ before: string | undefined,
198
+ nowMs: number,
199
+ ): { afterMs: number | null; beforeMs: number | null } {
200
+ try {
201
+ const afterMs = after !== undefined ? parseTimeInput(after, nowMs) : null;
202
+ const beforeMs = before !== undefined ? parseTimeInput(before, nowMs) : null;
203
+ return { afterMs, beforeMs };
204
+ } catch (e) {
205
+ const message = e instanceof Error ? e.message : String(e);
206
+ process.stderr.write(`${message}\n`);
207
+ process.exit(1);
208
+ }
209
+ }
210
+
211
+ function parsePaginationOptions(
212
+ skip: string | undefined,
213
+ take: string | undefined,
214
+ ): { skip: number | null; take: number | null } {
215
+ let skipVal: number | null = null;
216
+ let takeVal: number | null = null;
217
+
218
+ if (skip !== undefined) {
219
+ skipVal = Number.parseInt(skip, 10);
220
+ if (!Number.isInteger(skipVal) || skipVal < 0) {
221
+ process.stderr.write("--skip must be a non-negative integer\n");
222
+ process.exit(1);
223
+ }
224
+ }
225
+ if (take !== undefined) {
226
+ takeVal = Number.parseInt(take, 10);
227
+ if (!Number.isInteger(takeVal) || takeVal < 1) {
228
+ process.stderr.write("--take must be a positive integer\n");
229
+ process.exit(1);
230
+ }
231
+ }
232
+ return { skip: skipVal, take: takeVal };
233
+ }
234
+
235
+ thread
236
+ .command("list")
237
+ .description("List threads")
238
+ .option(
239
+ "--status <status>",
240
+ "Filter by status: idle, running, completed, cancelled, active (idle+running), or comma-separated values",
241
+ )
242
+ .option("--after <date>", "Filter threads created after this date (ISO or relative like '7d')")
243
+ .option("--before <date>", "Filter threads created before this date (ISO or relative like '7d')")
244
+ .option("--skip <n>", "Skip first n threads")
245
+ .option("--take <n>", "Return at most n threads")
246
+ .action(
247
+ (opts: {
248
+ status: string | undefined;
249
+ after: string | undefined;
250
+ before: string | undefined;
251
+ skip: string | undefined;
252
+ take: string | undefined;
253
+ }) => {
254
+ const storageRoot = resolveStorageRoot();
255
+ runAction(async () => {
256
+ const statusFilter = parseStatusFilter(opts.status);
257
+ const nowMs = Date.now();
258
+ const { afterMs, beforeMs } = parseTimeFilters(opts.after, opts.before, nowMs);
259
+ const { skip, take } = parsePaginationOptions(opts.skip, opts.take);
260
+
261
+ const result = await cmdThreadList(
262
+ storageRoot,
263
+ statusFilter,
264
+ afterMs,
265
+ beforeMs,
266
+ skip,
267
+ take,
268
+ );
269
+ writeOutput(result);
270
+ });
271
+ },
272
+ );
273
+
274
+ thread
275
+ .command("resume")
276
+ .description("Resume a suspended thread and re-run the suspended role")
277
+ .argument("<thread-id>", "Thread ULID")
278
+ .option("-p, --prompt <text>", "Supplementary info to append to the resume prompt")
279
+ .option("--agent <cmd>", "Override agent command")
280
+ .action((threadId: string, opts: { prompt: string | undefined; agent: string | undefined }) => {
281
+ const storageRoot = resolveStorageRoot();
282
+ runAction(async () => {
283
+ const supplement = opts.prompt ?? null;
284
+ const agentOverride = opts.agent ?? null;
285
+ const result = await cmdThreadResume(
286
+ storageRoot,
287
+ threadId as ThreadId,
288
+ supplement,
289
+ agentOverride,
290
+ );
291
+ writeOutput(result);
292
+ });
293
+ });
294
+
295
+ thread
296
+ .command("stop")
297
+ .description("Stop background execution of a thread (keep thread active)")
298
+ .argument("<thread-id>", "Thread ULID")
299
+ .action((threadId: string) => {
300
+ const storageRoot = resolveStorageRoot();
301
+ runAction(async () => {
302
+ const result = await cmdThreadStop(storageRoot, threadId);
303
+ writeOutput(result);
304
+ });
305
+ });
306
+
307
+ thread
308
+ .command("cancel")
309
+ .description("Cancel a thread (stop execution and move to history)")
310
+ .argument("<thread-id>", "Thread ULID")
311
+ .action((threadId: string) => {
312
+ const storageRoot = resolveStorageRoot();
313
+ runAction(async () => {
314
+ const result = await cmdThreadCancel(storageRoot, threadId);
315
+ writeOutput(result);
316
+ });
317
+ });
318
+
319
+ thread
320
+ .command("read")
321
+ .description("Read thread context as human-readable markdown")
322
+ .argument("<thread-id>", "Thread ULID")
323
+ .option("--quota <chars>", "Max output characters", String(THREAD_READ_DEFAULT_QUOTA))
324
+ .option("--before <step-hash>", "Load steps before this hash (exclusive)")
325
+ .option("--start", "Include start step in output")
326
+ .action(
327
+ (threadId: string, opts: { quota: string; before: string | undefined; start: boolean }) => {
328
+ const storageRoot = resolveStorageRoot();
329
+ runAction(async () => {
330
+ const quota = Number.parseInt(opts.quota, 10);
331
+ if (!Number.isFinite(quota) || quota < 1) {
332
+ process.stderr.write("invalid --quota: must be a positive integer\n");
333
+ process.exit(1);
334
+ }
335
+ const before = opts.before ?? null;
336
+ const markdown = await cmdThreadRead(
337
+ storageRoot,
338
+ threadId as ThreadId,
339
+ quota,
340
+ before,
341
+ opts.start ?? false,
342
+ );
343
+ process.stdout.write(markdown.endsWith("\n") ? markdown : `${markdown}\n`);
344
+ });
345
+ },
346
+ );
347
+
348
+ const step = program.command("step").description("Step results (layer 3: single cycle)");
349
+
350
+ step
351
+ .command("list")
352
+ .description("List all steps in a thread")
353
+ .argument("<thread-id>", "Thread ULID")
354
+ .action((threadId: string) => {
355
+ const storageRoot = resolveStorageRoot();
356
+ runAction(async () => {
357
+ const result = await cmdStepList(storageRoot, threadId);
358
+ writeOutput(result);
359
+ });
360
+ });
361
+
362
+ step
363
+ .command("show")
364
+ .description("Show details of a specific step")
365
+ .argument("<step-hash>", "CAS hash of the StepNode")
366
+ .action((stepHash: string) => {
367
+ const storageRoot = resolveStorageRoot();
368
+ runAction(async () => {
369
+ const detail = await cmdStepShow(storageRoot, stepHash as CasRef);
370
+ writeOutput(detail);
371
+ });
372
+ });
373
+
374
+ step
375
+ .command("read")
376
+ .description("Read a step's turns as human-readable markdown")
377
+ .argument("<step-hash>", "CAS hash of the StepNode")
378
+ .option("--quota <chars>", "Max output characters", "4000")
379
+ .option("--prompt", "Show the assembled prompt sent to the agent instead of turns")
380
+ .action((stepHash: string, opts: { quota: string; prompt: boolean }) => {
381
+ const storageRoot = resolveStorageRoot();
382
+ runAction(async () => {
383
+ const quota = Number.parseInt(opts.quota, 10);
384
+ if (!Number.isFinite(quota) || quota < 1) {
385
+ process.stderr.write("invalid --quota: must be a positive integer\n");
386
+ process.exit(1);
387
+ }
388
+ const markdown = await cmdStepRead(
389
+ storageRoot,
390
+ stepHash as CasRef,
391
+ quota,
392
+ opts.prompt === true,
393
+ );
394
+ process.stdout.write(markdown.endsWith("\n") ? markdown : `${markdown}\n`);
395
+ });
396
+ });
397
+
398
+ step
399
+ .command("fork")
400
+ .description("Fork a thread from a specific step")
401
+ .argument("<step-hash>", "CAS hash of the StartNode or StepNode to fork from")
402
+ .action((stepHash: string) => {
403
+ const storageRoot = resolveStorageRoot();
404
+ runAction(async () => {
405
+ const result = await cmdStepFork(storageRoot, stepHash as CasRef);
406
+ writeOutput(result);
407
+ });
408
+ });
409
+
410
+ // ── Deprecation Handlers ──────────────────────────────────────────────────────
411
+ // These commands have been removed. Show helpful error messages.
412
+
413
+ workflow
414
+ .command("put")
415
+ .description("[DEPRECATED] Use 'workflow add' instead")
416
+ .argument("<file>", "Workflow YAML file")
417
+ .action(() => {
418
+ process.stderr.write(`Error: Command 'workflow put' has been removed.
419
+ Use 'workflow add' instead.
420
+
421
+ For more information, see: uwf help workflow add
422
+ `);
423
+ process.exit(1);
424
+ });
425
+
426
+ thread
427
+ .command("step")
428
+ .description("[DEPRECATED] Use 'thread exec' instead")
429
+ .argument("<thread-id>", "Thread ULID")
430
+ .allowUnknownOption()
431
+ .action(() => {
432
+ process.stderr.write(`Error: Command 'thread step' has been removed.
433
+ Use 'thread exec' instead.
434
+
435
+ For more information, see: uwf help thread exec
436
+ `);
437
+ process.exit(1);
438
+ });
439
+
440
+ thread
441
+ .command("steps")
442
+ .description("[DEPRECATED] Use 'step list' instead")
443
+ .argument("<thread-id>", "Thread ULID")
444
+ .action(() => {
445
+ process.stderr.write(`Error: Command 'thread steps' has been removed.
446
+ Use 'step list' instead.
447
+
448
+ For more information, see: uwf help step list
449
+ `);
450
+ process.exit(1);
451
+ });
452
+
453
+ thread
454
+ .command("step-details")
455
+ .description("[DEPRECATED] Use 'step show' instead")
456
+ .argument("<step-hash>", "Step hash")
457
+ .action(() => {
458
+ process.stderr.write(`Error: Command 'thread step-details' has been removed.
459
+ Use 'step show' instead.
460
+
461
+ For more information, see: uwf help step show
462
+ `);
463
+ process.exit(1);
464
+ });
465
+
466
+ thread
467
+ .command("fork")
468
+ .description("[DEPRECATED] Use 'step fork' instead")
469
+ .argument("<step-hash>", "Step hash")
470
+ .action(() => {
471
+ process.stderr.write(`Error: Command 'thread fork' has been removed.
472
+ Use 'step fork' instead.
473
+
474
+ For more information, see: uwf help step fork
475
+ `);
476
+ process.exit(1);
477
+ });
478
+
479
+ thread
480
+ .command("kill")
481
+ .description("[DEPRECATED] Use 'thread stop' or 'thread cancel' instead")
482
+ .argument("<thread-id>", "Thread ULID")
483
+ .action(() => {
484
+ process.stderr.write(`Error: Command 'thread kill' has been removed.
485
+ Use 'thread stop' to stop background execution (keep thread active),
486
+ or 'thread cancel' to cancel and archive the thread.
487
+
488
+ For more information, see:
489
+ uwf help thread stop
490
+ uwf help thread cancel
491
+ `);
492
+ process.exit(1);
493
+ });
494
+
495
+ thread
496
+ .command("running")
497
+ .description("[DEPRECATED] Use 'thread list --status running' instead")
498
+ .action(() => {
499
+ process.stderr.write(`Error: Command 'thread running' has been removed.
500
+ Use 'thread list --status running' instead.
501
+
502
+ For more information, see: uwf help thread list
503
+ `);
504
+ process.exit(1);
505
+ });
506
+
507
+ const prompt = program.command("prompt").description("Built-in prompt references for agents");
508
+ prompt.addHelpCommand(false);
509
+
510
+ prompt
511
+ .command("usage")
512
+ .description("Print the complete skill content (all references combined)")
513
+ .action(() => {
514
+ console.log(cmdPromptUsage());
515
+ });
516
+
517
+ prompt
518
+ .command("setup")
519
+ .description("Print setup instructions for installing the uwf skill")
520
+ .action(() => {
521
+ console.log(cmdPromptSetup());
522
+ });
523
+
524
+ prompt
525
+ .command("usage-reference")
526
+ .description("Print the usage reference (CLI guide + typical workflows)")
527
+ .action(() => {
528
+ console.log(cmdPromptUsageReference());
529
+ });
530
+
531
+ prompt
532
+ .command("workflow-authoring")
533
+ .description("Print the workflow authoring reference (YAML design guide)")
534
+ .action(() => {
535
+ console.log(cmdPromptWorkflowAuthoring());
536
+ });
537
+
538
+ prompt
539
+ .command("adapter-developing")
540
+ .description("Print the adapter developing reference (building agent adapters)")
541
+ .action(() => {
542
+ console.log(cmdPromptAdapterDeveloping());
543
+ });
544
+
545
+ prompt
546
+ .command("bootstrap")
547
+ .description("Print the bootstrap skill YAML for Hermes agents")
548
+ .action(() => {
549
+ console.log(cmdPromptBootstrap());
550
+ });
551
+
552
+ prompt
553
+ .command("list")
554
+ .description("List all available prompt names")
555
+ .action(() => {
556
+ console.log(cmdPromptList().join("\n"));
557
+ });
558
+
559
+ program
560
+ .command("setup")
561
+ .description("Configure provider, model, and agent")
562
+ .option("--provider <name>", "Provider name")
563
+ .option("--base-url <url>", "OpenAI-compatible API base URL")
564
+ .option("--api-key <key>", "API key")
565
+ .option("--model <name>", "Default model name")
566
+ .option("--agent <name>", "Default agent adapter (e.g. hermes → uwf-hermes)")
567
+ .action(
568
+ (opts: {
569
+ provider?: string;
570
+ baseUrl?: string;
571
+ apiKey?: string;
572
+ model?: string;
573
+ agent?: string;
574
+ }) => {
575
+ const storageRoot = resolveStorageRoot();
576
+ runAction(async () => {
577
+ if (opts.provider && opts.baseUrl && opts.apiKey && opts.model) {
578
+ const result = await cmdSetup({
579
+ provider: opts.provider,
580
+ baseUrl: opts.baseUrl,
581
+ apiKey: opts.apiKey,
582
+ model: opts.model,
583
+ agent: opts.agent ?? undefined,
584
+ storageRoot,
585
+ });
586
+ writeOutput(result);
587
+ } else if (!opts.provider && !opts.baseUrl && !opts.apiKey && !opts.model) {
588
+ await cmdSetupInteractive(storageRoot);
589
+ } else {
590
+ throw new Error(
591
+ "Non-interactive setup requires all of: --provider, --base-url, --api-key, --model",
592
+ );
593
+ }
594
+ });
595
+ },
596
+ );
597
+
598
+ const log = program.command("log").description("Process-level debug logs");
599
+
600
+ log
601
+ .command("list")
602
+ .description("List log files with sizes")
603
+ .action(() => {
604
+ const storageRoot = resolveStorageRoot();
605
+ runAction(async () => {
606
+ const result = await cmdLogList(storageRoot);
607
+ writeOutput(result);
608
+ });
609
+ });
610
+
611
+ log
612
+ .command("show")
613
+ .description("Show and filter log entries")
614
+ .option("--thread <thread-id>", "Filter by thread ID")
615
+ .option("--process <pid>", "Filter by process ID")
616
+ .option("--date <date>", "Filter by date (YYYY-MM-DD)")
617
+ .action(
618
+ (opts: {
619
+ thread: string | undefined;
620
+ process: string | undefined;
621
+ date: string | undefined;
622
+ }) => {
623
+ const storageRoot = resolveStorageRoot();
624
+ runAction(async () => {
625
+ const result = await cmdLogShow(storageRoot, {
626
+ thread: opts.thread ?? null,
627
+ process: opts.process ?? null,
628
+ date: opts.date ?? null,
629
+ });
630
+ writeOutput(result);
631
+ });
632
+ },
633
+ );
634
+
635
+ log
636
+ .command("clean")
637
+ .description("Delete log files older than given date")
638
+ .requiredOption("--before <date>", "Delete files before this date (YYYY-MM-DD)")
639
+ .action((opts: { before: string }) => {
640
+ const storageRoot = resolveStorageRoot();
641
+ runAction(async () => {
642
+ const result = await cmdLogClean(storageRoot, opts.before);
643
+ writeOutput(result);
644
+ });
645
+ });
646
+
647
+ const config = program.command("config").description("Configuration management");
648
+
649
+ config
650
+ .command("list")
651
+ .description("Display all configuration values (masks API keys)")
652
+ .action(() => {
653
+ const storageRoot = resolveStorageRoot();
654
+ runAction(async () => {
655
+ const result = await cmdConfigList(storageRoot);
656
+ writeOutput(result);
657
+ });
658
+ });
659
+
660
+ config
661
+ .command("get")
662
+ .description("Get a specific configuration value")
663
+ .argument(
664
+ "<key>",
665
+ "Dot-notation path to config value (e.g., defaultAgent, providers.dashscope.baseUrl)",
666
+ )
667
+ .action((key: string) => {
668
+ const storageRoot = resolveStorageRoot();
669
+ runAction(async () => {
670
+ const result = await cmdConfigGet(storageRoot, key);
671
+ writeOutput({ value: result });
672
+ });
673
+ });
674
+
675
+ config
676
+ .command("set")
677
+ .description("Set a specific configuration value")
678
+ .argument("<key>", "Dot-notation path to config value")
679
+ .argument("<value>", "New value (use JSON array for 'args' key, e.g., '[\"--flag\"]')")
680
+ .action((key: string, value: string) => {
681
+ const storageRoot = resolveStorageRoot();
682
+ runAction(async () => {
683
+ const result = await cmdConfigSet(storageRoot, key, value);
684
+ writeOutput(result);
685
+ });
686
+ });
687
+
688
+ program.parseAsync(process.argv).catch((e: unknown) => {
689
+ const message = e instanceof Error ? e.message : String(e);
690
+ process.stderr.write(`${message}\n`);
691
+ process.exit(1);
692
+ });