@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,476 @@
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
+ import { mkdir, mkdtemp, rm } from "node:fs/promises";
21
+ import { tmpdir } from "node:os";
22
+ import { join } from "node:path";
23
+ import { putSchema } from "@ocas/core";
24
+ import { afterEach, beforeEach, describe, expect, test } from "vitest";
25
+ import { cmdStepTurns } from "../commands/step.js";
26
+ import { createUwfStore, getActiveTurnHead, setActiveStep, setActiveTurnHead, setThread, turnsOfStep, walkTurnChain, writeStepStart, writeTurnNode, } from "../store.js";
27
+ // ── schemas ─────────────────────────────────────────────────────────────────
28
+ const DETAIL_SCHEMA = {
29
+ title: "broker-detail-phase3",
30
+ type: "object",
31
+ required: ["sessionId", "duration", "turnCount"],
32
+ properties: {
33
+ sessionId: { type: "string" },
34
+ duration: { type: "integer" },
35
+ turnCount: { type: "integer" },
36
+ },
37
+ additionalProperties: false,
38
+ };
39
+ // ── fixtures ─────────────────────────────────────────────────────────────────
40
+ let tmpDir;
41
+ let savedOcasHome;
42
+ beforeEach(async () => {
43
+ savedOcasHome = process.env.OCAS_HOME;
44
+ tmpDir = await mkdtemp(join(tmpdir(), "step-turns-phase3-"));
45
+ const casDir = join(tmpDir, "cas");
46
+ await mkdir(casDir, { recursive: true });
47
+ process.env.OCAS_HOME = casDir;
48
+ });
49
+ afterEach(async () => {
50
+ if (savedOcasHome === undefined)
51
+ delete process.env.OCAS_HOME;
52
+ else
53
+ process.env.OCAS_HOME = savedOcasHome;
54
+ await rm(tmpDir, { recursive: true, force: true });
55
+ });
56
+ const THREAD_ID = "06FDPANORAMAPH3OWNERTEST1";
57
+ /**
58
+ * Seed a complete Phase 3 scenario:
59
+ * - Creates start node
60
+ * - Creates step-starts linked via prev chain
61
+ * - Creates turns linked via prev chain, each with owner pointing to its step-start
62
+ * - Creates StepNodes for completed steps (for backward compat with walkChain)
63
+ * - Sets thread head (StepNode or StartNode), active-step (if in-flight), active-turn-head
64
+ *
65
+ * Key insight: Thread head still points to StepNode (or StartNode), step-start is
66
+ * a parallel chain. The panorama should read from active-turn-head and walk
67
+ * owner -> step-start -> prev to reconstruct segments.
68
+ *
69
+ * Returns { startHash, stepStarts, stepNodes, turns } for verification.
70
+ */
71
+ async function seedPhase3Chain(uwf, threadId, steps) {
72
+ // Create workflow and start node
73
+ const workflowHash = uwf.store.cas.put(uwf.schemas.workflow, {
74
+ version: 1,
75
+ name: "phase3-test-wf",
76
+ description: "phase3",
77
+ roles: {},
78
+ graph: {},
79
+ });
80
+ const startHash = uwf.store.cas.put(uwf.schemas.startNode, {
81
+ workflow: workflowHash,
82
+ prompt: "task",
83
+ cwd: "/tmp/work",
84
+ });
85
+ const detailSchemaHash = putSchema(uwf.store, DETAIL_SCHEMA);
86
+ const outputHash = uwf.store.cas.put(uwf.schemas.text, "output");
87
+ const stepStarts = [];
88
+ const stepNodes = [];
89
+ const allTurns = [];
90
+ let prevStepStart = null;
91
+ let prevStepNode = null;
92
+ let prevTurn = null;
93
+ let inFlightStepStart = null;
94
+ for (let i = 0; i < steps.length; i++) {
95
+ const step = steps[i];
96
+ // Write step-start (new Phase 2 node)
97
+ const stepStart = writeStepStart(uwf, {
98
+ role: step.role,
99
+ edgePrompt: step.edgePrompt,
100
+ stepIndex: i,
101
+ prev: prevStepStart,
102
+ start: startHash,
103
+ startedAtMs: 1000 + i * 1000,
104
+ cwd: "/tmp/work",
105
+ });
106
+ stepStarts.push(stepStart);
107
+ // Write turns for this step
108
+ const stepTurns = [];
109
+ for (const content of step.turnContents) {
110
+ const turn = writeTurnNode(uwf, {
111
+ role: "assistant",
112
+ content,
113
+ prev: prevTurn,
114
+ owner: stepStart,
115
+ });
116
+ stepTurns.push(turn);
117
+ prevTurn = turn;
118
+ }
119
+ allTurns.push(stepTurns);
120
+ // Write StepNode if not in-flight (for backward compat with thread head)
121
+ if (step.inFlight) {
122
+ stepNodes.push(null);
123
+ inFlightStepStart = stepStart;
124
+ }
125
+ else {
126
+ const detail = uwf.store.cas.put(detailSchemaHash, {
127
+ sessionId: `ses_${step.role}_${i}`,
128
+ duration: 5,
129
+ turnCount: step.turnContents.length,
130
+ });
131
+ // Write a StepNode (legacy format for thread head)
132
+ const stepNode = uwf.store.cas.put(uwf.schemas.stepNode, {
133
+ start: startHash,
134
+ prev: prevStepNode,
135
+ role: step.role,
136
+ output: outputHash,
137
+ detail,
138
+ agent: "test-agent",
139
+ edgePrompt: step.edgePrompt,
140
+ startedAtMs: 1000 + i * 1000,
141
+ completedAtMs: 2000 + i * 1000,
142
+ cwd: "/tmp/work",
143
+ assembledPrompt: null,
144
+ usage: null,
145
+ previousAttempts: null,
146
+ });
147
+ stepNodes.push(stepNode);
148
+ prevStepNode = stepNode;
149
+ }
150
+ prevStepStart = stepStart;
151
+ }
152
+ // Set thread head to latest StepNode or StartNode if no completes
153
+ const lastStepNode = stepNodes.filter((n) => n !== null).pop();
154
+ const threadHead = lastStepNode ?? startHash;
155
+ setThread(uwf.varStore, threadId, {
156
+ head: threadHead,
157
+ status: inFlightStepStart !== null ? "running" : "idle",
158
+ suspendedRole: null,
159
+ suspendMessage: null,
160
+ completedAt: null,
161
+ });
162
+ // Set active-step if in-flight
163
+ if (inFlightStepStart !== null) {
164
+ setActiveStep(uwf.store, threadId, inFlightStepStart);
165
+ }
166
+ // Set active-turn-head to the latest turn
167
+ if (prevTurn !== null) {
168
+ setActiveTurnHead(uwf.store, threadId, prevTurn);
169
+ }
170
+ return { startHash, stepStarts, stepNodes, turns: allTurns };
171
+ }
172
+ // ── spec: step-turns-panorama-owner-segmentation.md ─────────────────────────
173
+ describe("buildTurnsPanorama segments turns by step-start owner (#421)", () => {
174
+ test("3 completed steps: each group shows only turns with matching owner", async () => {
175
+ const uwf = await createUwfStore(tmpDir);
176
+ await seedPhase3Chain(uwf, THREAD_ID, [
177
+ { role: "planner", edgePrompt: "Plan the task", turnContents: ["t0", "t1"], inFlight: false },
178
+ { role: "developer", edgePrompt: "Implement", turnContents: ["t2", "t3"], inFlight: false },
179
+ { role: "reviewer", edgePrompt: "Review", turnContents: ["t4", "t5"], inFlight: false },
180
+ ]);
181
+ const out = await cmdStepTurns(tmpDir, THREAD_ID, { live: false });
182
+ // All three step groups present in step-chain order
183
+ expect(out).toContain("## planner");
184
+ expect(out).toContain("## developer");
185
+ expect(out).toContain("## reviewer");
186
+ expect(out.indexOf("## planner")).toBeLessThan(out.indexOf("## developer"));
187
+ expect(out.indexOf("## developer")).toBeLessThan(out.indexOf("## reviewer"));
188
+ // Each group shows only its own turns (no cross-segment leakage)
189
+ const plannerSection = out.slice(out.indexOf("## planner"), out.indexOf("## developer"));
190
+ const developerSection = out.slice(out.indexOf("## developer"), out.indexOf("## reviewer"));
191
+ const reviewerSection = out.slice(out.indexOf("## reviewer"));
192
+ expect(plannerSection).toContain("t0");
193
+ expect(plannerSection).toContain("t1");
194
+ expect(plannerSection).not.toContain("t2");
195
+ expect(developerSection).toContain("t2");
196
+ expect(developerSection).toContain("t3");
197
+ expect(developerSection).not.toContain("t4");
198
+ expect(reviewerSection).toContain("t4");
199
+ expect(reviewerSection).toContain("t5");
200
+ expect(reviewerSection).not.toContain("t0");
201
+ // Each group is marked completed
202
+ expect(out).toMatch(/## planner.*✓/);
203
+ expect(out).toMatch(/## developer.*✓/);
204
+ expect(out).toMatch(/## reviewer.*✓/);
205
+ });
206
+ test("owner filtering via turnsOfStep returns correct subset", async () => {
207
+ const uwf = await createUwfStore(tmpDir);
208
+ const { stepStarts } = await seedPhase3Chain(uwf, THREAD_ID, [
209
+ { role: "planner", edgePrompt: "Plan", turnContents: ["p0", "p1"], inFlight: false },
210
+ { role: "developer", edgePrompt: "Dev", turnContents: ["d0", "d1"], inFlight: false },
211
+ { role: "reviewer", edgePrompt: "Rev", turnContents: ["r0", "r1"], inFlight: false },
212
+ ]);
213
+ const turnHead = getActiveTurnHead(uwf.store, THREAD_ID);
214
+ // Each step-start should own exactly its 2 turns
215
+ expect(turnsOfStep(uwf, turnHead, stepStarts[0])).toHaveLength(2);
216
+ expect(turnsOfStep(uwf, turnHead, stepStarts[1])).toHaveLength(2);
217
+ expect(turnsOfStep(uwf, turnHead, stepStarts[2])).toHaveLength(2);
218
+ // Full turn chain has 6 turns
219
+ expect(walkTurnChain(uwf, turnHead)).toHaveLength(6);
220
+ });
221
+ });
222
+ // ── spec: step-turns-panorama-412-recurring-role.md ─────────────────────────
223
+ describe("#412 recurring role with in-flight correctly handled (#421)", () => {
224
+ test("developer→reviewer→developer(in-flight): each segment correctly attributed", async () => {
225
+ const uwf = await createUwfStore(tmpDir);
226
+ await seedPhase3Chain(uwf, THREAD_ID, [
227
+ { role: "developer", edgePrompt: "Round 1", turnContents: ["t1", "t2"], inFlight: false },
228
+ { role: "reviewer", edgePrompt: "Review", turnContents: ["t3", "t4"], inFlight: false },
229
+ {
230
+ role: "developer",
231
+ edgePrompt: "Round 2",
232
+ turnContents: ["t5", "t6", "t7"],
233
+ inFlight: true,
234
+ },
235
+ ]);
236
+ const out = await cmdStepTurns(tmpDir, THREAD_ID, { live: false });
237
+ // Three groups in chronological order
238
+ const groups = out.match(/## (developer|reviewer)/g);
239
+ expect(groups).toEqual(["## developer", "## reviewer", "## developer"]);
240
+ // Round 1 developer: completed, 2 turns
241
+ const firstDev = out.indexOf("## developer");
242
+ const reviewer = out.indexOf("## reviewer");
243
+ const secondDev = out.indexOf("## developer", reviewer + 1);
244
+ const r1Section = out.slice(firstDev, reviewer);
245
+ expect(r1Section).toContain("✓");
246
+ expect(r1Section).not.toContain("进行中");
247
+ expect(r1Section).toContain("t1");
248
+ expect(r1Section).toContain("t2");
249
+ expect(r1Section).not.toContain("t5");
250
+ // Reviewer: completed
251
+ const revSection = out.slice(reviewer, secondDev);
252
+ expect(revSection).toContain("✓");
253
+ expect(revSection).toContain("t3");
254
+ expect(revSection).toContain("t4");
255
+ // Round 2 developer: in-flight, 3 turns
256
+ const r2Section = out.slice(secondDev);
257
+ expect(r2Section).toContain("🔄 进行中");
258
+ expect(r2Section).not.toContain("✓");
259
+ expect(r2Section).toContain("t5");
260
+ expect(r2Section).toContain("t6");
261
+ expect(r2Section).toContain("t7");
262
+ expect(r2Section).not.toContain("t1");
263
+ });
264
+ test("same role multi-round: turns never mixed between segments", async () => {
265
+ const uwf = await createUwfStore(tmpDir);
266
+ const { stepStarts } = await seedPhase3Chain(uwf, THREAD_ID, [
267
+ {
268
+ role: "developer",
269
+ edgePrompt: "R1",
270
+ turnContents: ["dev_r1_t1", "dev_r1_t2"],
271
+ inFlight: false,
272
+ },
273
+ { role: "reviewer", edgePrompt: "Rev", turnContents: ["rev_t1"], inFlight: false },
274
+ {
275
+ role: "developer",
276
+ edgePrompt: "R2",
277
+ turnContents: ["dev_r2_t1", "dev_r2_t2", "dev_r2_t3"],
278
+ inFlight: false,
279
+ },
280
+ ]);
281
+ // Verify turn ownership in CAS
282
+ const turnHead = getActiveTurnHead(uwf.store, THREAD_ID);
283
+ const dev1Turns = turnsOfStep(uwf, turnHead, stepStarts[0]);
284
+ const revTurns = turnsOfStep(uwf, turnHead, stepStarts[1]);
285
+ const dev2Turns = turnsOfStep(uwf, turnHead, stepStarts[2]);
286
+ expect(dev1Turns).toHaveLength(2);
287
+ expect(revTurns).toHaveLength(1);
288
+ expect(dev2Turns).toHaveLength(3);
289
+ // Verify content via panorama
290
+ const out = await cmdStepTurns(tmpDir, THREAD_ID, { live: false });
291
+ expect(out.match(/dev_r1/g)).toHaveLength(2);
292
+ expect(out.match(/dev_r2/g)).toHaveLength(3);
293
+ expect(out.match(/rev_t/g)).toHaveLength(1);
294
+ });
295
+ });
296
+ // ── spec: step-turns-panorama-role-filter.md ─────────────────────────────────
297
+ describe("--role filters by step-start role, preserving all segments (#421)", () => {
298
+ test("--role developer shows all developer segments", async () => {
299
+ const uwf = await createUwfStore(tmpDir);
300
+ await seedPhase3Chain(uwf, THREAD_ID, [
301
+ { role: "developer", edgePrompt: "R1", turnContents: ["d1"], inFlight: false },
302
+ { role: "reviewer", edgePrompt: "Rev", turnContents: ["r1"], inFlight: false },
303
+ { role: "developer", edgePrompt: "R2", turnContents: ["d2"], inFlight: false },
304
+ { role: "reviewer", edgePrompt: "Rev2", turnContents: ["r2"], inFlight: false },
305
+ { role: "developer", edgePrompt: "R3", turnContents: ["d3"], inFlight: false },
306
+ ]);
307
+ const out = await cmdStepTurns(tmpDir, THREAD_ID, { role: "developer", live: false });
308
+ // 3 developer groups
309
+ expect((out.match(/## developer/g) ?? []).length).toBe(3);
310
+ // No reviewer groups
311
+ expect(out).not.toContain("## reviewer");
312
+ // All developer turns present
313
+ expect(out).toContain("d1");
314
+ expect(out).toContain("d2");
315
+ expect(out).toContain("d3");
316
+ // No reviewer turns
317
+ expect(out).not.toContain("r1");
318
+ expect(out).not.toContain("r2");
319
+ });
320
+ test("--role for non-existent role returns empty panorama", async () => {
321
+ const uwf = await createUwfStore(tmpDir);
322
+ await seedPhase3Chain(uwf, THREAD_ID, [
323
+ { role: "developer", edgePrompt: "Dev", turnContents: ["d1"], inFlight: false },
324
+ ]);
325
+ const out = await cmdStepTurns(tmpDir, THREAD_ID, { role: "tester", live: false });
326
+ expect(out).toContain(`# Thread ${THREAD_ID}`);
327
+ expect(out).not.toContain("## Turn");
328
+ expect(out).not.toContain("d1");
329
+ });
330
+ });
331
+ // ── spec: step-turns-panorama-pagination.md ──────────────────────────────────
332
+ describe("--limit/--offset paginates on flattened cross-step turn sequence (#421)", () => {
333
+ test("pagination crosses step boundaries correctly", async () => {
334
+ const uwf = await createUwfStore(tmpDir);
335
+ // 12 turns total: 4 per step
336
+ await seedPhase3Chain(uwf, THREAD_ID, [
337
+ { role: "step0", edgePrompt: "S0", turnContents: ["t0", "t1", "t2", "t3"], inFlight: false },
338
+ { role: "step1", edgePrompt: "S1", turnContents: ["t4", "t5", "t6", "t7"], inFlight: false },
339
+ {
340
+ role: "step2",
341
+ edgePrompt: "S2",
342
+ turnContents: ["t8", "t9", "t10", "t11"],
343
+ inFlight: false,
344
+ },
345
+ ]);
346
+ // --offset 5 --limit 4: indices 5,6,7,8 → t5,t6,t7,t8
347
+ const out = await cmdStepTurns(tmpDir, THREAD_ID, { live: false, offset: 5, limit: 4 });
348
+ // Should span step1 (t5,t6,t7) and step2 (t8)
349
+ expect(out).toContain("t5");
350
+ expect(out).toContain("t6");
351
+ expect(out).toContain("t7");
352
+ expect(out).toContain("t8");
353
+ expect(out).not.toContain("t4");
354
+ expect(out).not.toContain("t9");
355
+ // Global indices: Turn 6, Turn 7, Turn 8, Turn 9 (1-based)
356
+ expect(out).toContain("## Turn 6");
357
+ expect(out).toContain("## Turn 9");
358
+ expect(out).not.toContain("## Turn 5");
359
+ expect(out).not.toContain("## Turn 10");
360
+ });
361
+ test("groups with no surviving turns after pagination still show header", async () => {
362
+ const uwf = await createUwfStore(tmpDir);
363
+ await seedPhase3Chain(uwf, THREAD_ID, [
364
+ { role: "step0", edgePrompt: "S0", turnContents: ["t0", "t1"], inFlight: false },
365
+ { role: "step1", edgePrompt: "S1", turnContents: ["t2", "t3"], inFlight: false },
366
+ ]);
367
+ // --offset 0 --limit 2: only step0 turns survive
368
+ const out = await cmdStepTurns(tmpDir, THREAD_ID, { live: false, offset: 0, limit: 2 });
369
+ // step1 header should still appear (empty)
370
+ expect(out).toContain("## step0");
371
+ expect(out).toContain("## step1");
372
+ expect(out).toContain("t0");
373
+ expect(out).toContain("t1");
374
+ expect(out).not.toContain("t2");
375
+ });
376
+ });
377
+ // ── spec: step-turns-panorama-in-flight-detection.md ─────────────────────────
378
+ describe("in-flight detection via active-step + missing step-complete (#421)", () => {
379
+ test("completed step (has step-complete) is marked ✓ even if active-step points elsewhere", async () => {
380
+ const uwf = await createUwfStore(tmpDir);
381
+ await seedPhase3Chain(uwf, THREAD_ID, [
382
+ { role: "step1", edgePrompt: "S1", turnContents: ["t1"], inFlight: false },
383
+ { role: "step2", edgePrompt: "S2", turnContents: ["t2"], inFlight: true },
384
+ ]);
385
+ const out = await cmdStepTurns(tmpDir, THREAD_ID, { live: false });
386
+ // step1 completed: ✓
387
+ expect(out).toMatch(/## step1.*✓/);
388
+ // step2 in-flight: 🔄 进行中
389
+ expect(out).toMatch(/## step2.*🔄 进行中/);
390
+ });
391
+ test("in-flight step is detected by active-step match AND no step-complete", async () => {
392
+ const uwf = await createUwfStore(tmpDir);
393
+ const { stepStarts } = await seedPhase3Chain(uwf, THREAD_ID, [
394
+ { role: "done", edgePrompt: "D", turnContents: ["d1"], inFlight: false },
395
+ { role: "wip", edgePrompt: "W", turnContents: ["w1"], inFlight: true },
396
+ ]);
397
+ // Verify active-step points to the in-flight step-start
398
+ const uwf2 = await createUwfStore(tmpDir);
399
+ const activeStep = uwf2.varStore.list({ exactName: `@uwf/active-step/${THREAD_ID}` });
400
+ expect(activeStep.length).toBe(1);
401
+ expect(activeStep[0].value).toBe(stepStarts[1]);
402
+ });
403
+ });
404
+ // ── spec: step-turns-panorama-live-mode.md ───────────────────────────────────
405
+ describe("--live follows active-turn-head growth (#421)", () => {
406
+ test("live mode polls active-turn-head and prints new turns", async () => {
407
+ const uwf = await createUwfStore(tmpDir);
408
+ const { stepStarts } = await seedPhase3Chain(uwf, THREAD_ID, [
409
+ { role: "coder", edgePrompt: "Code", turnContents: ["initial"], inFlight: true },
410
+ ]);
411
+ const printed = [];
412
+ let tick = 0;
413
+ const stepStart = stepStarts[0];
414
+ let prevTurn = getActiveTurnHead(uwf.store, THREAD_ID);
415
+ await cmdStepTurns(tmpDir, THREAD_ID, {
416
+ role: "coder",
417
+ live: true,
418
+ pollIntervalMs: 0,
419
+ onChunk: (chunk) => printed.push(chunk),
420
+ isRunning: async () => tick < 3,
421
+ sleep: async () => {
422
+ tick += 1;
423
+ if (tick === 1) {
424
+ const t = writeTurnNode(uwf, {
425
+ role: "assistant",
426
+ content: "live1",
427
+ prev: prevTurn,
428
+ owner: stepStart,
429
+ });
430
+ setActiveTurnHead(uwf.store, THREAD_ID, t);
431
+ prevTurn = t;
432
+ }
433
+ else if (tick === 2) {
434
+ const t = writeTurnNode(uwf, {
435
+ role: "assistant",
436
+ content: "live2",
437
+ prev: prevTurn,
438
+ owner: stepStart,
439
+ });
440
+ setActiveTurnHead(uwf.store, THREAD_ID, t);
441
+ prevTurn = t;
442
+ }
443
+ },
444
+ });
445
+ const joined = printed.join("\n");
446
+ expect(joined).toContain("initial");
447
+ expect(joined).toContain("live1");
448
+ expect(joined).toContain("live2");
449
+ });
450
+ });
451
+ // ── spec: step-turns-panorama-edge-prompt.md ─────────────────────────────────
452
+ describe("edgePrompt readable from step-start (#421)", () => {
453
+ test("step-start stores edgePrompt correctly", async () => {
454
+ const uwf = await createUwfStore(tmpDir);
455
+ const { stepStarts } = await seedPhase3Chain(uwf, THREAD_ID, [
456
+ {
457
+ role: "planner",
458
+ edgePrompt: "Initial prompt from user",
459
+ turnContents: ["t1"],
460
+ inFlight: false,
461
+ },
462
+ {
463
+ role: "developer",
464
+ edgePrompt: "Implement the plan from planner",
465
+ turnContents: ["t2"],
466
+ inFlight: false,
467
+ },
468
+ ]);
469
+ // Read step-start nodes and verify edgePrompt
470
+ const ss1 = uwf.store.cas.get(stepStarts[0]);
471
+ const ss2 = uwf.store.cas.get(stepStarts[1]);
472
+ expect((ss1?.payload).edgePrompt).toBe("Initial prompt from user");
473
+ expect((ss2?.payload).edgePrompt).toBe("Implement the plan from planner");
474
+ });
475
+ });
476
+ //# sourceMappingURL=step-turns-panorama-phase3.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-turns-panorama-phase3.test.js","sourceRoot":"","sources":["../../src/__tests__/step-turns-panorama-phase3.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * #409 — `uwf step turns <thread-id>` is the whole-thread turn panorama.
3
+ *
4
+ * It walks the entire thread chain (reusing `walkChain` + `collectOrderedSteps`,
5
+ * the same infra `cmdStepList` uses) and renders every step's turns in order —
6
+ * each completed step from its own immutable `detail.turns` (marked `✓`), the
7
+ * in-flight step from its `@uwf/active-turns/<tid>/<role>` var (marked
8
+ * `🔄 进行中`). `--role` filters the panorama to one role's steps across the
9
+ * whole chain; `--limit`/`--offset` paginate the flattened cross-step turn
10
+ * sequence (filter first, then paginate). Default is full + untruncated.
11
+ *
12
+ * Covers the issue's testing checklist via the six specs:
13
+ * - step-turns-chain-panorama.md
14
+ * - step-turns-role-selection.md (the #409 regression)
15
+ * - step-turns-read-order-active-then-detail.md
16
+ * - step-turns-pagination.md
17
+ * - step-turns-live-poll-active-var.md
18
+ *
19
+ * Per-turn blocks reuse the SAME pipeline as `step read`
20
+ * (loadTurnData → formatTurnBody), so a turn block here is byte-identical to the
21
+ * same turn under `uwf step read`.
22
+ */
23
+ export {};
24
+ //# sourceMappingURL=step-turns.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-turns.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/step-turns.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG"}