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,311 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- /**
4
- * FRAIM Generic OpenAPI Limits Validator
5
- * This script validates OpenAPI file sizes against specified limits.
6
- *
7
- * Validates ChatGPT limitations for any project:
8
- * - instructions.txt: 8,000 character limit
9
- * - OpenAPI endpoints: 35 endpoint limit
10
- * - OpenAPI descriptions: 300 character limit per operation
11
- * - Missing operationIds
12
- * - Missing schema definitions
13
- * - x-openai-isConsequential on non-GET endpoints
14
- *
15
- * Usage:
16
- * npx tsx scripts/validate-openapi-limits.ts [instructions-file] [openapi-file]
17
- *
18
- * Defaults:
19
- * instructions-file: src/openapi/instructions.txt
20
- * openapi-file: src/openapi/openapi.json
21
- */
22
- Object.defineProperty(exports, "__esModule", { value: true });
23
- exports.validateAll = validateAll;
24
- const fs_1 = require("fs");
25
- const INSTRUCTIONS_LIMIT = 8000;
26
- const OPENAPI_ENDPOINT_LIMIT = 35;
27
- const OPENAPI_DESC_LIMIT = 300;
28
- /**
29
- * Collect all schema references from an object recursively
30
- */
31
- function collectSchemaRefs(obj, refs = new Set()) {
32
- if (typeof obj !== 'object' || obj === null) {
33
- return refs;
34
- }
35
- if (Array.isArray(obj)) {
36
- obj.forEach(item => collectSchemaRefs(item, refs));
37
- return refs;
38
- }
39
- if (obj.$ref && typeof obj.$ref === 'string') {
40
- // Extract schema name from #/components/schemas/SchemaName
41
- const match = obj.$ref.match(/#\/components\/schemas\/(.+)$/);
42
- if (match) {
43
- refs.add(match[1]);
44
- }
45
- }
46
- Object.values(obj).forEach(value => collectSchemaRefs(value, refs));
47
- return refs;
48
- }
49
- /**
50
- * Validate instructions.txt length
51
- */
52
- function validateInstructions(instructionsPath) {
53
- const result = {
54
- passed: true,
55
- errors: [],
56
- warnings: []
57
- };
58
- if (!(0, fs_1.existsSync)(instructionsPath)) {
59
- result.warnings.push(`instructions.txt not found at ${instructionsPath}`);
60
- return result;
61
- }
62
- try {
63
- const instructionsContent = (0, fs_1.readFileSync)(instructionsPath, 'utf-8');
64
- const instructionsLength = instructionsContent.length;
65
- console.log(`📄 instructions.txt: ${instructionsLength} characters (limit: ${INSTRUCTIONS_LIMIT})`);
66
- if (instructionsLength > INSTRUCTIONS_LIMIT) {
67
- result.passed = false;
68
- result.errors.push(`instructions.txt exceeds ${INSTRUCTIONS_LIMIT} character limit (${instructionsLength} chars). Move detailed content to KB files.`);
69
- console.log(` ❌ FAILED: Exceeds limit`);
70
- }
71
- else {
72
- console.log(` ✅ PASSED: Within limit\n`);
73
- }
74
- }
75
- catch (error) {
76
- result.passed = false;
77
- result.errors.push(`Failed to read instructions.txt: ${error.message}`);
78
- }
79
- return result;
80
- }
81
- /**
82
- * Validate OpenAPI specification
83
- */
84
- function validateOpenAPI(openapiPath) {
85
- const result = {
86
- passed: true,
87
- errors: [],
88
- warnings: []
89
- };
90
- if (!(0, fs_1.existsSync)(openapiPath)) {
91
- result.warnings.push(`OpenAPI file not found at ${openapiPath}`);
92
- return result;
93
- }
94
- try {
95
- const openapiContent = (0, fs_1.readFileSync)(openapiPath, 'utf-8');
96
- const openapiSpec = JSON.parse(openapiContent);
97
- // Count endpoints (operations) and validate
98
- let endpointCount = 0;
99
- const endpointList = [];
100
- const longDescriptions = [];
101
- const missingOperationIds = [];
102
- const allSchemaRefs = new Set();
103
- const missingConsequential = [];
104
- const wrongConsequential = [];
105
- if (openapiSpec.paths) {
106
- for (const [path, methods] of Object.entries(openapiSpec.paths)) {
107
- for (const [method, details] of Object.entries(methods)) {
108
- if (typeof details === 'object' && details !== null) {
109
- // Skip if it's a parameter definition or response definition
110
- if (['parameters', 'responses', 'requestBody'].includes(method)) {
111
- continue;
112
- }
113
- endpointCount++;
114
- endpointList.push(`${method.toUpperCase()} ${path}`);
115
- // Check for operationId
116
- if (!details.operationId) {
117
- missingOperationIds.push({
118
- path,
119
- method: method.toUpperCase()
120
- });
121
- }
122
- // Check description length
123
- if (details.description) {
124
- const descLength = details.description.length;
125
- if (descLength > OPENAPI_DESC_LIMIT) {
126
- longDescriptions.push({
127
- path,
128
- method: method.toUpperCase(),
129
- length: descLength
130
- });
131
- }
132
- }
133
- // Collect all schema references from this operation
134
- collectSchemaRefs(details, allSchemaRefs);
135
- // Check for x-openai-isConsequential on non-GET endpoints
136
- const nonGetMethods = ['post', 'put', 'patch', 'delete'];
137
- if (nonGetMethods.includes(method.toLowerCase())) {
138
- const hasConsequential = details.hasOwnProperty('x-openai-isConsequential');
139
- const consequentialValue = details['x-openai-isConsequential'];
140
- // ALL non-GET endpoints should have x-openai-isConsequential: false
141
- if (!hasConsequential) {
142
- missingConsequential.push({
143
- path,
144
- method: method.toUpperCase()
145
- });
146
- }
147
- else if (consequentialValue !== false) {
148
- wrongConsequential.push({
149
- path,
150
- method: method.toUpperCase(),
151
- value: consequentialValue
152
- });
153
- }
154
- }
155
- }
156
- }
157
- }
158
- }
159
- // Also collect schema refs from components/responses and components/parameters if they exist
160
- if (openapiSpec.components) {
161
- if (openapiSpec.components.responses) {
162
- Object.values(openapiSpec.components.responses).forEach((response) => {
163
- collectSchemaRefs(response, allSchemaRefs);
164
- });
165
- }
166
- if (openapiSpec.components.parameters) {
167
- Object.values(openapiSpec.components.parameters).forEach((param) => {
168
- collectSchemaRefs(param, allSchemaRefs);
169
- });
170
- }
171
- }
172
- // Check for missing schema definitions
173
- const definedSchemas = new Set();
174
- if (openapiSpec.components && openapiSpec.components.schemas) {
175
- Object.keys(openapiSpec.components.schemas).forEach(schemaName => {
176
- definedSchemas.add(schemaName);
177
- });
178
- }
179
- const missingSchemas = [];
180
- allSchemaRefs.forEach(refName => {
181
- if (!definedSchemas.has(refName)) {
182
- missingSchemas.push(refName);
183
- }
184
- });
185
- // Validate endpoint count
186
- console.log(`📋 OpenAPI endpoints: ${endpointCount} (limit: ${OPENAPI_ENDPOINT_LIMIT})`);
187
- if (endpointCount > OPENAPI_ENDPOINT_LIMIT) {
188
- result.passed = false;
189
- result.errors.push(`OpenAPI spec exceeds ${OPENAPI_ENDPOINT_LIMIT} endpoint limit (${endpointCount} endpoints). ChatGPT cannot handle more than ${OPENAPI_ENDPOINT_LIMIT} endpoints.`);
190
- console.log(` ❌ FAILED: Too many endpoints`);
191
- console.log(` Endpoints:`);
192
- endpointList.slice(0, 10).forEach(ep => console.log(` - ${ep}`));
193
- if (endpointCount > 10) {
194
- console.log(` ... and ${endpointCount - 10} more`);
195
- }
196
- }
197
- else {
198
- console.log(` ✅ PASSED: Within limit`);
199
- }
200
- // Check description lengths
201
- if (longDescriptions.length > 0) {
202
- console.log(`\n📝 OpenAPI descriptions: ${longDescriptions.length} exceed ${OPENAPI_DESC_LIMIT} char limit`);
203
- longDescriptions.forEach(({ path, method, length }) => {
204
- result.passed = false;
205
- result.errors.push(`OpenAPI operation ${method} ${path} description exceeds ${OPENAPI_DESC_LIMIT} character limit (${length} chars). Shorten description or move details to KB files.`);
206
- console.log(` ❌ ${method} ${path}: ${length} chars`);
207
- });
208
- }
209
- else {
210
- console.log(`\n📝 OpenAPI descriptions: All within ${OPENAPI_DESC_LIMIT} char limit`);
211
- console.log(` ✅ PASSED: All descriptions within limit`);
212
- }
213
- // Check for missing operationIds
214
- if (missingOperationIds.length > 0) {
215
- console.log(`\n🔑 OpenAPI operationIds: ${missingOperationIds.length} missing`);
216
- missingOperationIds.forEach(({ path, method }) => {
217
- result.passed = false;
218
- result.errors.push(`OpenAPI operation ${method} ${path} is missing required 'operationId' field. Add a unique operationId (e.g., "getTask", "createTask").`);
219
- console.log(` ❌ ${method} ${path}: Missing operationId`);
220
- });
221
- }
222
- else {
223
- console.log(`\n🔑 OpenAPI operationIds: All operations have operationId`);
224
- console.log(` ✅ PASSED: All operations have operationId`);
225
- }
226
- // Check for missing schema definitions
227
- if (missingSchemas.length > 0) {
228
- console.log(`\n📚 OpenAPI schemas: ${missingSchemas.length} referenced but not defined`);
229
- missingSchemas.forEach(schemaName => {
230
- result.passed = false;
231
- result.errors.push(`OpenAPI schema '${schemaName}' is referenced but not defined in components.schemas. Add the schema definition to components.schemas.`);
232
- console.log(` ❌ Missing schema: ${schemaName}`);
233
- });
234
- }
235
- else {
236
- console.log(`\n📚 OpenAPI schemas: All referenced schemas are defined`);
237
- console.log(` ✅ PASSED: All schema references resolve`);
238
- }
239
- // Check for missing or incorrect x-openai-isConsequential on non-GET endpoints
240
- const allConsequentialIssues = [...missingConsequential, ...wrongConsequential];
241
- if (allConsequentialIssues.length > 0) {
242
- console.log(`\n🔐 OpenAPI x-openai-isConsequential: ${allConsequentialIssues.length} non-GET endpoint(s) missing or incorrectly set`);
243
- missingConsequential.forEach(({ path, method }) => {
244
- result.passed = false;
245
- result.errors.push(`OpenAPI operation ${method} ${path} is missing required 'x-openai-isConsequential: false' field. Add this field to bypass ChatGPT confirmation prompts.`);
246
- console.log(` ❌ ${method} ${path}: Missing x-openai-isConsequential`);
247
- });
248
- wrongConsequential.forEach(({ path, method, value }) => {
249
- result.passed = false;
250
- result.errors.push(`OpenAPI operation ${method} ${path} has x-openai-isConsequential set to ${JSON.stringify(value)} but should be false. Non-GET endpoints should have x-openai-isConsequential: false to bypass ChatGPT confirmation prompts.`);
251
- console.log(` ❌ ${method} ${path}: x-openai-isConsequential is ${JSON.stringify(value)}, should be false`);
252
- });
253
- }
254
- else {
255
- console.log(`\n🔐 OpenAPI x-openai-isConsequential: All non-GET endpoints have x-openai-isConsequential: false`);
256
- console.log(` ✅ PASSED: All non-GET endpoints configured to bypass confirmation`);
257
- }
258
- }
259
- catch (error) {
260
- result.passed = false;
261
- result.errors.push(`Failed to parse OpenAPI JSON: ${error.message}`);
262
- console.log(` ❌ ERROR: ${error.message}`);
263
- }
264
- return result;
265
- }
266
- /**
267
- * Main validation function
268
- */
269
- function validateAll(instructionsPath = 'src/openapi/instructions.txt', openapiPath = 'src/openapi/openapi.json') {
270
- console.log('🔍 Validating OpenAPI and instructions limits...\n');
271
- const instructionsResult = validateInstructions(instructionsPath);
272
- const openapiResult = validateOpenAPI(openapiPath);
273
- // Combine results
274
- const allErrors = [...instructionsResult.errors, ...openapiResult.errors];
275
- const allWarnings = [...instructionsResult.warnings, ...openapiResult.warnings];
276
- const passed = instructionsResult.passed && openapiResult.passed;
277
- // Summary
278
- console.log('\n' + '='.repeat(50));
279
- console.log('📊 VALIDATION SUMMARY');
280
- console.log('='.repeat(50));
281
- if (allWarnings.length > 0) {
282
- console.log('\n⚠️ WARNINGS:');
283
- allWarnings.forEach(w => console.log(` - ${w}`));
284
- }
285
- if (allErrors.length > 0) {
286
- console.log('\n❌ ERRORS:');
287
- allErrors.forEach(e => console.log(` - ${e}`));
288
- console.log('\n💡 Solutions:');
289
- console.log(' - Move detailed content from instructions.txt to KB files (KB-*.txt)');
290
- console.log(' - Reduce number of OpenAPI endpoints (merge or remove unused endpoints)');
291
- console.log(' - Shorten OpenAPI operation descriptions, reference KB files for details');
292
- console.log(' - Add missing operationId fields to all operations (e.g., "getTask", "createTask")');
293
- console.log(' - Define missing schemas in components.schemas section');
294
- console.log(' - Add x-openai-isConsequential: false to all non-GET endpoints (POST, PUT, PATCH, DELETE)');
295
- console.log('\n❌ BUILD FAILED: Fix errors above before proceeding\n');
296
- return false;
297
- }
298
- else {
299
- console.log('\n✅ ALL CHECKS PASSED');
300
- console.log(' Instructions and OpenAPI spec are within ChatGPT limits\n');
301
- return true;
302
- }
303
- }
304
- // Run if executed directly
305
- // @ts-ignore
306
- if (import.meta.url === `file://${process.argv[1]}`) {
307
- const instructionsPath = process.argv[2] || 'src/openapi/instructions.txt';
308
- const openapiPath = process.argv[3] || 'src/openapi/openapi.json';
309
- const passed = validateAll(instructionsPath, openapiPath);
310
- process.exit(passed ? 0 : 1);
311
- }
@@ -1,262 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- /**
4
- * Validation Plan Coverage Checker
5
- *
6
- * Extracts validation plan from spec/design documents and verifies evidence coverage.
7
- * Used by Gate 9 in code-quality-check.sh
8
- *
9
- * Usage: npx tsx <this-script> <issue-number>
10
- */
11
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
- if (k2 === undefined) k2 = k;
13
- var desc = Object.getOwnPropertyDescriptor(m, k);
14
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
- desc = { enumerable: true, get: function() { return m[k]; } };
16
- }
17
- Object.defineProperty(o, k2, desc);
18
- }) : (function(o, m, k, k2) {
19
- if (k2 === undefined) k2 = k;
20
- o[k2] = m[k];
21
- }));
22
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
- Object.defineProperty(o, "default", { enumerable: true, value: v });
24
- }) : function(o, v) {
25
- o["default"] = v;
26
- });
27
- var __importStar = (this && this.__importStar) || (function () {
28
- var ownKeys = function(o) {
29
- ownKeys = Object.getOwnPropertyNames || function (o) {
30
- var ar = [];
31
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
- return ar;
33
- };
34
- return ownKeys(o);
35
- };
36
- return function (mod) {
37
- if (mod && mod.__esModule) return mod;
38
- var result = {};
39
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
- __setModuleDefault(result, mod);
41
- return result;
42
- };
43
- })();
44
- Object.defineProperty(exports, "__esModule", { value: true });
45
- const fs = __importStar(require("fs"));
46
- const path = __importStar(require("path"));
47
- /**
48
- * Extract issue number from branch name
49
- */
50
- function extractIssueNumberFromBranch() {
51
- const branchName = process.env.GIT_BRANCH || '';
52
- const match = branchName.match(/feature\/(\d+)/);
53
- return match ? parseInt(match[1]) : null;
54
- }
55
- /**
56
- * Find spec or design file for an issue
57
- */
58
- function findSpecOrDesignFile(issueNumber) {
59
- const specDir = path.join(process.cwd(), 'docs', 'feature specs');
60
- const rfcDir = path.join(process.cwd(), 'docs', 'rfcs');
61
- // Try feature specs first
62
- if (fs.existsSync(specDir)) {
63
- const files = fs.readdirSync(specDir);
64
- const specFile = files.find(f => f.startsWith(`${issueNumber}-`) && f.endsWith('.md'));
65
- if (specFile) {
66
- return path.join(specDir, specFile);
67
- }
68
- }
69
- // Then try RFCs
70
- if (fs.existsSync(rfcDir)) {
71
- const files = fs.readdirSync(rfcDir);
72
- const rfcFile = files.find(f => f.startsWith(`${issueNumber}-`) && f.endsWith('.md'));
73
- if (rfcFile) {
74
- return path.join(rfcDir, rfcFile);
75
- }
76
- }
77
- return null;
78
- }
79
- /**
80
- * Extract validation plan table from markdown file
81
- */
82
- function extractValidationPlan(filePath) {
83
- const content = fs.readFileSync(filePath, 'utf-8');
84
- const scenarios = [];
85
- // Find "## Validation Plan" section (not "Validation Plan Coverage")
86
- const validationPlanMatch = content.match(/##\s+Validation Plan\s*\n[\s\S]*?(?=\n##|$)/i);
87
- if (!validationPlanMatch) {
88
- return scenarios;
89
- }
90
- const validationSection = validationPlanMatch[0];
91
- // Look for markdown table - find table header row with "User Scenario"
92
- // Pattern: | User Scenario | Expected outcome | Validation method |
93
- const tablePattern = /\|[\s\*]*User Scenario[\s\*]*\|[\s\*]*Expected outcome[\s\*]*\|[\s\*]*Validation method[\s\*]*\|[\s]*\n\|[\s:\-|]+\|[\s]*\n((?:\|.*?\|[\s]*\n)+)/i;
94
- const tableMatch = validationSection.match(tablePattern);
95
- if (!tableMatch) {
96
- return scenarios;
97
- }
98
- const tableRows = tableMatch[1].trim().split('\n').filter(row => row.trim().startsWith('|'));
99
- for (const row of tableRows) {
100
- // Skip separator rows (all dashes/pipes)
101
- if (row.match(/^\|[\s:\-|]+\|$/)) {
102
- continue;
103
- }
104
- // Parse table row: | Scenario | Outcome | Method |
105
- // Handle both formats: | **bold** | text | and | text | text |
106
- const cells = row.split('|').map(c => c.trim()).filter(c => c && c !== '');
107
- if (cells.length >= 2) {
108
- // Remove markdown bold (**text**) from cells
109
- const cleanCell = (cell) => {
110
- return cell
111
- .replace(/^\*\*/, '')
112
- .replace(/\*\*$/, '')
113
- .replace(/^\*\*/g, '')
114
- .replace(/\*\*/g, '')
115
- .trim();
116
- };
117
- const userScenario = cleanCell(cells[0] || '');
118
- const expectedOutcome = cleanCell(cells[1] || '');
119
- const validationMethod = cleanCell(cells[2] || 'Manual validation');
120
- // Skip header rows
121
- const scenarioLower = userScenario.toLowerCase();
122
- const outcomeLower = expectedOutcome.toLowerCase();
123
- if (scenarioLower.includes('user scenario') ||
124
- (scenarioLower.includes('scenario') && outcomeLower.includes('expected')) ||
125
- scenarioLower === 'user scenario' ||
126
- outcomeLower === 'expected outcome') {
127
- continue;
128
- }
129
- // Skip empty rows or separator rows
130
- if (!userScenario || userScenario === '-' || userScenario.length === 0) {
131
- continue;
132
- }
133
- scenarios.push({
134
- userScenario,
135
- expectedOutcome,
136
- validationMethod
137
- });
138
- }
139
- }
140
- return scenarios;
141
- }
142
- /**
143
- * Check if evidence exists for a scenario
144
- * Evidence can be in PR comments, test.log, or other sources
145
- */
146
- function checkEvidenceForScenario(scenario, issueNumber) {
147
- // Extract key terms from scenario for searching
148
- const scenarioKeywords = scenario.userScenario
149
- .toLowerCase()
150
- .replace(/\*\*/g, '')
151
- .split(/\s+/)
152
- .filter(w => w.length > 3 && !['agent', 'the', 'with', 'without'].includes(w));
153
- const outcomeKeywords = scenario.expectedOutcome
154
- .toLowerCase()
155
- .replace(/\*\*/g, '')
156
- .split(/\s+/)
157
- .filter(w => w.length > 3);
158
- // Method 1: Check test.log for scenario keywords
159
- const testLogPath = path.join(process.cwd(), 'test.log');
160
- if (fs.existsSync(testLogPath)) {
161
- const testLogContent = fs.readFileSync(testLogPath, 'utf-8').toLowerCase();
162
- // Check if multiple keywords from scenario appear
163
- const matchingKeywords = scenarioKeywords.filter(kw => testLogContent.includes(kw));
164
- if (matchingKeywords.length >= 2) {
165
- return true;
166
- }
167
- }
168
- // Method 2: Check for evidence file (created by agent with scenario validation)
169
- const evidenceFiles = ['test-evidence.md', 'validation-evidence.md', 'implementation-evidence.md'];
170
- for (const evidenceFile of evidenceFiles) {
171
- const evidencePath = path.join(process.cwd(), evidenceFile);
172
- if (fs.existsSync(evidencePath)) {
173
- const evidenceContent = fs.readFileSync(evidencePath, 'utf-8').toLowerCase();
174
- const matchingKeywords = scenarioKeywords.filter(kw => evidenceContent.includes(kw));
175
- if (matchingKeywords.length >= 2) {
176
- return true;
177
- }
178
- }
179
- }
180
- // Method 3: Check server.log for scenario-related activity
181
- const serverLogPath = path.join(process.cwd(), 'server.log');
182
- if (fs.existsSync(serverLogPath)) {
183
- const serverLogContent = fs.readFileSync(serverLogPath, 'utf-8').toLowerCase();
184
- // Look for validation-related keywords
185
- if (scenarioKeywords.some(kw => serverLogContent.includes(kw)) ||
186
- outcomeKeywords.some(kw => serverLogContent.includes('gate') && serverLogContent.includes(kw))) {
187
- return true;
188
- }
189
- }
190
- // Note: PR comment checking is done in the shell script (Gate 9)
191
- // This TypeScript tool focuses on file-based evidence
192
- return false; // Conservative: require evidence
193
- }
194
- /**
195
- * Main function
196
- */
197
- function main() {
198
- const issueNumberArg = process.argv[2];
199
- const issueNumber = issueNumberArg ? parseInt(issueNumberArg) : extractIssueNumberFromBranch();
200
- if (!issueNumber) {
201
- console.error('❌ ERROR: Could not determine issue number');
202
- console.error(' Usage: npx tsx validate-coverage.ts <issue-number>');
203
- console.error(' Or set GIT_BRANCH environment variable with feature/N-* format');
204
- process.exit(1);
205
- }
206
- const specFile = findSpecOrDesignFile(issueNumber);
207
- if (!specFile) {
208
- // No spec/design found - Gate 9 warns but doesn't block
209
- console.log('ℹ️ No spec/design found for issue #' + issueNumber);
210
- console.log(' Skipping validation plan coverage check');
211
- console.log(' Gate 9: Validation Plan Coverage - SKIPPED (no spec/design)');
212
- process.exit(0);
213
- }
214
- console.log(`Found spec/design: ${specFile}`);
215
- const scenarios = extractValidationPlan(specFile);
216
- if (scenarios.length === 0) {
217
- console.log('ℹ️ No validation plan table found in spec/design');
218
- console.log(' Gate 9: Validation Plan Coverage - SKIPPED (no validation plan)');
219
- process.exit(0);
220
- }
221
- console.log(`Found ${scenarios.length} validation scenario(s)`);
222
- // Check evidence for each scenario
223
- const covered = [];
224
- const missing = [];
225
- for (const scenario of scenarios) {
226
- if (checkEvidenceForScenario(scenario, issueNumber)) {
227
- covered.push(scenario);
228
- }
229
- else {
230
- missing.push(scenario);
231
- }
232
- }
233
- const coverage = {
234
- complete: missing.length === 0,
235
- totalScenarios: scenarios.length,
236
- coveredScenarios: covered.length,
237
- missingScenarios: missing,
238
- coverage: `${covered.length}/${scenarios.length} scenarios (${Math.round(covered.length / scenarios.length * 100)}%)`
239
- };
240
- // Output results
241
- console.log('\n📊 Validation Plan Coverage:');
242
- console.log(` ${coverage.coverage}`);
243
- if (coverage.complete) {
244
- console.log('✅ PASSED: All validation scenarios have evidence');
245
- console.log(' Gate 9: Validation Plan Coverage - PASSED');
246
- process.exit(0);
247
- }
248
- else {
249
- console.log('❌ FAILED: Missing evidence for validation scenarios:');
250
- for (const scenario of missing) {
251
- console.log(` - "${scenario.userScenario}"`);
252
- console.log(` Expected: ${scenario.expectedOutcome}`);
253
- console.log(` Method: ${scenario.validationMethod}`);
254
- }
255
- console.log('\n Required: Provide evidence for all validation scenarios before marking PR ready');
256
- console.log(' Evidence can be: PR comment, test output, manual verification log');
257
- console.log(' Gate 9: Validation Plan Coverage - FAILED');
258
- process.exit(1);
259
- }
260
- }
261
- // Run main function
262
- main();
@@ -1,66 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- /**
4
- * Test Coverage Verifier (Diagnostic Tool)
5
- *
6
- * Verifies test coverage against validation plans and outputs data to the console.
7
- * Used by the verify-test-coverage bootstrapping workflow.
8
- *
9
- * Usage: npx tsx <this-script>
10
- */
11
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
- if (k2 === undefined) k2 = k;
13
- var desc = Object.getOwnPropertyDescriptor(m, k);
14
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
- desc = { enumerable: true, get: function() { return m[k]; } };
16
- }
17
- Object.defineProperty(o, k2, desc);
18
- }) : (function(o, m, k, k2) {
19
- if (k2 === undefined) k2 = k;
20
- o[k2] = m[k];
21
- }));
22
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
- Object.defineProperty(o, "default", { enumerable: true, value: v });
24
- }) : function(o, v) {
25
- o["default"] = v;
26
- });
27
- var __importStar = (this && this.__importStar) || (function () {
28
- var ownKeys = function(o) {
29
- ownKeys = Object.getOwnPropertyNames || function (o) {
30
- var ar = [];
31
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
- return ar;
33
- };
34
- return ownKeys(o);
35
- };
36
- return function (mod) {
37
- if (mod && mod.__esModule) return mod;
38
- var result = {};
39
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
- __setModuleDefault(result, mod);
41
- return result;
42
- };
43
- })();
44
- Object.defineProperty(exports, "__esModule", { value: true });
45
- const path = __importStar(require("path"));
46
- const child_process_1 = require("child_process");
47
- const REGISTRY_SCRIPTS_DIR = __dirname;
48
- const VALIDATE_COVERAGE_SCRIPT = path.join(REGISTRY_SCRIPTS_DIR, 'validate-test-coverage.ts');
49
- function verifyCoverage() {
50
- console.log('🚀 Starting Coverage Verification...');
51
- console.log('📊 Analyzing scenario coverage...\n');
52
- // Run the existing validate-coverage script and pipe output to terminal
53
- const child = (0, child_process_1.spawn)('npx', ['tsx', VALIDATE_COVERAGE_SCRIPT], {
54
- stdio: 'inherit',
55
- shell: true // Needed for npx on Windows locally
56
- });
57
- child.on('exit', (code) => {
58
- if (code === 0) {
59
- console.log('\n✅ Coverage analysis completed successfully.');
60
- }
61
- else {
62
- console.log(`\n❌ Coverage analysis failed with exit code ${code}.`);
63
- }
64
- });
65
- }
66
- verifyCoverage();