fraim-framework 2.0.52 → 2.0.54

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 (98) hide show
  1. package/dist/registry/scripts/profile-server.js +2 -1
  2. package/dist/src/ai-manager/ai-manager.js +49 -1
  3. package/dist/src/ai-manager/phase-flow.js +68 -0
  4. package/dist/tests/test-debug-session.js +6 -2
  5. package/dist/tests/test-enhanced-session-init.js +6 -2
  6. package/dist/tests/test-mcp-lifecycle-methods.js +1 -2
  7. package/dist/tests/test-mcp-template-processing.js +6 -2
  8. package/dist/tests/test-modular-issue-tracking.js +6 -2
  9. package/dist/tests/test-node-compatibility.js +4 -2
  10. package/dist/tests/test-npm-install.js +4 -2
  11. package/dist/tests/test-productivity-integration.js +157 -0
  12. package/dist/tests/test-session-rehydration.js +1 -2
  13. package/dist/tests/test-telemetry.js +1 -2
  14. package/dist/tests/test-users-to-target-workflow.js +256 -0
  15. package/package.json +1 -1
  16. package/registry/agent-guardrails.md +62 -62
  17. package/registry/scripts/detect-tautological-tests.sh +38 -38
  18. package/registry/scripts/productivity/build-productivity-csv.mjs +242 -0
  19. package/registry/scripts/productivity/fetch-pr-details.mjs +144 -0
  20. package/registry/scripts/productivity/productivity-report.sh +147 -0
  21. package/registry/scripts/profile-server.ts +1 -1
  22. package/registry/scripts/validate-openapi-limits.ts +366 -366
  23. package/registry/scripts/validate-test-coverage.ts +280 -280
  24. package/registry/stubs/workflows/customer-development/ai-coach-phases/phase1-customer-profiling.md +11 -0
  25. package/registry/stubs/workflows/customer-development/ai-coach-phases/phase1-survey-scoping.md +11 -0
  26. package/registry/stubs/workflows/customer-development/ai-coach-phases/phase2-platform-discovery.md +11 -0
  27. package/registry/stubs/workflows/customer-development/ai-coach-phases/phase2-survey-build-linkedin.md +11 -0
  28. package/registry/stubs/workflows/customer-development/ai-coach-phases/phase3-prospect-qualification.md +11 -0
  29. package/registry/stubs/workflows/customer-development/ai-coach-phases/phase3-survey-build-reddit.md +11 -0
  30. package/registry/stubs/workflows/customer-development/ai-coach-phases/phase4-inventory-compilation.md +11 -0
  31. package/registry/stubs/workflows/customer-development/ai-coach-phases/phase4-survey-build-x.md +11 -0
  32. package/registry/stubs/workflows/customer-development/ai-coach-phases/phase5-survey-build-facebook.md +11 -0
  33. package/registry/stubs/workflows/customer-development/ai-coach-phases/phase6-survey-build-custom.md +11 -0
  34. package/registry/stubs/workflows/customer-development/ai-coach-phases/phase7-survey-dispatch.md +11 -0
  35. package/registry/stubs/workflows/customer-development/templates/customer-persona-template.md +11 -0
  36. package/registry/stubs/workflows/customer-development/templates/search-strategy-template.md +11 -0
  37. package/registry/stubs/workflows/customer-development/user-survey-dispatch.md +11 -0
  38. package/registry/stubs/workflows/customer-development/users-to-target.md +11 -0
  39. package/registry/stubs/workflows/productivity-report/productivity-report.md +11 -0
  40. package/bin/fraim.js +0 -8
  41. package/dist/registry/ai-manager-rules/design-phases/design.md +0 -108
  42. package/dist/registry/ai-manager-rules/design-phases/finalize.md +0 -60
  43. package/dist/registry/ai-manager-rules/design-phases/validate.md +0 -125
  44. package/dist/registry/ai-manager-rules/design.json +0 -97
  45. package/dist/registry/ai-manager-rules/implement-phases/code.md +0 -323
  46. package/dist/registry/ai-manager-rules/implement-phases/completeness-review.md +0 -94
  47. package/dist/registry/ai-manager-rules/implement-phases/finalize.md +0 -177
  48. package/dist/registry/ai-manager-rules/implement-phases/quality-review.md +0 -304
  49. package/dist/registry/ai-manager-rules/implement-phases/regression.md +0 -159
  50. package/dist/registry/ai-manager-rules/implement-phases/repro.md +0 -101
  51. package/dist/registry/ai-manager-rules/implement-phases/scoping.md +0 -93
  52. package/dist/registry/ai-manager-rules/implement-phases/smoke.md +0 -225
  53. package/dist/registry/ai-manager-rules/implement-phases/spike.md +0 -118
  54. package/dist/registry/ai-manager-rules/implement-phases/validate.md +0 -347
  55. package/dist/registry/ai-manager-rules/implement.json +0 -153
  56. package/dist/registry/ai-manager-rules/shared-phases/finalize.md +0 -169
  57. package/dist/registry/ai-manager-rules/spec-phases/finalize.md +0 -60
  58. package/dist/registry/ai-manager-rules/spec-phases/spec.md +0 -102
  59. package/dist/registry/ai-manager-rules/spec-phases/validate.md +0 -118
  60. package/dist/registry/ai-manager-rules/spec.json +0 -112
  61. package/dist/registry/ai-manager-rules/test.json +0 -98
  62. package/dist/registry/scripts/build-scripts-generator.js +0 -205
  63. package/dist/registry/scripts/fraim-config.js +0 -61
  64. package/dist/registry/scripts/generic-issues-api.js +0 -100
  65. package/dist/registry/scripts/openapi-generator.js +0 -664
  66. package/dist/registry/scripts/performance/profile-server.js +0 -390
  67. package/dist/src/ai-manager/evidence-validator.js +0 -309
  68. package/dist/src/fraim/issue-tracking/ado-provider.js +0 -304
  69. package/dist/src/fraim/issue-tracking/factory.js +0 -63
  70. package/dist/src/fraim/issue-tracking/github-provider.js +0 -200
  71. package/dist/src/fraim/issue-tracking/types.js +0 -7
  72. package/dist/src/fraim/issue-tracking-config.js +0 -83
  73. package/dist/src/static-website-middleware.js +0 -75
  74. package/dist/test-utils.js +0 -96
  75. package/dist/tests/esm-compat.js +0 -11
  76. package/dist/tests/test-ai-manager-phase-protocol.js +0 -147
  77. package/dist/tests/test-ai-manager.js +0 -118
  78. package/dist/tests/test-chalk-esm-issue.js +0 -159
  79. package/dist/tests/test-chalk-real-world.js +0 -265
  80. package/dist/tests/test-chalk-regression.js +0 -377
  81. package/dist/tests/test-chalk-resolution-issue.js +0 -304
  82. package/dist/tests/test-evidence-validation.js +0 -221
  83. package/dist/tests/test-first-run-interactive.js +0 -1
  84. package/dist/tests/test-fraim-install-chalk-issue.js +0 -254
  85. package/dist/tests/test-markdown-to-pdf.js +0 -454
  86. package/dist/tests/test-npm-resolution-diagnostic.js +0 -140
  87. package/dist/tests/test-pr-review-integration.js +0 -1
  88. package/dist/website/.nojekyll +0 -0
  89. package/dist/website/404.html +0 -101
  90. package/dist/website/CNAME +0 -1
  91. package/dist/website/README.md +0 -22
  92. package/dist/website/demo.html +0 -604
  93. package/dist/website/images/.gitkeep +0 -1
  94. package/dist/website/images/fraim-logo.png +0 -0
  95. package/dist/website/index.html +0 -290
  96. package/dist/website/pricing.html +0 -414
  97. package/dist/website/script.js +0 -55
  98. package/dist/website/styles.css +0 -2647
@@ -1,200 +0,0 @@
1
- "use strict";
2
- /**
3
- * GitHub Issue Tracking Provider
4
- *
5
- * Implements the IssueTrackingProvider interface for GitHub Issues
6
- */
7
- var __importDefault = (this && this.__importDefault) || function (mod) {
8
- return (mod && mod.__esModule) ? mod : { "default": mod };
9
- };
10
- Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.GitHubIssueProvider = void 0;
12
- const axios_1 = __importDefault(require("axios"));
13
- class GitHubIssueProvider {
14
- constructor(config) {
15
- this.config = config;
16
- this.baseUrl = `https://api.github.com/repos/${config.owner}/${config.repo}`;
17
- }
18
- async createIssue(params) {
19
- const { title, body, labels, assignee, dryRun } = params;
20
- const payload = {
21
- title,
22
- body
23
- };
24
- if (labels && labels.length > 0) {
25
- payload.labels = labels;
26
- }
27
- if (assignee) {
28
- payload.assignee = assignee;
29
- }
30
- if (dryRun) {
31
- return {
32
- success: true,
33
- dryRun: true,
34
- provider: 'github',
35
- message: `[DRY RUN] Would create GitHub issue: "${title}" in ${this.config.owner}/${this.config.repo}`
36
- };
37
- }
38
- try {
39
- const response = await axios_1.default.post(`${this.baseUrl}/issues`, payload, {
40
- headers: {
41
- 'Authorization': `Bearer ${this.config.token}`,
42
- 'Accept': 'application/vnd.github.v3+json',
43
- 'Content-Type': 'application/json',
44
- },
45
- });
46
- return {
47
- success: true,
48
- issueNumber: response.data.number,
49
- issueId: response.data.number,
50
- htmlUrl: response.data.html_url,
51
- provider: 'github'
52
- };
53
- }
54
- catch (error) {
55
- return {
56
- success: false,
57
- provider: 'github',
58
- message: this.formatError(error)
59
- };
60
- }
61
- }
62
- async getIssue(issueId) {
63
- try {
64
- const response = await axios_1.default.get(`${this.baseUrl}/issues/${issueId}`, {
65
- headers: {
66
- 'Authorization': `Bearer ${this.config.token}`,
67
- 'Accept': 'application/vnd.github.v3+json',
68
- },
69
- });
70
- const issue = response.data;
71
- return {
72
- id: issue.number,
73
- title: issue.title,
74
- body: issue.body || '',
75
- state: issue.state === 'open' ? 'open' : 'closed',
76
- assignee: issue.assignee?.login,
77
- labels: issue.labels.map((label) => label.name),
78
- createdAt: new Date(issue.created_at),
79
- updatedAt: new Date(issue.updated_at),
80
- htmlUrl: issue.html_url
81
- };
82
- }
83
- catch (error) {
84
- if (error.response?.status === 404) {
85
- return null;
86
- }
87
- throw new Error(this.formatError(error));
88
- }
89
- }
90
- async updateIssue(issueId, updates) {
91
- const payload = {};
92
- if (updates.title)
93
- payload.title = updates.title;
94
- if (updates.body)
95
- payload.body = updates.body;
96
- if (updates.labels)
97
- payload.labels = updates.labels;
98
- if (updates.assignee)
99
- payload.assignee = updates.assignee;
100
- if (updates.dryRun) {
101
- return {
102
- success: true,
103
- dryRun: true,
104
- provider: 'github',
105
- message: `[DRY RUN] Would update GitHub issue #${issueId} in ${this.config.owner}/${this.config.repo}`
106
- };
107
- }
108
- try {
109
- const response = await axios_1.default.patch(`${this.baseUrl}/issues/${issueId}`, payload, {
110
- headers: {
111
- 'Authorization': `Bearer ${this.config.token}`,
112
- 'Accept': 'application/vnd.github.v3+json',
113
- 'Content-Type': 'application/json',
114
- },
115
- });
116
- return {
117
- success: true,
118
- issueNumber: response.data.number,
119
- issueId: response.data.number,
120
- htmlUrl: response.data.html_url,
121
- provider: 'github'
122
- };
123
- }
124
- catch (error) {
125
- return {
126
- success: false,
127
- provider: 'github',
128
- message: this.formatError(error)
129
- };
130
- }
131
- }
132
- async listIssues(filters) {
133
- const params = {
134
- per_page: filters?.limit || 30
135
- };
136
- if (filters?.state && filters.state !== 'all') {
137
- params.state = filters.state;
138
- }
139
- if (filters?.assignee) {
140
- params.assignee = filters.assignee;
141
- }
142
- if (filters?.labels && filters.labels.length > 0) {
143
- params.labels = filters.labels.join(',');
144
- }
145
- try {
146
- const response = await axios_1.default.get(`${this.baseUrl}/issues`, {
147
- headers: {
148
- 'Authorization': `Bearer ${this.config.token}`,
149
- 'Accept': 'application/vnd.github.v3+json',
150
- },
151
- params
152
- });
153
- return response.data.map((issue) => ({
154
- id: issue.number,
155
- title: issue.title,
156
- body: issue.body || '',
157
- state: issue.state === 'open' ? 'open' : 'closed',
158
- assignee: issue.assignee?.login,
159
- labels: issue.labels.map((label) => label.name),
160
- createdAt: new Date(issue.created_at),
161
- updatedAt: new Date(issue.updated_at),
162
- htmlUrl: issue.html_url
163
- }));
164
- }
165
- catch (error) {
166
- throw new Error(this.formatError(error));
167
- }
168
- }
169
- async validateConfig() {
170
- try {
171
- // Test by getting repository info
172
- const response = await axios_1.default.get(this.baseUrl, {
173
- headers: {
174
- 'Authorization': `Bearer ${this.config.token}`,
175
- 'Accept': 'application/vnd.github.v3+json',
176
- },
177
- });
178
- return {
179
- valid: true,
180
- message: `Connected to ${response.data.full_name}`
181
- };
182
- }
183
- catch (error) {
184
- return {
185
- valid: false,
186
- message: this.formatError(error)
187
- };
188
- }
189
- }
190
- formatError(error) {
191
- if (axios_1.default.isAxiosError(error)) {
192
- return `GitHub API Error: ${error.response?.status} - ${JSON.stringify(error.response?.data)}`;
193
- }
194
- else if (error instanceof Error) {
195
- return `GitHub Error: ${error.message}`;
196
- }
197
- return 'Unknown GitHub error';
198
- }
199
- }
200
- exports.GitHubIssueProvider = GitHubIssueProvider;
@@ -1,7 +0,0 @@
1
- "use strict";
2
- /**
3
- * Issue Tracking System Types
4
- *
5
- * Defines the common interface for all issue tracking systems (GitHub, ADO, etc.)
6
- */
7
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,83 +0,0 @@
1
- "use strict";
2
- /**
3
- * Issue Tracking Configuration Helper
4
- *
5
- * Provides guidance on which MCP tools to use based on configuration.
6
- * This replaces custom providers with MCP tool recommendations.
7
- */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.getIssueTrackingGuidance = getIssueTrackingGuidance;
10
- exports.getRepositoryInfo = getRepositoryInfo;
11
- const config_loader_1 = require("./config-loader");
12
- /**
13
- * Get guidance on which MCP tools to use for issue tracking
14
- */
15
- function getIssueTrackingGuidance() {
16
- const config = (0, config_loader_1.loadFraimConfig)();
17
- // Check for ADO configuration
18
- if (config.repository?.provider === 'ado') {
19
- return {
20
- provider: 'ado',
21
- mcpTools: {
22
- createIssue: 'mcp_ado_create_work_item',
23
- getIssue: 'mcp_ado_get_work_item',
24
- updateIssue: 'mcp_ado_update_work_item',
25
- listIssues: 'mcp_ado_list_work_items',
26
- createPR: 'mcp_ado_create_pull_request',
27
- getPR: 'mcp_ado_get_pull_request',
28
- mergePR: 'mcp_ado_merge_pull_request'
29
- },
30
- config: {
31
- organization: config.repository.organization,
32
- project: config.repository.project
33
- },
34
- environmentVars: ['ADO_TOKEN', 'AZURE_DEVOPS_TOKEN'],
35
- setupInstructions: `Configure ADO MCP server in your IDE with:
36
- - Organization: ${config.repository.organization}
37
- - Project: ${config.repository.project}
38
- - Token: Set ADO_TOKEN or AZURE_DEVOPS_TOKEN environment variable`
39
- };
40
- }
41
- // Default to GitHub
42
- const owner = config.repository?.owner || config.git?.repoOwner || 'mathursrus';
43
- const repo = config.repository?.name || config.git?.repoName || 'FRAIM';
44
- return {
45
- provider: 'github',
46
- mcpTools: {
47
- createIssue: 'mcp_github_issue_write',
48
- getIssue: 'mcp_github_issue_read',
49
- updateIssue: 'mcp_github_issue_write',
50
- listIssues: 'mcp_github_list_issues',
51
- createPR: 'mcp_github_create_pull_request',
52
- getPR: 'mcp_github_pull_request_read',
53
- mergePR: 'mcp_github_merge_pull_request'
54
- },
55
- config: {
56
- owner,
57
- repo
58
- },
59
- environmentVars: ['GITHUB_TOKEN'],
60
- setupInstructions: `GitHub MCP tools are configured for:
61
- - Repository: ${owner}/${repo}
62
- - Token: Set GITHUB_TOKEN environment variable
63
- - MCP Server: Ensure GitHub MCP server is configured in your IDE`
64
- };
65
- }
66
- /**
67
- * Get repository information from .fraim/config.json
68
- */
69
- function getRepositoryInfo() {
70
- try {
71
- const config = (0, config_loader_1.loadFraimConfig)();
72
- const owner = config.repository?.owner || config.git?.repoOwner;
73
- const repo = config.repository?.name || config.git?.repoName;
74
- return {
75
- owner,
76
- repo,
77
- url: owner && repo ? `https://github.com/${owner}/${repo}.git` : undefined
78
- };
79
- }
80
- catch (e) {
81
- return {};
82
- }
83
- }
@@ -1,75 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.createStaticWebsiteMiddleware = createStaticWebsiteMiddleware;
7
- const express_1 = __importDefault(require("express"));
8
- const path_1 = require("path");
9
- const fs_1 = require("fs");
10
- /**
11
- * Middleware to serve the FRAIM website at /fraim endpoint
12
- * This serves the static website files from the website directory
13
- */
14
- function createStaticWebsiteMiddleware() {
15
- const router = express_1.default.Router();
16
- // Find the website directory
17
- const websitePath = findWebsitePath();
18
- if (!websitePath) {
19
- console.warn('⚠️ Website directory not found. FRAIM website will not be available at /fraim');
20
- return router;
21
- }
22
- console.log(`🌐 Serving FRAIM website from: ${websitePath}`);
23
- // Serve static files from website directory at /fraim endpoint only
24
- router.use('/fraim', express_1.default.static(websitePath, {
25
- index: 'index.html',
26
- setHeaders: (res, path) => {
27
- // Set proper MIME types
28
- if (path.endsWith('.css')) {
29
- res.setHeader('Content-Type', 'text/css');
30
- }
31
- else if (path.endsWith('.js')) {
32
- res.setHeader('Content-Type', 'application/javascript');
33
- }
34
- else if (path.endsWith('.png')) {
35
- res.setHeader('Content-Type', 'image/png');
36
- }
37
- else if (path.endsWith('.jpg') || path.endsWith('.jpeg')) {
38
- res.setHeader('Content-Type', 'image/jpeg');
39
- }
40
- else if (path.endsWith('.svg')) {
41
- res.setHeader('Content-Type', 'image/svg+xml');
42
- }
43
- // Cache static assets for 1 hour
44
- if (path.match(/\.(css|js|png|jpg|jpeg|svg|ico)$/)) {
45
- res.setHeader('Cache-Control', 'public, max-age=3600');
46
- }
47
- }
48
- }));
49
- return router;
50
- }
51
- /**
52
- * Find the website directory
53
- * Checks multiple possible locations
54
- */
55
- function findWebsitePath() {
56
- const possiblePaths = [
57
- // Production: dist/website
58
- (0, path_1.join)(process.cwd(), 'dist', 'website'),
59
- // Development: website
60
- (0, path_1.join)(process.cwd(), 'website'),
61
- // Relative to server file: ../website
62
- (0, path_1.join)(__dirname, '..', 'website'),
63
- // Relative to server file: ../../website
64
- (0, path_1.join)(__dirname, '..', '..', 'website')
65
- ];
66
- for (const path of possiblePaths) {
67
- if ((0, fs_1.existsSync)(path)) {
68
- const indexPath = (0, path_1.join)(path, 'index.html');
69
- if ((0, fs_1.existsSync)(indexPath)) {
70
- return path;
71
- }
72
- }
73
- }
74
- return null;
75
- }
@@ -1,96 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.runTests = runTests;
7
- const dotenv_1 = __importDefault(require("dotenv"));
8
- dotenv_1.default.config({ override: true });
9
- const node_test_1 = require("node:test");
10
- // Global tracker for failed tests across all suites
11
- const globalFailedTests = [];
12
- // Generic test runner function that can run any type of test
13
- async function runTests(testCases, runTestFn, testTitle) {
14
- console.log(`🧪 Testing ${testTitle}...\n`);
15
- // Check if we need to filter by tags
16
- let tagsFilter = [];
17
- console.log(`Command line arguments: ${process.argv.join(', ')}`);
18
- // First try command line arguments
19
- const tagsArg = process.argv.find(arg => arg && typeof arg === 'string' && arg.startsWith('--tags='));
20
- if (tagsArg) {
21
- const tagValue = tagsArg.split('=')[1];
22
- if (tagValue) {
23
- tagsFilter = tagValue.split(',');
24
- console.log(`Filtering tests by tags (from CLI): ${tagsFilter.join(', ')}`);
25
- }
26
- }
27
- // Then try environment variable (for npm scripts)
28
- if (tagsFilter.length === 0 && process.env.TAGS) {
29
- tagsFilter = process.env.TAGS.split(',');
30
- console.log(`Filtering tests by tags (from ENV): ${tagsFilter.join(', ')}`);
31
- }
32
- // Check for exclusion tags
33
- let excludeTags = [];
34
- if (process.env.EXCLUDE_TAGS) {
35
- excludeTags = process.env.EXCLUDE_TAGS.split(',');
36
- console.log(`Excluding tests with tags (from ENV): ${excludeTags.join(', ')}`);
37
- }
38
- // Filter test cases by tags if specified
39
- const testsToRun = testCases.filter(test => {
40
- // First check inclusion filter
41
- if (tagsFilter.length > 0) {
42
- // Ensure test.tags exists before calling .some() on it
43
- if (!test.tags || !test.tags.some(tag => tagsFilter.includes(tag))) {
44
- return false;
45
- }
46
- }
47
- // Then check exclusion filter
48
- if (excludeTags.length > 0) {
49
- // Exclude tests with specified tags
50
- if (test.tags && test.tags.some(tag => excludeTags.includes(tag))) {
51
- return false;
52
- }
53
- }
54
- return true;
55
- });
56
- if (testsToRun.length === 0) {
57
- console.log('No tests to run for suite: ' + testTitle);
58
- return;
59
- }
60
- console.log(`Running ${testsToRun.length} tests${tagsFilter.length > 0 ? ` with tags: ${tagsFilter.join(', ')}` : ''}\n`);
61
- // Use Node.js built-in test() function for each test case
62
- // This allows the TAP reporter to properly aggregate results across all test files
63
- for (const testCase of testsToRun) {
64
- await (0, node_test_1.test)(testCase.name, async () => {
65
- try {
66
- const success = await runTestFn(testCase);
67
- if (!success) {
68
- const failedTestName = `${testTitle}: ${testCase.name}`;
69
- if (!globalFailedTests.includes(failedTestName)) {
70
- globalFailedTests.push(failedTestName);
71
- }
72
- throw new Error(`Test failed: ${testCase.name}`);
73
- }
74
- }
75
- catch (error) {
76
- const failedTestName = `${testTitle}: ${testCase.name}`;
77
- if (!globalFailedTests.includes(failedTestName)) {
78
- globalFailedTests.push(failedTestName);
79
- }
80
- throw error;
81
- }
82
- });
83
- }
84
- // Display comprehensive final summary
85
- console.log(`\n🚨 FINAL TEST SUMMARY:`);
86
- console.log(` ❌ Total Failed Tests: ${globalFailedTests.length}`);
87
- if (globalFailedTests.length > 0) {
88
- console.log(` 📋 Failed Test Names:`);
89
- globalFailedTests.forEach(testName => {
90
- console.log(` - ${testName}`);
91
- });
92
- }
93
- if (globalFailedTests.length > 0) {
94
- process.exitCode = 1;
95
- }
96
- }
@@ -1,11 +0,0 @@
1
- "use strict";
2
- /**
3
- * ESM Compatibility Helper
4
- * Provides __dirname and __filename for ESM modules
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.__dirname = exports.__filename = void 0;
8
- const url_1 = require("url");
9
- const path_1 = require("path");
10
- exports.__filename = (0, url_1.fileURLToPath)(import.meta.url);
11
- exports.__dirname = (0, path_1.dirname)(exports.__filename);
@@ -1,147 +0,0 @@
1
- "use strict";
2
- /**
3
- * Integration tests for AI Manager phase-based protocol
4
- */
5
- var __importDefault = (this && this.__importDefault) || function (mod) {
6
- return (mod && mod.__esModule) ? mod : { "default": mod };
7
- };
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- const node_test_1 = require("node:test");
10
- const node_assert_1 = __importDefault(require("node:assert"));
11
- const ai_manager_js_1 = require("../src/ai-manager/ai-manager.js");
12
- const phase_flow_js_1 = require("../src/ai-manager/phase-flow.js");
13
- (0, node_test_1.describe)('AI Manager Phase-Based Protocol', () => {
14
- (0, node_test_1.describe)('Phase Flow Logic', () => {
15
- (0, node_test_1.it)('should return correct next phase for bug workflow', () => {
16
- node_assert_1.default.strictEqual((0, phase_flow_js_1.getNextPhase)('scoping', 'bug'), 'repro');
17
- node_assert_1.default.strictEqual((0, phase_flow_js_1.getNextPhase)('repro', 'bug'), 'code');
18
- node_assert_1.default.strictEqual((0, phase_flow_js_1.getNextPhase)('code', 'bug'), 'validate');
19
- node_assert_1.default.strictEqual((0, phase_flow_js_1.getNextPhase)('finalize', 'bug'), null);
20
- });
21
- (0, node_test_1.it)('should return correct next phase for feature workflow', () => {
22
- node_assert_1.default.strictEqual((0, phase_flow_js_1.getNextPhase)('scoping', 'feature'), 'spike');
23
- node_assert_1.default.strictEqual((0, phase_flow_js_1.getNextPhase)('spike', 'feature'), 'code');
24
- node_assert_1.default.strictEqual((0, phase_flow_js_1.getNextPhase)('code', 'feature'), 'validate');
25
- node_assert_1.default.strictEqual((0, phase_flow_js_1.getNextPhase)('finalize', 'feature'), null);
26
- });
27
- (0, node_test_1.it)('should validate phase for issue type', () => {
28
- node_assert_1.default.strictEqual((0, phase_flow_js_1.isPhaseValidForIssueType)('repro', 'bug'), true);
29
- node_assert_1.default.strictEqual((0, phase_flow_js_1.isPhaseValidForIssueType)('repro', 'feature'), false);
30
- node_assert_1.default.strictEqual((0, phase_flow_js_1.isPhaseValidForIssueType)('spike', 'feature'), true);
31
- node_assert_1.default.strictEqual((0, phase_flow_js_1.isPhaseValidForIssueType)('spike', 'bug'), false);
32
- node_assert_1.default.strictEqual((0, phase_flow_js_1.isPhaseValidForIssueType)('code', 'bug'), true);
33
- node_assert_1.default.strictEqual((0, phase_flow_js_1.isPhaseValidForIssueType)('code', 'feature'), true);
34
- });
35
- (0, node_test_1.it)('should return all phases for issue type', () => {
36
- const bugPhases = (0, phase_flow_js_1.getPhasesForIssueType)('bug');
37
- node_assert_1.default.ok(bugPhases.includes('scoping'));
38
- node_assert_1.default.ok(bugPhases.includes('repro'));
39
- node_assert_1.default.ok(!bugPhases.includes('spike'));
40
- node_assert_1.default.ok(bugPhases.includes('finalize'));
41
- const featurePhases = (0, phase_flow_js_1.getPhasesForIssueType)('feature');
42
- node_assert_1.default.ok(featurePhases.includes('scoping'));
43
- node_assert_1.default.ok(featurePhases.includes('spike'));
44
- node_assert_1.default.ok(!featurePhases.includes('repro'));
45
- node_assert_1.default.ok(featurePhases.includes('finalize'));
46
- });
47
- });
48
- (0, node_test_1.describe)('Phase Instructions Generation', () => {
49
- const aiCoach = new ai_manager_js_1.AICoach();
50
- (0, node_test_1.it)('should generate phase instructions for scoping phase', () => {
51
- const instructions = aiCoach.generatePhaseInstructions({
52
- workflowType: 'implement',
53
- issueNumber: '123',
54
- phase: 'scoping'
55
- });
56
- node_assert_1.default.ok(instructions.includes('AI Manager Phase Instructions'));
57
- node_assert_1.default.ok(instructions.includes('# Phase: Scoping'));
58
- node_assert_1.default.ok(instructions.includes('INTENT'));
59
- node_assert_1.default.ok(instructions.includes('OUTCOME'));
60
- node_assert_1.default.ok(instructions.includes('PRINCIPLES'));
61
- });
62
- (0, node_test_1.it)('should generate phase instructions for code phase with issue type', () => {
63
- const instructions = aiCoach.generatePhaseInstructions({
64
- workflowType: 'implement',
65
- issueNumber: '456',
66
- phase: 'code',
67
- issueType: 'bug'
68
- });
69
- node_assert_1.default.ok(instructions.includes('AI Manager Phase Instructions'));
70
- node_assert_1.default.ok(instructions.includes('**Phase:** code'));
71
- node_assert_1.default.ok(instructions.includes('**Issue Type:** bug'));
72
- node_assert_1.default.ok(instructions.includes('# Phase: Code'));
73
- });
74
- (0, node_test_1.it)('should throw error for invalid phase', () => {
75
- node_assert_1.default.throws(() => {
76
- aiCoach.generatePhaseInstructions({
77
- workflowType: 'implement',
78
- issueNumber: '789',
79
- phase: 'invalid-phase'
80
- });
81
- }, /No phase instructions found/);
82
- });
83
- });
84
- (0, node_test_1.describe)('Next Phase Instructions', () => {
85
- const aiCoach = new ai_manager_js_1.AICoach();
86
- (0, node_test_1.it)('should provide next phase instructions when phase completes', () => {
87
- const instructions = aiCoach.getNextPhaseInstructions({
88
- workflowType: 'implement',
89
- issueNumber: '123',
90
- currentPhase: 'scoping',
91
- findings: { issueType: 'bug' },
92
- iterationCount: 1
93
- });
94
- node_assert_1.default.ok(instructions.includes('AI Manager Phase Instructions'));
95
- node_assert_1.default.ok(instructions.includes('**Phase:** repro'));
96
- node_assert_1.default.ok(instructions.includes('# Phase: Repro'));
97
- });
98
- (0, node_test_1.it)('should complete workflow at finalize phase', () => {
99
- const instructions = aiCoach.getNextPhaseInstructions({
100
- workflowType: 'implement',
101
- issueNumber: '123',
102
- currentPhase: 'finalize',
103
- findings: { issueType: 'bug' },
104
- iterationCount: 1
105
- });
106
- node_assert_1.default.ok(instructions.includes('Implementation Complete'));
107
- node_assert_1.default.ok(instructions.includes('All phases complete'));
108
- });
109
- (0, node_test_1.it)('should provide iteration instructions when stuck', () => {
110
- const instructions = aiCoach.getIterationInstructions({
111
- workflowType: 'implement',
112
- issueNumber: '123',
113
- phase: 'code',
114
- findings: { uncertainties: ['Tests failing'] },
115
- iterationCount: 1,
116
- issueType: 'bug'
117
- });
118
- node_assert_1.default.ok(instructions.includes('Iteration 1/3'));
119
- node_assert_1.default.ok(instructions.includes('Previous attempts'));
120
- });
121
- (0, node_test_1.it)('should escalate after max iterations', () => {
122
- const instructions = aiCoach.getIterationInstructions({
123
- workflowType: 'implement',
124
- issueNumber: '123',
125
- phase: 'code',
126
- findings: { uncertainties: ['Still failing'] },
127
- iterationCount: 3,
128
- issueType: 'bug'
129
- });
130
- node_assert_1.default.ok(instructions.includes('Maximum Iterations Reached'));
131
- node_assert_1.default.ok(instructions.includes('Escalation Required'));
132
- });
133
- });
134
- (0, node_test_1.describe)('Backward Compatibility', () => {
135
- const aiCoach = new ai_manager_js_1.AICoach();
136
- (0, node_test_1.it)('should still work with non-phase workflows', () => {
137
- const instructions = aiCoach.generatePhaseInstructions({
138
- workflowType: 'spec',
139
- issueNumber: '123',
140
- phase: 'specification'
141
- });
142
- // Should fall back to JSON-based rules
143
- node_assert_1.default.ok(instructions.includes('AI Manager Review Instructions'));
144
- node_assert_1.default.ok(instructions.includes('Workflow: SPEC'));
145
- });
146
- });
147
- });