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.
- package/dist/registry/scripts/profile-server.js +2 -1
- package/dist/src/ai-manager/ai-manager.js +49 -1
- package/dist/src/ai-manager/phase-flow.js +68 -0
- package/dist/tests/test-debug-session.js +6 -2
- package/dist/tests/test-enhanced-session-init.js +6 -2
- package/dist/tests/test-mcp-lifecycle-methods.js +1 -2
- package/dist/tests/test-mcp-template-processing.js +6 -2
- package/dist/tests/test-modular-issue-tracking.js +6 -2
- package/dist/tests/test-node-compatibility.js +4 -2
- package/dist/tests/test-npm-install.js +4 -2
- package/dist/tests/test-productivity-integration.js +157 -0
- package/dist/tests/test-session-rehydration.js +1 -2
- package/dist/tests/test-telemetry.js +1 -2
- package/dist/tests/test-users-to-target-workflow.js +256 -0
- package/package.json +1 -1
- package/registry/agent-guardrails.md +62 -62
- package/registry/scripts/detect-tautological-tests.sh +38 -38
- package/registry/scripts/productivity/build-productivity-csv.mjs +242 -0
- package/registry/scripts/productivity/fetch-pr-details.mjs +144 -0
- package/registry/scripts/productivity/productivity-report.sh +147 -0
- package/registry/scripts/profile-server.ts +1 -1
- package/registry/scripts/validate-openapi-limits.ts +366 -366
- package/registry/scripts/validate-test-coverage.ts +280 -280
- package/registry/stubs/workflows/customer-development/ai-coach-phases/phase1-customer-profiling.md +11 -0
- package/registry/stubs/workflows/customer-development/ai-coach-phases/phase1-survey-scoping.md +11 -0
- package/registry/stubs/workflows/customer-development/ai-coach-phases/phase2-platform-discovery.md +11 -0
- package/registry/stubs/workflows/customer-development/ai-coach-phases/phase2-survey-build-linkedin.md +11 -0
- package/registry/stubs/workflows/customer-development/ai-coach-phases/phase3-prospect-qualification.md +11 -0
- package/registry/stubs/workflows/customer-development/ai-coach-phases/phase3-survey-build-reddit.md +11 -0
- package/registry/stubs/workflows/customer-development/ai-coach-phases/phase4-inventory-compilation.md +11 -0
- package/registry/stubs/workflows/customer-development/ai-coach-phases/phase4-survey-build-x.md +11 -0
- package/registry/stubs/workflows/customer-development/ai-coach-phases/phase5-survey-build-facebook.md +11 -0
- package/registry/stubs/workflows/customer-development/ai-coach-phases/phase6-survey-build-custom.md +11 -0
- package/registry/stubs/workflows/customer-development/ai-coach-phases/phase7-survey-dispatch.md +11 -0
- package/registry/stubs/workflows/customer-development/templates/customer-persona-template.md +11 -0
- package/registry/stubs/workflows/customer-development/templates/search-strategy-template.md +11 -0
- package/registry/stubs/workflows/customer-development/user-survey-dispatch.md +11 -0
- package/registry/stubs/workflows/customer-development/users-to-target.md +11 -0
- package/registry/stubs/workflows/productivity-report/productivity-report.md +11 -0
- package/bin/fraim.js +0 -8
- package/dist/registry/ai-manager-rules/design-phases/design.md +0 -108
- package/dist/registry/ai-manager-rules/design-phases/finalize.md +0 -60
- package/dist/registry/ai-manager-rules/design-phases/validate.md +0 -125
- package/dist/registry/ai-manager-rules/design.json +0 -97
- package/dist/registry/ai-manager-rules/implement-phases/code.md +0 -323
- package/dist/registry/ai-manager-rules/implement-phases/completeness-review.md +0 -94
- package/dist/registry/ai-manager-rules/implement-phases/finalize.md +0 -177
- package/dist/registry/ai-manager-rules/implement-phases/quality-review.md +0 -304
- package/dist/registry/ai-manager-rules/implement-phases/regression.md +0 -159
- package/dist/registry/ai-manager-rules/implement-phases/repro.md +0 -101
- package/dist/registry/ai-manager-rules/implement-phases/scoping.md +0 -93
- package/dist/registry/ai-manager-rules/implement-phases/smoke.md +0 -225
- package/dist/registry/ai-manager-rules/implement-phases/spike.md +0 -118
- package/dist/registry/ai-manager-rules/implement-phases/validate.md +0 -347
- package/dist/registry/ai-manager-rules/implement.json +0 -153
- package/dist/registry/ai-manager-rules/shared-phases/finalize.md +0 -169
- package/dist/registry/ai-manager-rules/spec-phases/finalize.md +0 -60
- package/dist/registry/ai-manager-rules/spec-phases/spec.md +0 -102
- package/dist/registry/ai-manager-rules/spec-phases/validate.md +0 -118
- package/dist/registry/ai-manager-rules/spec.json +0 -112
- package/dist/registry/ai-manager-rules/test.json +0 -98
- package/dist/registry/scripts/build-scripts-generator.js +0 -205
- package/dist/registry/scripts/fraim-config.js +0 -61
- package/dist/registry/scripts/generic-issues-api.js +0 -100
- package/dist/registry/scripts/openapi-generator.js +0 -664
- package/dist/registry/scripts/performance/profile-server.js +0 -390
- package/dist/src/ai-manager/evidence-validator.js +0 -309
- package/dist/src/fraim/issue-tracking/ado-provider.js +0 -304
- package/dist/src/fraim/issue-tracking/factory.js +0 -63
- package/dist/src/fraim/issue-tracking/github-provider.js +0 -200
- package/dist/src/fraim/issue-tracking/types.js +0 -7
- package/dist/src/fraim/issue-tracking-config.js +0 -83
- package/dist/src/static-website-middleware.js +0 -75
- package/dist/test-utils.js +0 -96
- package/dist/tests/esm-compat.js +0 -11
- package/dist/tests/test-ai-manager-phase-protocol.js +0 -147
- package/dist/tests/test-ai-manager.js +0 -118
- package/dist/tests/test-chalk-esm-issue.js +0 -159
- package/dist/tests/test-chalk-real-world.js +0 -265
- package/dist/tests/test-chalk-regression.js +0 -377
- package/dist/tests/test-chalk-resolution-issue.js +0 -304
- package/dist/tests/test-evidence-validation.js +0 -221
- package/dist/tests/test-first-run-interactive.js +0 -1
- package/dist/tests/test-fraim-install-chalk-issue.js +0 -254
- package/dist/tests/test-markdown-to-pdf.js +0 -454
- package/dist/tests/test-npm-resolution-diagnostic.js +0 -140
- package/dist/tests/test-pr-review-integration.js +0 -1
- package/dist/website/.nojekyll +0 -0
- package/dist/website/404.html +0 -101
- package/dist/website/CNAME +0 -1
- package/dist/website/README.md +0 -22
- package/dist/website/demo.html +0 -604
- package/dist/website/images/.gitkeep +0 -1
- package/dist/website/images/fraim-logo.png +0 -0
- package/dist/website/index.html +0 -290
- package/dist/website/pricing.html +0 -414
- package/dist/website/script.js +0 -55
- 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,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
|
-
}
|
package/dist/test-utils.js
DELETED
|
@@ -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
|
-
}
|
package/dist/tests/esm-compat.js
DELETED
|
@@ -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
|
-
});
|