@united-workforce/cli 0.6.1 → 0.8.1

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 (167) hide show
  1. package/README.md +120 -5
  2. package/dist/.build-fingerprint +1 -1
  3. package/dist/__tests__/agent-resolution-llm-free.test.js +9 -2
  4. package/dist/__tests__/agent-resolution-llm-free.test.js.map +1 -1
  5. package/dist/__tests__/broker-prompt.test.d.ts +10 -0
  6. package/dist/__tests__/broker-prompt.test.d.ts.map +1 -0
  7. package/dist/__tests__/broker-prompt.test.js +129 -0
  8. package/dist/__tests__/broker-prompt.test.js.map +1 -0
  9. package/dist/__tests__/broker-step-active-turns.test.d.ts +20 -0
  10. package/dist/__tests__/broker-step-active-turns.test.d.ts.map +1 -0
  11. package/dist/__tests__/broker-step-active-turns.test.js +428 -0
  12. package/dist/__tests__/broker-step-active-turns.test.js.map +1 -0
  13. package/dist/__tests__/broker-step-turn-chain-phase2.test.d.ts +13 -0
  14. package/dist/__tests__/broker-step-turn-chain-phase2.test.d.ts.map +1 -0
  15. package/dist/__tests__/broker-step-turn-chain-phase2.test.js +429 -0
  16. package/dist/__tests__/broker-step-turn-chain-phase2.test.js.map +1 -0
  17. package/dist/__tests__/config.test.js +33 -37
  18. package/dist/__tests__/config.test.js.map +1 -1
  19. package/dist/__tests__/e2e-broker-step-suspend.test.d.ts +18 -0
  20. package/dist/__tests__/e2e-broker-step-suspend.test.d.ts.map +1 -0
  21. package/dist/__tests__/e2e-broker-step-suspend.test.js +313 -0
  22. package/dist/__tests__/e2e-broker-step-suspend.test.js.map +1 -0
  23. package/dist/__tests__/e2e-broker-step.test.d.ts +13 -0
  24. package/dist/__tests__/e2e-broker-step.test.d.ts.map +1 -0
  25. package/dist/__tests__/e2e-broker-step.test.js +278 -0
  26. package/dist/__tests__/e2e-broker-step.test.js.map +1 -0
  27. package/dist/__tests__/e2e-mock-agent.test.js +1 -1
  28. package/dist/__tests__/e2e-mock-agent.test.js.map +1 -1
  29. package/dist/__tests__/e2e-thread-resume-timeout-suspend.test.d.ts +28 -0
  30. package/dist/__tests__/e2e-thread-resume-timeout-suspend.test.d.ts.map +1 -0
  31. package/dist/__tests__/e2e-thread-resume-timeout-suspend.test.js +322 -0
  32. package/dist/__tests__/e2e-thread-resume-timeout-suspend.test.js.map +1 -0
  33. package/dist/__tests__/log-tag-validity.test.d.ts +2 -0
  34. package/dist/__tests__/log-tag-validity.test.d.ts.map +1 -0
  35. package/dist/__tests__/log-tag-validity.test.js +110 -0
  36. package/dist/__tests__/log-tag-validity.test.js.map +1 -0
  37. package/dist/__tests__/setup-agent-discovery.test.js +35 -23
  38. package/dist/__tests__/setup-agent-discovery.test.js.map +1 -1
  39. package/dist/__tests__/setup-no-llm.test.js +5 -2
  40. package/dist/__tests__/setup-no-llm.test.js.map +1 -1
  41. package/dist/__tests__/step-ask.test.js +9 -6
  42. package/dist/__tests__/step-ask.test.js.map +1 -1
  43. package/dist/__tests__/step-show-json.test.js +5 -5
  44. package/dist/__tests__/step-show-json.test.js.map +1 -1
  45. package/dist/__tests__/step-show-text.test.d.ts +2 -0
  46. package/dist/__tests__/step-show-text.test.d.ts.map +1 -0
  47. package/dist/__tests__/step-show-text.test.js +192 -0
  48. package/dist/__tests__/step-show-text.test.js.map +1 -0
  49. package/dist/__tests__/step-turns-cli-subprocess.test.d.ts +21 -0
  50. package/dist/__tests__/step-turns-cli-subprocess.test.d.ts.map +1 -0
  51. package/dist/__tests__/step-turns-cli-subprocess.test.js +356 -0
  52. package/dist/__tests__/step-turns-cli-subprocess.test.js.map +1 -0
  53. package/dist/__tests__/step-turns-panorama-phase3.test.d.ts +21 -0
  54. package/dist/__tests__/step-turns-panorama-phase3.test.d.ts.map +1 -0
  55. package/dist/__tests__/step-turns-panorama-phase3.test.js +476 -0
  56. package/dist/__tests__/step-turns-panorama-phase3.test.js.map +1 -0
  57. package/dist/__tests__/step-turns.test.d.ts +24 -0
  58. package/dist/__tests__/step-turns.test.d.ts.map +1 -0
  59. package/dist/__tests__/step-turns.test.js +646 -0
  60. package/dist/__tests__/step-turns.test.js.map +1 -0
  61. package/dist/__tests__/store-turn-chain.test.d.ts +2 -0
  62. package/dist/__tests__/store-turn-chain.test.d.ts.map +1 -0
  63. package/dist/__tests__/store-turn-chain.test.js +341 -0
  64. package/dist/__tests__/store-turn-chain.test.js.map +1 -0
  65. package/dist/__tests__/thread-agent-failure-suspended.test.js +3 -3
  66. package/dist/__tests__/thread-agent-failure-suspended.test.js.map +1 -1
  67. package/dist/__tests__/thread-list-limit-offset.test.d.ts +24 -0
  68. package/dist/__tests__/thread-list-limit-offset.test.d.ts.map +1 -0
  69. package/dist/__tests__/thread-list-limit-offset.test.js +254 -0
  70. package/dist/__tests__/thread-list-limit-offset.test.js.map +1 -0
  71. package/dist/__tests__/thread-list-template-ms-date.test.js +7 -2
  72. package/dist/__tests__/thread-list-template-ms-date.test.js.map +1 -1
  73. package/dist/__tests__/thread-poke.test.js +6 -6
  74. package/dist/__tests__/thread-poke.test.js.map +1 -1
  75. package/dist/__tests__/thread-resume.test.js +2 -2
  76. package/dist/__tests__/thread-resume.test.js.map +1 -1
  77. package/dist/__tests__/thread-suspend-step.test.js +1 -1
  78. package/dist/__tests__/thread-suspend-step.test.js.map +1 -1
  79. package/dist/__tests__/thread.test.js +28 -14
  80. package/dist/__tests__/thread.test.js.map +1 -1
  81. package/dist/cli.js +910 -344
  82. package/dist/cli.js.map +1 -1
  83. package/dist/commands/broker-step.d.ts +117 -0
  84. package/dist/commands/broker-step.d.ts.map +1 -0
  85. package/dist/commands/broker-step.js +654 -0
  86. package/dist/commands/broker-step.js.map +1 -0
  87. package/dist/commands/config.d.ts.map +1 -1
  88. package/dist/commands/config.js +2 -23
  89. package/dist/commands/config.js.map +1 -1
  90. package/dist/commands/prompt.d.ts.map +1 -1
  91. package/dist/commands/prompt.js +43 -51
  92. package/dist/commands/prompt.js.map +1 -1
  93. package/dist/commands/setup.d.ts +6 -4
  94. package/dist/commands/setup.d.ts.map +1 -1
  95. package/dist/commands/setup.js +24 -27
  96. package/dist/commands/setup.js.map +1 -1
  97. package/dist/commands/step.d.ts +54 -6
  98. package/dist/commands/step.d.ts.map +1 -1
  99. package/dist/commands/step.js +484 -134
  100. package/dist/commands/step.js.map +1 -1
  101. package/dist/commands/thread.d.ts +4 -0
  102. package/dist/commands/thread.d.ts.map +1 -1
  103. package/dist/commands/thread.js +77 -151
  104. package/dist/commands/thread.js.map +1 -1
  105. package/dist/output-mappers.d.ts +8 -0
  106. package/dist/output-mappers.d.ts.map +1 -1
  107. package/dist/output-mappers.js +72 -18
  108. package/dist/output-mappers.js.map +1 -1
  109. package/dist/schemas.d.ts +3 -0
  110. package/dist/schemas.d.ts.map +1 -1
  111. package/dist/schemas.js +17 -3
  112. package/dist/schemas.js.map +1 -1
  113. package/dist/store.d.ts +147 -1
  114. package/dist/store.d.ts.map +1 -1
  115. package/dist/store.js +254 -1
  116. package/dist/store.js.map +1 -1
  117. package/dist/text-renderers.d.ts.map +1 -1
  118. package/dist/text-renderers.js +27 -2
  119. package/dist/text-renderers.js.map +1 -1
  120. package/package.json +7 -5
  121. package/src/__tests__/agent-resolution-llm-free.test.ts +14 -2
  122. package/src/__tests__/broker-prompt.test.ts +142 -0
  123. package/src/__tests__/broker-step-active-turns.test.ts +509 -0
  124. package/src/__tests__/broker-step-turn-chain-phase2.test.ts +525 -0
  125. package/src/__tests__/config.test.ts +35 -39
  126. package/src/__tests__/e2e-broker-step-suspend.test.ts +351 -0
  127. package/src/__tests__/e2e-broker-step.test.ts +320 -0
  128. package/src/__tests__/e2e-mock-agent.test.ts +1 -1
  129. package/src/__tests__/e2e-thread-resume-timeout-suspend.test.ts +360 -0
  130. package/src/__tests__/log-tag-validity.test.ts +124 -0
  131. package/src/__tests__/setup-agent-discovery.test.ts +35 -23
  132. package/src/__tests__/setup-no-llm.test.ts +5 -2
  133. package/src/__tests__/step-ask.test.ts +9 -6
  134. package/src/__tests__/step-show-json.test.ts +5 -5
  135. package/src/__tests__/step-show-text.test.ts +236 -0
  136. package/src/__tests__/step-turns-cli-subprocess.test.ts +411 -0
  137. package/src/__tests__/step-turns-panorama-phase3.test.ts +579 -0
  138. package/src/__tests__/step-turns.test.ts +734 -0
  139. package/src/__tests__/store-turn-chain.test.ts +386 -0
  140. package/src/__tests__/thread-agent-failure-suspended.test.ts +3 -3
  141. package/src/__tests__/thread-list-limit-offset.test.ts +305 -0
  142. package/src/__tests__/thread-list-template-ms-date.test.ts +7 -2
  143. package/src/__tests__/thread-poke.test.ts +6 -6
  144. package/src/__tests__/thread-resume.test.ts +2 -2
  145. package/src/__tests__/thread-suspend-step.test.ts +1 -1
  146. package/src/__tests__/thread.test.ts +29 -15
  147. package/src/cli.ts +1056 -483
  148. package/src/commands/broker-step.ts +913 -0
  149. package/src/commands/config.ts +2 -24
  150. package/src/commands/prompt.ts +43 -51
  151. package/src/commands/setup.ts +25 -29
  152. package/src/commands/step.ts +645 -176
  153. package/src/commands/thread.ts +87 -192
  154. package/src/output-mappers.ts +99 -21
  155. package/src/schemas.ts +32 -2
  156. package/src/store.ts +297 -2
  157. package/src/text-renderers.ts +35 -2
  158. package/dist/__tests__/adapter-json-roundtrip.test.d.ts +0 -2
  159. package/dist/__tests__/adapter-json-roundtrip.test.d.ts.map +0 -1
  160. package/dist/__tests__/adapter-json-roundtrip.test.js +0 -160
  161. package/dist/__tests__/adapter-json-roundtrip.test.js.map +0 -1
  162. package/dist/__tests__/spawn-agent-json.test.d.ts +0 -2
  163. package/dist/__tests__/spawn-agent-json.test.d.ts.map +0 -1
  164. package/dist/__tests__/spawn-agent-json.test.js +0 -79
  165. package/dist/__tests__/spawn-agent-json.test.js.map +0 -1
  166. package/src/__tests__/adapter-json-roundtrip.test.ts +0 -193
  167. package/src/__tests__/spawn-agent-json.test.ts +0 -100
@@ -0,0 +1,356 @@
1
+ /**
2
+ * #423 — CLI subprocess integration test for `uwf step turns`.
3
+ *
4
+ * This test exercises the full CLI invocation path via subprocess (`execFileSync`),
5
+ * catching regressions that function-level tests cannot detect:
6
+ * - Argument parsing (yargs configuration)
7
+ * - Output formatting at the command boundary
8
+ * - Environment variable handling (UWF_HOME, OCAS_HOME)
9
+ * - Exit code behavior
10
+ *
11
+ * The test covers a RECURRING ROLE scenario (developer → reviewer → developer)
12
+ * which was the root cause of #412 and is the most likely to regress.
13
+ *
14
+ * Existing function-level tests (step-turns.test.ts, step-turns-panorama-phase3.test.ts)
15
+ * verify `cmdStepTurns` directly — this test does NOT duplicate those; it only
16
+ * adds the missing subprocess/CLI-level coverage.
17
+ *
18
+ * Follows the pattern established in thread-start-cwd-cli.test.ts.
19
+ */
20
+ import { execFileSync } from "node:child_process";
21
+ import { mkdir, rm } from "node:fs/promises";
22
+ import { tmpdir } from "node:os";
23
+ import { dirname, join } from "node:path";
24
+ import { fileURLToPath } from "node:url";
25
+ import { putSchema } from "@ocas/core";
26
+ import { afterEach, beforeEach, describe, expect, test } from "vitest";
27
+ import { createUwfStore, setActiveTurnHead, setThread, writeStepStart, writeTurnNode, } from "../store.js";
28
+ // ── test setup ───────────────────────────────────────────────────────────────
29
+ const THREAD_ID = "06FD9WEG5BH7C8JPD04X4184E4";
30
+ const DETAIL_SCHEMA = {
31
+ title: "broker-detail-cli-test",
32
+ type: "object",
33
+ required: ["sessionId", "duration", "turnCount"],
34
+ properties: {
35
+ sessionId: { type: "string" },
36
+ duration: { type: "integer" },
37
+ turnCount: { type: "integer" },
38
+ },
39
+ additionalProperties: false,
40
+ };
41
+ let tmpDir;
42
+ let storageRoot;
43
+ let casDir;
44
+ let savedUwfHome;
45
+ let savedOcasHome;
46
+ beforeEach(async () => {
47
+ savedUwfHome = process.env.UWF_HOME;
48
+ savedOcasHome = process.env.OCAS_HOME;
49
+ tmpDir = join(tmpdir(), `uwf-step-turns-cli-${Date.now()}`);
50
+ storageRoot = join(tmpDir, "storage");
51
+ casDir = join(tmpDir, "cas");
52
+ await mkdir(storageRoot, { recursive: true });
53
+ await mkdir(casDir, { recursive: true });
54
+ });
55
+ afterEach(async () => {
56
+ if (savedUwfHome === undefined)
57
+ delete process.env.UWF_HOME;
58
+ else
59
+ process.env.UWF_HOME = savedUwfHome;
60
+ if (savedOcasHome === undefined)
61
+ delete process.env.OCAS_HOME;
62
+ else
63
+ process.env.OCAS_HOME = savedOcasHome;
64
+ if (tmpDir) {
65
+ await rm(tmpDir, { recursive: true, force: true });
66
+ }
67
+ });
68
+ /**
69
+ * Seed a thread with a recurring role pattern: developer → reviewer → developer.
70
+ * This scenario exercises the #412 fix (owner-based segmentation) and ensures
71
+ * the CLI correctly renders separate segments for the same role.
72
+ *
73
+ * Returns the thread ID for CLI invocation.
74
+ */
75
+ async function seedRecurringRoleThread(uwf) {
76
+ // Create workflow and start node
77
+ const workflowHash = uwf.store.cas.put(uwf.schemas.workflow, {
78
+ version: 1,
79
+ name: "recurring-role-test",
80
+ description: "test workflow for recurring role CLI test",
81
+ roles: {},
82
+ graph: {},
83
+ });
84
+ const startHash = uwf.store.cas.put(uwf.schemas.startNode, {
85
+ workflow: workflowHash,
86
+ prompt: "implement feature X",
87
+ cwd: "/tmp/test",
88
+ });
89
+ const detailSchemaHash = putSchema(uwf.store, DETAIL_SCHEMA);
90
+ const outputHash = uwf.store.cas.put(uwf.schemas.text, "output");
91
+ // Step 1: developer round 1 — 2 turns
92
+ const stepStart1 = writeStepStart(uwf, {
93
+ role: "developer",
94
+ edgePrompt: "Implement feature X",
95
+ stepIndex: 0,
96
+ prev: null,
97
+ start: startHash,
98
+ startedAtMs: 1000,
99
+ cwd: "/tmp/test",
100
+ });
101
+ const t1 = writeTurnNode(uwf, {
102
+ role: "assistant",
103
+ content: "DEV_R1_TURN_1: Reading requirements...",
104
+ prev: null,
105
+ owner: stepStart1,
106
+ });
107
+ const t2 = writeTurnNode(uwf, {
108
+ role: "assistant",
109
+ content: "DEV_R1_TURN_2: Implementation complete.",
110
+ prev: t1,
111
+ owner: stepStart1,
112
+ });
113
+ const detail1 = uwf.store.cas.put(detailSchemaHash, {
114
+ sessionId: "ses_dev_r1",
115
+ duration: 5,
116
+ turnCount: 2,
117
+ });
118
+ const stepNode1 = uwf.store.cas.put(uwf.schemas.stepNode, {
119
+ start: startHash,
120
+ prev: null,
121
+ role: "developer",
122
+ output: outputHash,
123
+ detail: detail1,
124
+ agent: "test-agent",
125
+ edgePrompt: "Implement feature X",
126
+ startedAtMs: 1000,
127
+ completedAtMs: 2000,
128
+ cwd: "/tmp/test",
129
+ assembledPrompt: null,
130
+ usage: null,
131
+ previousAttempts: null,
132
+ });
133
+ // Step 2: reviewer — 2 turns
134
+ const stepStart2 = writeStepStart(uwf, {
135
+ role: "reviewer",
136
+ edgePrompt: "Review the implementation",
137
+ stepIndex: 1,
138
+ prev: stepStart1,
139
+ start: startHash,
140
+ startedAtMs: 3000,
141
+ cwd: "/tmp/test",
142
+ });
143
+ const t3 = writeTurnNode(uwf, {
144
+ role: "assistant",
145
+ content: "REV_TURN_1: Reviewing code quality...",
146
+ prev: t2,
147
+ owner: stepStart2,
148
+ });
149
+ const t4 = writeTurnNode(uwf, {
150
+ role: "assistant",
151
+ content: "REV_TURN_2: Found issues, requesting changes.",
152
+ prev: t3,
153
+ owner: stepStart2,
154
+ });
155
+ const detail2 = uwf.store.cas.put(detailSchemaHash, {
156
+ sessionId: "ses_rev",
157
+ duration: 4,
158
+ turnCount: 2,
159
+ });
160
+ const stepNode2 = uwf.store.cas.put(uwf.schemas.stepNode, {
161
+ start: startHash,
162
+ prev: stepNode1,
163
+ role: "reviewer",
164
+ output: outputHash,
165
+ detail: detail2,
166
+ agent: "test-agent",
167
+ edgePrompt: "Review the implementation",
168
+ startedAtMs: 3000,
169
+ completedAtMs: 4000,
170
+ cwd: "/tmp/test",
171
+ assembledPrompt: null,
172
+ usage: null,
173
+ previousAttempts: null,
174
+ });
175
+ // Step 3: developer round 2 — 3 turns
176
+ const stepStart3 = writeStepStart(uwf, {
177
+ role: "developer",
178
+ edgePrompt: "Address reviewer feedback",
179
+ stepIndex: 2,
180
+ prev: stepStart2,
181
+ start: startHash,
182
+ startedAtMs: 5000,
183
+ cwd: "/tmp/test",
184
+ });
185
+ const t5 = writeTurnNode(uwf, {
186
+ role: "assistant",
187
+ content: "DEV_R2_TURN_1: Reading feedback...",
188
+ prev: t4,
189
+ owner: stepStart3,
190
+ });
191
+ const t6 = writeTurnNode(uwf, {
192
+ role: "assistant",
193
+ content: "DEV_R2_TURN_2: Making requested changes...",
194
+ prev: t5,
195
+ owner: stepStart3,
196
+ });
197
+ const t7 = writeTurnNode(uwf, {
198
+ role: "assistant",
199
+ content: "DEV_R2_TURN_3: Changes complete, ready for re-review.",
200
+ prev: t6,
201
+ owner: stepStart3,
202
+ });
203
+ const detail3 = uwf.store.cas.put(detailSchemaHash, {
204
+ sessionId: "ses_dev_r2",
205
+ duration: 6,
206
+ turnCount: 3,
207
+ });
208
+ const stepNode3 = uwf.store.cas.put(uwf.schemas.stepNode, {
209
+ start: startHash,
210
+ prev: stepNode2,
211
+ role: "developer",
212
+ output: outputHash,
213
+ detail: detail3,
214
+ agent: "test-agent",
215
+ edgePrompt: "Address reviewer feedback",
216
+ startedAtMs: 5000,
217
+ completedAtMs: 6000,
218
+ cwd: "/tmp/test",
219
+ assembledPrompt: null,
220
+ usage: null,
221
+ previousAttempts: null,
222
+ });
223
+ // Set thread state — all steps completed
224
+ setThread(uwf.varStore, THREAD_ID, {
225
+ head: stepNode3,
226
+ status: "idle",
227
+ suspendedRole: null,
228
+ suspendMessage: null,
229
+ completedAt: null,
230
+ });
231
+ // Set active-turn-head to the last turn
232
+ setActiveTurnHead(uwf.store, THREAD_ID, t7);
233
+ return THREAD_ID;
234
+ }
235
+ // ── spec: step-turns-cli-subprocess-recurring-role.md ────────────────────────
236
+ describe("uwf step turns CLI subprocess integration (#423)", () => {
237
+ test("recurring role scenario (developer→reviewer→developer) via subprocess", async () => {
238
+ // Setup: seed the store with recurring role thread
239
+ process.env.OCAS_HOME = casDir;
240
+ const uwf = await createUwfStore(storageRoot);
241
+ const threadId = await seedRecurringRoleThread(uwf);
242
+ // Build paths to CLI binary
243
+ const pkgRoot = dirname(dirname(dirname(fileURLToPath(import.meta.url))));
244
+ const uwfBin = join(pkgRoot, "dist", "cli.js");
245
+ // Invoke CLI via subprocess
246
+ const output = execFileSync(process.execPath, [uwfBin, "step", "turns", threadId], {
247
+ env: { ...process.env, UWF_HOME: storageRoot, OCAS_HOME: casDir },
248
+ encoding: "utf8",
249
+ });
250
+ // Exit code 0 is implicit — execFileSync throws on non-zero exit
251
+ // Verify: 3 step groups in chronological order
252
+ const groups = output.match(/## (developer|reviewer)/g);
253
+ expect(groups).toEqual(["## developer", "## reviewer", "## developer"]);
254
+ // Verify: Both developer segments present (NOT collapsed)
255
+ const firstDevIdx = output.indexOf("## developer");
256
+ const reviewerIdx = output.indexOf("## reviewer");
257
+ const secondDevIdx = output.indexOf("## developer", reviewerIdx + 1);
258
+ expect(firstDevIdx).toBeLessThan(reviewerIdx);
259
+ expect(reviewerIdx).toBeLessThan(secondDevIdx);
260
+ // Verify: Each segment's turns are correctly attributed (no cross-segment leakage)
261
+ const devR1Section = output.slice(firstDevIdx, reviewerIdx);
262
+ const revSection = output.slice(reviewerIdx, secondDevIdx);
263
+ const devR2Section = output.slice(secondDevIdx);
264
+ // Developer round 1: 2 turns
265
+ expect(devR1Section).toContain("DEV_R1_TURN_1");
266
+ expect(devR1Section).toContain("DEV_R1_TURN_2");
267
+ expect(devR1Section).not.toContain("REV_TURN");
268
+ expect(devR1Section).not.toContain("DEV_R2_TURN");
269
+ // Reviewer: 2 turns
270
+ expect(revSection).toContain("REV_TURN_1");
271
+ expect(revSection).toContain("REV_TURN_2");
272
+ expect(revSection).not.toContain("DEV_R1_TURN");
273
+ expect(revSection).not.toContain("DEV_R2_TURN");
274
+ // Developer round 2: 3 turns
275
+ expect(devR2Section).toContain("DEV_R2_TURN_1");
276
+ expect(devR2Section).toContain("DEV_R2_TURN_2");
277
+ expect(devR2Section).toContain("DEV_R2_TURN_3");
278
+ expect(devR2Section).not.toContain("DEV_R1_TURN");
279
+ expect(devR2Section).not.toContain("REV_TURN");
280
+ // Verify: All 7 turns rendered with global numbering (Turn 1 through Turn 7)
281
+ expect(output).toContain("## Turn 1");
282
+ expect(output).toContain("## Turn 2");
283
+ expect(output).toContain("## Turn 3");
284
+ expect(output).toContain("## Turn 4");
285
+ expect(output).toContain("## Turn 5");
286
+ expect(output).toContain("## Turn 6");
287
+ expect(output).toContain("## Turn 7");
288
+ // Verify: All steps marked as completed (✓)
289
+ const checkmarks = output.match(/✓/g);
290
+ expect(checkmarks).toHaveLength(3);
291
+ });
292
+ test("CLI accepts --role filter via subprocess", async () => {
293
+ // Setup
294
+ process.env.OCAS_HOME = casDir;
295
+ const uwf = await createUwfStore(storageRoot);
296
+ const threadId = await seedRecurringRoleThread(uwf);
297
+ const pkgRoot = dirname(dirname(dirname(fileURLToPath(import.meta.url))));
298
+ const uwfBin = join(pkgRoot, "dist", "cli.js");
299
+ // Invoke CLI with --role developer
300
+ const output = execFileSync(process.execPath, [uwfBin, "step", "turns", threadId, "--role", "developer"], {
301
+ env: { ...process.env, UWF_HOME: storageRoot, OCAS_HOME: casDir },
302
+ encoding: "utf8",
303
+ });
304
+ // Verify: Only developer groups present
305
+ const groups = output.match(/## (developer|reviewer)/g);
306
+ expect(groups).toEqual(["## developer", "## developer"]);
307
+ // Verify: No reviewer turns
308
+ expect(output).not.toContain("REV_TURN");
309
+ // Verify: Both developer segment turns present
310
+ expect(output).toContain("DEV_R1_TURN");
311
+ expect(output).toContain("DEV_R2_TURN");
312
+ });
313
+ test("CLI accepts --limit and --offset pagination via subprocess", async () => {
314
+ // Setup
315
+ process.env.OCAS_HOME = casDir;
316
+ const uwf = await createUwfStore(storageRoot);
317
+ const threadId = await seedRecurringRoleThread(uwf);
318
+ const pkgRoot = dirname(dirname(dirname(fileURLToPath(import.meta.url))));
319
+ const uwfBin = join(pkgRoot, "dist", "cli.js");
320
+ // Invoke CLI with --offset 2 --limit 3 (turns 3, 4, 5)
321
+ const output = execFileSync(process.execPath, [uwfBin, "step", "turns", threadId, "--offset", "2", "--limit", "3"], {
322
+ env: { ...process.env, UWF_HOME: storageRoot, OCAS_HOME: casDir },
323
+ encoding: "utf8",
324
+ });
325
+ // Verify: Global indices Turn 3, Turn 4, Turn 5 (1-based display)
326
+ expect(output).toContain("## Turn 3");
327
+ expect(output).toContain("## Turn 4");
328
+ expect(output).toContain("## Turn 5");
329
+ // Verify: Turns 1, 2 are skipped
330
+ expect(output).not.toContain("## Turn 1");
331
+ expect(output).not.toContain("## Turn 2");
332
+ // Verify: Turns 6, 7 are beyond the limit
333
+ expect(output).not.toContain("## Turn 6");
334
+ expect(output).not.toContain("## Turn 7");
335
+ });
336
+ test("CLI exits with error for invalid thread ID", async () => {
337
+ const pkgRoot = dirname(dirname(dirname(fileURLToPath(import.meta.url))));
338
+ const uwfBin = join(pkgRoot, "dist", "cli.js");
339
+ // Invoke CLI with a non-existent thread ID
340
+ const invalidThreadId = "06FDINVALIDTHREADID000000";
341
+ try {
342
+ execFileSync(process.execPath, [uwfBin, "step", "turns", invalidThreadId], {
343
+ env: { ...process.env, UWF_HOME: storageRoot, OCAS_HOME: casDir },
344
+ encoding: "utf8",
345
+ });
346
+ // If we get here, the command didn't fail as expected
347
+ expect.fail("Expected CLI to exit with non-zero code for invalid thread ID");
348
+ }
349
+ catch (err) {
350
+ // execFileSync throws on non-zero exit — this is expected
351
+ const error = err;
352
+ expect(error.status).not.toBe(0);
353
+ }
354
+ });
355
+ });
356
+ //# sourceMappingURL=step-turns-cli-subprocess.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-turns-cli-subprocess.test.js","sourceRoot":"","sources":["../../src/__tests__/step-turns-cli-subprocess.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Phase 3 (#421) — buildTurnsPanorama rewritten to use owner-based segmentation.
3
+ *
4
+ * This is the consumer-side rewrite that root-causes #412 (recurring role in-flight
5
+ * mis-attribution). The panorama now:
6
+ * 1. Walks the step chain (step-start prev) instead of role-keyed vars
7
+ * 2. Each segment's turns are sourced via `turnsOfStep(turnHead, stepStartHash)`
8
+ * 3. In-flight detection: active-step matches step-start AND no step-complete
9
+ * 4. edgePrompt is read directly from step-start
10
+ *
11
+ * Covers the specs:
12
+ * - step-turns-panorama-owner-segmentation.md
13
+ * - step-turns-panorama-412-recurring-role.md
14
+ * - step-turns-panorama-role-filter.md
15
+ * - step-turns-panorama-pagination.md
16
+ * - step-turns-panorama-live-mode.md
17
+ * - step-turns-panorama-in-flight-detection.md
18
+ * - step-turns-panorama-edge-prompt.md
19
+ */
20
+ export {};
21
+ //# sourceMappingURL=step-turns-panorama-phase3.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-turns-panorama-phase3.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/step-turns-panorama-phase3.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG"}