fraim-framework 2.0.43 → 2.0.45

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 (73) hide show
  1. package/bin/fraim.js +1 -1
  2. package/dist/registry/ai-manager-rules/design-phases/design-completeness-review.md +73 -0
  3. package/dist/registry/ai-manager-rules/design-phases/design-design.md +145 -0
  4. package/dist/registry/ai-manager-rules/design-phases/design.md +108 -0
  5. package/dist/registry/ai-manager-rules/design-phases/finalize.md +60 -0
  6. package/dist/registry/ai-manager-rules/design-phases/validate.md +125 -0
  7. package/dist/registry/ai-manager-rules/implement-phases/code.md +323 -0
  8. package/dist/registry/ai-manager-rules/implement-phases/completeness-review.md +94 -0
  9. package/dist/registry/ai-manager-rules/implement-phases/finalize.md +177 -0
  10. package/dist/registry/ai-manager-rules/implement-phases/implement-code.md +286 -0
  11. package/dist/registry/ai-manager-rules/implement-phases/implement-completeness-review.md +120 -0
  12. package/dist/registry/ai-manager-rules/implement-phases/implement-regression.md +173 -0
  13. package/dist/registry/ai-manager-rules/implement-phases/implement-repro.md +104 -0
  14. package/dist/registry/ai-manager-rules/implement-phases/implement-scoping.md +100 -0
  15. package/dist/registry/ai-manager-rules/implement-phases/implement-smoke.md +230 -0
  16. package/dist/registry/ai-manager-rules/implement-phases/implement-spike.md +121 -0
  17. package/dist/registry/ai-manager-rules/implement-phases/implement-validate.md +371 -0
  18. package/dist/registry/ai-manager-rules/implement-phases/quality-review.md +304 -0
  19. package/dist/registry/ai-manager-rules/implement-phases/regression.md +159 -0
  20. package/dist/registry/ai-manager-rules/implement-phases/repro.md +101 -0
  21. package/dist/registry/ai-manager-rules/implement-phases/scoping.md +93 -0
  22. package/dist/registry/ai-manager-rules/implement-phases/smoke.md +225 -0
  23. package/dist/registry/ai-manager-rules/implement-phases/spike.md +118 -0
  24. package/dist/registry/ai-manager-rules/implement-phases/validate.md +347 -0
  25. package/dist/registry/ai-manager-rules/shared-phases/finalize.md +169 -0
  26. package/dist/registry/ai-manager-rules/shared-phases/submit-pr.md +202 -0
  27. package/dist/registry/ai-manager-rules/shared-phases/wait-for-pr-review.md +170 -0
  28. package/dist/registry/ai-manager-rules/spec-phases/finalize.md +60 -0
  29. package/dist/registry/ai-manager-rules/spec-phases/spec-completeness-review.md +66 -0
  30. package/dist/registry/ai-manager-rules/spec-phases/spec-spec.md +139 -0
  31. package/dist/registry/ai-manager-rules/spec-phases/spec.md +102 -0
  32. package/dist/registry/ai-manager-rules/spec-phases/validate.md +118 -0
  33. package/dist/src/ai-manager/ai-manager.js +380 -119
  34. package/dist/src/ai-manager/evidence-validator.js +309 -0
  35. package/dist/src/ai-manager/phase-flow.js +244 -0
  36. package/dist/src/ai-manager/types.js +5 -0
  37. package/dist/src/fraim-mcp-server.js +45 -153
  38. package/dist/src/static-website-middleware.js +75 -0
  39. package/dist/tests/test-ai-coach-edge-cases.js +415 -0
  40. package/dist/tests/test-ai-coach-mcp-integration.js +432 -0
  41. package/dist/tests/test-ai-coach-performance.js +328 -0
  42. package/dist/tests/test-ai-coach-phase-content.js +264 -0
  43. package/dist/tests/test-ai-coach-workflows.js +487 -0
  44. package/dist/tests/test-ai-manager-phase-protocol.js +147 -0
  45. package/dist/tests/test-ai-manager.js +60 -71
  46. package/dist/tests/test-evidence-validation.js +221 -0
  47. package/dist/tests/test-mcp-lifecycle-methods.js +18 -23
  48. package/dist/tests/test-pr-review-integration.js +1 -0
  49. package/dist/tests/test-pr-review-workflow.js +299 -0
  50. package/dist/website/.nojekyll +0 -0
  51. package/dist/website/404.html +101 -0
  52. package/dist/website/CNAME +1 -0
  53. package/dist/website/README.md +22 -0
  54. package/dist/website/demo.html +604 -0
  55. package/dist/website/images/.gitkeep +1 -0
  56. package/dist/website/images/fraim-logo.png +0 -0
  57. package/dist/website/index.html +290 -0
  58. package/dist/website/pricing.html +414 -0
  59. package/dist/website/script.js +55 -0
  60. package/dist/website/styles.css +2647 -0
  61. package/package.json +2 -1
  62. package/registry/agent-guardrails.md +1 -1
  63. package/registry/stubs/workflows/brainstorming/blue-sky-brainstorming.md +11 -0
  64. package/registry/stubs/workflows/brainstorming/codebase-brainstorming.md +11 -0
  65. package/registry/stubs/workflows/compliance/detect-compliance-requirements.md +11 -0
  66. package/registry/stubs/workflows/compliance/generate-audit-evidence.md +11 -0
  67. package/registry/stubs/workflows/learning/synthesize-learnings.md +11 -0
  68. package/registry/stubs/workflows/legal/nda.md +11 -0
  69. package/registry/stubs/workflows/legal/patent-filing.md +11 -0
  70. package/registry/stubs/workflows/legal/trademark-filing.md +11 -0
  71. package/registry/stubs/workflows/marketing/domain-registration.md +11 -0
  72. package/registry/stubs/workflows/product-building/design.md +1 -1
  73. package/registry/stubs/workflows/product-building/implement.md +1 -2
@@ -0,0 +1,432 @@
1
+ "use strict";
2
+ /**
3
+ * Tests for AI Coach MCP integration
4
+ * Tests the seekCoachingOnNextStep MCP tool and server integration
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ const node_test_1 = require("node:test");
11
+ const node_assert_1 = __importDefault(require("node:assert"));
12
+ const shared_server_utils_js_1 = require("./shared-server-utils.js");
13
+ (0, node_test_1.describe)('AI Coach MCP Integration', () => {
14
+ (0, node_test_1.before)(async () => {
15
+ // Wait for the test server to be ready
16
+ await (0, shared_server_utils_js_1.waitForServer)();
17
+ });
18
+ (0, node_test_1.describe)('MCP Tool Registration', () => {
19
+ (0, node_test_1.it)('should register seekCoachingOnNextStep tool', async () => {
20
+ const axios = require('axios');
21
+ // Test MCP tools/list endpoint
22
+ const response = await axios.post((0, shared_server_utils_js_1.getMcpEndpoint)(), {
23
+ jsonrpc: '2.0',
24
+ id: 1,
25
+ method: 'tools/list'
26
+ });
27
+ node_assert_1.default.strictEqual(response.status, 200);
28
+ node_assert_1.default.ok(response.data.result);
29
+ node_assert_1.default.ok(Array.isArray(response.data.result.tools));
30
+ // Find the seekCoachingOnNextStep tool
31
+ const coachingTool = response.data.result.tools.find((tool) => tool.name === 'seekCoachingOnNextStep');
32
+ node_assert_1.default.ok(coachingTool, 'seekCoachingOnNextStep tool should be registered');
33
+ node_assert_1.default.ok(coachingTool.description, 'Tool should have description');
34
+ node_assert_1.default.ok(coachingTool.inputSchema, 'Tool should have input schema');
35
+ });
36
+ (0, node_test_1.it)('should have correct tool schema for seekCoachingOnNextStep', async () => {
37
+ const axios = require('axios');
38
+ const response = await axios.post((0, shared_server_utils_js_1.getMcpEndpoint)(), {
39
+ jsonrpc: '2.0',
40
+ id: 1,
41
+ method: 'tools/list'
42
+ });
43
+ const coachingTool = response.data.result.tools.find((tool) => tool.name === 'seekCoachingOnNextStep');
44
+ const schema = coachingTool.inputSchema;
45
+ node_assert_1.default.ok(schema.properties, 'Tool schema should have properties');
46
+ // Check required properties
47
+ const requiredProps = ['workflowType', 'issueNumber', 'currentPhase', 'status'];
48
+ for (const prop of requiredProps) {
49
+ node_assert_1.default.ok(schema.properties[prop], `Tool schema should have ${prop} property`);
50
+ }
51
+ // Check optional properties
52
+ const optionalProps = ['evidence', 'findings'];
53
+ for (const prop of optionalProps) {
54
+ node_assert_1.default.ok(schema.properties[prop], `Tool schema should have ${prop} property`);
55
+ }
56
+ // Check that required properties are marked as required
57
+ node_assert_1.default.ok(schema.required, 'Tool schema should have required array');
58
+ for (const prop of requiredProps) {
59
+ node_assert_1.default.ok(schema.required.includes(prop), `${prop} should be required`);
60
+ }
61
+ });
62
+ });
63
+ (0, node_test_1.describe)('MCP Tool Execution', () => {
64
+ (0, node_test_1.it)('should execute seekCoachingOnNextStep for spec workflow starting phase', async () => {
65
+ const axios = require('axios');
66
+ const response = await axios.post((0, shared_server_utils_js_1.getMcpEndpoint)(), {
67
+ jsonrpc: '2.0',
68
+ id: 1,
69
+ method: 'tools/call',
70
+ params: {
71
+ name: 'seekCoachingOnNextStep',
72
+ arguments: {
73
+ workflowType: 'spec',
74
+ issueNumber: '123',
75
+ currentPhase: 'spec-spec',
76
+ status: 'starting',
77
+ evidence: { issueType: 'feature' }
78
+ }
79
+ }
80
+ });
81
+ node_assert_1.default.strictEqual(response.status, 200);
82
+ node_assert_1.default.ok(response.data.result);
83
+ node_assert_1.default.ok(response.data.result.content);
84
+ node_assert_1.default.ok(Array.isArray(response.data.result.content));
85
+ const content = response.data.result.content[0];
86
+ node_assert_1.default.strictEqual(content.type, 'text');
87
+ node_assert_1.default.ok(content.text.includes('Phase:'), 'Response should contain phase instructions');
88
+ node_assert_1.default.ok(content.text.includes('INTENT'), 'Response should contain INTENT section');
89
+ });
90
+ (0, node_test_1.it)('should execute seekCoachingOnNextStep for implement workflow starting phase', async () => {
91
+ const axios = require('axios');
92
+ const response = await axios.post((0, shared_server_utils_js_1.getMcpEndpoint)(), {
93
+ jsonrpc: '2.0',
94
+ id: 1,
95
+ method: 'tools/call',
96
+ params: {
97
+ name: 'seekCoachingOnNextStep',
98
+ arguments: {
99
+ workflowType: 'implement',
100
+ issueNumber: '456',
101
+ currentPhase: 'implement-scoping',
102
+ status: 'starting',
103
+ evidence: { issueType: 'bug' }
104
+ }
105
+ }
106
+ });
107
+ node_assert_1.default.strictEqual(response.status, 200);
108
+ node_assert_1.default.ok(response.data.result);
109
+ const content = response.data.result.content[0];
110
+ node_assert_1.default.ok(content.text.includes('Phase:'), 'Response should contain phase instructions');
111
+ node_assert_1.default.ok(content.text.includes('INTENT'), 'Response should contain INTENT section');
112
+ });
113
+ (0, node_test_1.it)('should execute seekCoachingOnNextStep for design workflow starting phase', async () => {
114
+ const axios = require('axios');
115
+ const response = await axios.post((0, shared_server_utils_js_1.getMcpEndpoint)(), {
116
+ jsonrpc: '2.0',
117
+ id: 1,
118
+ method: 'tools/call',
119
+ params: {
120
+ name: 'seekCoachingOnNextStep',
121
+ arguments: {
122
+ workflowType: 'design',
123
+ issueNumber: '789',
124
+ currentPhase: 'design-design',
125
+ status: 'starting',
126
+ evidence: { issueType: 'feature' }
127
+ }
128
+ }
129
+ });
130
+ node_assert_1.default.strictEqual(response.status, 200);
131
+ node_assert_1.default.ok(response.data.result);
132
+ const content = response.data.result.content[0];
133
+ node_assert_1.default.ok(content.text.includes('Phase:'), 'Response should contain phase instructions');
134
+ node_assert_1.default.ok(content.text.includes('INTENT'), 'Response should contain INTENT section');
135
+ });
136
+ (0, node_test_1.it)('should handle phase completion and provide next phase', async () => {
137
+ const axios = require('axios');
138
+ const response = await axios.post((0, shared_server_utils_js_1.getMcpEndpoint)(), {
139
+ jsonrpc: '2.0',
140
+ id: 1,
141
+ method: 'tools/call',
142
+ params: {
143
+ name: 'seekCoachingOnNextStep',
144
+ arguments: {
145
+ workflowType: 'spec',
146
+ issueNumber: '123',
147
+ currentPhase: 'spec-spec',
148
+ status: 'complete',
149
+ evidence: {
150
+ issueType: 'feature',
151
+ specComplete: true,
152
+ specDocument: 'docs/feature specs/123-test-feature.md'
153
+ }
154
+ }
155
+ }
156
+ });
157
+ node_assert_1.default.strictEqual(response.status, 200);
158
+ const content = response.data.result.content[0];
159
+ node_assert_1.default.ok(content.text.includes('Phase Complete!'), 'Should indicate phase completion');
160
+ node_assert_1.default.ok(content.text.includes('Next Phase: spec-completeness-review'), 'Should provide next phase');
161
+ });
162
+ (0, node_test_1.it)('should handle incomplete phase with help message', async () => {
163
+ const axios = require('axios');
164
+ const response = await axios.post((0, shared_server_utils_js_1.getMcpEndpoint)(), {
165
+ jsonrpc: '2.0',
166
+ id: 1,
167
+ method: 'tools/call',
168
+ params: {
169
+ name: 'seekCoachingOnNextStep',
170
+ arguments: {
171
+ workflowType: 'implement',
172
+ issueNumber: '456',
173
+ currentPhase: 'implement-code',
174
+ status: 'incomplete',
175
+ evidence: { issueType: 'bug' },
176
+ findings: {
177
+ uncertainties: ['Tests are failing', 'Build errors']
178
+ }
179
+ }
180
+ }
181
+ });
182
+ node_assert_1.default.strictEqual(response.status, 200);
183
+ const content = response.data.result.content[0];
184
+ node_assert_1.default.ok(content.text.includes('🤝 AI Coach Assistance'), 'Should show assistance header');
185
+ node_assert_1.default.ok(content.text.includes('Tests are failing'), 'Should include uncertainties');
186
+ node_assert_1.default.ok(content.text.includes('Build errors'), 'Should include all uncertainties');
187
+ });
188
+ (0, node_test_1.it)('should handle finalize phase completion', async () => {
189
+ const axios = require('axios');
190
+ const response = await axios.post((0, shared_server_utils_js_1.getMcpEndpoint)(), {
191
+ jsonrpc: '2.0',
192
+ id: 1,
193
+ method: 'tools/call',
194
+ params: {
195
+ name: 'seekCoachingOnNextStep',
196
+ arguments: {
197
+ workflowType: 'spec',
198
+ issueNumber: '123',
199
+ currentPhase: 'wait-for-pr-review',
200
+ status: 'complete',
201
+ evidence: {
202
+ issueType: 'feature',
203
+ prApproved: true,
204
+ reviewComplete: true
205
+ }
206
+ }
207
+ }
208
+ });
209
+ node_assert_1.default.strictEqual(response.status, 200);
210
+ const content = response.data.result.content[0];
211
+ node_assert_1.default.ok(content.text.includes('Spec Complete!'), 'Should show workflow completion');
212
+ node_assert_1.default.ok(content.text.includes('Congratulations!'), 'Should include congratulations');
213
+ });
214
+ });
215
+ (0, node_test_1.describe)('MCP Error Handling', () => {
216
+ (0, node_test_1.it)('should return error for invalid workflow type', async () => {
217
+ const axios = require('axios');
218
+ const response = await axios.post((0, shared_server_utils_js_1.getMcpEndpoint)(), {
219
+ jsonrpc: '2.0',
220
+ id: 1,
221
+ method: 'tools/call',
222
+ params: {
223
+ name: 'seekCoachingOnNextStep',
224
+ arguments: {
225
+ workflowType: 'invalid',
226
+ issueNumber: '123',
227
+ currentPhase: 'some-phase',
228
+ status: 'starting'
229
+ }
230
+ }
231
+ });
232
+ node_assert_1.default.strictEqual(response.status, 200);
233
+ node_assert_1.default.ok(response.data.error ||
234
+ (response.data.result && response.data.result.isError), 'Should return error for invalid workflow type');
235
+ });
236
+ (0, node_test_1.it)('should return error for invalid phase', async () => {
237
+ const axios = require('axios');
238
+ const response = await axios.post((0, shared_server_utils_js_1.getMcpEndpoint)(), {
239
+ jsonrpc: '2.0',
240
+ id: 1,
241
+ method: 'tools/call',
242
+ params: {
243
+ name: 'seekCoachingOnNextStep',
244
+ arguments: {
245
+ workflowType: 'spec',
246
+ issueNumber: '123',
247
+ currentPhase: 'implement-scoping', // Wrong phase for spec workflow
248
+ status: 'starting',
249
+ evidence: { issueType: 'feature' }
250
+ }
251
+ }
252
+ });
253
+ node_assert_1.default.strictEqual(response.status, 200);
254
+ node_assert_1.default.ok(response.data.error ||
255
+ (response.data.result && response.data.result.isError), 'Should return error for invalid phase');
256
+ });
257
+ (0, node_test_1.it)('should handle missing required parameters', async () => {
258
+ const axios = require('axios');
259
+ const response = await axios.post((0, shared_server_utils_js_1.getMcpEndpoint)(), {
260
+ jsonrpc: '2.0',
261
+ id: 1,
262
+ method: 'tools/call',
263
+ params: {
264
+ name: 'seekCoachingOnNextStep',
265
+ arguments: {
266
+ workflowType: 'spec',
267
+ // Missing issueNumber, currentPhase, status
268
+ }
269
+ }
270
+ });
271
+ node_assert_1.default.strictEqual(response.status, 200);
272
+ node_assert_1.default.ok(response.data.error ||
273
+ (response.data.result && response.data.result.isError), 'Should return error for missing required parameters');
274
+ });
275
+ });
276
+ (0, node_test_1.describe)('MCP Response Format', () => {
277
+ (0, node_test_1.it)('should return properly formatted MCP response', async () => {
278
+ const axios = require('axios');
279
+ const response = await axios.post((0, shared_server_utils_js_1.getMcpEndpoint)(), {
280
+ jsonrpc: '2.0',
281
+ id: 1,
282
+ method: 'tools/call',
283
+ params: {
284
+ name: 'seekCoachingOnNextStep',
285
+ arguments: {
286
+ workflowType: 'spec',
287
+ issueNumber: '123',
288
+ currentPhase: 'spec-spec',
289
+ status: 'starting',
290
+ evidence: { issueType: 'feature' }
291
+ }
292
+ }
293
+ });
294
+ node_assert_1.default.strictEqual(response.status, 200);
295
+ node_assert_1.default.strictEqual(response.data.jsonrpc, '2.0');
296
+ node_assert_1.default.strictEqual(response.data.id, 1);
297
+ node_assert_1.default.ok(response.data.result);
298
+ const result = response.data.result;
299
+ node_assert_1.default.ok(result.content);
300
+ node_assert_1.default.ok(Array.isArray(result.content));
301
+ node_assert_1.default.strictEqual(result.content.length, 1);
302
+ const content = result.content[0];
303
+ node_assert_1.default.strictEqual(content.type, 'text');
304
+ node_assert_1.default.ok(typeof content.text === 'string');
305
+ node_assert_1.default.ok(content.text.length > 0);
306
+ });
307
+ (0, node_test_1.it)('should include metadata in response when appropriate', async () => {
308
+ const axios = require('axios');
309
+ const response = await axios.post((0, shared_server_utils_js_1.getMcpEndpoint)(), {
310
+ jsonrpc: '2.0',
311
+ id: 1,
312
+ method: 'tools/call',
313
+ params: {
314
+ name: 'seekCoachingOnNextStep',
315
+ arguments: {
316
+ workflowType: 'spec',
317
+ issueNumber: '123',
318
+ currentPhase: 'spec-spec',
319
+ status: 'complete',
320
+ evidence: { issueType: 'feature', specComplete: true }
321
+ }
322
+ }
323
+ });
324
+ node_assert_1.default.strictEqual(response.status, 200);
325
+ const content = response.data.result.content[0];
326
+ // Should include both completion message and next phase instructions
327
+ node_assert_1.default.ok(content.text.includes('Phase Complete!'), 'Should include completion message');
328
+ node_assert_1.default.ok(content.text.includes('Next Phase:'), 'Should include next phase info');
329
+ node_assert_1.default.ok(content.text.length > 1000, 'Should include substantial content');
330
+ });
331
+ });
332
+ (0, node_test_1.describe)('Workflow Integration Tests', () => {
333
+ (0, node_test_1.it)('should support complete spec workflow via MCP', async () => {
334
+ const axios = require('axios');
335
+ // Start spec phase
336
+ let response = await axios.post((0, shared_server_utils_js_1.getMcpEndpoint)(), {
337
+ jsonrpc: '2.0',
338
+ id: 1,
339
+ method: 'tools/call',
340
+ params: {
341
+ name: 'seekCoachingOnNextStep',
342
+ arguments: {
343
+ workflowType: 'spec',
344
+ issueNumber: '999',
345
+ currentPhase: 'spec-spec',
346
+ status: 'starting',
347
+ evidence: { issueType: 'feature' }
348
+ }
349
+ }
350
+ });
351
+ node_assert_1.default.strictEqual(response.status, 200);
352
+ let content = response.data.result.content[0];
353
+ node_assert_1.default.ok(content.text.includes('Phase: Spec-Spec'), 'Should start with spec phase');
354
+ // Complete spec phase
355
+ response = await axios.post((0, shared_server_utils_js_1.getMcpEndpoint)(), {
356
+ jsonrpc: '2.0',
357
+ id: 2,
358
+ method: 'tools/call',
359
+ params: {
360
+ name: 'seekCoachingOnNextStep',
361
+ arguments: {
362
+ workflowType: 'spec',
363
+ issueNumber: '999',
364
+ currentPhase: 'spec-spec',
365
+ status: 'complete',
366
+ evidence: { issueType: 'feature', specComplete: true }
367
+ }
368
+ }
369
+ });
370
+ node_assert_1.default.strictEqual(response.status, 200);
371
+ content = response.data.result.content[0];
372
+ node_assert_1.default.ok(content.text.includes('Next Phase: spec-completeness-review'), 'Should transition to review');
373
+ // Complete review phase
374
+ response = await axios.post((0, shared_server_utils_js_1.getMcpEndpoint)(), {
375
+ jsonrpc: '2.0',
376
+ id: 3,
377
+ method: 'tools/call',
378
+ params: {
379
+ name: 'seekCoachingOnNextStep',
380
+ arguments: {
381
+ workflowType: 'spec',
382
+ issueNumber: '999',
383
+ currentPhase: 'spec-completeness-review',
384
+ status: 'complete',
385
+ evidence: { issueType: 'feature', reviewComplete: true }
386
+ }
387
+ }
388
+ });
389
+ node_assert_1.default.strictEqual(response.status, 200);
390
+ content = response.data.result.content[0];
391
+ node_assert_1.default.ok(content.text.includes('Next Phase: submit-pr'), 'Should transition to submit-pr');
392
+ // Complete submit-pr
393
+ response = await axios.post((0, shared_server_utils_js_1.getMcpEndpoint)(), {
394
+ jsonrpc: '2.0',
395
+ id: 4,
396
+ method: 'tools/call',
397
+ params: {
398
+ name: 'seekCoachingOnNextStep',
399
+ arguments: {
400
+ workflowType: 'spec',
401
+ issueNumber: '999',
402
+ currentPhase: 'submit-pr',
403
+ status: 'complete',
404
+ evidence: { issueType: 'feature', prSubmitted: true }
405
+ }
406
+ }
407
+ });
408
+ node_assert_1.default.strictEqual(response.status, 200);
409
+ content = response.data.result.content[0];
410
+ node_assert_1.default.ok(content.text.includes('Next Phase: wait-for-pr-review'), 'Should transition to wait-for-pr-review');
411
+ // Complete wait-for-pr-review
412
+ response = await axios.post((0, shared_server_utils_js_1.getMcpEndpoint)(), {
413
+ jsonrpc: '2.0',
414
+ id: 5,
415
+ method: 'tools/call',
416
+ params: {
417
+ name: 'seekCoachingOnNextStep',
418
+ arguments: {
419
+ workflowType: 'spec',
420
+ issueNumber: '999',
421
+ currentPhase: 'wait-for-pr-review',
422
+ status: 'complete',
423
+ evidence: { issueType: 'feature', prApproved: true }
424
+ }
425
+ }
426
+ });
427
+ node_assert_1.default.strictEqual(response.status, 200);
428
+ content = response.data.result.content[0];
429
+ node_assert_1.default.ok(content.text.includes('Spec Complete!'), 'Should show completion');
430
+ });
431
+ });
432
+ });