fraim-framework 2.0.35 โ†’ 2.0.36

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 (51) hide show
  1. package/bin/fraim.js +52 -5
  2. package/dist/registry/scripts/cleanup-branch.js +62 -33
  3. package/dist/registry/scripts/generate-engagement-emails.js +119 -44
  4. package/dist/registry/scripts/newsletter-helpers.js +208 -268
  5. package/dist/registry/scripts/profile-server.js +387 -0
  6. package/dist/tests/test-chalk-regression.js +18 -2
  7. package/dist/tests/test-client-scripts-validation.js +133 -0
  8. package/dist/tests/test-prep-issue.js +1 -34
  9. package/dist/tests/test-script-location-independence.js +76 -28
  10. package/package.json +2 -2
  11. package/registry/agent-guardrails.md +62 -62
  12. package/registry/rules/communication.md +121 -121
  13. package/registry/rules/continuous-learning.md +54 -54
  14. package/registry/rules/hitl-ppe-record-analysis.md +302 -302
  15. package/registry/rules/software-development-lifecycle.md +104 -104
  16. package/registry/scripts/cleanup-branch.ts +341 -0
  17. package/registry/scripts/code-quality-check.sh +559 -559
  18. package/registry/scripts/detect-tautological-tests.sh +38 -38
  19. package/registry/scripts/generate-engagement-emails.ts +830 -0
  20. package/registry/scripts/markdown-to-pdf.js +7 -3
  21. package/registry/scripts/newsletter-helpers.ts +777 -0
  22. package/registry/scripts/prep-issue.sh +30 -61
  23. package/registry/scripts/profile-server.ts +424 -0
  24. package/registry/scripts/run-thank-you-workflow.ts +122 -0
  25. package/registry/scripts/send-newsletter-simple.ts +102 -0
  26. package/registry/scripts/send-thank-you-emails.ts +57 -0
  27. package/registry/scripts/validate-openapi-limits.ts +366 -366
  28. package/registry/scripts/validate-test-coverage.ts +280 -280
  29. package/registry/scripts/verify-pr-comments.sh +70 -70
  30. package/registry/templates/bootstrap/ARCHITECTURE-TEMPLATE.md +53 -53
  31. package/registry/templates/evidence/Implementation-BugEvidence.md +85 -85
  32. package/registry/templates/evidence/Implementation-FeatureEvidence.md +120 -120
  33. package/registry/workflows/customer-development/insight-analysis.md +156 -156
  34. package/registry/workflows/customer-development/interview-preparation.md +421 -421
  35. package/registry/workflows/customer-development/strategic-brainstorming.md +146 -146
  36. package/registry/workflows/quality-assurance/iterative-improvement-cycle.md +562 -562
  37. package/registry/workflows/reviewer/review-implementation-vs-feature-spec.md +669 -669
  38. package/dist/registry/scripts/build-scripts-generator.js +0 -205
  39. package/dist/registry/scripts/fraim-config.js +0 -61
  40. package/dist/registry/scripts/generic-issues-api.js +0 -100
  41. package/dist/registry/scripts/openapi-generator.js +0 -664
  42. package/dist/registry/scripts/performance/profile-server.js +0 -390
  43. package/dist/test-utils.js +0 -96
  44. package/dist/tests/esm-compat.js +0 -11
  45. package/dist/tests/test-chalk-esm-issue.js +0 -159
  46. package/dist/tests/test-chalk-real-world.js +0 -265
  47. package/dist/tests/test-chalk-resolution-issue.js +0 -304
  48. package/dist/tests/test-fraim-install-chalk-issue.js +0 -254
  49. package/dist/tests/test-npm-resolution-diagnostic.js +0 -140
  50. package/registry/templates/marketing/STORYTELLING-TEMPLATE.md +0 -130
  51. package/registry/workflows/marketing/storytelling.md +0 -65
@@ -1,265 +0,0 @@
1
- "use strict";
2
- /**
3
- * Real-world test for the chalk ESM issue
4
- *
5
- * This test simulates what the user's friend experienced:
6
- * Running `npx fraim-framework init` in a fresh environment
7
- */
8
- var __importDefault = (this && this.__importDefault) || function (mod) {
9
- return (mod && mod.__esModule) ? mod : { "default": mod };
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- const node_child_process_1 = require("node:child_process");
13
- const test_utils_1 = require("./test-utils");
14
- const fs_1 = __importDefault(require("fs"));
15
- const path_1 = __importDefault(require("path"));
16
- const os_1 = __importDefault(require("os"));
17
- async function runCommand(command, args, cwd) {
18
- return new Promise((resolve) => {
19
- const proc = (0, node_child_process_1.spawn)(command, args, {
20
- cwd,
21
- stdio: 'pipe',
22
- shell: true
23
- });
24
- let stdout = '';
25
- let stderr = '';
26
- proc.stdout?.on('data', (data) => {
27
- stdout += data.toString();
28
- });
29
- proc.stderr?.on('data', (data) => {
30
- stderr += data.toString();
31
- });
32
- proc.on('close', (code) => {
33
- resolve({ code, stdout, stderr });
34
- });
35
- });
36
- }
37
- async function testFreshInstall() {
38
- console.log(' ๐Ÿงช Testing fresh fraim-framework install (simulating user experience)...');
39
- const tempDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'fraim-fresh-'));
40
- console.log(` ๐Ÿ“‚ Created temp dir: ${tempDir}`);
41
- try {
42
- // 1. Pack the current fraim-framework
43
- console.log(' ๐Ÿ“ฆ Packing fraim-framework...');
44
- const projectRoot = process.cwd();
45
- const packResult = (0, node_child_process_1.execSync)('npm pack', {
46
- cwd: projectRoot,
47
- encoding: 'utf-8'
48
- });
49
- const tarballName = packResult.trim().split('\n').pop()?.trim();
50
- if (!tarballName) {
51
- console.log(' โŒ Failed to get tarball name');
52
- return false;
53
- }
54
- const tarballPath = path_1.default.join(projectRoot, tarballName);
55
- console.log(` โœ… Created tarball: ${tarballName}`);
56
- // 2. Create an empty project (simulating user's environment)
57
- const testPackageJson = {
58
- name: 'user-project',
59
- version: '1.0.0',
60
- private: true
61
- };
62
- fs_1.default.writeFileSync(path_1.default.join(tempDir, 'package.json'), JSON.stringify(testPackageJson, null, 2));
63
- // 3. Install fraim-framework
64
- console.log(' ๐Ÿ“ฅ Installing fraim-framework (like user would)...');
65
- const installResult = await runCommand('npm', ['install', tarballPath], tempDir);
66
- if (installResult.code !== 0) {
67
- console.log(' โŒ npm install failed');
68
- console.log(` stderr: ${installResult.stderr.substring(0, 500)}`);
69
- fs_1.default.unlinkSync(tarballPath);
70
- return false;
71
- }
72
- console.log(' โœ… fraim-framework installed');
73
- // 4. Check chalk version
74
- const chalkPath = path_1.default.join(tempDir, 'node_modules', 'chalk', 'package.json');
75
- if (fs_1.default.existsSync(chalkPath)) {
76
- const chalkPkg = JSON.parse(fs_1.default.readFileSync(chalkPath, 'utf-8'));
77
- console.log(` ๐Ÿ“‹ Installed chalk version: ${chalkPkg.version}`);
78
- if (!chalkPkg.version.startsWith('4.')) {
79
- console.log(` โŒ Wrong chalk version! Expected 4.x, got ${chalkPkg.version}`);
80
- fs_1.default.unlinkSync(tarballPath);
81
- return false;
82
- }
83
- }
84
- // 5. Try to run fraim CLI (this is what the user did)
85
- console.log(' ๐Ÿš€ Running fraim CLI...');
86
- const testScript = `
87
- try {
88
- const fraimCli = require('./node_modules/fraim-framework/dist/src/cli/fraim.js');
89
- console.log('SUCCESS: fraim CLI loaded');
90
- process.exit(0);
91
- } catch (error) {
92
- if (error.code === 'ERR_REQUIRE_ESM') {
93
- console.log('ERROR: ERR_REQUIRE_ESM');
94
- console.log('Message:', error.message);
95
- process.exit(1);
96
- } else {
97
- console.log('ERROR: Other error:', error.message);
98
- process.exit(2);
99
- }
100
- }
101
- `;
102
- fs_1.default.writeFileSync(path_1.default.join(tempDir, 'test.js'), testScript);
103
- const testResult = await runCommand('node', ['test.js'], tempDir);
104
- if (testResult.code === 0) {
105
- console.log(' โœ… SUCCESS! fraim CLI works in fresh install');
106
- console.log(' โœ… No ERR_REQUIRE_ESM error');
107
- }
108
- else if (testResult.code === 1) {
109
- console.log(' โŒ FAILED! Got ERR_REQUIRE_ESM in fresh install');
110
- console.log(' โŒ This means the fix doesn\'t work');
111
- console.log(` Output: ${testResult.stdout}`);
112
- fs_1.default.unlinkSync(tarballPath);
113
- return false;
114
- }
115
- else {
116
- console.log(' โš ๏ธ Got unexpected error');
117
- console.log(` stdout: ${testResult.stdout}`);
118
- console.log(` stderr: ${testResult.stderr.substring(0, 300)}`);
119
- }
120
- // Cleanup
121
- fs_1.default.unlinkSync(tarballPath);
122
- return true;
123
- }
124
- catch (error) {
125
- console.error(' โŒ Test failed with error:', error);
126
- return false;
127
- }
128
- finally {
129
- try {
130
- fs_1.default.rmSync(tempDir, { recursive: true, force: true });
131
- console.log(' ๐Ÿงน Cleaned up temp directory');
132
- }
133
- catch (e) {
134
- console.log(' โš ๏ธ Could not clean up temp directory');
135
- }
136
- }
137
- }
138
- async function testInstallInProjectWithChalkV5() {
139
- console.log(' ๐Ÿงช Testing fraim install in project that already has chalk v5...');
140
- const tempDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'fraim-with-v5-'));
141
- console.log(` ๐Ÿ“‚ Created temp dir: ${tempDir}`);
142
- try {
143
- // 1. Create a project that already has chalk v5
144
- console.log(' ๐Ÿ“ฆ Creating project with chalk v5...');
145
- const testPackageJson = {
146
- name: 'user-project-with-chalk5',
147
- version: '1.0.0',
148
- private: true,
149
- dependencies: {
150
- 'chalk': '^5.0.0'
151
- }
152
- };
153
- fs_1.default.writeFileSync(path_1.default.join(tempDir, 'package.json'), JSON.stringify(testPackageJson, null, 2));
154
- // Install chalk v5 first
155
- console.log(' ๐Ÿ“ฅ Installing chalk v5...');
156
- const installChalkResult = await runCommand('npm', ['install'], tempDir);
157
- if (installChalkResult.code !== 0) {
158
- console.log(' โš ๏ธ Failed to install chalk v5');
159
- return true; // Skip this test
160
- }
161
- // 2. Pack fraim-framework
162
- console.log(' ๐Ÿ“ฆ Packing fraim-framework...');
163
- const projectRoot = process.cwd();
164
- const packResult = (0, node_child_process_1.execSync)('npm pack', {
165
- cwd: projectRoot,
166
- encoding: 'utf-8'
167
- });
168
- const tarballName = packResult.trim().split('\n').pop()?.trim();
169
- if (!tarballName) {
170
- console.log(' โŒ Failed to get tarball name');
171
- return false;
172
- }
173
- const tarballPath = path_1.default.join(projectRoot, tarballName);
174
- // 3. Install fraim-framework into project with chalk v5
175
- console.log(' ๐Ÿ“ฅ Installing fraim-framework into project with chalk v5...');
176
- const installResult = await runCommand('npm', ['install', tarballPath], tempDir);
177
- if (installResult.code !== 0) {
178
- console.log(' โš ๏ธ npm install failed');
179
- }
180
- // 4. Check chalk versions
181
- const rootChalkPath = path_1.default.join(tempDir, 'node_modules', 'chalk', 'package.json');
182
- const fraimChalkPath = path_1.default.join(tempDir, 'node_modules', 'fraim-framework', 'node_modules', 'chalk', 'package.json');
183
- let rootChalkVersion = null;
184
- let fraimChalkVersion = null;
185
- if (fs_1.default.existsSync(rootChalkPath)) {
186
- const chalkPkg = JSON.parse(fs_1.default.readFileSync(rootChalkPath, 'utf-8'));
187
- rootChalkVersion = chalkPkg.version;
188
- console.log(` ๐Ÿ“‹ Root chalk version: ${rootChalkVersion}`);
189
- }
190
- if (fs_1.default.existsSync(fraimChalkPath)) {
191
- const chalkPkg = JSON.parse(fs_1.default.readFileSync(fraimChalkPath, 'utf-8'));
192
- fraimChalkVersion = chalkPkg.version;
193
- console.log(` ๐Ÿ“‹ fraim-framework's chalk version: ${fraimChalkVersion}`);
194
- }
195
- else {
196
- console.log(' ๐Ÿ“‹ fraim-framework doesn\'t have its own chalk (using root)');
197
- }
198
- // 5. Try to run fraim CLI
199
- console.log(' ๐Ÿš€ Testing if fraim CLI works with chalk v5 in project...');
200
- const testScript = `
201
- try {
202
- const fraimCli = require('./node_modules/fraim-framework/dist/src/cli/fraim.js');
203
- console.log('SUCCESS: fraim CLI loaded even with chalk v5 in project');
204
- process.exit(0);
205
- } catch (error) {
206
- if (error.code === 'ERR_REQUIRE_ESM') {
207
- console.log('ERROR: ERR_REQUIRE_ESM - fraim is using project\\'s chalk v5!');
208
- process.exit(1);
209
- } else {
210
- console.log('ERROR: Other error:', error.message);
211
- process.exit(2);
212
- }
213
- }
214
- `;
215
- fs_1.default.writeFileSync(path_1.default.join(tempDir, 'test.js'), testScript);
216
- const testResult = await runCommand('node', ['test.js'], tempDir);
217
- if (testResult.code === 0) {
218
- console.log(' โœ… SUCCESS! fraim CLI works even in project with chalk v5');
219
- console.log(' โœ… fraim-framework has its own chalk v4');
220
- }
221
- else if (testResult.code === 1) {
222
- console.log(' โŒ FAILED! fraim is using project\'s chalk v5');
223
- console.log(' โŒ Pinned version didn\'t create isolated chalk v4');
224
- console.log(' โš ๏ธ This is the real issue - npm didn\'t install separate chalk for fraim');
225
- // This is actually expected behavior with npm's deduplication
226
- // The fix would need to be different (e.g., bundling chalk, or using overrides)
227
- console.log(' โ„น๏ธ Note: This might be expected npm behavior');
228
- console.log(' โ„น๏ธ Pinning prevents upgrades but doesn\'t force isolation');
229
- }
230
- // Cleanup
231
- fs_1.default.unlinkSync(tarballPath);
232
- return true;
233
- }
234
- catch (error) {
235
- console.error(' โŒ Test failed with error:', error);
236
- return false;
237
- }
238
- finally {
239
- try {
240
- fs_1.default.rmSync(tempDir, { recursive: true, force: true });
241
- console.log(' ๐Ÿงน Cleaned up temp directory');
242
- }
243
- catch (e) {
244
- console.log(' โš ๏ธ Could not clean up temp directory');
245
- }
246
- }
247
- }
248
- async function runRealWorldTest(testCase) {
249
- return await testCase.testFunction();
250
- }
251
- const testCases = [
252
- {
253
- name: 'Fresh Install Test',
254
- description: 'Simulates user installing fraim-framework in a fresh project',
255
- testFunction: testFreshInstall,
256
- tags: ['real-world', 'fresh-install']
257
- },
258
- {
259
- name: 'Install in Project with Chalk v5',
260
- description: 'Tests fraim-framework install in a project that already has chalk v5',
261
- testFunction: testInstallInProjectWithChalkV5,
262
- tags: ['real-world', 'conflict', 'chalk-v5']
263
- }
264
- ];
265
- (0, test_utils_1.runTests)(testCases, runRealWorldTest, 'Real World Chalk Issue Test');
@@ -1,304 +0,0 @@
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');