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
@@ -0,0 +1,172 @@
1
+ /* Professional PDF Styling for Business Documents */
2
+
3
+ body {
4
+ font-family: 'Times New Roman', 'Georgia', serif;
5
+ font-size: 11pt;
6
+ line-height: 1.4;
7
+ color: #333;
8
+ margin: 0;
9
+ padding: 0;
10
+ }
11
+
12
+ /* Headers */
13
+ h1 {
14
+ font-size: 18pt;
15
+ font-weight: bold;
16
+ color: #2c3e50;
17
+ margin: 20pt 0 12pt 0;
18
+ border-bottom: 2px solid #3498db;
19
+ padding-bottom: 6pt;
20
+ }
21
+
22
+ h2 {
23
+ font-size: 14pt;
24
+ font-weight: bold;
25
+ color: #34495e;
26
+ margin: 16pt 0 8pt 0;
27
+ }
28
+
29
+ h3 {
30
+ font-size: 12pt;
31
+ font-weight: bold;
32
+ color: #34495e;
33
+ margin: 12pt 0 6pt 0;
34
+ }
35
+
36
+ /* Paragraphs */
37
+ p {
38
+ margin: 6pt 0;
39
+ text-align: justify;
40
+ }
41
+
42
+ /* Lists */
43
+ ul, ol {
44
+ margin: 6pt 0;
45
+ padding-left: 20pt;
46
+ }
47
+
48
+ li {
49
+ margin: 3pt 0;
50
+ }
51
+
52
+ /* Tables */
53
+ table {
54
+ border-collapse: collapse;
55
+ width: 100%;
56
+ margin: 12pt 0;
57
+ font-size: 10pt;
58
+ }
59
+
60
+ th, td {
61
+ border: 1px solid #ddd;
62
+ padding: 6pt 8pt;
63
+ text-align: left;
64
+ }
65
+
66
+ th {
67
+ background-color: #f8f9fa;
68
+ font-weight: bold;
69
+ }
70
+
71
+ /* Code blocks */
72
+ code {
73
+ font-family: 'Courier New', monospace;
74
+ font-size: 9pt;
75
+ background-color: #f8f9fa;
76
+ padding: 2pt 4pt;
77
+ border: 1px solid #e9ecef;
78
+ border-radius: 2pt;
79
+ }
80
+
81
+ pre {
82
+ font-family: 'Courier New', monospace;
83
+ font-size: 9pt;
84
+ background-color: #f8f9fa;
85
+ padding: 8pt;
86
+ border: 1px solid #e9ecef;
87
+ border-radius: 4pt;
88
+ overflow-x: auto;
89
+ margin: 8pt 0;
90
+ }
91
+
92
+ /* Blockquotes */
93
+ blockquote {
94
+ margin: 8pt 0;
95
+ padding: 8pt 12pt;
96
+ border-left: 4pt solid #3498db;
97
+ background-color: #f8f9fa;
98
+ font-style: italic;
99
+ }
100
+
101
+ /* Horizontal rules */
102
+ hr {
103
+ border: none;
104
+ border-top: 1px solid #bdc3c7;
105
+ margin: 16pt 0;
106
+ }
107
+
108
+ /* Strong and emphasis */
109
+ strong, b {
110
+ font-weight: bold;
111
+ }
112
+
113
+ em, i {
114
+ font-style: italic;
115
+ }
116
+
117
+ /* Page settings */
118
+ @page {
119
+ size: A4;
120
+ margin: 1in;
121
+
122
+ @top-center {
123
+ content: "";
124
+ font-size: 9pt;
125
+ color: #7f8c8d;
126
+ }
127
+
128
+ @bottom-center {
129
+ content: "Page " counter(page) " of " counter(pages);
130
+ font-size: 9pt;
131
+ color: #7f8c8d;
132
+ }
133
+ }
134
+
135
+ /* Print-specific adjustments */
136
+ @media print {
137
+ body {
138
+ font-size: 10pt;
139
+ }
140
+
141
+ h1 {
142
+ font-size: 16pt;
143
+ }
144
+
145
+ h2 {
146
+ font-size: 13pt;
147
+ }
148
+
149
+ h3 {
150
+ font-size: 11pt;
151
+ }
152
+ }
153
+
154
+ /* Signature sections */
155
+ .signature-section {
156
+ margin-top: 24pt;
157
+ page-break-inside: avoid;
158
+ }
159
+
160
+ /* Contact information */
161
+ .contact-info {
162
+ font-size: 10pt;
163
+ margin-top: 16pt;
164
+ }
165
+
166
+ /* Legal text formatting */
167
+ .legal-text {
168
+ font-size: 10pt;
169
+ text-transform: uppercase;
170
+ font-weight: bold;
171
+ margin: 12pt 0;
172
+ }
@@ -153,21 +153,63 @@ try {
153
153
  } else {
154
154
  // Extract defaultBranch from repository config
155
155
  defaultBranch = repo.defaultBranch || 'master';
156
+ // Ensure URL is present - construct it if missing
157
+ if (!repo.url && repo.owner && repo.name) {
158
+ repo.url = \`https://github.com/\${repo.owner}/\${repo.name}.git\`;
159
+ }
156
160
  }
157
161
 
158
- if (!repo || !repo.owner || !repo.name || !repo.url) {
162
+ if (!repo || !repo.owner || !repo.name) {
163
+ console.error('āŒ Config validation failed: Missing required repository fields');
164
+ console.error(' Required: repository.owner, repository.name');
165
+ console.error(' Found in config:', JSON.stringify(repo, null, 2));
159
166
  process.exit(1);
160
167
  }
168
+
169
+ if (!repo.url) {
170
+ console.error('āŒ Config validation failed: Missing repository.url field');
171
+ console.error(' This field is required for cloning the repository');
172
+ console.error(' Expected format: https://github.com/owner/repo.git');
173
+ console.error(' Current config:', JSON.stringify(repo, null, 2));
174
+ console.error('');
175
+ console.error('šŸ’” To fix this:');
176
+ console.error(' 1. Add \"url\": \"https://github.com/\${repo.owner}/\${repo.name}.git\" to your .fraim/config.json');
177
+ console.error(' 2. Or run: fraim init-project (if using FRAIM CLI)');
178
+ process.exit(1);
179
+ }
180
+
161
181
  console.log(\`\${repo.owner}|\${repo.name}|\${repo.url}|\${defaultBranch}\`);
162
182
  } catch (e) {
183
+ console.error('āŒ Failed to parse .fraim/config.json');
184
+ console.error(' Error:', e.message);
185
+ console.error('');
186
+ console.error('šŸ’” Common issues:');
187
+ console.error(' • Invalid JSON syntax');
188
+ console.error(' • Missing required fields: repository.owner, repository.name, repository.url');
189
+ console.error(' • File encoding issues');
190
+ console.error('');
191
+ console.error('šŸ“ Expected config format:');
192
+ console.error('{');
193
+ console.error(' \"repository\": {');
194
+ console.error(' \"provider\": \"github\",');
195
+ console.error(' \"owner\": \"your-username\",');
196
+ console.error(' \"name\": \"your-repo\",');
197
+ console.error(' \"url\": \"https://github.com/your-username/your-repo.git\",');
198
+ console.error(' \"defaultBranch\": \"main\"');
199
+ console.error(' }');
200
+ console.error('}');
163
201
  process.exit(1);
164
202
  }
165
203
  "
166
204
 
167
- REPO_INFO=$(cat "$CONFIG_FILE" | node -e "$NODE_SCRIPT")
205
+ REPO_INFO=$(cat "$CONFIG_FILE" | node -e "$NODE_SCRIPT" 2>&1)
168
206
  if [ $? -ne 0 ]; then
169
- echo "Error: Failed to parse repository config from $CONFIG_FILE" >&2
170
- echo "Required: repository.owner, repository.name, repository.url" >&2
207
+ echo "$REPO_INFO" >&2
208
+ echo "" >&2
209
+ echo "šŸ”§ To fix this issue:" >&2
210
+ echo " 1. Check your .fraim/config.json file" >&2
211
+ echo " 2. Ensure it has the required repository fields" >&2
212
+ echo " 3. Run 'fraim init-project' to regenerate the config" >&2
171
213
  exit 1
172
214
  fi
173
215
 
@@ -45,9 +45,9 @@ function getEnvOr(keys: string[], fallback: string): string {
45
45
  }
46
46
 
47
47
  interface ProfilingConfig {
48
- env: 'prod' | 'preprod' | 'local';
49
- appName: string;
50
- resourceGroup: string;
48
+ env: 'prod' | 'preprod' | 'local';
49
+ appName: string;
50
+ resourceGroup: string;
51
51
  }
52
52
 
53
53
  function checkAzureCLI(): boolean {
@@ -71,7 +71,7 @@ function checkAzureAuth(): boolean {
71
71
  async function getAppServicePlanMetrics(appName: string, resourceGroup: string): Promise<void> {
72
72
  try {
73
73
  console.log('\n--- ā˜ļø App Service Plan Metrics ---');
74
-
74
+
75
75
  // Get App Service Plan ID
76
76
  const planIdCmd = `az webapp show --name ${appName} --resource-group ${resourceGroup} --query "appServicePlanId" -o tsv`;
77
77
  const planId = execSync(planIdCmd, { encoding: 'utf8' }).trim();
@@ -81,10 +81,10 @@ async function getAppServicePlanMetrics(appName: string, resourceGroup: string):
81
81
  // Get CPU and Memory metrics for last 5 minutes
82
82
  console.log('šŸ“Š Fetching CPU and Memory metrics (last 5 minutes)...');
83
83
  const metricsCmd = `az monitor metrics list --resource "${planId}" --metrics CpuPercentage MemoryPercentage --interval PT1M --query "value[].{name:name.value, data:timeseries[0].data}" -o json`;
84
-
84
+
85
85
  const metricsOutput = execSync(metricsCmd, { encoding: 'utf8' });
86
86
  const metrics = JSON.parse(metricsOutput);
87
-
87
+
88
88
  for (const metric of metrics) {
89
89
  const latestData = metric.data[metric.data.length - 1];
90
90
  const value = latestData?.average || latestData?.total || 'N/A';
@@ -98,24 +98,25 @@ async function getAppServicePlanMetrics(appName: string, resourceGroup: string):
98
98
  async function getAppServiceMetrics(appName: string, resourceGroup: string): Promise<void> {
99
99
  try {
100
100
  console.log('\n--- šŸ–„ļø App Service Metrics ---');
101
-
101
+
102
102
  // Get subscription ID
103
103
  const subscriptionId = execSync('az account show --query id -o tsv', { encoding: 'utf8' }).trim();
104
-
104
+
105
105
  // Get app-level metrics using Azure CLI
106
106
  console.log('šŸ“Š Fetching App Service metrics (last 5 minutes)...');
107
- const appResourceId = `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}/providers/Microsoft.Web/sites/${appName}`;
108
-
107
+ const root = '/';
108
+ const appResourceId = `${root}subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}/providers/Microsoft.Web/sites/${appName}`;
109
+
109
110
  const appMetricsCmd = `az monitor metrics list --resource "${appResourceId}" --metrics CpuTime Requests Http2xx Http4xx Http5xx --interval PT1M --query "value[].{name:name.value, data:timeseries[0].data}" -o json`;
110
-
111
+
111
112
  const appMetricsOutput = execSync(appMetricsCmd, { encoding: 'utf8' });
112
113
  const appMetrics = JSON.parse(appMetricsOutput);
113
-
114
+
114
115
  for (const metric of appMetrics) {
115
116
  const latestData = metric.data[metric.data.length - 1];
116
117
  const value = latestData?.total || latestData?.average || 'N/A';
117
118
  let displayValue = value;
118
-
119
+
119
120
  if (typeof value === 'number') {
120
121
  if (metric.name === 'CpuTime') {
121
122
  displayValue = `${value.toFixed(2)}s`;
@@ -123,7 +124,7 @@ async function getAppServiceMetrics(appName: string, resourceGroup: string): Pro
123
124
  displayValue = value.toString();
124
125
  }
125
126
  }
126
-
127
+
127
128
  console.log(` ${metric.name}: ${displayValue}`);
128
129
  }
129
130
  } catch (error: any) {
@@ -134,41 +135,41 @@ async function getAppServiceMetrics(appName: string, resourceGroup: string): Pro
134
135
  async function getProcessInformation(appName: string): Promise<void> {
135
136
  try {
136
137
  console.log('\n--- āš™ļø Process Information (Kudu API) ---');
137
-
138
+
138
139
  // Get access token for Kudu API
139
140
  const token = execSync('az account get-access-token --resource https://management.azure.com/ --query accessToken -o tsv', { encoding: 'utf8' }).trim();
140
-
141
+
141
142
  // Import axios dynamically
142
143
  const axios = (await import('axios')).default;
143
-
144
+
144
145
  // Get process list from Kudu
145
146
  console.log('šŸ“‹ Fetching running processes...');
146
147
  const processResponse = await axios.get(`https://${appName}.scm.azurewebsites.net/api/processes`, {
147
148
  headers: { Authorization: `Bearer ${token}` },
148
149
  timeout: 10000
149
150
  });
150
-
151
+
151
152
  const processes = processResponse.data;
152
-
153
+
153
154
  // Sort by CPU usage and show top processes
154
155
  const sortedProcesses = processes
155
156
  .filter((p: any) => p.cpu_usage !== undefined)
156
157
  .sort((a: any, b: any) => (b.cpu_usage || 0) - (a.cpu_usage || 0))
157
158
  .slice(0, 10);
158
-
159
+
159
160
  console.log('\nšŸ”„ Top 10 Processes by CPU Usage:');
160
161
  console.log('PID\tCPU%\tMemory(MB)\tName');
161
162
  console.log('---\t----\t---------\t----');
162
-
163
+
163
164
  for (const process of sortedProcesses) {
164
165
  const pid = process.id || 'N/A';
165
166
  const cpu = process.cpu_usage ? process.cpu_usage.toFixed(2) : '0.00';
166
167
  const memory = process.working_set ? (process.working_set / 1024 / 1024).toFixed(1) : 'N/A';
167
168
  const name = process.name || 'Unknown';
168
-
169
+
169
170
  console.log(`${pid}\t${cpu}\t${memory}\t\t${name.substring(0, 30)}`);
170
171
  }
171
-
172
+
172
173
  } catch (error: any) {
173
174
  console.log(`āš ļø Could not fetch process information: ${error.message.split('\n')[0]}`);
174
175
  console.log(' This might be due to authentication issues or Kudu API being unavailable.');
@@ -178,39 +179,39 @@ async function getProcessInformation(appName: string): Promise<void> {
178
179
  async function getSystemInformation(appName: string): Promise<void> {
179
180
  try {
180
181
  console.log('\n--- šŸ–„ļø System Information ---');
181
-
182
+
182
183
  const token = execSync('az account get-access-token --resource https://management.azure.com/ --query accessToken -o tsv', { encoding: 'utf8' }).trim();
183
184
  const axios = (await import('axios')).default;
184
-
185
+
185
186
  // Get system info using Kudu command API
186
187
  console.log('šŸ“Š Fetching system information...');
187
-
188
+
188
189
  const commands = [
189
190
  { name: 'Memory Info', cmd: 'cat /proc/meminfo | head -10' },
190
191
  { name: 'CPU Info', cmd: 'cat /proc/cpuinfo | grep "model name" | head -1' },
191
192
  { name: 'Disk Usage', cmd: 'df -h | head -5' },
192
193
  { name: 'Load Average', cmd: 'uptime' }
193
194
  ];
194
-
195
+
195
196
  for (const command of commands) {
196
197
  try {
197
198
  const response = await axios.post(`https://${appName}.scm.azurewebsites.net/api/command`, {
198
199
  command: command.cmd,
199
- dir: path.join('/', 'home')
200
+ dir: path.join(path.sep, 'home')
200
201
  }, {
201
202
  headers: { Authorization: `Bearer ${token}` },
202
203
  timeout: 5000
203
204
  });
204
-
205
+
205
206
  console.log(`\n${command.name}:`);
206
207
  const output = response.data.Output || response.data.Error || 'No output';
207
208
  console.log(output.split('\n').map((line: string) => ` ${line}`).join('\n'));
208
-
209
+
209
210
  } catch (cmdError: any) {
210
211
  console.log(`\n${command.name}: Could not retrieve (${cmdError.message.split('\n')[0]})`);
211
212
  }
212
213
  }
213
-
214
+
214
215
  } catch (error: any) {
215
216
  console.log(`āš ļø Could not fetch system information: ${error.message.split('\n')[0]}`);
216
217
  }
@@ -219,11 +220,11 @@ async function getSystemInformation(appName: string): Promise<void> {
219
220
  async function getApplicationLogs(appName: string, resourceGroup: string): Promise<void> {
220
221
  try {
221
222
  console.log('\n--- šŸ“‹ Recent Application Logs ---');
222
-
223
+
223
224
  // Get recent logs using Azure CLI
224
225
  console.log('šŸ“„ Fetching recent application logs...');
225
226
  const logsCmd = `az webapp log tail --name ${appName} --resource-group ${resourceGroup} --provider application --timeout 5`;
226
-
227
+
227
228
  try {
228
229
  const logs = execSync(logsCmd, { encoding: 'utf8', timeout: 10000 });
229
230
  console.log('Recent logs:');
@@ -232,7 +233,7 @@ async function getApplicationLogs(appName: string, resourceGroup: string): Promi
232
233
  console.log('āš ļø Could not fetch logs - they may not be enabled or available');
233
234
  console.log(' Enable application logging in Azure portal for better diagnostics');
234
235
  }
235
-
236
+
236
237
  } catch (error: any) {
237
238
  console.log(`āš ļø Could not fetch application logs: ${error.message.split('\n')[0]}`);
238
239
  }
@@ -240,11 +241,11 @@ async function getApplicationLogs(appName: string, resourceGroup: string): Promi
240
241
 
241
242
  async function profileLocalEnvironment(): Promise<void> {
242
243
  console.log('\n--- šŸ  Local Environment Profiling ---');
243
-
244
+
244
245
  try {
245
246
  // Basic system information
246
247
  console.log('šŸ’» System Information:');
247
-
248
+
248
249
  if (process.platform === 'win32') {
249
250
  try {
250
251
  const systemInfo = execSync('systeminfo | findstr /C:"Total Physical Memory" /C:"Available Physical Memory" /C:"Processor"', { encoding: 'utf8' });
@@ -264,7 +265,7 @@ async function profileLocalEnvironment(): Promise<void> {
264
265
  console.log(' Could not retrieve Linux system info');
265
266
  }
266
267
  }
267
-
268
+
268
269
  // Node.js process information
269
270
  console.log('\n🟢 Node.js Process Information:');
270
271
  console.log(` Node Version: ${process.version}`);
@@ -276,49 +277,49 @@ async function profileLocalEnvironment(): Promise<void> {
276
277
  console.log(` Heap Used: ${(memUsage.heapUsed / 1024 / 1024).toFixed(2)} MB`);
277
278
  console.log(` Heap Total: ${(memUsage.heapTotal / 1024 / 1024).toFixed(2)} MB`);
278
279
  console.log(` External: ${(memUsage.external / 1024 / 1024).toFixed(2)} MB`);
279
-
280
+
280
281
  } catch (error: any) {
281
282
  console.log(`āš ļø Error profiling local environment: ${error.message}`);
282
283
  }
283
284
  }
284
285
 
285
286
  async function main() {
286
- const config = loadClientConfig();
287
-
288
- // Azure configuration with environment variable fallbacks
289
- const azureConfig = {
290
- prodAppName: config.azure?.prodAppName || getEnvOr(['FRAIM_AZURE_PROD_APP_NAME'], 'fraim-app-prod'),
291
- prodResourceGroup: config.azure?.prodResourceGroup || getEnvOr(['FRAIM_AZURE_PROD_RESOURCE_GROUP'], 'fraim-prod-rg'),
292
- preprodAppName: config.azure?.preprodAppName || getEnvOr(['FRAIM_AZURE_PREPROD_APP_NAME'], 'fraim-app-pre-prod'),
293
- preprodResourceGroup: config.azure?.preprodResourceGroup || getEnvOr(['FRAIM_AZURE_PREPROD_RESOURCE_GROUP'], 'fraim-pre-prod-rg'),
294
- localAppName: config.azure?.localAppName || getEnvOr(['FRAIM_AZURE_LOCAL_APP_NAME'], 'local'),
295
- localResourceGroup: config.azure?.localResourceGroup || getEnvOr(['FRAIM_AZURE_LOCAL_RESOURCE_GROUP'], 'local')
296
- };
297
-
298
- const CONFIGS: Record<string, ProfilingConfig> = {
299
- prod: {
300
- env: 'prod',
301
- appName: azureConfig.prodAppName,
302
- resourceGroup: azureConfig.prodResourceGroup
303
- },
304
- preprod: {
305
- env: 'preprod',
306
- appName: azureConfig.preprodAppName,
307
- resourceGroup: azureConfig.preprodResourceGroup
308
- },
309
- local: {
310
- env: 'local',
311
- appName: azureConfig.localAppName,
312
- resourceGroup: azureConfig.localResourceGroup
313
- }
314
- };
287
+ const config = loadClientConfig();
288
+
289
+ // Azure configuration with environment variable fallbacks
290
+ const azureConfig = {
291
+ prodAppName: config.azure?.prodAppName || getEnvOr(['FRAIM_AZURE_PROD_APP_NAME'], 'fraim-app-prod'),
292
+ prodResourceGroup: config.azure?.prodResourceGroup || getEnvOr(['FRAIM_AZURE_PROD_RESOURCE_GROUP'], 'fraim-prod-rg'),
293
+ preprodAppName: config.azure?.preprodAppName || getEnvOr(['FRAIM_AZURE_PREPROD_APP_NAME'], 'fraim-app-pre-prod'),
294
+ preprodResourceGroup: config.azure?.preprodResourceGroup || getEnvOr(['FRAIM_AZURE_PREPROD_RESOURCE_GROUP'], 'fraim-pre-prod-rg'),
295
+ localAppName: config.azure?.localAppName || getEnvOr(['FRAIM_AZURE_LOCAL_APP_NAME'], 'local'),
296
+ localResourceGroup: config.azure?.localResourceGroup || getEnvOr(['FRAIM_AZURE_LOCAL_RESOURCE_GROUP'], 'local')
297
+ };
298
+
299
+ const CONFIGS: Record<string, ProfilingConfig> = {
300
+ prod: {
301
+ env: 'prod',
302
+ appName: azureConfig.prodAppName,
303
+ resourceGroup: azureConfig.prodResourceGroup
304
+ },
305
+ preprod: {
306
+ env: 'preprod',
307
+ appName: azureConfig.preprodAppName,
308
+ resourceGroup: azureConfig.preprodResourceGroup
309
+ },
310
+ local: {
311
+ env: 'local',
312
+ appName: azureConfig.localAppName,
313
+ resourceGroup: azureConfig.localResourceGroup
314
+ }
315
+ };
315
316
 
316
- const args = process.argv.slice(2);
317
- let profileConfig: ProfilingConfig = CONFIGS.local;
318
- const includeLogs = args.includes('--logs');
317
+ const args = process.argv.slice(2);
318
+ let profileConfig: ProfilingConfig = CONFIGS.local;
319
+ const includeLogs = args.includes('--logs');
319
320
 
320
- if (args.includes('--help') || args.includes('-h')) {
321
- console.log(`
321
+ if (args.includes('--help') || args.includes('-h')) {
322
+ console.log(`
322
323
  šŸ” Azure App Service Profiler
323
324
 
324
325
  Usage:
@@ -353,72 +354,72 @@ Configuration:
353
354
  - FRAIM_AZURE_PREPROD_APP_NAME
354
355
  - FRAIM_AZURE_PREPROD_RESOURCE_GROUP
355
356
  `);
356
- return;
357
- }
357
+ return;
358
+ }
358
359
 
359
- if (args.includes('--prod')) profileConfig = CONFIGS.prod;
360
- else if (args.includes('--preprod')) profileConfig = CONFIGS.preprod;
361
- else if (args.includes('--local')) profileConfig = CONFIGS.local;
360
+ if (args.includes('--prod')) profileConfig = CONFIGS.prod;
361
+ else if (args.includes('--preprod')) profileConfig = CONFIGS.preprod;
362
+ else if (args.includes('--local')) profileConfig = CONFIGS.local;
362
363
 
363
- console.log(`\nšŸš€ Starting Server Profiling`);
364
- console.log(`šŸ“Š Environment: ${profileConfig.env.toUpperCase()}`);
365
- console.log(`šŸ·ļø App: ${profileConfig.appName}`);
366
- console.log(`šŸ“ Resource Group: ${profileConfig.resourceGroup}`);
364
+ console.log(`\nšŸš€ Starting Server Profiling`);
365
+ console.log(`šŸ“Š Environment: ${profileConfig.env.toUpperCase()}`);
366
+ console.log(`šŸ·ļø App: ${profileConfig.appName}`);
367
+ console.log(`šŸ“ Resource Group: ${profileConfig.resourceGroup}`);
367
368
 
368
- if (profileConfig.env === 'local') {
369
- await profileLocalEnvironment();
370
- console.log('\nāœ… Local profiling completed');
371
- return;
372
- }
369
+ if (profileConfig.env === 'local') {
370
+ await profileLocalEnvironment();
371
+ console.log('\nāœ… Local profiling completed');
372
+ return;
373
+ }
373
374
 
374
- // Check prerequisites for Azure profiling
375
- console.log('\nšŸ” Checking prerequisites...');
376
-
377
- if (!checkAzureCLI()) {
378
- console.error('āŒ Azure CLI not found. Please install Azure CLI first.');
379
- console.error(' Download from: https://docs.microsoft.com/en-us/cli/azure/install-azure-cli');
380
- process.exit(1);
381
- }
382
- console.log('āœ… Azure CLI found');
375
+ // Check prerequisites for Azure profiling
376
+ console.log('\nšŸ” Checking prerequisites...');
383
377
 
384
- if (!checkAzureAuth()) {
385
- console.error('āŒ Not authenticated with Azure. Please run: az login');
386
- process.exit(1);
387
- }
388
- console.log('āœ… Azure authentication verified');
378
+ if (!checkAzureCLI()) {
379
+ console.error('āŒ Azure CLI not found. Please install Azure CLI first.');
380
+ console.error(' Download from: https://docs.microsoft.com/en-us/cli/azure/install-azure-cli');
381
+ process.exit(1);
382
+ }
383
+ console.log('āœ… Azure CLI found');
389
384
 
390
- try {
391
- // Verify app exists
392
- console.log(`\nšŸ” Verifying App Service: ${profileConfig.appName}`);
393
- execSync(`az webapp show --name ${profileConfig.appName} --resource-group ${profileConfig.resourceGroup} --query name -o tsv`, { stdio: 'pipe' });
394
- console.log('āœ… App Service found');
395
-
396
- // Run profiling analysis
397
- await getAppServicePlanMetrics(profileConfig.appName, profileConfig.resourceGroup);
398
- await getAppServiceMetrics(profileConfig.appName, profileConfig.resourceGroup);
399
- await getProcessInformation(profileConfig.appName);
400
- await getSystemInformation(profileConfig.appName);
401
-
402
- if (includeLogs) {
403
- await getApplicationLogs(profileConfig.appName, profileConfig.resourceGroup);
404
- }
385
+ if (!checkAzureAuth()) {
386
+ console.error('āŒ Not authenticated with Azure. Please run: az login');
387
+ process.exit(1);
388
+ }
389
+ console.log('āœ… Azure authentication verified');
405
390
 
406
- console.log('\nāœ… Server profiling completed successfully');
407
- console.log('\nšŸ’” Tips:');
408
- console.log(' - Use --logs flag to include application logs');
409
- console.log(' - High CPU usage may indicate performance bottlenecks');
410
- console.log(' - High memory usage may indicate memory leaks');
411
- console.log(' - Check process list for unexpected or resource-heavy processes');
412
-
413
- } catch (error: any) {
414
- console.error(`\nāŒ Profiling failed: ${error.message}`);
415
- console.error('\nTroubleshooting:');
416
- console.error(' - Verify app name and resource group are correct');
417
- console.error(' - Ensure you have proper permissions (Contributor role)');
418
- console.error(' - Check if the App Service is running');
419
- console.error(' - Try: az webapp list --query "[].{name:name, resourceGroup:resourceGroup}"');
420
- process.exit(1);
391
+ try {
392
+ // Verify app exists
393
+ console.log(`\nšŸ” Verifying App Service: ${profileConfig.appName}`);
394
+ execSync(`az webapp show --name ${profileConfig.appName} --resource-group ${profileConfig.resourceGroup} --query name -o tsv`, { stdio: 'pipe' });
395
+ console.log('āœ… App Service found');
396
+
397
+ // Run profiling analysis
398
+ await getAppServicePlanMetrics(profileConfig.appName, profileConfig.resourceGroup);
399
+ await getAppServiceMetrics(profileConfig.appName, profileConfig.resourceGroup);
400
+ await getProcessInformation(profileConfig.appName);
401
+ await getSystemInformation(profileConfig.appName);
402
+
403
+ if (includeLogs) {
404
+ await getApplicationLogs(profileConfig.appName, profileConfig.resourceGroup);
421
405
  }
406
+
407
+ console.log('\nāœ… Server profiling completed successfully');
408
+ console.log('\nšŸ’” Tips:');
409
+ console.log(' - Use --logs flag to include application logs');
410
+ console.log(' - High CPU usage may indicate performance bottlenecks');
411
+ console.log(' - High memory usage may indicate memory leaks');
412
+ console.log(' - Check process list for unexpected or resource-heavy processes');
413
+
414
+ } catch (error: any) {
415
+ console.error(`\nāŒ Profiling failed: ${error.message}`);
416
+ console.error('\nTroubleshooting:');
417
+ console.error(' - Verify app name and resource group are correct');
418
+ console.error(' - Ensure you have proper permissions (Contributor role)');
419
+ console.error(' - Check if the App Service is running');
420
+ console.error(' - Try: az webapp list --query "[].{name:name, resourceGroup:resourceGroup}"');
421
+ process.exit(1);
422
+ }
422
423
  }
423
424
 
424
425
  // Run the main function