fraim-framework 2.0.36 โ 2.0.38
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/bin/fraim.js +5 -52
- package/dist/registry/scripts/build-scripts-generator.js +205 -0
- package/dist/registry/scripts/fraim-config.js +61 -0
- package/dist/registry/scripts/generic-issues-api.js +100 -0
- package/dist/registry/scripts/openapi-generator.js +664 -0
- package/dist/registry/scripts/performance/profile-server.js +390 -0
- package/dist/scripts/build-stub-registry.js +108 -0
- package/dist/src/cli/commands/doctor.js +5 -5
- package/dist/src/cli/commands/init-project.js +74 -0
- package/dist/src/cli/commands/setup.js +176 -0
- package/dist/src/cli/commands/sync.js +33 -19
- package/dist/src/cli/commands/test-mcp.js +135 -0
- package/dist/src/cli/fraim.js +6 -0
- package/dist/src/cli/setup/auto-mcp-setup.js +367 -0
- package/dist/src/cli/setup/ide-detector.js +163 -0
- package/dist/src/cli/setup/mcp-config-generator.js +115 -0
- package/dist/src/cli/setup/token-validator.js +49 -0
- package/dist/test-utils.js +96 -0
- package/dist/tests/debug-tools.js +2 -2
- package/dist/tests/esm-compat.js +11 -0
- package/dist/tests/shared-server-utils.js +57 -0
- package/dist/tests/test-chalk-esm-issue.js +159 -0
- package/dist/tests/test-chalk-real-world.js +265 -0
- package/dist/tests/test-chalk-regression.js +2 -18
- package/dist/tests/test-chalk-resolution-issue.js +304 -0
- package/dist/tests/test-client-scripts-validation.js +27 -5
- package/dist/tests/test-complete-setup-flow.js +110 -0
- package/dist/tests/test-fraim-install-chalk-issue.js +254 -0
- package/dist/tests/test-ide-detector.js +46 -0
- package/dist/tests/test-improved-setup.js +121 -0
- package/dist/tests/test-mcp-config-generator.js +70 -0
- package/dist/tests/test-mcp-connection.js +58 -117
- package/dist/tests/test-mcp-issue-integration.js +2 -2
- package/dist/tests/test-mcp-lifecycle-methods.js +34 -100
- package/dist/tests/test-mcp-shared-server.js +308 -0
- package/dist/tests/test-npm-resolution-diagnostic.js +140 -0
- package/dist/tests/test-package-size.js +101 -0
- package/dist/tests/test-prep-issue.js +34 -1
- package/dist/tests/test-script-location-independence.js +39 -62
- package/dist/tests/test-server-utils.js +32 -0
- package/dist/tests/test-session-rehydration.js +2 -2
- package/dist/tests/test-setup-integration.js +98 -0
- package/dist/tests/test-standalone.js +2 -2
- package/dist/tests/test-stub-registry.js +136 -0
- package/dist/tests/test-sync-stubs.js +143 -0
- package/dist/tests/test-telemetry.js +2 -2
- package/dist/tests/test-token-validator.js +30 -0
- package/dist/tests/test-user-journey.js +2 -1
- package/package.json +7 -9
- package/registry/agent-guardrails.md +62 -62
- package/registry/scripts/code-quality-check.sh +559 -559
- package/registry/scripts/detect-tautological-tests.sh +38 -38
- package/registry/scripts/prep-issue.sh +61 -30
- package/registry/scripts/validate-openapi-limits.ts +366 -366
- package/registry/scripts/validate-test-coverage.ts +280 -280
- package/registry/scripts/verify-pr-comments.sh +70 -70
- package/registry/stubs/workflows/bootstrap/create-architecture.md +11 -0
- package/registry/stubs/workflows/bootstrap/detect-broken-windows.md +11 -0
- package/registry/stubs/workflows/bootstrap/evaluate-code-quality.md +11 -0
- package/registry/stubs/workflows/bootstrap/verify-test-coverage.md +11 -0
- package/registry/stubs/workflows/business-development/create-business-plan.md +11 -0
- package/registry/stubs/workflows/business-development/ideate-business-opportunity.md +11 -0
- package/registry/stubs/workflows/business-development/price-product.md +18 -0
- package/registry/stubs/workflows/convert-to-pdf.md +11 -0
- package/registry/stubs/workflows/customer-development/insight-analysis.md +11 -0
- package/registry/stubs/workflows/customer-development/insight-triage.md +11 -0
- package/registry/stubs/workflows/customer-development/interview-preparation.md +11 -0
- package/registry/stubs/workflows/customer-development/linkedin-outreach.md +11 -0
- package/registry/stubs/workflows/customer-development/strategic-brainstorming.md +11 -0
- package/registry/stubs/workflows/customer-development/thank-customers.md +11 -0
- package/registry/stubs/workflows/customer-development/weekly-newsletter.md +11 -0
- package/registry/stubs/workflows/deploy/cloud-deployment.md +11 -0
- package/registry/stubs/workflows/improve-fraim/contribute.md +11 -0
- package/registry/stubs/workflows/improve-fraim/file-issue.md +11 -0
- package/registry/stubs/workflows/marketing/content-creation.md +11 -0
- package/registry/stubs/workflows/marketing/hbr-article.md +11 -0
- package/registry/stubs/workflows/marketing/launch-checklist.md +11 -0
- package/registry/stubs/workflows/marketing/marketing-strategy.md +11 -0
- package/registry/stubs/workflows/marketing/storytelling.md +11 -0
- package/registry/stubs/workflows/performance/analyze-performance.md +11 -0
- package/registry/stubs/workflows/product-building/design.md +11 -0
- package/registry/stubs/workflows/product-building/implement.md +12 -0
- package/registry/stubs/workflows/product-building/iterate-on-pr-comments.md +11 -0
- package/registry/stubs/workflows/product-building/prep-issue.md +11 -0
- package/registry/stubs/workflows/product-building/prototype.md +11 -0
- package/registry/stubs/workflows/product-building/resolve.md +11 -0
- package/registry/stubs/workflows/product-building/retrospect.md +11 -0
- package/registry/stubs/workflows/product-building/spec.md +11 -0
- package/registry/stubs/workflows/product-building/test.md +11 -0
- package/registry/stubs/workflows/quality-assurance/browser-validation.md +11 -0
- package/registry/stubs/workflows/quality-assurance/iterative-improvement-cycle.md +11 -0
- package/registry/stubs/workflows/replicate/replicate-discovery.md +11 -0
- package/registry/stubs/workflows/replicate/replicate-to-issues.md +11 -0
- package/registry/stubs/workflows/reviewer/review-implementation-vs-design-spec.md +11 -0
- package/registry/stubs/workflows/reviewer/review-implementation-vs-feature-spec.md +11 -0
- package/registry/stubs/workflows/startup-credits/aws-activate-application.md +11 -0
- package/registry/stubs/workflows/startup-credits/google-cloud-application.md +11 -0
- package/registry/stubs/workflows/startup-credits/microsoft-azure-application.md +11 -0
- package/.github/workflows/ci.yml +0 -65
- package/.github/workflows/deploy-fraim.yml +0 -87
- package/.github/workflows/phase-change.yml +0 -251
- package/.github/workflows/status-change.yml +0 -68
- package/.github/workflows/sync-on-pr-review.yml +0 -66
- package/examples/simple-webapp/TESTING.md +0 -62
- package/examples/simple-webapp/example-test.ts +0 -186
- package/registry/github/workflows/ci.yml +0 -51
- package/registry/github/workflows/phase-change.yml +0 -251
- package/registry/github/workflows/status-change.yml +0 -68
- package/registry/github/workflows/sync-on-pr-review.yml +0 -66
- package/registry/mcp-template.jsonc +0 -29
- package/registry/rules/agent-success-criteria.md +0 -52
- package/registry/rules/agent-testing-guidelines.md +0 -502
- package/registry/rules/architecture.md +0 -52
- package/registry/rules/communication.md +0 -122
- package/registry/rules/continuous-learning.md +0 -55
- package/registry/rules/debugging-multitenancy-issues.md +0 -85
- package/registry/rules/ephemeral-execution.md +0 -57
- package/registry/rules/git-safe-commands.md +0 -34
- package/registry/rules/hitl-ppe-record-analysis.md +0 -302
- package/registry/rules/integrity-and-test-ethics.md +0 -275
- package/registry/rules/local-development.md +0 -254
- package/registry/rules/merge-requirements.md +0 -231
- package/registry/rules/simplicity.md +0 -118
- package/registry/rules/software-development-lifecycle.md +0 -105
- package/registry/rules/spike-first-development.md +0 -205
- package/registry/rules/successful-debugging-patterns.md +0 -491
- package/registry/rules/telemetry.md +0 -67
- package/registry/templates/bootstrap/ARCHITECTURE-TEMPLATE.md +0 -53
- package/registry/templates/bootstrap/CODE-QUALITY-REPORT-TEMPLATE.md +0 -37
- package/registry/templates/bootstrap/TEST-COVERAGE-REPORT-TEMPLATE.md +0 -35
- package/registry/templates/business-development/IDEATION-REPORT-TEMPLATE.md +0 -29
- package/registry/templates/business-development/PRICING-STRATEGY-TEMPLATE.md +0 -126
- package/registry/templates/customer-development/customer-interview-template.md +0 -99
- package/registry/templates/customer-development/follow-up-email-templates.md +0 -132
- package/registry/templates/customer-development/insight-analysis-template.md +0 -74
- package/registry/templates/customer-development/strategic-recommendations-template.md +0 -53
- package/registry/templates/customer-development/thank-you-email-template.html +0 -124
- package/registry/templates/customer-development/thank-you-note-template.md +0 -16
- package/registry/templates/customer-development/triage-log-template.md +0 -278
- package/registry/templates/customer-development/weekly-newsletter-template.html +0 -204
- package/registry/templates/evidence/Design-Evidence.md +0 -30
- package/registry/templates/evidence/Implementation-BugEvidence.md +0 -86
- package/registry/templates/evidence/Implementation-FeatureEvidence.md +0 -121
- package/registry/templates/evidence/Spec-Evidence.md +0 -19
- package/registry/templates/help/HelpNeeded.md +0 -14
- package/registry/templates/marketing/HBR-ARTICLE-TEMPLATE.md +0 -66
- package/registry/templates/replicate/implementation-checklist.md +0 -39
- package/registry/templates/replicate/use-cases-template.md +0 -88
- package/registry/templates/retrospective/RETROSPECTIVE-TEMPLATE.md +0 -55
- package/registry/templates/specs/BUGSPEC-TEMPLATE.md +0 -37
- package/registry/templates/specs/FEATURESPEC-TEMPLATE.md +0 -29
- package/registry/templates/specs/TECHSPEC-TEMPLATE.md +0 -39
- package/registry/workflows/bootstrap/create-architecture.md +0 -38
- package/registry/workflows/bootstrap/evaluate-code-quality.md +0 -36
- package/registry/workflows/bootstrap/verify-test-coverage.md +0 -37
- package/registry/workflows/business-development/create-business-plan.md +0 -737
- package/registry/workflows/business-development/ideate-business-opportunity.md +0 -55
- package/registry/workflows/business-development/price-product.md +0 -325
- package/registry/workflows/convert-to-pdf.md +0 -235
- package/registry/workflows/customer-development/insight-analysis.md +0 -156
- package/registry/workflows/customer-development/insight-triage.md +0 -933
- package/registry/workflows/customer-development/interview-preparation.md +0 -421
- package/registry/workflows/customer-development/linkedin-outreach.md +0 -593
- package/registry/workflows/customer-development/strategic-brainstorming.md +0 -146
- package/registry/workflows/customer-development/thank-customers.md +0 -203
- package/registry/workflows/customer-development/weekly-newsletter.md +0 -366
- package/registry/workflows/deploy/cloud-deployment.md +0 -310
- package/registry/workflows/improve-fraim/contribute.md +0 -32
- package/registry/workflows/improve-fraim/file-issue.md +0 -32
- package/registry/workflows/marketing/content-creation.md +0 -37
- package/registry/workflows/marketing/hbr-article.md +0 -73
- package/registry/workflows/marketing/launch-checklist.md +0 -37
- package/registry/workflows/marketing/marketing-strategy.md +0 -45
- package/registry/workflows/performance/analyze-performance.md +0 -65
- package/registry/workflows/product-building/design.md +0 -130
- package/registry/workflows/product-building/implement.md +0 -315
- package/registry/workflows/product-building/iterate-on-pr-comments.md +0 -70
- package/registry/workflows/product-building/prep-issue.md +0 -43
- package/registry/workflows/product-building/prototype.md +0 -60
- package/registry/workflows/product-building/resolve.md +0 -164
- package/registry/workflows/product-building/retrospect.md +0 -86
- package/registry/workflows/product-building/spec.md +0 -117
- package/registry/workflows/product-building/test.md +0 -120
- package/registry/workflows/quality-assurance/browser-validation.md +0 -221
- package/registry/workflows/quality-assurance/iterative-improvement-cycle.md +0 -562
- package/registry/workflows/replicate/replicate-discovery.md +0 -336
- package/registry/workflows/replicate/replicate-to-issues.md +0 -319
- package/registry/workflows/reviewer/review-implementation-vs-design-spec.md +0 -632
- package/registry/workflows/reviewer/review-implementation-vs-feature-spec.md +0 -669
- package/registry/workflows/startup-credits/aws-activate-application.md +0 -535
- package/registry/workflows/startup-credits/google-cloud-application.md +0 -647
- package/registry/workflows/startup-credits/microsoft-azure-application.md +0 -538
|
@@ -124,17 +124,9 @@ try {
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
try {
|
|
127
|
-
const
|
|
127
|
+
const fraimCli = require('./node_modules/fraim-framework/dist/src/cli/fraim.js');
|
|
128
128
|
console.log('โ FRAIM CLI loaded successfully');
|
|
129
129
|
console.log('โ No ERR_REQUIRE_ESM error');
|
|
130
|
-
|
|
131
|
-
// Test that we can access the loadCli function
|
|
132
|
-
if (fraimBin && typeof fraimBin.loadCli === 'function') {
|
|
133
|
-
console.log('โ loadCli function available');
|
|
134
|
-
} else {
|
|
135
|
-
console.log('โ ๏ธ loadCli function not found, but require succeeded');
|
|
136
|
-
}
|
|
137
|
-
|
|
138
130
|
process.exit(0);
|
|
139
131
|
} catch (error) {
|
|
140
132
|
if (error.code === 'ERR_REQUIRE_ESM') {
|
|
@@ -287,16 +279,8 @@ async function testFreshInstall() {
|
|
|
287
279
|
console.log(' ๐ Testing if fraim CLI can be required...');
|
|
288
280
|
const testScript = `
|
|
289
281
|
try {
|
|
290
|
-
const
|
|
282
|
+
const fraimCli = require('./node_modules/fraim-framework/dist/src/cli/fraim.js');
|
|
291
283
|
console.log('โ FRAIM CLI loaded successfully');
|
|
292
|
-
|
|
293
|
-
// Test that we can access the loadCli function
|
|
294
|
-
if (fraimBin && typeof fraimBin.loadCli === 'function') {
|
|
295
|
-
console.log('โ loadCli function available');
|
|
296
|
-
} else {
|
|
297
|
-
console.log('โ ๏ธ loadCli function not found, but require succeeded');
|
|
298
|
-
}
|
|
299
|
-
|
|
300
284
|
process.exit(0);
|
|
301
285
|
} catch (error) {
|
|
302
286
|
if (error.code === 'ERR_REQUIRE_ESM') {
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Test to reproduce and verify the fix for the chalk v5 resolution issue
|
|
4
|
+
*
|
|
5
|
+
* This test creates a scenario where npm might resolve chalk to v5 by:
|
|
6
|
+
* 1. Creating a dependency that requires chalk v5
|
|
7
|
+
* 2. Testing if fraim-framework with ^4.1.2 gets upgraded
|
|
8
|
+
* 3. Testing if fraim-framework with 4.1.2 (pinned) stays at v4
|
|
9
|
+
*/
|
|
10
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
11
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
const node_child_process_1 = require("node:child_process");
|
|
15
|
+
const test_utils_1 = require("./test-utils");
|
|
16
|
+
const fs_1 = __importDefault(require("fs"));
|
|
17
|
+
const path_1 = __importDefault(require("path"));
|
|
18
|
+
const os_1 = __importDefault(require("os"));
|
|
19
|
+
async function runCommand(command, args, cwd) {
|
|
20
|
+
return new Promise((resolve) => {
|
|
21
|
+
const proc = (0, node_child_process_1.spawn)(command, args, {
|
|
22
|
+
cwd,
|
|
23
|
+
stdio: 'pipe',
|
|
24
|
+
shell: true
|
|
25
|
+
});
|
|
26
|
+
let stdout = '';
|
|
27
|
+
let stderr = '';
|
|
28
|
+
proc.stdout?.on('data', (data) => {
|
|
29
|
+
stdout += data.toString();
|
|
30
|
+
});
|
|
31
|
+
proc.stderr?.on('data', (data) => {
|
|
32
|
+
stderr += data.toString();
|
|
33
|
+
});
|
|
34
|
+
proc.on('close', (code) => {
|
|
35
|
+
resolve({ code, stdout, stderr });
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
async function testChalkResolutionWithConflict() {
|
|
40
|
+
console.log(' ๐งช Testing chalk resolution with conflicting dependency...');
|
|
41
|
+
const tempDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'chalk-conflict-'));
|
|
42
|
+
console.log(` ๐ Created temp dir: ${tempDir}`);
|
|
43
|
+
try {
|
|
44
|
+
// 1. Create a package that depends on chalk v5
|
|
45
|
+
console.log(' ๐ฆ Creating fake package that requires chalk v5...');
|
|
46
|
+
const fakePackageDir = path_1.default.join(tempDir, 'fake-chalk5-package');
|
|
47
|
+
fs_1.default.mkdirSync(fakePackageDir, { recursive: true });
|
|
48
|
+
const fakePackageJson = {
|
|
49
|
+
name: 'fake-chalk5-package',
|
|
50
|
+
version: '1.0.0',
|
|
51
|
+
dependencies: {
|
|
52
|
+
'chalk': '^5.0.0'
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
fs_1.default.writeFileSync(path_1.default.join(fakePackageDir, 'package.json'), JSON.stringify(fakePackageJson, null, 2));
|
|
56
|
+
// Create a simple index.js that uses chalk
|
|
57
|
+
fs_1.default.writeFileSync(path_1.default.join(fakePackageDir, 'index.js'), 'export { default as chalk } from "chalk";\n');
|
|
58
|
+
// 2. Pack fraim-framework with ^4.1.2 (unpinned)
|
|
59
|
+
console.log(' ๐ฆ Packing fraim-framework with ^4.1.2...');
|
|
60
|
+
const projectRoot = process.cwd();
|
|
61
|
+
const packageJsonPath = path_1.default.join(projectRoot, 'package.json');
|
|
62
|
+
const originalPackageJson = fs_1.default.readFileSync(packageJsonPath, 'utf-8');
|
|
63
|
+
const packageJson = JSON.parse(originalPackageJson);
|
|
64
|
+
// Temporarily change to ^4.1.2
|
|
65
|
+
packageJson.dependencies.chalk = '^4.1.2';
|
|
66
|
+
fs_1.default.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
67
|
+
const packResult = (0, node_child_process_1.execSync)('npm pack', {
|
|
68
|
+
cwd: projectRoot,
|
|
69
|
+
encoding: 'utf-8'
|
|
70
|
+
});
|
|
71
|
+
const tarballName = packResult.trim().split('\n').pop()?.trim();
|
|
72
|
+
if (!tarballName) {
|
|
73
|
+
fs_1.default.writeFileSync(packageJsonPath, originalPackageJson);
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
const tarballPath = path_1.default.join(projectRoot, tarballName);
|
|
77
|
+
// Restore original package.json
|
|
78
|
+
fs_1.default.writeFileSync(packageJsonPath, originalPackageJson);
|
|
79
|
+
// 3. Create test project that depends on BOTH packages
|
|
80
|
+
console.log(' ๐ง Creating test project with conflicting dependencies...');
|
|
81
|
+
const testPackageJson = {
|
|
82
|
+
name: 'chalk-conflict-test',
|
|
83
|
+
version: '1.0.0',
|
|
84
|
+
dependencies: {
|
|
85
|
+
'fake-chalk5-package': 'file:./fake-chalk5-package',
|
|
86
|
+
'fraim-framework': `file:${tarballPath}`
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
fs_1.default.writeFileSync(path_1.default.join(tempDir, 'package.json'), JSON.stringify(testPackageJson, null, 2));
|
|
90
|
+
// 4. Install dependencies - npm will try to resolve chalk
|
|
91
|
+
console.log(' ๐ฅ Installing with conflicting chalk requirements...');
|
|
92
|
+
console.log(' โ ๏ธ fake-chalk5-package wants chalk ^5.0.0');
|
|
93
|
+
console.log(' โ ๏ธ fraim-framework wants chalk ^4.1.2');
|
|
94
|
+
const installResult = await runCommand('npm', ['install'], tempDir);
|
|
95
|
+
if (installResult.code !== 0) {
|
|
96
|
+
console.log(' โ ๏ธ npm install failed (might be expected)');
|
|
97
|
+
console.log(` stderr: ${installResult.stderr.substring(0, 300)}`);
|
|
98
|
+
}
|
|
99
|
+
// 5. Check what version of chalk was installed for fraim-framework
|
|
100
|
+
const fraimChalkPath = path_1.default.join(tempDir, 'node_modules', 'fraim-framework', 'node_modules', 'chalk', 'package.json');
|
|
101
|
+
const rootChalkPath = path_1.default.join(tempDir, 'node_modules', 'chalk', 'package.json');
|
|
102
|
+
let fraimChalkVersion = null;
|
|
103
|
+
let rootChalkVersion = null;
|
|
104
|
+
if (fs_1.default.existsSync(fraimChalkPath)) {
|
|
105
|
+
const chalkPkg = JSON.parse(fs_1.default.readFileSync(fraimChalkPath, 'utf-8'));
|
|
106
|
+
fraimChalkVersion = chalkPkg.version;
|
|
107
|
+
console.log(` ๐ fraim-framework's chalk: ${fraimChalkVersion}`);
|
|
108
|
+
}
|
|
109
|
+
if (fs_1.default.existsSync(rootChalkPath)) {
|
|
110
|
+
const chalkPkg = JSON.parse(fs_1.default.readFileSync(rootChalkPath, 'utf-8'));
|
|
111
|
+
rootChalkVersion = chalkPkg.version;
|
|
112
|
+
console.log(` ๐ Root chalk: ${rootChalkVersion}`);
|
|
113
|
+
}
|
|
114
|
+
// 6. Try to load fraim CLI
|
|
115
|
+
console.log(' ๐ Testing if fraim CLI loads...');
|
|
116
|
+
const testScript = `
|
|
117
|
+
try {
|
|
118
|
+
const fraimCli = require('./node_modules/fraim-framework/dist/src/cli/fraim.js');
|
|
119
|
+
console.log('SUCCESS: fraim CLI loaded');
|
|
120
|
+
process.exit(0);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
if (error.code === 'ERR_REQUIRE_ESM') {
|
|
123
|
+
console.log('ERROR: ERR_REQUIRE_ESM - chalk v5 was used!');
|
|
124
|
+
console.log('Chalk version caused issue:', error.message);
|
|
125
|
+
process.exit(1);
|
|
126
|
+
} else {
|
|
127
|
+
console.log('ERROR: Other error:', error.message);
|
|
128
|
+
process.exit(2);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
`;
|
|
132
|
+
fs_1.default.writeFileSync(path_1.default.join(tempDir, 'test.js'), testScript);
|
|
133
|
+
const testResult = await runCommand('node', ['test.js'], tempDir);
|
|
134
|
+
if (testResult.code === 1) {
|
|
135
|
+
console.log(' โ REPRODUCED THE BUG! npm resolved chalk to v5');
|
|
136
|
+
console.log(' โ fraim-framework with ^4.1.2 got chalk v5 due to conflict');
|
|
137
|
+
console.log(' โ
This proves the issue exists with ^4.1.2');
|
|
138
|
+
// Cleanup
|
|
139
|
+
fs_1.default.unlinkSync(tarballPath);
|
|
140
|
+
return true; // We successfully reproduced the bug!
|
|
141
|
+
}
|
|
142
|
+
else if (testResult.code === 0) {
|
|
143
|
+
console.log(' โน๏ธ fraim CLI loaded successfully');
|
|
144
|
+
console.log(' โน๏ธ npm resolved the conflict without upgrading to v5');
|
|
145
|
+
console.log(' โน๏ธ This scenario didn\'t trigger the bug, but it could in other environments');
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
console.log(' โ ๏ธ Got unexpected error');
|
|
149
|
+
console.log(` stdout: ${testResult.stdout}`);
|
|
150
|
+
}
|
|
151
|
+
// Cleanup
|
|
152
|
+
fs_1.default.unlinkSync(tarballPath);
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
console.error(' โ Test failed with error:', error);
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
finally {
|
|
160
|
+
try {
|
|
161
|
+
fs_1.default.rmSync(tempDir, { recursive: true, force: true });
|
|
162
|
+
console.log(' ๐งน Cleaned up temp directory');
|
|
163
|
+
}
|
|
164
|
+
catch (e) {
|
|
165
|
+
console.log(' โ ๏ธ Could not clean up temp directory');
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
async function testChalkResolutionWithPinnedVersion() {
|
|
170
|
+
console.log(' ๐งช Testing chalk resolution with PINNED version (4.1.2)...');
|
|
171
|
+
const tempDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'chalk-pinned-'));
|
|
172
|
+
console.log(` ๐ Created temp dir: ${tempDir}`);
|
|
173
|
+
try {
|
|
174
|
+
// 1. Create a package that depends on chalk v5
|
|
175
|
+
console.log(' ๐ฆ Creating fake package that requires chalk v5...');
|
|
176
|
+
const fakePackageDir = path_1.default.join(tempDir, 'fake-chalk5-package');
|
|
177
|
+
fs_1.default.mkdirSync(fakePackageDir, { recursive: true });
|
|
178
|
+
const fakePackageJson = {
|
|
179
|
+
name: 'fake-chalk5-package',
|
|
180
|
+
version: '1.0.0',
|
|
181
|
+
dependencies: {
|
|
182
|
+
'chalk': '^5.0.0'
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
fs_1.default.writeFileSync(path_1.default.join(fakePackageDir, 'package.json'), JSON.stringify(fakePackageJson, null, 2));
|
|
186
|
+
fs_1.default.writeFileSync(path_1.default.join(fakePackageDir, 'index.js'), 'export { default as chalk } from "chalk";\n');
|
|
187
|
+
// 2. Pack fraim-framework with 4.1.2 (PINNED - current state)
|
|
188
|
+
console.log(' ๐ฆ Packing fraim-framework with pinned 4.1.2...');
|
|
189
|
+
const projectRoot = process.cwd();
|
|
190
|
+
const packResult = (0, node_child_process_1.execSync)('npm pack', {
|
|
191
|
+
cwd: projectRoot,
|
|
192
|
+
encoding: 'utf-8'
|
|
193
|
+
});
|
|
194
|
+
const tarballName = packResult.trim().split('\n').pop()?.trim();
|
|
195
|
+
if (!tarballName) {
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
const tarballPath = path_1.default.join(projectRoot, tarballName);
|
|
199
|
+
// 3. Create test project with conflicting dependencies
|
|
200
|
+
console.log(' ๐ง Creating test project with conflicting dependencies...');
|
|
201
|
+
const testPackageJson = {
|
|
202
|
+
name: 'chalk-pinned-test',
|
|
203
|
+
version: '1.0.0',
|
|
204
|
+
dependencies: {
|
|
205
|
+
'fake-chalk5-package': 'file:./fake-chalk5-package',
|
|
206
|
+
'fraim-framework': `file:${tarballPath}`
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
fs_1.default.writeFileSync(path_1.default.join(tempDir, 'package.json'), JSON.stringify(testPackageJson, null, 2));
|
|
210
|
+
// 4. Install dependencies
|
|
211
|
+
console.log(' ๐ฅ Installing with conflicting chalk requirements...');
|
|
212
|
+
console.log(' โ ๏ธ fake-chalk5-package wants chalk ^5.0.0');
|
|
213
|
+
console.log(' โ
fraim-framework wants chalk 4.1.2 (PINNED)');
|
|
214
|
+
const installResult = await runCommand('npm', ['install'], tempDir);
|
|
215
|
+
if (installResult.code !== 0) {
|
|
216
|
+
console.log(' โ ๏ธ npm install failed');
|
|
217
|
+
}
|
|
218
|
+
// 5. Check chalk versions
|
|
219
|
+
const fraimChalkPath = path_1.default.join(tempDir, 'node_modules', 'fraim-framework', 'node_modules', 'chalk', 'package.json');
|
|
220
|
+
const rootChalkPath = path_1.default.join(tempDir, 'node_modules', 'chalk', 'package.json');
|
|
221
|
+
let fraimChalkVersion = null;
|
|
222
|
+
let rootChalkVersion = null;
|
|
223
|
+
if (fs_1.default.existsSync(fraimChalkPath)) {
|
|
224
|
+
const chalkPkg = JSON.parse(fs_1.default.readFileSync(fraimChalkPath, 'utf-8'));
|
|
225
|
+
fraimChalkVersion = chalkPkg.version;
|
|
226
|
+
console.log(` ๐ fraim-framework's chalk: ${fraimChalkVersion}`);
|
|
227
|
+
}
|
|
228
|
+
if (fs_1.default.existsSync(rootChalkPath)) {
|
|
229
|
+
const chalkPkg = JSON.parse(fs_1.default.readFileSync(rootChalkPath, 'utf-8'));
|
|
230
|
+
rootChalkVersion = chalkPkg.version;
|
|
231
|
+
console.log(` ๐ Root chalk: ${rootChalkVersion}`);
|
|
232
|
+
}
|
|
233
|
+
// Verify fraim has v4
|
|
234
|
+
if (fraimChalkVersion && !fraimChalkVersion.startsWith('4.')) {
|
|
235
|
+
console.log(` โ PINNED version failed! Got chalk ${fraimChalkVersion}`);
|
|
236
|
+
fs_1.default.unlinkSync(tarballPath);
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
// 6. Try to load fraim CLI
|
|
240
|
+
console.log(' ๐ Testing if fraim CLI loads...');
|
|
241
|
+
const testScript = `
|
|
242
|
+
try {
|
|
243
|
+
const fraimCli = require('./node_modules/fraim-framework/dist/src/cli/fraim.js');
|
|
244
|
+
console.log('SUCCESS: fraim CLI loaded with pinned chalk');
|
|
245
|
+
process.exit(0);
|
|
246
|
+
} catch (error) {
|
|
247
|
+
if (error.code === 'ERR_REQUIRE_ESM') {
|
|
248
|
+
console.log('ERROR: ERR_REQUIRE_ESM even with pinned version!');
|
|
249
|
+
process.exit(1);
|
|
250
|
+
} else {
|
|
251
|
+
console.log('ERROR: Other error:', error.message);
|
|
252
|
+
process.exit(2);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
`;
|
|
256
|
+
fs_1.default.writeFileSync(path_1.default.join(tempDir, 'test.js'), testScript);
|
|
257
|
+
const testResult = await runCommand('node', ['test.js'], tempDir);
|
|
258
|
+
if (testResult.code === 0) {
|
|
259
|
+
console.log(' โ
SUCCESS! Pinned version prevents chalk v5 upgrade');
|
|
260
|
+
console.log(' โ
fraim CLI works even with chalk v5 dependency nearby');
|
|
261
|
+
console.log(' โ
This proves the fix works!');
|
|
262
|
+
}
|
|
263
|
+
else if (testResult.code === 1) {
|
|
264
|
+
console.log(' โ FAILED! Even pinned version got chalk v5');
|
|
265
|
+
console.log(' โ The fix doesn\'t work!');
|
|
266
|
+
fs_1.default.unlinkSync(tarballPath);
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
269
|
+
// Cleanup
|
|
270
|
+
fs_1.default.unlinkSync(tarballPath);
|
|
271
|
+
return true;
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
console.error(' โ Test failed with error:', error);
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
finally {
|
|
278
|
+
try {
|
|
279
|
+
fs_1.default.rmSync(tempDir, { recursive: true, force: true });
|
|
280
|
+
console.log(' ๐งน Cleaned up temp directory');
|
|
281
|
+
}
|
|
282
|
+
catch (e) {
|
|
283
|
+
console.log(' โ ๏ธ Could not clean up temp directory');
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
async function runChalkResolutionTest(testCase) {
|
|
288
|
+
return await testCase.testFunction();
|
|
289
|
+
}
|
|
290
|
+
const testCases = [
|
|
291
|
+
{
|
|
292
|
+
name: 'Chalk Resolution with Conflict (^4.1.2)',
|
|
293
|
+
description: 'Tests if ^4.1.2 allows npm to upgrade to chalk v5 when there\'s a conflicting dependency',
|
|
294
|
+
testFunction: testChalkResolutionWithConflict,
|
|
295
|
+
tags: ['chalk', 'resolution', 'conflict']
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
name: 'Chalk Resolution with Pinned Version (4.1.2)',
|
|
299
|
+
description: 'Tests if pinned 4.1.2 prevents npm from upgrading to chalk v5',
|
|
300
|
+
testFunction: testChalkResolutionWithPinnedVersion,
|
|
301
|
+
tags: ['chalk', 'resolution', 'pinned', 'fix']
|
|
302
|
+
}
|
|
303
|
+
];
|
|
304
|
+
(0, test_utils_1.runTests)(testCases, runChalkResolutionTest, 'Chalk Resolution Issue Test');
|
|
@@ -8,10 +8,28 @@ const child_process_1 = require("child_process");
|
|
|
8
8
|
const fs_1 = require("fs");
|
|
9
9
|
const path_1 = require("path");
|
|
10
10
|
const node_assert_1 = __importDefault(require("node:assert"));
|
|
11
|
+
const path_2 = __importDefault(require("path"));
|
|
12
|
+
/**
|
|
13
|
+
* Client-side script validation tests
|
|
14
|
+
* Ensures scripts can run without FRAIM internal imports
|
|
15
|
+
* Following the project's standard test structure from test-utils.ts
|
|
16
|
+
*/
|
|
17
|
+
// Find project root by looking for package.json
|
|
18
|
+
function findProjectRoot() {
|
|
19
|
+
let currentDir = __dirname;
|
|
20
|
+
while (currentDir !== path_2.default.dirname(currentDir)) {
|
|
21
|
+
if ((0, fs_1.existsSync)(path_2.default.join(currentDir, 'package.json'))) {
|
|
22
|
+
return currentDir;
|
|
23
|
+
}
|
|
24
|
+
currentDir = path_2.default.dirname(currentDir);
|
|
25
|
+
}
|
|
26
|
+
throw new Error('Could not find project root (package.json not found)');
|
|
27
|
+
}
|
|
11
28
|
async function testNoFraimInternalImports() {
|
|
12
29
|
console.log(' ๐งช Testing registry scripts do not import FRAIM internals...');
|
|
13
30
|
try {
|
|
14
|
-
const
|
|
31
|
+
const projectRoot = findProjectRoot();
|
|
32
|
+
const scriptsDir = (0, path_1.join)(projectRoot, 'registry', 'scripts');
|
|
15
33
|
const scriptFiles = ['cleanup-branch.ts', 'generate-engagement-emails.ts', 'newsletter-helpers.ts'];
|
|
16
34
|
for (const scriptFile of scriptFiles) {
|
|
17
35
|
const scriptPath = (0, path_1.join)(scriptsDir, scriptFile);
|
|
@@ -35,7 +53,8 @@ async function testNoFraimInternalImports() {
|
|
|
35
53
|
async function testInlineUtilityFunctions() {
|
|
36
54
|
console.log(' ๐งช Testing scripts have inline utility functions...');
|
|
37
55
|
try {
|
|
38
|
-
const
|
|
56
|
+
const projectRoot = findProjectRoot();
|
|
57
|
+
const scriptsDir = (0, path_1.join)(projectRoot, 'registry', 'scripts');
|
|
39
58
|
const scriptPath = (0, path_1.join)(scriptsDir, 'cleanup-branch.ts');
|
|
40
59
|
if ((0, fs_1.existsSync)(scriptPath)) {
|
|
41
60
|
const content = (0, fs_1.readFileSync)(scriptPath, 'utf-8');
|
|
@@ -54,7 +73,8 @@ async function testInlineUtilityFunctions() {
|
|
|
54
73
|
async function testConfigLoadingFromJson() {
|
|
55
74
|
console.log(' ๐งช Testing scripts load config from .fraim/config.json...');
|
|
56
75
|
try {
|
|
57
|
-
const
|
|
76
|
+
const projectRoot = findProjectRoot();
|
|
77
|
+
const scriptsDir = (0, path_1.join)(projectRoot, 'registry', 'scripts');
|
|
58
78
|
const scriptPath = (0, path_1.join)(scriptsDir, 'generate-engagement-emails.ts');
|
|
59
79
|
if ((0, fs_1.existsSync)(scriptPath)) {
|
|
60
80
|
const content = (0, fs_1.readFileSync)(scriptPath, 'utf-8');
|
|
@@ -73,7 +93,8 @@ async function testConfigLoadingFromJson() {
|
|
|
73
93
|
async function testRegistryPathValidator() {
|
|
74
94
|
console.log(' ๐งช Testing registry path validator passes...');
|
|
75
95
|
try {
|
|
76
|
-
|
|
96
|
+
const projectRoot = findProjectRoot();
|
|
97
|
+
(0, child_process_1.execSync)('npm run validate:registry', { stdio: 'pipe', cwd: projectRoot });
|
|
77
98
|
return true;
|
|
78
99
|
}
|
|
79
100
|
catch (error) {
|
|
@@ -84,7 +105,8 @@ async function testRegistryPathValidator() {
|
|
|
84
105
|
async function testScriptExecutability() {
|
|
85
106
|
console.log(' ๐งช Testing scripts are executable without import errors...');
|
|
86
107
|
try {
|
|
87
|
-
const
|
|
108
|
+
const projectRoot = findProjectRoot();
|
|
109
|
+
const scriptsDir = (0, path_1.join)(projectRoot, 'registry', 'scripts');
|
|
88
110
|
const scriptPath = (0, path_1.join)(scriptsDir, 'cleanup-branch.ts');
|
|
89
111
|
if ((0, fs_1.existsSync)(scriptPath)) {
|
|
90
112
|
// Test that the script can be parsed without import errors
|
|
@@ -0,0 +1,110 @@
|
|
|
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
|
+
const node_test_1 = require("node:test");
|
|
7
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const os_1 = __importDefault(require("os"));
|
|
11
|
+
const ide_detector_1 = require("../src/cli/setup/ide-detector");
|
|
12
|
+
const mcp_config_generator_1 = require("../src/cli/setup/mcp-config-generator");
|
|
13
|
+
const token_validator_1 = require("../src/cli/setup/token-validator");
|
|
14
|
+
(0, node_test_1.test)('Complete setup flow - end to end simulation', async () => {
|
|
15
|
+
const testFraimKey = 'fraim_test123456789012345';
|
|
16
|
+
const testGithubToken = 'ghp_test123456789012345';
|
|
17
|
+
// Step 1: Validate tokens (as setup command would)
|
|
18
|
+
(0, node_assert_1.default)((0, token_validator_1.isValidTokenFormat)(testFraimKey, 'fraim'), 'FRAIM key should be valid format');
|
|
19
|
+
(0, node_assert_1.default)((0, token_validator_1.isValidTokenFormat)(testGithubToken, 'github'), 'GitHub token should be valid format');
|
|
20
|
+
(0, node_assert_1.default)(await (0, token_validator_1.validateFraimKey)(testFraimKey), 'FRAIM key should validate');
|
|
21
|
+
// Step 2: Detect IDEs (as setup command would)
|
|
22
|
+
const detectedIDEs = (0, ide_detector_1.detectInstalledIDEs)();
|
|
23
|
+
console.log(`Detected ${detectedIDEs.length} IDEs in test environment`);
|
|
24
|
+
// Step 3: Generate configs for each detected IDE type
|
|
25
|
+
const configTypes = ['standard', 'kiro', 'codex', 'windsurf'];
|
|
26
|
+
for (const configType of configTypes) {
|
|
27
|
+
const config = (0, mcp_config_generator_1.generateMCPConfig)(configType, testFraimKey, testGithubToken);
|
|
28
|
+
if (configType === 'codex') {
|
|
29
|
+
// TOML config
|
|
30
|
+
(0, node_assert_1.default)(typeof config === 'string', `${configType} should return string`);
|
|
31
|
+
(0, node_assert_1.default)(config.includes(testFraimKey), `${configType} should contain FRAIM key`);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
// JSON configs
|
|
35
|
+
(0, node_assert_1.default)(typeof config === 'object', `${configType} should return object`);
|
|
36
|
+
(0, node_assert_1.default)(config.mcpServers, `${configType} should have mcpServers`);
|
|
37
|
+
(0, node_assert_1.default)(config.mcpServers.fraim, `${configType} should have fraim server`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Step 4: Simulate global config creation
|
|
41
|
+
const testGlobalDir = path_1.default.join(os_1.default.tmpdir(), 'fraim-global-test-' + Date.now());
|
|
42
|
+
fs_1.default.mkdirSync(testGlobalDir, { recursive: true });
|
|
43
|
+
const globalConfig = {
|
|
44
|
+
version: '2.0.37',
|
|
45
|
+
apiKey: testFraimKey,
|
|
46
|
+
configuredAt: new Date().toISOString(),
|
|
47
|
+
userPreferences: {
|
|
48
|
+
autoSync: true,
|
|
49
|
+
backupConfigs: true
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const globalConfigPath = path_1.default.join(testGlobalDir, 'config.json');
|
|
53
|
+
fs_1.default.writeFileSync(globalConfigPath, JSON.stringify(globalConfig, null, 2));
|
|
54
|
+
(0, node_assert_1.default)(fs_1.default.existsSync(globalConfigPath), 'Global config should be created');
|
|
55
|
+
// Step 5: Simulate project config creation (as init-project would)
|
|
56
|
+
const testProjectDir = path_1.default.join(os_1.default.tmpdir(), 'fraim-project-test-' + Date.now());
|
|
57
|
+
fs_1.default.mkdirSync(testProjectDir, { recursive: true });
|
|
58
|
+
const fraimProjectDir = path_1.default.join(testProjectDir, '.fraim');
|
|
59
|
+
fs_1.default.mkdirSync(fraimProjectDir, { recursive: true });
|
|
60
|
+
const projectConfig = {
|
|
61
|
+
version: '2.0.37',
|
|
62
|
+
project: {
|
|
63
|
+
name: 'test-project'
|
|
64
|
+
},
|
|
65
|
+
git: {
|
|
66
|
+
defaultBranch: 'master',
|
|
67
|
+
repoOwner: 'test-owner',
|
|
68
|
+
repoName: 'test-project'
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
const projectConfigPath = path_1.default.join(fraimProjectDir, 'config.json');
|
|
72
|
+
fs_1.default.writeFileSync(projectConfigPath, JSON.stringify(projectConfig, null, 2));
|
|
73
|
+
(0, node_assert_1.default)(fs_1.default.existsSync(projectConfigPath), 'Project config should be created');
|
|
74
|
+
// Step 6: Verify configs can be read back correctly
|
|
75
|
+
const savedGlobalConfig = JSON.parse(fs_1.default.readFileSync(globalConfigPath, 'utf8'));
|
|
76
|
+
const savedProjectConfig = JSON.parse(fs_1.default.readFileSync(projectConfigPath, 'utf8'));
|
|
77
|
+
(0, node_assert_1.default)(savedGlobalConfig.apiKey === testFraimKey, 'Global config should contain API key');
|
|
78
|
+
(0, node_assert_1.default)(savedProjectConfig.project.name === 'test-project', 'Project config should contain project name');
|
|
79
|
+
// Cleanup
|
|
80
|
+
fs_1.default.rmSync(testGlobalDir, { recursive: true, force: true });
|
|
81
|
+
fs_1.default.rmSync(testProjectDir, { recursive: true, force: true });
|
|
82
|
+
console.log('โ
Complete setup flow simulation passed');
|
|
83
|
+
});
|
|
84
|
+
(0, node_test_1.test)('Error handling - invalid tokens should be rejected', async () => {
|
|
85
|
+
const invalidFraimKey = 'invalid_key';
|
|
86
|
+
const invalidGithubToken = 'invalid_token';
|
|
87
|
+
const shortFraimKey = 'fraim_short';
|
|
88
|
+
(0, node_assert_1.default)(!(0, token_validator_1.isValidTokenFormat)(invalidFraimKey, 'fraim'), 'Invalid FRAIM key should be rejected');
|
|
89
|
+
(0, node_assert_1.default)(!(0, token_validator_1.isValidTokenFormat)(invalidGithubToken, 'github'), 'Invalid GitHub token should be rejected');
|
|
90
|
+
(0, node_assert_1.default)(!(0, token_validator_1.isValidTokenFormat)(shortFraimKey, 'fraim'), 'Short FRAIM key should be rejected');
|
|
91
|
+
(0, node_assert_1.default)(!await (0, token_validator_1.validateFraimKey)(invalidFraimKey), 'Invalid FRAIM key should not validate');
|
|
92
|
+
(0, node_assert_1.default)(!await (0, token_validator_1.validateFraimKey)(shortFraimKey), 'Short FRAIM key should not validate');
|
|
93
|
+
console.log('โ
Error handling tests passed');
|
|
94
|
+
});
|
|
95
|
+
(0, node_test_1.test)('Path expansion works correctly across platforms', () => {
|
|
96
|
+
const testPaths = [
|
|
97
|
+
'~/.fraim/config.json',
|
|
98
|
+
'~/.claude/settings.json',
|
|
99
|
+
'~/.kiro/settings/mcp.json'
|
|
100
|
+
];
|
|
101
|
+
testPaths.forEach(testPath => {
|
|
102
|
+
const expanded = (0, ide_detector_1.expandPath)(testPath);
|
|
103
|
+
(0, node_assert_1.default)(expanded.includes(os_1.default.homedir()), `${testPath} should expand to include home directory`);
|
|
104
|
+
(0, node_assert_1.default)(!expanded.includes('~'), `${testPath} should not contain tilde after expansion`);
|
|
105
|
+
});
|
|
106
|
+
// Test absolute paths remain unchanged
|
|
107
|
+
const absolutePath = '/usr/local/bin/fraim';
|
|
108
|
+
(0, node_assert_1.default)((0, ide_detector_1.expandPath)(absolutePath) === absolutePath, 'Absolute paths should remain unchanged');
|
|
109
|
+
console.log('โ
Path expansion tests passed');
|
|
110
|
+
});
|