fraim-framework 2.0.55 → 2.0.57
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.
- package/CHANGELOG.md +10 -0
- package/dist/src/cli/commands/init-project.js +10 -4
- package/dist/src/cli/setup/mcp-config-generator.js +23 -15
- package/dist/src/local-mcp-server/stdio-server.js +207 -0
- package/dist/src/utils/validate-workflows.js +101 -0
- package/dist/src/utils/workflow-parser.js +81 -0
- package/package.json +16 -11
- package/registry/scripts/pdf-styles.css +172 -0
- package/registry/scripts/prep-issue.sh +46 -4
- package/registry/scripts/profile-server.ts +131 -130
- package/registry/stubs/workflows/customer-development/user-survey-dispatch.md +1 -1
- package/registry/stubs/workflows/customer-development/users-to-target.md +1 -1
- package/registry/stubs/workflows/product-building/design.md +1 -1
- package/registry/stubs/workflows/product-building/implement.md +1 -1
- package/Claude.md +0 -1
- package/dist/registry/ai-manager-rules/design-phases/design-completeness-review.md +0 -73
- package/dist/registry/ai-manager-rules/design-phases/design-design.md +0 -145
- package/dist/registry/ai-manager-rules/implement-phases/implement-code.md +0 -283
- package/dist/registry/ai-manager-rules/implement-phases/implement-completeness-review.md +0 -120
- package/dist/registry/ai-manager-rules/implement-phases/implement-regression.md +0 -173
- package/dist/registry/ai-manager-rules/implement-phases/implement-repro.md +0 -104
- package/dist/registry/ai-manager-rules/implement-phases/implement-scoping.md +0 -100
- package/dist/registry/ai-manager-rules/implement-phases/implement-smoke.md +0 -237
- package/dist/registry/ai-manager-rules/implement-phases/implement-spike.md +0 -121
- package/dist/registry/ai-manager-rules/implement-phases/implement-validate.md +0 -375
- package/dist/registry/ai-manager-rules/retrospective.md +0 -116
- package/dist/registry/ai-manager-rules/shared-phases/address-pr-feedback.md +0 -188
- package/dist/registry/ai-manager-rules/shared-phases/submit-pr.md +0 -202
- package/dist/registry/ai-manager-rules/shared-phases/wait-for-pr-review.md +0 -170
- package/dist/registry/ai-manager-rules/spec-phases/spec-competitor-analysis.md +0 -105
- package/dist/registry/ai-manager-rules/spec-phases/spec-completeness-review.md +0 -66
- package/dist/registry/ai-manager-rules/spec-phases/spec-spec.md +0 -139
- package/dist/registry/providers/ado.json +0 -19
- package/dist/registry/providers/github.json +0 -19
- package/dist/registry/scripts/cleanup-branch.js +0 -287
- package/dist/registry/scripts/evaluate-code-quality.js +0 -66
- package/dist/registry/scripts/exec-with-timeout.js +0 -142
- package/dist/registry/scripts/generate-engagement-emails.js +0 -705
- package/dist/registry/scripts/newsletter-helpers.js +0 -671
- package/dist/registry/scripts/profile-server.js +0 -388
- package/dist/registry/scripts/run-thank-you-workflow.js +0 -92
- package/dist/registry/scripts/send-newsletter-simple.js +0 -85
- package/dist/registry/scripts/send-thank-you-emails.js +0 -54
- package/dist/registry/scripts/validate-openapi-limits.js +0 -311
- package/dist/registry/scripts/validate-test-coverage.js +0 -262
- package/dist/registry/scripts/verify-test-coverage.js +0 -66
- package/dist/scripts/build-stub-registry.js +0 -108
- package/dist/src/ai-manager/ai-manager.js +0 -482
- package/dist/src/ai-manager/phase-flow.js +0 -357
- package/dist/src/ai-manager/types.js +0 -5
- package/dist/src/fraim-mcp-server.js +0 -1885
- package/dist/tests/debug-tools.js +0 -80
- package/dist/tests/shared-server-utils.js +0 -57
- package/dist/tests/test-add-ide.js +0 -283
- package/dist/tests/test-ai-coach-edge-cases.js +0 -420
- package/dist/tests/test-ai-coach-mcp-integration.js +0 -450
- package/dist/tests/test-ai-coach-performance.js +0 -328
- package/dist/tests/test-ai-coach-phase-content.js +0 -264
- package/dist/tests/test-ai-coach-workflows.js +0 -514
- package/dist/tests/test-cli.js +0 -228
- package/dist/tests/test-client-scripts-validation.js +0 -167
- package/dist/tests/test-complete-setup-flow.js +0 -110
- package/dist/tests/test-config-system.js +0 -279
- package/dist/tests/test-debug-session.js +0 -134
- package/dist/tests/test-end-to-end-hybrid-validation.js +0 -328
- package/dist/tests/test-enhanced-session-init.js +0 -188
- package/dist/tests/test-first-run-journey.js +0 -368
- package/dist/tests/test-fraim-issues.js +0 -59
- package/dist/tests/test-genericization.js +0 -44
- package/dist/tests/test-hybrid-script-execution.js +0 -340
- package/dist/tests/test-ide-detector.js +0 -46
- package/dist/tests/test-improved-setup.js +0 -121
- package/dist/tests/test-mcp-config-generator.js +0 -99
- package/dist/tests/test-mcp-connection.js +0 -107
- package/dist/tests/test-mcp-issue-integration.js +0 -156
- package/dist/tests/test-mcp-lifecycle-methods.js +0 -240
- package/dist/tests/test-mcp-shared-server.js +0 -308
- package/dist/tests/test-mcp-template-processing.js +0 -160
- package/dist/tests/test-modular-issue-tracking.js +0 -165
- package/dist/tests/test-node-compatibility.js +0 -95
- package/dist/tests/test-npm-install.js +0 -68
- package/dist/tests/test-package-size.js +0 -108
- package/dist/tests/test-pr-review-workflow.js +0 -307
- package/dist/tests/test-prep-issue.js +0 -129
- package/dist/tests/test-productivity-integration.js +0 -157
- package/dist/tests/test-script-location-independence.js +0 -198
- package/dist/tests/test-script-sync.js +0 -557
- package/dist/tests/test-server-utils.js +0 -32
- package/dist/tests/test-session-rehydration.js +0 -148
- package/dist/tests/test-setup-integration.js +0 -98
- package/dist/tests/test-setup-scenarios.js +0 -322
- package/dist/tests/test-standalone.js +0 -143
- package/dist/tests/test-stub-registry.js +0 -136
- package/dist/tests/test-sync-stubs.js +0 -143
- package/dist/tests/test-sync-version-update.js +0 -93
- package/dist/tests/test-telemetry.js +0 -193
- package/dist/tests/test-token-validator.js +0 -30
- package/dist/tests/test-user-journey.js +0 -236
- package/dist/tests/test-users-to-target-workflow.js +0 -253
- package/dist/tests/test-utils.js +0 -109
- package/dist/tests/test-wizard.js +0 -71
- package/dist/tests/test-workflow-discovery.js +0 -242
- package/labels.json +0 -52
- package/registry/agent-guardrails.md +0 -63
- package/registry/fraim.md +0 -48
- package/registry/stubs/workflows/customer-development/ai-coach-phases/phase1-customer-profiling.md +0 -11
- package/registry/stubs/workflows/customer-development/ai-coach-phases/phase1-survey-scoping.md +0 -11
- package/registry/stubs/workflows/customer-development/ai-coach-phases/phase2-platform-discovery.md +0 -11
- package/registry/stubs/workflows/customer-development/ai-coach-phases/phase2-survey-build-linkedin.md +0 -11
- package/registry/stubs/workflows/customer-development/ai-coach-phases/phase3-prospect-qualification.md +0 -11
- package/registry/stubs/workflows/customer-development/ai-coach-phases/phase3-survey-build-reddit.md +0 -11
- package/registry/stubs/workflows/customer-development/ai-coach-phases/phase4-inventory-compilation.md +0 -11
- package/registry/stubs/workflows/customer-development/ai-coach-phases/phase4-survey-build-x.md +0 -11
- package/registry/stubs/workflows/customer-development/ai-coach-phases/phase5-survey-build-facebook.md +0 -11
- package/registry/stubs/workflows/customer-development/ai-coach-phases/phase6-survey-build-custom.md +0 -11
- package/registry/stubs/workflows/customer-development/ai-coach-phases/phase7-survey-dispatch.md +0 -11
- package/registry/stubs/workflows/customer-development/templates/customer-persona-template.md +0 -11
- package/registry/stubs/workflows/customer-development/templates/search-strategy-template.md +0 -11
- package/setup.js +0 -171
- package/tsconfig.json +0 -23
|
@@ -1,420 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Tests for AI Coach edge cases and error scenarios
|
|
4
|
-
* Ensures robust handling of unusual inputs and error conditions
|
|
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 ai_manager_js_1 = require("../src/ai-manager/ai-manager.js");
|
|
13
|
-
const phase_flow_js_1 = require("../src/ai-manager/phase-flow.js");
|
|
14
|
-
(0, node_test_1.describe)('AI Coach Edge Cases and Error Scenarios', () => {
|
|
15
|
-
let coach;
|
|
16
|
-
let emptyFileIndex;
|
|
17
|
-
let partialFileIndex;
|
|
18
|
-
(0, node_test_1.before)(() => {
|
|
19
|
-
// Create different file index scenarios for testing
|
|
20
|
-
emptyFileIndex = new Map();
|
|
21
|
-
partialFileIndex = new Map();
|
|
22
|
-
partialFileIndex.set('ai-manager-rules/shared-phases/finalize.md', {
|
|
23
|
-
fullPath: './registry/ai-manager-rules/shared-phases/finalize.md'
|
|
24
|
-
});
|
|
25
|
-
coach = new ai_manager_js_1.AICoach(emptyFileIndex);
|
|
26
|
-
});
|
|
27
|
-
(0, node_test_1.describe)('Invalid Input Handling', () => {
|
|
28
|
-
(0, node_test_1.it)('should reject null or undefined workflow type', async () => {
|
|
29
|
-
const testCases = [null, undefined, ''];
|
|
30
|
-
for (const workflowType of testCases) {
|
|
31
|
-
try {
|
|
32
|
-
await coach.handleCoachingRequest({
|
|
33
|
-
workflowType: workflowType,
|
|
34
|
-
currentPhase: 'spec-spec',
|
|
35
|
-
status: 'starting',
|
|
36
|
-
issueNumber: '123'
|
|
37
|
-
});
|
|
38
|
-
node_assert_1.default.fail(`Should have thrown error for workflowType: ${workflowType}`);
|
|
39
|
-
}
|
|
40
|
-
catch (error) {
|
|
41
|
-
node_assert_1.default.ok(error instanceof Error);
|
|
42
|
-
node_assert_1.default.ok(error.message.includes('Invalid workflow type') ||
|
|
43
|
-
error.message.includes('workflow') ||
|
|
44
|
-
error.message.includes('required'));
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
(0, node_test_1.it)('should reject invalid workflow types', async () => {
|
|
49
|
-
const invalidTypes = ['invalid', 'SPEC', 'Implement', 'test123', 'spec-workflow'];
|
|
50
|
-
for (const workflowType of invalidTypes) {
|
|
51
|
-
try {
|
|
52
|
-
await coach.handleCoachingRequest({
|
|
53
|
-
workflowType,
|
|
54
|
-
currentPhase: 'some-phase',
|
|
55
|
-
status: 'starting',
|
|
56
|
-
issueNumber: '123'
|
|
57
|
-
});
|
|
58
|
-
node_assert_1.default.fail(`Should have thrown error for workflowType: ${workflowType}`);
|
|
59
|
-
}
|
|
60
|
-
catch (error) {
|
|
61
|
-
node_assert_1.default.ok(error instanceof Error);
|
|
62
|
-
node_assert_1.default.ok(error.message.includes('Invalid workflow type'));
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
(0, node_test_1.it)('should reject null or undefined phase names', async () => {
|
|
67
|
-
const testCases = [null, undefined, ''];
|
|
68
|
-
for (const currentPhase of testCases) {
|
|
69
|
-
try {
|
|
70
|
-
await coach.handleCoachingRequest({
|
|
71
|
-
workflowType: 'spec',
|
|
72
|
-
currentPhase: currentPhase,
|
|
73
|
-
status: 'starting',
|
|
74
|
-
issueNumber: '123'
|
|
75
|
-
});
|
|
76
|
-
node_assert_1.default.fail(`Should have thrown error for currentPhase: ${currentPhase}`);
|
|
77
|
-
}
|
|
78
|
-
catch (error) {
|
|
79
|
-
node_assert_1.default.ok(error instanceof Error);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
(0, node_test_1.it)('should reject invalid phase names for workflow types', async () => {
|
|
84
|
-
const testCases = [
|
|
85
|
-
{ workflow: 'spec', phase: 'implement-scoping' },
|
|
86
|
-
{ workflow: 'spec', phase: 'design-design' },
|
|
87
|
-
{ workflow: 'implement', phase: 'spec-spec' },
|
|
88
|
-
{ workflow: 'implement', phase: 'design-completeness-review' },
|
|
89
|
-
{ workflow: 'design', phase: 'implement-code' },
|
|
90
|
-
{ workflow: 'design', phase: 'spec-completeness-review' }
|
|
91
|
-
];
|
|
92
|
-
for (const { workflow, phase } of testCases) {
|
|
93
|
-
try {
|
|
94
|
-
await coach.handleCoachingRequest({
|
|
95
|
-
workflowType: workflow,
|
|
96
|
-
currentPhase: phase,
|
|
97
|
-
status: 'starting',
|
|
98
|
-
issueNumber: '123',
|
|
99
|
-
evidence: { issueType: 'feature' }
|
|
100
|
-
});
|
|
101
|
-
node_assert_1.default.fail(`Should have thrown error for ${workflow}/${phase}`);
|
|
102
|
-
}
|
|
103
|
-
catch (error) {
|
|
104
|
-
node_assert_1.default.ok(error instanceof Error);
|
|
105
|
-
node_assert_1.default.ok(error.message.toLowerCase().includes('invalid phase'));
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
(0, node_test_1.it)('should reject invalid status values', async () => {
|
|
110
|
-
const invalidStatuses = ['invalid', 'COMPLETE', 'Complete', 'done', 'finished'];
|
|
111
|
-
for (const status of invalidStatuses) {
|
|
112
|
-
try {
|
|
113
|
-
await coach.handleCoachingRequest({
|
|
114
|
-
workflowType: 'spec',
|
|
115
|
-
currentPhase: 'spec-spec',
|
|
116
|
-
status: status,
|
|
117
|
-
issueNumber: '123'
|
|
118
|
-
});
|
|
119
|
-
node_assert_1.default.fail(`Should have thrown error for status: ${status}`);
|
|
120
|
-
}
|
|
121
|
-
catch (error) {
|
|
122
|
-
node_assert_1.default.ok(error instanceof Error);
|
|
123
|
-
// Note: Some invalid statuses might be handled gracefully
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
(0, node_test_1.it)('should handle missing issue number gracefully', async () => {
|
|
128
|
-
const testCases = [null, undefined, '', ' '];
|
|
129
|
-
for (const issueNumber of testCases) {
|
|
130
|
-
// This should not throw an error, but should handle gracefully
|
|
131
|
-
const result = await coach.handleCoachingRequest({
|
|
132
|
-
workflowType: 'spec',
|
|
133
|
-
currentPhase: 'spec-spec',
|
|
134
|
-
status: 'starting',
|
|
135
|
-
issueNumber: issueNumber
|
|
136
|
-
});
|
|
137
|
-
node_assert_1.default.ok(typeof result === 'string');
|
|
138
|
-
node_assert_1.default.ok(result.length > 0);
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
(0, node_test_1.describe)('Missing File Handling', () => {
|
|
143
|
-
(0, node_test_1.it)('should handle missing phase files gracefully', async () => {
|
|
144
|
-
const coachWithEmptyIndex = new ai_manager_js_1.AICoach(emptyFileIndex);
|
|
145
|
-
const result = await coachWithEmptyIndex.handleCoachingRequest({
|
|
146
|
-
workflowType: 'spec',
|
|
147
|
-
currentPhase: 'spec-spec',
|
|
148
|
-
status: 'starting',
|
|
149
|
-
issueNumber: '123',
|
|
150
|
-
evidence: { issueType: 'feature' }
|
|
151
|
-
});
|
|
152
|
-
// Should return valid phase instructions (fallback mechanism works)
|
|
153
|
-
node_assert_1.default.ok(typeof result === 'string');
|
|
154
|
-
node_assert_1.default.ok(result.length > 0);
|
|
155
|
-
node_assert_1.default.ok(result.includes('# Phase: Spec-Spec') || result.includes('INTENT'));
|
|
156
|
-
});
|
|
157
|
-
(0, node_test_1.it)('should provide helpful error messages for missing files', async () => {
|
|
158
|
-
const coachWithEmptyIndex = new ai_manager_js_1.AICoach(emptyFileIndex);
|
|
159
|
-
const result = await coachWithEmptyIndex.handleCoachingRequest({
|
|
160
|
-
workflowType: 'implement',
|
|
161
|
-
currentPhase: 'implement-scoping',
|
|
162
|
-
status: 'starting',
|
|
163
|
-
issueNumber: '123',
|
|
164
|
-
evidence: { issueType: 'bug' }
|
|
165
|
-
});
|
|
166
|
-
// Should return valid phase instructions (fallback mechanism works)
|
|
167
|
-
node_assert_1.default.ok(typeof result === 'string');
|
|
168
|
-
node_assert_1.default.ok(result.length > 0);
|
|
169
|
-
node_assert_1.default.ok(result.includes('# Phase: Implement-Scoping') || result.includes('INTENT'));
|
|
170
|
-
});
|
|
171
|
-
(0, node_test_1.it)('should list available phases when file not found', async () => {
|
|
172
|
-
const coachWithEmptyIndex = new ai_manager_js_1.AICoach(emptyFileIndex);
|
|
173
|
-
const result = await coachWithEmptyIndex.handleCoachingRequest({
|
|
174
|
-
workflowType: 'spec',
|
|
175
|
-
currentPhase: 'spec-spec',
|
|
176
|
-
status: 'starting',
|
|
177
|
-
issueNumber: '123',
|
|
178
|
-
evidence: { issueType: 'feature' }
|
|
179
|
-
});
|
|
180
|
-
// Should return valid phase instructions (fallback mechanism works)
|
|
181
|
-
node_assert_1.default.ok(typeof result === 'string');
|
|
182
|
-
node_assert_1.default.ok(result.length > 0);
|
|
183
|
-
node_assert_1.default.ok(result.includes('# Phase: Spec-Spec') || result.includes('INTENT'));
|
|
184
|
-
});
|
|
185
|
-
});
|
|
186
|
-
(0, node_test_1.describe)('Malformed Data Handling', () => {
|
|
187
|
-
(0, node_test_1.it)('should handle malformed evidence objects', async () => {
|
|
188
|
-
const malformedEvidence = [
|
|
189
|
-
{ issueType: null },
|
|
190
|
-
{ issueType: 123 },
|
|
191
|
-
{ issueType: [] },
|
|
192
|
-
{ issueType: {} },
|
|
193
|
-
'not an object',
|
|
194
|
-
123,
|
|
195
|
-
null
|
|
196
|
-
];
|
|
197
|
-
for (const evidence of malformedEvidence) {
|
|
198
|
-
const result = await coach.handleCoachingRequest({
|
|
199
|
-
workflowType: 'spec',
|
|
200
|
-
currentPhase: 'spec-spec',
|
|
201
|
-
status: 'starting',
|
|
202
|
-
issueNumber: '123',
|
|
203
|
-
evidence: evidence
|
|
204
|
-
});
|
|
205
|
-
// Should handle gracefully, not throw
|
|
206
|
-
node_assert_1.default.ok(typeof result === 'string');
|
|
207
|
-
node_assert_1.default.ok(result.length > 0);
|
|
208
|
-
}
|
|
209
|
-
});
|
|
210
|
-
(0, node_test_1.it)('should handle malformed findings objects', async () => {
|
|
211
|
-
const malformedFindings = [
|
|
212
|
-
{ uncertainties: 'not an array' },
|
|
213
|
-
{ uncertainties: 123 },
|
|
214
|
-
{ uncertainties: null },
|
|
215
|
-
'not an object',
|
|
216
|
-
123,
|
|
217
|
-
null
|
|
218
|
-
];
|
|
219
|
-
for (const findings of malformedFindings) {
|
|
220
|
-
const result = await coach.handleCoachingRequest({
|
|
221
|
-
workflowType: 'implement',
|
|
222
|
-
currentPhase: 'implement-code',
|
|
223
|
-
status: 'incomplete',
|
|
224
|
-
issueNumber: '123',
|
|
225
|
-
evidence: { issueType: 'bug' },
|
|
226
|
-
findings: findings
|
|
227
|
-
});
|
|
228
|
-
// Should handle gracefully
|
|
229
|
-
node_assert_1.default.ok(typeof result === 'string');
|
|
230
|
-
node_assert_1.default.ok(result.length > 0);
|
|
231
|
-
}
|
|
232
|
-
});
|
|
233
|
-
(0, node_test_1.it)('should handle extremely long input strings', async () => {
|
|
234
|
-
const longString = 'x'.repeat(10000);
|
|
235
|
-
const result = await coach.handleCoachingRequest({
|
|
236
|
-
workflowType: 'spec',
|
|
237
|
-
currentPhase: 'spec-spec',
|
|
238
|
-
status: 'starting',
|
|
239
|
-
issueNumber: longString,
|
|
240
|
-
evidence: { issueType: 'feature' }
|
|
241
|
-
});
|
|
242
|
-
node_assert_1.default.ok(typeof result === 'string');
|
|
243
|
-
node_assert_1.default.ok(result.length > 0);
|
|
244
|
-
});
|
|
245
|
-
(0, node_test_1.it)('should handle special characters in input', async () => {
|
|
246
|
-
const specialChars = ['<script>', '"; DROP TABLE;', '\\n\\r\\t', '🎉💻🚀', '中文测试'];
|
|
247
|
-
for (const specialChar of specialChars) {
|
|
248
|
-
const result = await coach.handleCoachingRequest({
|
|
249
|
-
workflowType: 'spec',
|
|
250
|
-
currentPhase: 'spec-spec',
|
|
251
|
-
status: 'starting',
|
|
252
|
-
issueNumber: specialChar,
|
|
253
|
-
evidence: { issueType: 'feature' }
|
|
254
|
-
});
|
|
255
|
-
node_assert_1.default.ok(typeof result === 'string');
|
|
256
|
-
node_assert_1.default.ok(result.length > 0);
|
|
257
|
-
}
|
|
258
|
-
});
|
|
259
|
-
});
|
|
260
|
-
(0, node_test_1.describe)('Phase Flow Edge Cases', () => {
|
|
261
|
-
(0, node_test_1.it)('should handle invalid phase transitions', () => {
|
|
262
|
-
// Test invalid phases that don't exist in any workflow
|
|
263
|
-
const invalidPhases = ['nonexistent-phase', 'random-phase', 'phase-123'];
|
|
264
|
-
for (const phase of invalidPhases) {
|
|
265
|
-
node_assert_1.default.throws(() => {
|
|
266
|
-
(0, phase_flow_js_1.getNextPhase)(phase, 'spec');
|
|
267
|
-
}, /Invalid phase/);
|
|
268
|
-
}
|
|
269
|
-
});
|
|
270
|
-
(0, node_test_1.it)('should handle missing issue type for implement workflow', () => {
|
|
271
|
-
node_assert_1.default.throws(() => {
|
|
272
|
-
(0, phase_flow_js_1.getNextPhase)('implement-scoping', 'implement');
|
|
273
|
-
}, /Issue type is required/);
|
|
274
|
-
node_assert_1.default.throws(() => {
|
|
275
|
-
(0, phase_flow_js_1.getNextPhase)('implement-scoping', 'implement', undefined);
|
|
276
|
-
}, /Issue type is required/);
|
|
277
|
-
});
|
|
278
|
-
(0, node_test_1.it)('should validate phase names case-sensitively', () => {
|
|
279
|
-
const caseSensitiveTests = [
|
|
280
|
-
{ phase: 'SPEC-SPEC', workflow: 'spec', shouldBeValid: false },
|
|
281
|
-
{ phase: 'Spec-Spec', workflow: 'spec', shouldBeValid: false },
|
|
282
|
-
{ phase: 'spec-SPEC', workflow: 'spec', shouldBeValid: false },
|
|
283
|
-
{ phase: 'implement-SCOPING', workflow: 'implement', shouldBeValid: false },
|
|
284
|
-
{ phase: 'IMPLEMENT-scoping', workflow: 'implement', shouldBeValid: false }
|
|
285
|
-
];
|
|
286
|
-
for (const test of caseSensitiveTests) {
|
|
287
|
-
const isValid = (0, phase_flow_js_1.isPhaseValidForWorkflow)(test.phase, test.workflow, 'feature');
|
|
288
|
-
node_assert_1.default.strictEqual(isValid, test.shouldBeValid, `Phase ${test.phase} should ${test.shouldBeValid ? 'be' : 'not be'} valid for ${test.workflow}`);
|
|
289
|
-
}
|
|
290
|
-
});
|
|
291
|
-
(0, node_test_1.it)('should handle boundary conditions in phase flows', () => {
|
|
292
|
-
// Test last phase in each workflow - retrospective is now the final phase
|
|
293
|
-
node_assert_1.default.strictEqual((0, phase_flow_js_1.getNextPhase)('retrospective', 'spec'), null);
|
|
294
|
-
node_assert_1.default.strictEqual((0, phase_flow_js_1.getNextPhase)('retrospective', 'design'), null);
|
|
295
|
-
node_assert_1.default.strictEqual((0, phase_flow_js_1.getNextPhase)('retrospective', 'implement', 'bug'), null);
|
|
296
|
-
node_assert_1.default.strictEqual((0, phase_flow_js_1.getNextPhase)('retrospective', 'implement', 'feature'), null);
|
|
297
|
-
// Test that wait-for-pr-review transitions to retrospective
|
|
298
|
-
node_assert_1.default.strictEqual((0, phase_flow_js_1.getNextPhase)('wait-for-pr-review', 'spec'), 'retrospective');
|
|
299
|
-
node_assert_1.default.strictEqual((0, phase_flow_js_1.getNextPhase)('wait-for-pr-review', 'design'), 'retrospective');
|
|
300
|
-
node_assert_1.default.strictEqual((0, phase_flow_js_1.getNextPhase)('wait-for-pr-review', 'implement', 'bug'), 'retrospective');
|
|
301
|
-
node_assert_1.default.strictEqual((0, phase_flow_js_1.getNextPhase)('wait-for-pr-review', 'implement', 'feature'), 'retrospective');
|
|
302
|
-
});
|
|
303
|
-
});
|
|
304
|
-
(0, node_test_1.describe)('Concurrent Access Handling', () => {
|
|
305
|
-
(0, node_test_1.it)('should handle multiple simultaneous requests', async () => {
|
|
306
|
-
const requests = Array.from({ length: 10 }, (_, i) => coach.handleCoachingRequest({
|
|
307
|
-
workflowType: 'spec',
|
|
308
|
-
currentPhase: 'spec-spec',
|
|
309
|
-
status: 'starting',
|
|
310
|
-
issueNumber: `${i}`,
|
|
311
|
-
evidence: { issueType: 'feature' }
|
|
312
|
-
}));
|
|
313
|
-
const results = await Promise.all(requests);
|
|
314
|
-
// All requests should complete successfully
|
|
315
|
-
node_assert_1.default.strictEqual(results.length, 10);
|
|
316
|
-
for (const result of results) {
|
|
317
|
-
node_assert_1.default.ok(typeof result === 'string');
|
|
318
|
-
node_assert_1.default.ok(result.length > 0);
|
|
319
|
-
}
|
|
320
|
-
});
|
|
321
|
-
(0, node_test_1.it)('should handle mixed workflow types concurrently', async () => {
|
|
322
|
-
const workflows = ['spec', 'design', 'implement'];
|
|
323
|
-
const phases = ['spec-spec', 'design-design', 'implement-scoping'];
|
|
324
|
-
const requests = workflows.map((workflow, i) => coach.handleCoachingRequest({
|
|
325
|
-
workflowType: workflow,
|
|
326
|
-
currentPhase: phases[i],
|
|
327
|
-
status: 'starting',
|
|
328
|
-
issueNumber: `${i}`,
|
|
329
|
-
evidence: { issueType: 'feature' }
|
|
330
|
-
}));
|
|
331
|
-
const results = await Promise.all(requests);
|
|
332
|
-
node_assert_1.default.strictEqual(results.length, 3);
|
|
333
|
-
for (const result of results) {
|
|
334
|
-
node_assert_1.default.ok(typeof result === 'string');
|
|
335
|
-
node_assert_1.default.ok(result.length > 0);
|
|
336
|
-
}
|
|
337
|
-
});
|
|
338
|
-
});
|
|
339
|
-
(0, node_test_1.describe)('Memory and Performance Edge Cases', () => {
|
|
340
|
-
(0, node_test_1.it)('should handle large evidence objects', async () => {
|
|
341
|
-
const largeEvidence = {
|
|
342
|
-
issueType: 'feature',
|
|
343
|
-
largeData: Array.from({ length: 1000 }, (_, i) => `item-${i}`),
|
|
344
|
-
nestedObject: {
|
|
345
|
-
level1: {
|
|
346
|
-
level2: {
|
|
347
|
-
level3: Array.from({ length: 100 }, (_, i) => ({ id: i, data: `data-${i}` }))
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
};
|
|
352
|
-
const result = await coach.handleCoachingRequest({
|
|
353
|
-
workflowType: 'spec',
|
|
354
|
-
currentPhase: 'spec-spec',
|
|
355
|
-
status: 'starting',
|
|
356
|
-
issueNumber: '123',
|
|
357
|
-
evidence: largeEvidence
|
|
358
|
-
});
|
|
359
|
-
node_assert_1.default.ok(typeof result === 'string');
|
|
360
|
-
node_assert_1.default.ok(result.length > 0);
|
|
361
|
-
});
|
|
362
|
-
(0, node_test_1.it)('should handle rapid sequential requests', async () => {
|
|
363
|
-
const startTime = Date.now();
|
|
364
|
-
for (let i = 0; i < 50; i++) {
|
|
365
|
-
const result = await coach.handleCoachingRequest({
|
|
366
|
-
workflowType: 'spec',
|
|
367
|
-
currentPhase: 'spec-spec',
|
|
368
|
-
status: 'starting',
|
|
369
|
-
issueNumber: `${i}`,
|
|
370
|
-
evidence: { issueType: 'feature' }
|
|
371
|
-
});
|
|
372
|
-
node_assert_1.default.ok(typeof result === 'string');
|
|
373
|
-
}
|
|
374
|
-
const duration = Date.now() - startTime;
|
|
375
|
-
console.log(`50 sequential requests completed in ${duration}ms`);
|
|
376
|
-
// Should complete reasonably quickly (less than 10 seconds)
|
|
377
|
-
node_assert_1.default.ok(duration < 10000, 'Sequential requests should complete in reasonable time');
|
|
378
|
-
});
|
|
379
|
-
});
|
|
380
|
-
(0, node_test_1.describe)('File System Edge Cases', () => {
|
|
381
|
-
(0, node_test_1.it)('should handle file system errors gracefully', async () => {
|
|
382
|
-
// Test that the system handles corrupted file index gracefully
|
|
383
|
-
// This tests the robustness of the fallback mechanism
|
|
384
|
-
const corruptedIndex = new Map();
|
|
385
|
-
corruptedIndex.set('ai-manager-rules/spec-phases/spec-spec.md', {
|
|
386
|
-
fullPath: '/completely/nonexistent/path/that/will/never/exist.md'
|
|
387
|
-
});
|
|
388
|
-
const corruptedCoach = new ai_manager_js_1.AICoach(corruptedIndex);
|
|
389
|
-
const result = await corruptedCoach.handleCoachingRequest({
|
|
390
|
-
workflowType: 'spec',
|
|
391
|
-
currentPhase: 'spec-spec',
|
|
392
|
-
status: 'starting',
|
|
393
|
-
issueNumber: '123',
|
|
394
|
-
evidence: { issueType: 'feature' }
|
|
395
|
-
});
|
|
396
|
-
// Should handle gracefully - either return error message or fallback to working file
|
|
397
|
-
node_assert_1.default.ok(typeof result === 'string');
|
|
398
|
-
node_assert_1.default.ok(result.length > 0);
|
|
399
|
-
// The system should either show an error or successfully fall back to the working file
|
|
400
|
-
node_assert_1.default.ok(result.includes('**Error**') || result.includes('Phase instructions not found') || result.includes('# Phase: Spec-Spec'));
|
|
401
|
-
});
|
|
402
|
-
(0, node_test_1.it)('should handle corrupted file index', async () => {
|
|
403
|
-
const corruptedIndex = new Map();
|
|
404
|
-
corruptedIndex.set('ai-manager-rules/spec-phases/spec-spec.md', null);
|
|
405
|
-
corruptedIndex.set('ai-manager-rules/spec-phases/spec-completeness-review.md', undefined);
|
|
406
|
-
corruptedIndex.set('ai-manager-rules/shared-phases/finalize.md', 'not an object');
|
|
407
|
-
const corruptedCoach = new ai_manager_js_1.AICoach(corruptedIndex);
|
|
408
|
-
const result = await corruptedCoach.handleCoachingRequest({
|
|
409
|
-
workflowType: 'spec',
|
|
410
|
-
currentPhase: 'spec-spec',
|
|
411
|
-
status: 'starting',
|
|
412
|
-
issueNumber: '123',
|
|
413
|
-
evidence: { issueType: 'feature' }
|
|
414
|
-
});
|
|
415
|
-
// Should handle gracefully
|
|
416
|
-
node_assert_1.default.ok(typeof result === 'string');
|
|
417
|
-
node_assert_1.default.ok(result.length > 0);
|
|
418
|
-
});
|
|
419
|
-
});
|
|
420
|
-
});
|