@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
@@ -0,0 +1,129 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { describe, expect, test } from "vitest";
5
+
6
+ const __dirname = dirname(fileURLToPath(import.meta.url));
7
+
8
+ import {
9
+ cmdPromptAdapterDeveloping,
10
+ cmdPromptBootstrap,
11
+ cmdPromptList,
12
+ cmdPromptSetup,
13
+ cmdPromptUsage,
14
+ cmdPromptUsageReference,
15
+ cmdPromptWorkflowAuthoring,
16
+ } from "../commands/prompt.js";
17
+
18
+ describe("prompt commands", () => {
19
+ test("prompt list returns new prompt names", () => {
20
+ const result = cmdPromptList();
21
+ expect(result).toBeInstanceOf(Array);
22
+ expect(result).toContain("usage");
23
+ expect(result).toContain("workflow-authoring");
24
+ expect(result).toContain("adapter-developing");
25
+ expect(result).toContain("bootstrap");
26
+ expect(result).not.toContain("user");
27
+ expect(result).not.toContain("author");
28
+ expect(result).not.toContain("developer");
29
+ expect(result).not.toContain("adapter");
30
+ for (const name of result) {
31
+ expect(name).toMatch(/^\S+$/);
32
+ }
33
+ });
34
+
35
+ test("prompt usage-reference returns non-empty markdown string with frontmatter", () => {
36
+ const result = cmdPromptUsageReference();
37
+ expect(typeof result).toBe("string");
38
+ expect(result).toContain("uwf");
39
+ expect(result).toContain("thread");
40
+ expect(result).toContain("workflow");
41
+ expect(result).toContain("Quick Start");
42
+ expect(result).toContain("---");
43
+ expect(result).toContain("name:");
44
+ expect(result).toContain("version:");
45
+ expect(result.length).toBeGreaterThan(500);
46
+ });
47
+
48
+ test("prompt workflow-authoring returns non-empty markdown string with frontmatter", () => {
49
+ const result = cmdPromptWorkflowAuthoring();
50
+ expect(typeof result).toBe("string");
51
+ expect(result).toContain("frontmatter");
52
+ expect(result).toContain("graph");
53
+ expect(result).toContain("$START");
54
+ expect(result).toContain("$END");
55
+ expect(result).toContain("$status");
56
+ expect(result).toContain("---");
57
+ expect(result).toContain("name:");
58
+ expect(result).toContain("version:");
59
+ expect(result.length).toBeGreaterThan(500);
60
+ });
61
+
62
+ test("prompt adapter-developing returns non-empty markdown string with frontmatter", () => {
63
+ const result = cmdPromptAdapterDeveloping();
64
+ expect(typeof result).toBe("string");
65
+ expect(result).toContain("createAgent");
66
+ expect(result).toContain("AgentContext");
67
+ expect(result).toContain("frontmatter");
68
+ expect(result).toContain("---");
69
+ expect(result).toContain("name:");
70
+ expect(result).toContain("version:");
71
+ expect(result.length).toBeGreaterThan(500);
72
+ });
73
+
74
+ test("prompt bootstrap returns non-empty skill with frontmatter", () => {
75
+ const result = cmdPromptBootstrap();
76
+ expect(typeof result).toBe("string");
77
+ expect(result).toContain("uwf");
78
+ expect(result).toContain("---");
79
+ expect(result.length).toBeGreaterThan(100);
80
+ });
81
+
82
+ test("prompt usage combines remaining references (no developer)", () => {
83
+ const result = cmdPromptUsage();
84
+ expect(typeof result).toBe("string");
85
+ expect(result).toContain("Usage Reference");
86
+ expect(result).toContain("Workflow Authoring Reference");
87
+ expect(result).toContain("Adapter Developing Reference");
88
+ expect(result).not.toContain("Developer Reference");
89
+ expect(result).toContain("---");
90
+ expect(result.length).toBeGreaterThan(2000);
91
+ });
92
+
93
+ test("prompt setup returns simplified setup instructions", () => {
94
+ const result = cmdPromptSetup();
95
+ expect(typeof result).toBe("string");
96
+ expect(result).toContain("uwf Skill Setup");
97
+ expect(result).toContain("uwf prompt bootstrap");
98
+ expect(result).toContain("SKILL.md");
99
+ expect(result).toContain("version");
100
+ expect(result).not.toMatch(/\bbun (install|run|test|changeset|version|release)\b/);
101
+ });
102
+
103
+ test("prompt setup references new subcommand names", () => {
104
+ const result = cmdPromptSetup();
105
+ expect(result).toContain("uwf prompt usage");
106
+ expect(result).toContain("uwf prompt workflow-authoring");
107
+ expect(result).toContain("uwf prompt adapter-developing");
108
+ expect(result).not.toContain("uwf prompt user");
109
+ expect(result).not.toContain("uwf prompt author");
110
+ expect(result).not.toContain("uwf prompt developer");
111
+ expect(result).not.toMatch(/uwf prompt adapter\b(?!-developing)/);
112
+ });
113
+
114
+ test("prompt help subcommand is suppressed", { timeout: 30_000 }, () => {
115
+ const cliPath = join(__dirname, "..", "..", "dist", "cli.js");
116
+ const output = execFileSync("node", [cliPath, "prompt", "--help"], {
117
+ encoding: "utf-8",
118
+ env: { ...process.env },
119
+ });
120
+ expect(output).not.toMatch(/help\s+\[command\]/i);
121
+ expect(output).toContain("usage");
122
+ expect(output).toContain("setup");
123
+ expect(output).toContain("workflow-authoring");
124
+ expect(output).toContain("adapter-developing");
125
+ expect(output).toContain("bootstrap");
126
+ expect(output).toContain("list");
127
+ expect(output).not.toContain("developer");
128
+ });
129
+ });
@@ -0,0 +1,86 @@
1
+ import { mkdir, mkdtemp, rm } from "node:fs/promises";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { type CasRef, createThreadIndexEntry, type ThreadId } from "@united-workforce/protocol";
5
+ import { afterEach, beforeEach, describe, expect, test } from "vitest";
6
+ import { resolveHeadHash } from "../commands/shared.js";
7
+ import { completeThread, createUwfStore, setThread } from "../store.js";
8
+
9
+ let tmpDir: string;
10
+
11
+ beforeEach(async () => {
12
+ tmpDir = await mkdtemp(join(tmpdir(), "cli-uwf-resolve-head-"));
13
+ const casDir = join(tmpDir, "cas");
14
+ await mkdir(casDir, { recursive: true });
15
+ process.env.OCAS_HOME = casDir;
16
+ });
17
+
18
+ afterEach(async () => {
19
+ await rm(tmpDir, { recursive: true, force: true });
20
+ });
21
+
22
+ describe("resolveHeadHash", () => {
23
+ test("returns head hash from variable store for active thread", async () => {
24
+ const threadId = "01JTEST0000000000000000001" as ThreadId;
25
+ const uwf = await createUwfStore(tmpDir);
26
+ const headHash = (await uwf.store.cas.put(uwf.schemas.text, "active")) as CasRef;
27
+ setThread(uwf.varStore, threadId, createThreadIndexEntry(headHash as CasRef));
28
+
29
+ const result = await resolveHeadHash(tmpDir, threadId);
30
+
31
+ expect(result).toBe(headHash);
32
+ });
33
+
34
+ test("finds completed thread", async () => {
35
+ const threadId = "01JTEST0000000000000000002" as ThreadId;
36
+
37
+ const uwf = await createUwfStore(tmpDir);
38
+ const headHash = (await uwf.store.cas.put(uwf.schemas.text, "completed-head")) as CasRef;
39
+ setThread(uwf.varStore, threadId, createThreadIndexEntry(headHash));
40
+ completeThread(uwf.varStore, threadId, "completed");
41
+
42
+ const result = await resolveHeadHash(tmpDir, threadId);
43
+
44
+ expect(result).toBe(headHash);
45
+ });
46
+
47
+ // Note: Testing the error case requires CLI-level testing because resolveHeadHash
48
+ // calls fail() which does process.exit(1), terminating the test runner.
49
+ // The error behavior is tested in integration tests below via CLI invocation.
50
+
51
+ test("prioritizes active thread", async () => {
52
+ const threadId = "01JTEST0000000000000000004" as ThreadId;
53
+
54
+ const uwf = await createUwfStore(tmpDir);
55
+ const activeHead = (await uwf.store.cas.put(uwf.schemas.text, "active-v2")) as CasRef;
56
+ setThread(uwf.varStore, threadId, createThreadIndexEntry(activeHead));
57
+
58
+ const result = await resolveHeadHash(tmpDir, threadId);
59
+
60
+ // Should return the active head
61
+ expect(result).toBe(activeHead);
62
+ });
63
+
64
+ test("finds thread from multiple completed threads", async () => {
65
+ const threadId1 = "01JTEST0000000000000000005" as ThreadId;
66
+ const threadId2 = "01JTEST0000000000000000006" as ThreadId;
67
+ const threadId3 = "01JTEST0000000000000000007" as ThreadId;
68
+ const uwf = await createUwfStore(tmpDir);
69
+ const hash1 = (await uwf.store.cas.put(uwf.schemas.text, "hash-thread1")) as CasRef;
70
+ const hash2 = (await uwf.store.cas.put(uwf.schemas.text, "hash-thread2")) as CasRef;
71
+ const hash3 = (await uwf.store.cas.put(uwf.schemas.text, "hash-thread3")) as CasRef;
72
+
73
+ setThread(uwf.varStore, threadId1, createThreadIndexEntry(hash1));
74
+ completeThread(uwf.varStore, threadId1, "completed");
75
+
76
+ setThread(uwf.varStore, threadId2, createThreadIndexEntry(hash2));
77
+ completeThread(uwf.varStore, threadId2, "completed");
78
+
79
+ setThread(uwf.varStore, threadId3, createThreadIndexEntry(hash3));
80
+ completeThread(uwf.varStore, threadId3, "completed");
81
+
82
+ const result = await resolveHeadHash(tmpDir, threadId2);
83
+
84
+ expect(result).toBe(hash2);
85
+ });
86
+ });
@@ -0,0 +1,167 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { mkdtemp, rm } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
6
+ import { parse } from "yaml";
7
+ import { _agentNameFromBinary, _printAgentMenu, cmdSetup } from "../commands/setup.js";
8
+
9
+ // ─── _agentNameFromBinary ────────────────────────────────────────────────────
10
+
11
+ describe("_agentNameFromBinary", () => {
12
+ test("strips uwf- prefix", () => {
13
+ expect(_agentNameFromBinary("uwf-hermes")).toBe("hermes");
14
+ });
15
+
16
+ test("strips uwf- prefix for compound names", () => {
17
+ expect(_agentNameFromBinary("uwf-claude-code")).toBe("claude-code");
18
+ });
19
+
20
+ test("returns as-is when no uwf- prefix", () => {
21
+ expect(_agentNameFromBinary("hermes")).toBe("hermes");
22
+ });
23
+
24
+ test("handles uwf-builtin", () => {
25
+ expect(_agentNameFromBinary("uwf-builtin")).toBe("builtin");
26
+ });
27
+ });
28
+
29
+ // ─── _printAgentMenu ─────────────────────────────────────────────────────────
30
+
31
+ describe("_printAgentMenu", () => {
32
+ test("prints known agents with labels", () => {
33
+ const logs: string[] = [];
34
+ vi.spyOn(console, "log").mockImplementation((...args: unknown[]) => {
35
+ logs.push(args.join(" "));
36
+ });
37
+
38
+ _printAgentMenu(["uwf-hermes", "uwf-claude-code"]);
39
+
40
+ expect(logs.some((l) => l.includes("Hermes"))).toBe(true);
41
+ expect(logs.some((l) => l.includes("Claude Code"))).toBe(true);
42
+
43
+ vi.restoreAllMocks();
44
+ });
45
+
46
+ test("prints unknown agents with binary name as label", () => {
47
+ const logs: string[] = [];
48
+ vi.spyOn(console, "log").mockImplementation((...args: unknown[]) => {
49
+ logs.push(args.join(" "));
50
+ });
51
+
52
+ _printAgentMenu(["uwf-custom-agent"]);
53
+
54
+ expect(logs.some((l) => l.includes("uwf-custom-agent"))).toBe(true);
55
+
56
+ vi.restoreAllMocks();
57
+ });
58
+ });
59
+
60
+ // ─── cmdSetup agent config ───────────────────────────────────────────────────
61
+
62
+ describe("cmdSetup agent configuration", () => {
63
+ let storageRoot: string;
64
+
65
+ beforeEach(async () => {
66
+ storageRoot = await mkdtemp(join(tmpdir(), "uwf-setup-agent-"));
67
+ });
68
+
69
+ afterEach(async () => {
70
+ vi.restoreAllMocks();
71
+ await rm(storageRoot, { recursive: true, force: true });
72
+ });
73
+
74
+ const baseArgs = () => ({
75
+ provider: "testprovider",
76
+ baseUrl: "https://api.test.com/v1",
77
+ apiKey: "sk-test",
78
+ model: "test-model",
79
+ storageRoot,
80
+ });
81
+
82
+ test("defaults to hermes agent when no agent specified", async () => {
83
+ vi.spyOn(globalThis, "fetch").mockResolvedValue(
84
+ new Response(JSON.stringify({}), { status: 200 }),
85
+ );
86
+
87
+ const result = await cmdSetup(baseArgs());
88
+
89
+ expect(result.defaultAgent).toBe("hermes");
90
+ const config = parse(readFileSync(join(storageRoot, "config.yaml"), "utf8"));
91
+ expect(config.agents.hermes).toEqual({ command: "uwf-hermes", args: [] });
92
+ expect(config.defaultAgent).toBe("hermes");
93
+ });
94
+
95
+ test("writes specified agent as default", async () => {
96
+ vi.spyOn(globalThis, "fetch").mockResolvedValue(
97
+ new Response(JSON.stringify({}), { status: 200 }),
98
+ );
99
+
100
+ const result = await cmdSetup({ ...baseArgs(), agent: "claude-code" });
101
+
102
+ expect(result.defaultAgent).toBe("claude-code");
103
+ const config = parse(readFileSync(join(storageRoot, "config.yaml"), "utf8"));
104
+ expect(config.agents["claude-code"]).toEqual({ command: "uwf-claude-code", args: [] });
105
+ expect(config.defaultAgent).toBe("claude-code");
106
+ });
107
+
108
+ test("preserves existing agents when adding new one", async () => {
109
+ vi.spyOn(globalThis, "fetch").mockResolvedValue(
110
+ new Response(JSON.stringify({}), { status: 200 }),
111
+ );
112
+
113
+ // First setup with hermes
114
+ await cmdSetup(baseArgs());
115
+ // Second setup with claude-code
116
+ await cmdSetup({ ...baseArgs(), agent: "claude-code" });
117
+
118
+ const config = parse(readFileSync(join(storageRoot, "config.yaml"), "utf8"));
119
+ expect(config.agents.hermes).toBeDefined();
120
+ expect(config.agents["claude-code"]).toBeDefined();
121
+ expect(config.defaultAgent).toBe("claude-code");
122
+ });
123
+
124
+ test("updates defaultAgent on re-run with different agent", async () => {
125
+ vi.spyOn(globalThis, "fetch").mockResolvedValue(
126
+ new Response(JSON.stringify({}), { status: 200 }),
127
+ );
128
+
129
+ await cmdSetup(baseArgs());
130
+ const config1 = parse(readFileSync(join(storageRoot, "config.yaml"), "utf8"));
131
+ expect(config1.defaultAgent).toBe("hermes");
132
+
133
+ await cmdSetup({ ...baseArgs(), agent: "builtin" });
134
+ const config2 = parse(readFileSync(join(storageRoot, "config.yaml"), "utf8"));
135
+ expect(config2.defaultAgent).toBe("builtin");
136
+ });
137
+
138
+ test("normalizes agent name with uwf- prefix to bare name", async () => {
139
+ vi.spyOn(globalThis, "fetch").mockResolvedValue(
140
+ new Response(JSON.stringify({}), { status: 200 }),
141
+ );
142
+
143
+ const result = await cmdSetup({ ...baseArgs(), agent: "uwf-hermes" });
144
+
145
+ expect(result.defaultAgent).toBe("hermes");
146
+ const config = parse(readFileSync(join(storageRoot, "config.yaml"), "utf8"));
147
+ expect(config.agents.hermes).toEqual({ command: "uwf-hermes", args: [] });
148
+ expect(config.defaultAgent).toBe("hermes");
149
+ // Verify no duplicate uwf- prefix
150
+ expect(config.agents["uwf-hermes"]).toBeUndefined();
151
+ });
152
+
153
+ test("normalizes uwf-claude-code to claude-code", async () => {
154
+ vi.spyOn(globalThis, "fetch").mockResolvedValue(
155
+ new Response(JSON.stringify({}), { status: 200 }),
156
+ );
157
+
158
+ const result = await cmdSetup({ ...baseArgs(), agent: "uwf-claude-code" });
159
+
160
+ expect(result.defaultAgent).toBe("claude-code");
161
+ const config = parse(readFileSync(join(storageRoot, "config.yaml"), "utf8"));
162
+ expect(config.agents["claude-code"]).toEqual({ command: "uwf-claude-code", args: [] });
163
+ expect(config.defaultAgent).toBe("claude-code");
164
+ // Verify no duplicate uwf- prefix
165
+ expect(config.agents["uwf-claude-code"]).toBeUndefined();
166
+ });
167
+ });