fraim-framework 2.0.56 → 2.0.58

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 (224) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/bin/fraim-mcp.js +14 -0
  3. package/bin/fraim.js +23 -0
  4. package/dist/src/cli/commands/init-project.js +10 -4
  5. package/dist/src/cli/commands/mcp.js +65 -0
  6. package/dist/src/cli/setup/mcp-config-generator.js +19 -16
  7. package/dist/src/fraim/issue-tracking/ado-provider.js +304 -0
  8. package/dist/src/fraim/issue-tracking/factory.js +63 -0
  9. package/dist/src/fraim/issue-tracking/github-provider.js +200 -0
  10. package/dist/src/fraim/issue-tracking/types.js +7 -0
  11. package/dist/src/fraim/issue-tracking-config.js +83 -0
  12. package/dist/src/local-mcp-server/stdio-server.js +207 -0
  13. package/dist/src/utils/workflow-parser.js +81 -0
  14. package/package.json +17 -12
  15. package/registry/scripts/pdf-styles.css +172 -0
  16. package/registry/scripts/prep-issue.sh +46 -4
  17. package/registry/scripts/profile-server.ts +131 -130
  18. package/registry/stubs/workflows/customer-development/user-survey-dispatch.md +1 -1
  19. package/registry/stubs/workflows/customer-development/users-to-target.md +1 -1
  20. package/registry/stubs/workflows/product-building/design.md +1 -1
  21. package/registry/stubs/workflows/product-building/implement.md +1 -1
  22. package/Claude.md +0 -1
  23. package/dist/registry/ai-manager-rules/customer-development-phases/phase1-customer-profiling.md +0 -101
  24. package/dist/registry/ai-manager-rules/customer-development-phases/phase2-platform-discovery.md +0 -235
  25. package/dist/registry/ai-manager-rules/customer-development-phases/phase3-prospect-qualification.md +0 -243
  26. package/dist/registry/ai-manager-rules/customer-development-phases/phase4-inventory-compilation.md +0 -206
  27. package/dist/registry/ai-manager-rules/design-phases/design-completeness-review.md +0 -73
  28. package/dist/registry/ai-manager-rules/design-phases/design-design.md +0 -145
  29. package/dist/registry/ai-manager-rules/implement-phases/implement-code.md +0 -283
  30. package/dist/registry/ai-manager-rules/implement-phases/implement-completeness-review.md +0 -120
  31. package/dist/registry/ai-manager-rules/implement-phases/implement-regression.md +0 -173
  32. package/dist/registry/ai-manager-rules/implement-phases/implement-repro.md +0 -104
  33. package/dist/registry/ai-manager-rules/implement-phases/implement-scoping.md +0 -100
  34. package/dist/registry/ai-manager-rules/implement-phases/implement-smoke.md +0 -237
  35. package/dist/registry/ai-manager-rules/implement-phases/implement-spike.md +0 -121
  36. package/dist/registry/ai-manager-rules/implement-phases/implement-validate.md +0 -375
  37. package/dist/registry/ai-manager-rules/retrospective.md +0 -116
  38. package/dist/registry/ai-manager-rules/shared-phases/address-pr-feedback.md +0 -188
  39. package/dist/registry/ai-manager-rules/shared-phases/submit-pr.md +0 -202
  40. package/dist/registry/ai-manager-rules/shared-phases/wait-for-pr-review.md +0 -170
  41. package/dist/registry/ai-manager-rules/spec-phases/spec-competitor-analysis.md +0 -105
  42. package/dist/registry/ai-manager-rules/spec-phases/spec-completeness-review.md +0 -66
  43. package/dist/registry/ai-manager-rules/spec-phases/spec-spec.md +0 -139
  44. package/dist/registry/ai-manager-rules/user-survey-phases/phase1-survey-scoping.md +0 -60
  45. package/dist/registry/ai-manager-rules/user-survey-phases/phase2-survey-build-linkedin.md +0 -23
  46. package/dist/registry/ai-manager-rules/user-survey-phases/phase3-survey-build-reddit.md +0 -22
  47. package/dist/registry/ai-manager-rules/user-survey-phases/phase4-survey-build-x.md +0 -21
  48. package/dist/registry/ai-manager-rules/user-survey-phases/phase5-survey-build-facebook.md +0 -19
  49. package/dist/registry/ai-manager-rules/user-survey-phases/phase6-survey-build-custom.md +0 -15
  50. package/dist/registry/ai-manager-rules/user-survey-phases/phase7-survey-dispatch.md +0 -45
  51. package/dist/registry/providers/ado.json +0 -19
  52. package/dist/registry/providers/github.json +0 -19
  53. package/dist/registry/scripts/cleanup-branch.js +0 -287
  54. package/dist/registry/scripts/evaluate-code-quality.js +0 -66
  55. package/dist/registry/scripts/exec-with-timeout.js +0 -142
  56. package/dist/registry/scripts/generate-engagement-emails.js +0 -705
  57. package/dist/registry/scripts/newsletter-helpers.js +0 -671
  58. package/dist/registry/scripts/profile-server.js +0 -388
  59. package/dist/registry/scripts/run-thank-you-workflow.js +0 -92
  60. package/dist/registry/scripts/send-newsletter-simple.js +0 -85
  61. package/dist/registry/scripts/send-thank-you-emails.js +0 -54
  62. package/dist/registry/scripts/validate-openapi-limits.js +0 -311
  63. package/dist/registry/scripts/validate-test-coverage.js +0 -262
  64. package/dist/registry/scripts/verify-test-coverage.js +0 -66
  65. package/dist/registry/templates/bootstrap/ARCHITECTURE-TEMPLATE.md +0 -53
  66. package/dist/registry/templates/bootstrap/CODE-QUALITY-REPORT-TEMPLATE.md +0 -37
  67. package/dist/registry/templates/bootstrap/TEST-COVERAGE-REPORT-TEMPLATE.md +0 -35
  68. package/dist/registry/templates/business-development/IDEATION-REPORT-TEMPLATE.md +0 -29
  69. package/dist/registry/templates/business-development/PRICING-STRATEGY-TEMPLATE.md +0 -126
  70. package/dist/registry/templates/customer-development/customer-interview-template.md +0 -99
  71. package/dist/registry/templates/customer-development/customer-persona-template.md +0 -69
  72. package/dist/registry/templates/customer-development/follow-up-email-templates.md +0 -132
  73. package/dist/registry/templates/customer-development/insight-analysis-template.md +0 -74
  74. package/dist/registry/templates/customer-development/prospect-inventory-template.csv +0 -3
  75. package/dist/registry/templates/customer-development/search-strategy-template.md +0 -123
  76. package/dist/registry/templates/customer-development/strategic-recommendations-template.md +0 -53
  77. package/dist/registry/templates/customer-development/thank-you-email-template.html +0 -124
  78. package/dist/registry/templates/customer-development/thank-you-note-template.md +0 -16
  79. package/dist/registry/templates/customer-development/triage-log-template.md +0 -278
  80. package/dist/registry/templates/customer-development/weekly-newsletter-template.html +0 -204
  81. package/dist/registry/templates/evidence/Design-Evidence.md +0 -30
  82. package/dist/registry/templates/evidence/Implementation-BugEvidence.md +0 -94
  83. package/dist/registry/templates/evidence/Implementation-FeatureEvidence.md +0 -129
  84. package/dist/registry/templates/evidence/Spec-Evidence.md +0 -19
  85. package/dist/registry/templates/help/HelpNeeded.md +0 -14
  86. package/dist/registry/templates/legal/NDA-TEMPLATE.md +0 -170
  87. package/dist/registry/templates/legal/PATENT-TEMPLATE.md +0 -372
  88. package/dist/registry/templates/legal/TRADEMARK-TEMPLATE.md +0 -339
  89. package/dist/registry/templates/legal/contract-review-checklist.md +0 -193
  90. package/dist/registry/templates/legal/review-report-template.md +0 -198
  91. package/dist/registry/templates/legal/saas-terms-template.md +0 -174
  92. package/dist/registry/templates/legal/sow-template.md +0 -117
  93. package/dist/registry/templates/legal/template-variables.md +0 -131
  94. package/dist/registry/templates/marketing/DOMAIN-REGISTRATION-TEMPLATE.md +0 -194
  95. package/dist/registry/templates/marketing/HBR-ARTICLE-TEMPLATE.md +0 -66
  96. package/dist/registry/templates/marketing/STORYTELLING-TEMPLATE.md +0 -130
  97. package/dist/registry/templates/marketing/WEBSITE-TEMPLATE.md +0 -262
  98. package/dist/registry/templates/marketing/github-pages-workflow.yml +0 -64
  99. package/dist/registry/templates/replicate/implementation-checklist.md +0 -39
  100. package/dist/registry/templates/replicate/use-cases-template.md +0 -88
  101. package/dist/registry/templates/retrospective/RETROSPECTIVE-TEMPLATE.md +0 -55
  102. package/dist/registry/templates/specs/BUGSPEC-TEMPLATE.md +0 -37
  103. package/dist/registry/templates/specs/FEATURESPEC-TEMPLATE.md +0 -66
  104. package/dist/registry/templates/specs/TECHSPEC-TEMPLATE.md +0 -39
  105. package/dist/registry/workflows/bootstrap/create-architecture.md +0 -38
  106. package/dist/registry/workflows/bootstrap/detect-broken-windows.md +0 -300
  107. package/dist/registry/workflows/bootstrap/evaluate-code-quality.md +0 -35
  108. package/dist/registry/workflows/bootstrap/verify-test-coverage.md +0 -36
  109. package/dist/registry/workflows/brainstorming/blue-sky-brainstorming.md +0 -211
  110. package/dist/registry/workflows/brainstorming/codebase-brainstorming.md +0 -165
  111. package/dist/registry/workflows/business-development/create-business-plan.md +0 -737
  112. package/dist/registry/workflows/business-development/ideate-business-opportunity.md +0 -55
  113. package/dist/registry/workflows/business-development/price-product.md +0 -325
  114. package/dist/registry/workflows/compliance/detect-compliance-requirements.md +0 -78
  115. package/dist/registry/workflows/compliance/generate-audit-evidence.md +0 -75
  116. package/dist/registry/workflows/compliance/soc2-evidence-generator.md +0 -332
  117. package/dist/registry/workflows/customer-development/insight-analysis.md +0 -156
  118. package/dist/registry/workflows/customer-development/insight-triage.md +0 -938
  119. package/dist/registry/workflows/customer-development/interview-preparation.md +0 -452
  120. package/dist/registry/workflows/customer-development/linkedin-outreach.md +0 -593
  121. package/dist/registry/workflows/customer-development/strategic-brainstorming.md +0 -146
  122. package/dist/registry/workflows/customer-development/thank-customers.md +0 -203
  123. package/dist/registry/workflows/customer-development/user-survey-dispatch.md +0 -60
  124. package/dist/registry/workflows/customer-development/users-to-target.md +0 -112
  125. package/dist/registry/workflows/customer-development/weekly-newsletter.md +0 -366
  126. package/dist/registry/workflows/deploy/cloud-deployment.md +0 -310
  127. package/dist/registry/workflows/improve-fraim/contribute.md +0 -32
  128. package/dist/registry/workflows/improve-fraim/file-issue.md +0 -32
  129. package/dist/registry/workflows/learning/build-skillset.md +0 -212
  130. package/dist/registry/workflows/learning/synthesize-learnings.md +0 -284
  131. package/dist/registry/workflows/legal/contract-review-analysis.md +0 -382
  132. package/dist/registry/workflows/legal/nda.md +0 -69
  133. package/dist/registry/workflows/legal/patent-filing.md +0 -76
  134. package/dist/registry/workflows/legal/saas-contract-development.md +0 -213
  135. package/dist/registry/workflows/legal/trademark-filing.md +0 -77
  136. package/dist/registry/workflows/marketing/content-creation.md +0 -37
  137. package/dist/registry/workflows/marketing/convert-to-pdf.md +0 -235
  138. package/dist/registry/workflows/marketing/create-modern-website.md +0 -456
  139. package/dist/registry/workflows/marketing/domain-registration.md +0 -323
  140. package/dist/registry/workflows/marketing/hbr-article.md +0 -73
  141. package/dist/registry/workflows/marketing/launch-checklist.md +0 -37
  142. package/dist/registry/workflows/marketing/marketing-strategy.md +0 -45
  143. package/dist/registry/workflows/marketing/storytelling.md +0 -65
  144. package/dist/registry/workflows/performance/analyze-performance.md +0 -65
  145. package/dist/registry/workflows/product-building/design.md +0 -103
  146. package/dist/registry/workflows/product-building/implement.md +0 -74
  147. package/dist/registry/workflows/product-building/iterate-on-pr-comments.md +0 -70
  148. package/dist/registry/workflows/product-building/prep-issue.md +0 -41
  149. package/dist/registry/workflows/product-building/prototype.md +0 -65
  150. package/dist/registry/workflows/product-building/resolve.md +0 -168
  151. package/dist/registry/workflows/product-building/retrospect.md +0 -86
  152. package/dist/registry/workflows/product-building/spec.md +0 -181
  153. package/dist/registry/workflows/product-building/test.md +0 -125
  154. package/dist/registry/workflows/productivity-report/productivity-report.md +0 -263
  155. package/dist/registry/workflows/quality-assurance/browser-validation.md +0 -221
  156. package/dist/registry/workflows/quality-assurance/iterative-improvement-cycle.md +0 -562
  157. package/dist/registry/workflows/replicate/replicate-discovery.md +0 -336
  158. package/dist/registry/workflows/replicate/replicate-to-issues.md +0 -324
  159. package/dist/registry/workflows/reviewer/review-implementation-vs-design-spec.md +0 -638
  160. package/dist/registry/workflows/reviewer/review-implementation-vs-feature-spec.md +0 -675
  161. package/dist/registry/workflows/startup-credits/aws-activate-application.md +0 -535
  162. package/dist/registry/workflows/startup-credits/google-cloud-application.md +0 -647
  163. package/dist/registry/workflows/startup-credits/microsoft-azure-application.md +0 -538
  164. package/dist/scripts/build-stub-registry.js +0 -108
  165. package/dist/src/ai-manager/ai-manager.js +0 -480
  166. package/dist/src/ai-manager/phase-flow.js +0 -357
  167. package/dist/src/ai-manager/types.js +0 -5
  168. package/dist/src/fraim-mcp-server.js +0 -1885
  169. package/dist/tests/debug-tools.js +0 -80
  170. package/dist/tests/shared-server-utils.js +0 -57
  171. package/dist/tests/test-add-ide.js +0 -283
  172. package/dist/tests/test-ai-coach-edge-cases.js +0 -420
  173. package/dist/tests/test-ai-coach-mcp-integration.js +0 -450
  174. package/dist/tests/test-ai-coach-performance.js +0 -328
  175. package/dist/tests/test-ai-coach-phase-content.js +0 -264
  176. package/dist/tests/test-ai-coach-workflows.js +0 -514
  177. package/dist/tests/test-cli.js +0 -228
  178. package/dist/tests/test-client-scripts-validation.js +0 -167
  179. package/dist/tests/test-complete-setup-flow.js +0 -110
  180. package/dist/tests/test-config-system.js +0 -279
  181. package/dist/tests/test-debug-session.js +0 -134
  182. package/dist/tests/test-end-to-end-hybrid-validation.js +0 -328
  183. package/dist/tests/test-enhanced-session-init.js +0 -188
  184. package/dist/tests/test-first-run-journey.js +0 -368
  185. package/dist/tests/test-fraim-issues.js +0 -59
  186. package/dist/tests/test-genericization.js +0 -44
  187. package/dist/tests/test-hybrid-script-execution.js +0 -340
  188. package/dist/tests/test-ide-detector.js +0 -46
  189. package/dist/tests/test-improved-setup.js +0 -121
  190. package/dist/tests/test-mcp-config-generator.js +0 -99
  191. package/dist/tests/test-mcp-connection.js +0 -107
  192. package/dist/tests/test-mcp-issue-integration.js +0 -156
  193. package/dist/tests/test-mcp-lifecycle-methods.js +0 -240
  194. package/dist/tests/test-mcp-shared-server.js +0 -308
  195. package/dist/tests/test-mcp-template-processing.js +0 -160
  196. package/dist/tests/test-modular-issue-tracking.js +0 -165
  197. package/dist/tests/test-node-compatibility.js +0 -95
  198. package/dist/tests/test-npm-install.js +0 -68
  199. package/dist/tests/test-package-size.js +0 -108
  200. package/dist/tests/test-pr-review-workflow.js +0 -307
  201. package/dist/tests/test-prep-issue.js +0 -129
  202. package/dist/tests/test-productivity-integration.js +0 -157
  203. package/dist/tests/test-script-location-independence.js +0 -198
  204. package/dist/tests/test-script-sync.js +0 -557
  205. package/dist/tests/test-server-utils.js +0 -32
  206. package/dist/tests/test-session-rehydration.js +0 -148
  207. package/dist/tests/test-setup-integration.js +0 -98
  208. package/dist/tests/test-setup-scenarios.js +0 -322
  209. package/dist/tests/test-standalone.js +0 -143
  210. package/dist/tests/test-stub-registry.js +0 -136
  211. package/dist/tests/test-sync-stubs.js +0 -143
  212. package/dist/tests/test-sync-version-update.js +0 -93
  213. package/dist/tests/test-telemetry.js +0 -193
  214. package/dist/tests/test-token-validator.js +0 -30
  215. package/dist/tests/test-user-journey.js +0 -236
  216. package/dist/tests/test-users-to-target-workflow.js +0 -253
  217. package/dist/tests/test-utils.js +0 -109
  218. package/dist/tests/test-wizard.js +0 -71
  219. package/dist/tests/test-workflow-discovery.js +0 -242
  220. package/labels.json +0 -52
  221. package/registry/agent-guardrails.md +0 -63
  222. package/registry/fraim.md +0 -48
  223. package/setup.js +0 -171
  224. package/tsconfig.json +0 -23
@@ -1,557 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- const node_child_process_1 = require("node:child_process");
40
- const test_utils_1 = require("./test-utils");
41
- const node_assert_1 = __importDefault(require("node:assert"));
42
- const fs_1 = __importDefault(require("fs"));
43
- const path_1 = __importDefault(require("path"));
44
- const os_1 = __importDefault(require("os"));
45
- async function testScriptSyncDuringInit() {
46
- console.log(' 🚀 Testing Script Sync During Init...');
47
- const tempDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'fraim-script-sync-test-'));
48
- const userFraimDir = path_1.default.join(os_1.default.homedir(), '.fraim-test');
49
- const userScriptsDir = path_1.default.join(userFraimDir, 'scripts');
50
- console.log(` 📂 Created temp dir: ${tempDir}`);
51
- console.log(` 🏠 Using test user dir: ${userFraimDir}`);
52
- try {
53
- // Clean up any existing test user directory
54
- if (fs_1.default.existsSync(userFraimDir)) {
55
- fs_1.default.rmSync(userFraimDir, { recursive: true, force: true });
56
- }
57
- const platform = process.platform;
58
- const npx = platform === 'win32' ? 'npx.cmd' : 'npx';
59
- const cliScript = (0, test_utils_1.resolveProjectPath)('dist/src/cli/fraim.js');
60
- // Helper to run CLI commands
61
- const runFraim = (args, cwdOverride) => {
62
- return new Promise((resolve) => {
63
- const ps = (0, node_child_process_1.spawn)(npx, ['node', `"${cliScript}"`, ...args], {
64
- cwd: cwdOverride || tempDir,
65
- env: {
66
- ...process.env,
67
- TEST_MODE: 'true',
68
- FRAIM_USER_DIR: userFraimDir // Override user directory for testing
69
- },
70
- shell: true
71
- });
72
- let stdout = '';
73
- let stderr = '';
74
- ps.stdout.on('data', d => stdout += d.toString());
75
- ps.stderr.on('data', d => stderr += d.toString());
76
- ps.on('close', (code) => {
77
- resolve({ stdout, stderr, code });
78
- });
79
- });
80
- };
81
- // Set up git repository
82
- const { execSync } = await Promise.resolve().then(() => __importStar(require('child_process')));
83
- execSync('git init', { cwd: tempDir });
84
- execSync('git remote add origin https://github.com/test-owner/test-project.git', { cwd: tempDir });
85
- // Run fraim init
86
- console.log(' Testing fraim init with script sync...');
87
- const initRes = await runFraim(['init'], tempDir);
88
- node_assert_1.default.strictEqual(initRes.code, 0, 'Init should succeed');
89
- // Verify user scripts directory was created
90
- node_assert_1.default.ok(fs_1.default.existsSync(userScriptsDir), 'User scripts directory should be created');
91
- // Verify scripts were copied
92
- const expectedScripts = ['prep-issue.sh', 'code-quality-check.sh'];
93
- for (const scriptName of expectedScripts) {
94
- const scriptPath = path_1.default.join(userScriptsDir, scriptName);
95
- node_assert_1.default.ok(fs_1.default.existsSync(scriptPath), `Script ${scriptName} should be copied to user directory`);
96
- // Verify script is executable on Unix systems
97
- if (process.platform !== 'win32') {
98
- const stats = fs_1.default.statSync(scriptPath);
99
- node_assert_1.default.ok(stats.mode & 0o111, `Script ${scriptName} should be executable`);
100
- }
101
- }
102
- // Verify script content matches registry
103
- const prepIssueUserPath = path_1.default.join(userScriptsDir, 'prep-issue.sh');
104
- // Handle both source and compiled execution
105
- const prepIssueRegistryPath = fs_1.default.existsSync(path_1.default.join(__dirname, '../registry/scripts/prep-issue.sh'))
106
- ? path_1.default.join(__dirname, '../registry/scripts/prep-issue.sh')
107
- : path_1.default.resolve(__dirname, '../../registry/scripts/prep-issue.sh');
108
- if (fs_1.default.existsSync(prepIssueRegistryPath)) {
109
- const userContent = fs_1.default.readFileSync(prepIssueUserPath, 'utf-8');
110
- const registryContent = fs_1.default.readFileSync(prepIssueRegistryPath, 'utf-8');
111
- node_assert_1.default.strictEqual(userContent, registryContent, 'User script content should match registry');
112
- }
113
- console.log(' ✅ Script sync during init verified!');
114
- return true;
115
- }
116
- catch (error) {
117
- console.error(' ❌ Script sync test failed:', error);
118
- return false;
119
- }
120
- finally {
121
- try {
122
- fs_1.default.rmSync(tempDir, { recursive: true, force: true });
123
- if (fs_1.default.existsSync(userFraimDir)) {
124
- fs_1.default.rmSync(userFraimDir, { recursive: true, force: true });
125
- }
126
- }
127
- catch (e) { }
128
- }
129
- }
130
- async function testScriptExecutionFromUserDirectory() {
131
- console.log(' 🚀 Testing Script Execution From User Directory...');
132
- const tempProjectDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'fraim-project-test-'));
133
- const userFraimDir = path_1.default.join(os_1.default.homedir(), '.fraim-test');
134
- const userScriptsDir = path_1.default.join(userFraimDir, 'scripts');
135
- console.log(` 📂 Created temp project dir: ${tempProjectDir}`);
136
- console.log(` 🏠 Using test user dir: ${userFraimDir}`);
137
- try {
138
- // Clean up any existing test user directory
139
- if (fs_1.default.existsSync(userFraimDir)) {
140
- fs_1.default.rmSync(userFraimDir, { recursive: true, force: true });
141
- }
142
- // Create user scripts directory and copy a test script
143
- fs_1.default.mkdirSync(userScriptsDir, { recursive: true });
144
- // Create a simple test script that validates working directory behavior
145
- const testScript = `#!/bin/bash
146
- set -e
147
-
148
- # Validate we can find .fraim/config.json in working directory
149
- if [ ! -f ".fraim/config.json" ]; then
150
- echo "ERROR: Cannot find .fraim/config.json in working directory"
151
- exit 1
152
- fi
153
-
154
- # Output current working directory for validation
155
- echo "WORKING_DIR=$(pwd)"
156
-
157
- # Output script location for validation
158
- echo "SCRIPT_DIR=$(dirname "$0")"
159
-
160
- # Validate they are different (script in user dir, working in project dir)
161
- if [ "$(pwd)" = "$(dirname "$0")" ]; then
162
- echo "ERROR: Working directory should not be same as script directory"
163
- exit 1
164
- fi
165
-
166
- echo "SUCCESS: Script executed from user directory, operating on project directory"
167
- `;
168
- const testScriptPath = path_1.default.join(userScriptsDir, 'test-script.sh');
169
- fs_1.default.writeFileSync(testScriptPath, testScript);
170
- // Make script executable on Unix systems
171
- if (process.platform !== 'win32') {
172
- fs_1.default.chmodSync(testScriptPath, 0o755);
173
- }
174
- // Set up project directory with .fraim/config.json
175
- const projectFraimDir = path_1.default.join(tempProjectDir, '.fraim');
176
- fs_1.default.mkdirSync(projectFraimDir, { recursive: true });
177
- const testConfig = {
178
- project: { name: 'test-project' },
179
- git: { repoOwner: 'test', repoName: 'test-project' }
180
- };
181
- fs_1.default.writeFileSync(path_1.default.join(projectFraimDir, 'config.json'), JSON.stringify(testConfig, null, 2));
182
- // Execute script from project directory
183
- console.log(' Executing script from project directory...');
184
- const { execSync } = await Promise.resolve().then(() => __importStar(require('child_process')));
185
- // Use Git Bash on Windows, regular bash on Unix
186
- const bashCommand = process.platform === 'win32'
187
- ? `"C:\\Program Files\\Git\\bin\\bash.exe" "${testScriptPath}"`
188
- : `"${testScriptPath}"`;
189
- let output;
190
- try {
191
- output = execSync(bashCommand, {
192
- cwd: tempProjectDir,
193
- encoding: 'utf-8'
194
- });
195
- }
196
- catch (error) {
197
- // If Git Bash not found on Windows, skip this test
198
- if (process.platform === 'win32' && error.message.includes('not recognized')) {
199
- console.log(' ⚠️ Git Bash not found on Windows, skipping script execution test');
200
- return true;
201
- }
202
- throw error;
203
- }
204
- // Validate output
205
- node_assert_1.default.ok(output.includes('SUCCESS'), 'Script should execute successfully');
206
- // On Windows with Git Bash, paths get converted to Unix style
207
- // Extract the actual working directory from output
208
- const workingDirMatch = output.match(/WORKING_DIR=(.+)/);
209
- const scriptDirMatch = output.match(/SCRIPT_DIR=(.+)/);
210
- if (workingDirMatch && scriptDirMatch) {
211
- const actualWorkingDir = workingDirMatch[1].trim();
212
- const actualScriptDir = scriptDirMatch[1].trim();
213
- // Check that working directory and script directory are different
214
- node_assert_1.default.notStrictEqual(actualWorkingDir, actualScriptDir, 'Working directory should be different from script directory');
215
- // Check that script directory contains the expected user scripts path
216
- const normalizedUserScriptsDir = userScriptsDir.replace(/\\/g, '/');
217
- const hasCorrectScriptDir = actualScriptDir.includes('.fraim-test/scripts') ||
218
- actualScriptDir === userScriptsDir ||
219
- actualScriptDir === normalizedUserScriptsDir;
220
- node_assert_1.default.ok(hasCorrectScriptDir, `Script directory should be user scripts directory. Got: ${actualScriptDir}`);
221
- }
222
- else {
223
- throw new Error('Could not parse working directory and script directory from output');
224
- }
225
- console.log(' ✅ Script execution from user directory verified!');
226
- return true;
227
- }
228
- catch (error) {
229
- console.error(' ❌ Script execution test failed:', error);
230
- return false;
231
- }
232
- finally {
233
- try {
234
- fs_1.default.rmSync(tempProjectDir, { recursive: true, force: true });
235
- if (fs_1.default.existsSync(userFraimDir)) {
236
- fs_1.default.rmSync(userFraimDir, { recursive: true, force: true });
237
- }
238
- }
239
- catch (e) { }
240
- }
241
- }
242
- async function testScriptSyncDuringSync() {
243
- console.log(' 🚀 Testing Script Sync During Sync Command...');
244
- const tempDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'fraim-sync-test-'));
245
- const userFraimDir = path_1.default.join(os_1.default.homedir(), '.fraim-test');
246
- const userScriptsDir = path_1.default.join(userFraimDir, 'scripts');
247
- console.log(` 📂 Created temp dir: ${tempDir}`);
248
- try {
249
- // Clean up any existing test user directory
250
- if (fs_1.default.existsSync(userFraimDir)) {
251
- fs_1.default.rmSync(userFraimDir, { recursive: true, force: true });
252
- }
253
- const platform = process.platform;
254
- const npx = platform === 'win32' ? 'npx.cmd' : 'npx';
255
- const cliScript = (0, test_utils_1.resolveProjectPath)('dist/src/cli/fraim.js');
256
- const runFraim = (args) => {
257
- return new Promise((resolve) => {
258
- const ps = (0, node_child_process_1.spawn)(npx, ['node', `"${cliScript}"`, ...args], {
259
- cwd: tempDir,
260
- env: {
261
- ...process.env,
262
- TEST_MODE: 'true',
263
- FRAIM_USER_DIR: userFraimDir
264
- },
265
- shell: true
266
- });
267
- let stdout = '';
268
- let stderr = '';
269
- ps.stdout.on('data', d => stdout += d.toString());
270
- ps.stderr.on('data', d => stderr += d.toString());
271
- ps.on('close', (code) => {
272
- resolve({ stdout, stderr, code });
273
- });
274
- });
275
- };
276
- // Set up project
277
- const { execSync } = await Promise.resolve().then(() => __importStar(require('child_process')));
278
- execSync('git init', { cwd: tempDir });
279
- execSync('git remote add origin https://github.com/test-owner/test-project.git', { cwd: tempDir });
280
- // Initialize project first
281
- const initRes = await runFraim(['init']);
282
- node_assert_1.default.strictEqual(initRes.code, 0, 'Init should succeed');
283
- // Verify initial scripts exist
284
- node_assert_1.default.ok(fs_1.default.existsSync(userScriptsDir), 'User scripts directory should exist after init');
285
- // Modify a script to simulate an update
286
- const testScriptPath = path_1.default.join(userScriptsDir, 'prep-issue.sh');
287
- const originalContent = fs_1.default.readFileSync(testScriptPath, 'utf-8');
288
- const modifiedContent = originalContent + '\n# Modified for test';
289
- fs_1.default.writeFileSync(testScriptPath, modifiedContent);
290
- // Run sync command
291
- console.log(' Testing fraim sync with script updates...');
292
- const syncRes = await runFraim(['sync']);
293
- // Sync might succeed or warn depending on environment
294
- if (syncRes.code !== 0) {
295
- console.log(' ⚠️ Sync returned non-zero (environment dependent)');
296
- }
297
- // Verify script was restored to original content (simulating update from registry)
298
- // Note: In real implementation, this would compare versions and update if needed
299
- const currentContent = fs_1.default.readFileSync(testScriptPath, 'utf-8');
300
- // For now, just verify the file still exists and is readable
301
- node_assert_1.default.ok(currentContent.length > 0, 'Script should have content after sync');
302
- console.log(' ✅ Script sync during sync command verified!');
303
- return true;
304
- }
305
- catch (error) {
306
- console.error(' ❌ Script sync during sync test failed:', error);
307
- return false;
308
- }
309
- finally {
310
- try {
311
- fs_1.default.rmSync(tempDir, { recursive: true, force: true });
312
- if (fs_1.default.existsSync(userFraimDir)) {
313
- fs_1.default.rmSync(userFraimDir, { recursive: true, force: true });
314
- }
315
- }
316
- catch (e) { }
317
- }
318
- }
319
- async function testCrossPlatformScriptExecution() {
320
- console.log(' 🚀 Testing Cross-Platform Script Execution...');
321
- const tempProjectDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'fraim-cross-platform-test-'));
322
- const userFraimDir = path_1.default.join(os_1.default.homedir(), '.fraim-test');
323
- const userScriptsDir = path_1.default.join(userFraimDir, 'scripts');
324
- try {
325
- // Clean up any existing test user directory
326
- if (fs_1.default.existsSync(userFraimDir)) {
327
- fs_1.default.rmSync(userFraimDir, { recursive: true, force: true });
328
- }
329
- // Create user scripts directory
330
- fs_1.default.mkdirSync(userScriptsDir, { recursive: true });
331
- // Create cross-platform test script
332
- const crossPlatformScript = `#!/bin/bash
333
- set -e
334
-
335
- # Test cross-platform path handling
336
- echo "Platform: $(uname -s 2>/dev/null || echo "Windows")"
337
- echo "Working Directory: $(pwd)"
338
- echo "Script Directory: $(dirname "$0")"
339
-
340
- # Test config file access
341
- if [ -f ".fraim/config.json" ]; then
342
- echo "Config found: YES"
343
- else
344
- echo "Config found: NO"
345
- exit 1
346
- fi
347
-
348
- # Test that we can create files in working directory
349
- echo "test content" > test-output.txt
350
- if [ -f "test-output.txt" ]; then
351
- echo "File creation: SUCCESS"
352
- rm test-output.txt
353
- else
354
- echo "File creation: FAILED"
355
- exit 1
356
- fi
357
-
358
- echo "Cross-platform test: SUCCESS"
359
- `;
360
- const scriptPath = path_1.default.join(userScriptsDir, 'cross-platform-test.sh');
361
- fs_1.default.writeFileSync(scriptPath, crossPlatformScript);
362
- // Set executable permissions on Unix
363
- if (process.platform !== 'win32') {
364
- fs_1.default.chmodSync(scriptPath, 0o755);
365
- }
366
- // Set up project directory
367
- const projectFraimDir = path_1.default.join(tempProjectDir, '.fraim');
368
- fs_1.default.mkdirSync(projectFraimDir, { recursive: true });
369
- const testConfig = { project: { name: 'cross-platform-test' } };
370
- fs_1.default.writeFileSync(path_1.default.join(projectFraimDir, 'config.json'), JSON.stringify(testConfig));
371
- // Execute script
372
- console.log(' Executing cross-platform script...');
373
- const { execSync } = await Promise.resolve().then(() => __importStar(require('child_process')));
374
- // Use Git Bash on Windows, regular bash on Unix
375
- const bashCommand = process.platform === 'win32'
376
- ? `"C:\\Program Files\\Git\\bin\\bash.exe" "${scriptPath}"`
377
- : `"${scriptPath}"`;
378
- let output;
379
- try {
380
- output = execSync(bashCommand, {
381
- cwd: tempProjectDir,
382
- encoding: 'utf-8'
383
- });
384
- }
385
- catch (error) {
386
- // If Git Bash not found on Windows, skip this test
387
- if (process.platform === 'win32' && error.message.includes('not recognized')) {
388
- console.log(' ⚠️ Git Bash not found on Windows, skipping cross-platform test');
389
- return true;
390
- }
391
- throw error;
392
- }
393
- // Validate output
394
- node_assert_1.default.ok(output.includes('Cross-platform test: SUCCESS'), 'Cross-platform test should succeed');
395
- node_assert_1.default.ok(output.includes('Config found: YES'), 'Should find config file');
396
- node_assert_1.default.ok(output.includes('File creation: SUCCESS'), 'Should be able to create files');
397
- console.log(' ✅ Cross-platform script execution verified!');
398
- return true;
399
- }
400
- catch (error) {
401
- console.error(' ❌ Cross-platform test failed:', error);
402
- return false;
403
- }
404
- finally {
405
- try {
406
- fs_1.default.rmSync(tempProjectDir, { recursive: true, force: true });
407
- if (fs_1.default.existsSync(userFraimDir)) {
408
- fs_1.default.rmSync(userFraimDir, { recursive: true, force: true });
409
- }
410
- }
411
- catch (e) { }
412
- }
413
- }
414
- async function testNestedDirectoryExecution() {
415
- console.log(' 🚀 Testing Nested Directory Execution...');
416
- const tempProjectDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'fraim-nested-test-'));
417
- const userFraimDir = path_1.default.join(os_1.default.homedir(), '.fraim-test');
418
- const userScriptsDir = path_1.default.join(userFraimDir, 'scripts');
419
- try {
420
- // Clean up and setup
421
- if (fs_1.default.existsSync(userFraimDir)) {
422
- fs_1.default.rmSync(userFraimDir, { recursive: true, force: true });
423
- }
424
- fs_1.default.mkdirSync(userScriptsDir, { recursive: true });
425
- // Create script that finds project root
426
- const rootFinderScript = `#!/bin/bash
427
- set -e
428
-
429
- # Function to find project root (directory containing .fraim/config.json)
430
- find_project_root() {
431
- local current_dir="$(pwd)"
432
- while [ "$current_dir" != "/" ] && [ "$current_dir" != "" ]; do
433
- if [ -f "$current_dir/.fraim/config.json" ]; then
434
- echo "$current_dir"
435
- return 0
436
- fi
437
- current_dir="$(dirname "$current_dir")"
438
- done
439
- return 1
440
- }
441
-
442
- echo "Current working directory: $(pwd)"
443
- echo "Script directory: $(dirname "$0")"
444
-
445
- # Find project root
446
- PROJECT_ROOT=$(find_project_root)
447
- if [ $? -eq 0 ]; then
448
- echo "Project root found: $PROJECT_ROOT"
449
- echo "Config exists: $([ -f "$PROJECT_ROOT/.fraim/config.json" ] && echo "YES" || echo "NO")"
450
- else
451
- echo "ERROR: Could not find project root"
452
- exit 1
453
- fi
454
-
455
- echo "Nested execution test: SUCCESS"
456
- `;
457
- const scriptPath = path_1.default.join(userScriptsDir, 'nested-test.sh');
458
- fs_1.default.writeFileSync(scriptPath, rootFinderScript);
459
- if (process.platform !== 'win32') {
460
- fs_1.default.chmodSync(scriptPath, 0o755);
461
- }
462
- // Set up project with nested directories
463
- const projectFraimDir = path_1.default.join(tempProjectDir, '.fraim');
464
- const nestedDir = path_1.default.join(tempProjectDir, 'src', 'components', 'deep');
465
- fs_1.default.mkdirSync(projectFraimDir, { recursive: true });
466
- fs_1.default.mkdirSync(nestedDir, { recursive: true });
467
- const testConfig = { project: { name: 'nested-test' } };
468
- fs_1.default.writeFileSync(path_1.default.join(projectFraimDir, 'config.json'), JSON.stringify(testConfig));
469
- // Execute script from nested directory
470
- console.log(' Executing script from nested directory...');
471
- const { execSync } = await Promise.resolve().then(() => __importStar(require('child_process')));
472
- // Use Git Bash on Windows, regular bash on Unix
473
- const bashCommand = process.platform === 'win32'
474
- ? `"C:\\Program Files\\Git\\bin\\bash.exe" "${scriptPath}"`
475
- : `"${scriptPath}"`;
476
- let output;
477
- try {
478
- output = execSync(bashCommand, {
479
- cwd: nestedDir,
480
- encoding: 'utf-8'
481
- });
482
- }
483
- catch (error) {
484
- // If Git Bash not found on Windows, skip this test
485
- if (process.platform === 'win32' && error.message.includes('not recognized')) {
486
- console.log(' ⚠️ Git Bash not found on Windows, skipping nested directory test');
487
- return true;
488
- }
489
- throw error;
490
- }
491
- // Validate output
492
- node_assert_1.default.ok(output.includes('Nested execution test: SUCCESS'), 'Nested execution should succeed');
493
- // Extract the actual project root from output (Git Bash may convert paths)
494
- const projectRootMatch = output.match(/Project root found: (.+)/);
495
- if (projectRootMatch) {
496
- const actualProjectRoot = projectRootMatch[1].trim();
497
- // Check that the project root contains the expected directory name
498
- const projectDirName = path_1.default.basename(tempProjectDir);
499
- node_assert_1.default.ok(actualProjectRoot.includes(projectDirName), `Should find project directory. Got: ${actualProjectRoot}, Expected to contain: ${projectDirName}`);
500
- }
501
- else {
502
- throw new Error('Could not parse project root from output');
503
- }
504
- node_assert_1.default.ok(output.includes('Config exists: YES'), 'Should find config in project root');
505
- console.log(' ✅ Nested directory execution verified!');
506
- return true;
507
- }
508
- catch (error) {
509
- console.error(' ❌ Nested directory test failed:', error);
510
- return false;
511
- }
512
- finally {
513
- try {
514
- fs_1.default.rmSync(tempProjectDir, { recursive: true, force: true });
515
- if (fs_1.default.existsSync(userFraimDir)) {
516
- fs_1.default.rmSync(userFraimDir, { recursive: true, force: true });
517
- }
518
- }
519
- catch (e) { }
520
- }
521
- }
522
- async function runScriptSyncTest(testCase) {
523
- return await testCase.testFunction();
524
- }
525
- const testCases = [
526
- {
527
- name: 'Script Sync During Init',
528
- description: 'Tests that fraim init copies scripts to user directory with correct permissions',
529
- testFunction: testScriptSyncDuringInit,
530
- tags: ['script-sync', 'init']
531
- },
532
- {
533
- name: 'Script Execution From User Directory',
534
- description: 'Tests that scripts execute from user directory but operate on project directory',
535
- testFunction: testScriptExecutionFromUserDirectory,
536
- tags: ['script-sync', 'execution']
537
- },
538
- {
539
- name: 'Script Sync During Sync Command',
540
- description: 'Tests that fraim sync updates scripts in user directory',
541
- testFunction: testScriptSyncDuringSync,
542
- tags: ['script-sync', 'sync']
543
- },
544
- {
545
- name: 'Cross-Platform Script Execution',
546
- description: 'Tests that scripts work correctly on Windows, macOS, and Linux',
547
- testFunction: testCrossPlatformScriptExecution,
548
- tags: ['script-sync', 'cross-platform']
549
- },
550
- {
551
- name: 'Nested Directory Execution',
552
- description: 'Tests that scripts work when executed from nested project directories',
553
- testFunction: testNestedDirectoryExecution,
554
- tags: ['script-sync', 'nested']
555
- }
556
- ];
557
- (0, test_utils_1.runTests)(testCases, runScriptSyncTest, 'Script Synchronization Tests');
@@ -1,32 +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.getServerScriptPath = getServerScriptPath;
7
- const path_1 = __importDefault(require("path"));
8
- const fs_1 = __importDefault(require("fs"));
9
- /**
10
- * Utility function to get the correct server script path
11
- * Handles different execution contexts (running from project root, tests directory, etc.)
12
- */
13
- function getServerScriptPath() {
14
- // Try to find the server script from various possible locations
15
- const possiblePaths = [
16
- path_1.default.resolve(__dirname, '../dist/src/fraim-mcp-server.js'),
17
- path_1.default.resolve(process.cwd(), 'dist/src/fraim-mcp-server.js'),
18
- path_1.default.resolve(__dirname, '../../dist/src/fraim-mcp-server.js'),
19
- path_1.default.resolve(__dirname, '../../../dist/src/fraim-mcp-server.js')
20
- ];
21
- for (const scriptPath of possiblePaths) {
22
- if (fs_1.default.existsSync(scriptPath)) {
23
- console.log(` 📍 Found server script at: ${scriptPath}`);
24
- return scriptPath;
25
- }
26
- }
27
- // If none found, log all attempted paths and use the first one
28
- console.warn(' ⚠️ Server script not found at any of these paths:');
29
- possiblePaths.forEach(p => console.warn(` ${p}`));
30
- console.warn(' Using first path (may fail)...');
31
- return possiblePaths[0];
32
- }