faf-mcp 1.0.0

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 (207) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/CLAUDE.md +73 -0
  3. package/LICENSE +22 -0
  4. package/README.md +165 -0
  5. package/assets/Project-faf-pckg-json-README.png +0 -0
  6. package/assets/icons/faf-icon-128.png +0 -0
  7. package/assets/icons/faf-icon-256.png +0 -0
  8. package/assets/icons/faf-icon-48.png +0 -0
  9. package/assets/icons/faf-icon-512.png +0 -0
  10. package/assets/icons/orange-smiley.svg +6 -0
  11. package/dist/src/compiler/index.d.ts +7 -0
  12. package/dist/src/compiler/index.js +24 -0
  13. package/dist/src/compiler/index.js.map +1 -0
  14. package/dist/src/compiler/scorer.d.ts +53 -0
  15. package/dist/src/compiler/scorer.js +189 -0
  16. package/dist/src/compiler/scorer.js.map +1 -0
  17. package/dist/src/compiler/slot-validator.d.ts +32 -0
  18. package/dist/src/compiler/slot-validator.js +293 -0
  19. package/dist/src/compiler/slot-validator.js.map +1 -0
  20. package/dist/src/compiler/type-detector.d.ts +62 -0
  21. package/dist/src/compiler/type-detector.js +388 -0
  22. package/dist/src/compiler/type-detector.js.map +1 -0
  23. package/dist/src/config/visibility.d.ts +41 -0
  24. package/dist/src/config/visibility.js +158 -0
  25. package/dist/src/config/visibility.js.map +1 -0
  26. package/dist/src/faf-core/commands/audit.d.ts +21 -0
  27. package/dist/src/faf-core/commands/audit.js +83 -0
  28. package/dist/src/faf-core/commands/audit.js.map +1 -0
  29. package/dist/src/faf-core/commands/auto.d.ts +25 -0
  30. package/dist/src/faf-core/commands/auto.js +74 -0
  31. package/dist/src/faf-core/commands/auto.js.map +1 -0
  32. package/dist/src/faf-core/commands/bi-sync.d.ts +26 -0
  33. package/dist/src/faf-core/commands/bi-sync.js +157 -0
  34. package/dist/src/faf-core/commands/bi-sync.js.map +1 -0
  35. package/dist/src/faf-core/commands/doctor.d.ts +17 -0
  36. package/dist/src/faf-core/commands/doctor.js +198 -0
  37. package/dist/src/faf-core/commands/doctor.js.map +1 -0
  38. package/dist/src/faf-core/commands/enhance.d.ts +46 -0
  39. package/dist/src/faf-core/commands/enhance.js +360 -0
  40. package/dist/src/faf-core/commands/enhance.js.map +1 -0
  41. package/dist/src/faf-core/commands/formats.d.ts +22 -0
  42. package/dist/src/faf-core/commands/formats.js +117 -0
  43. package/dist/src/faf-core/commands/formats.js.map +1 -0
  44. package/dist/src/faf-core/commands/init.d.ts +26 -0
  45. package/dist/src/faf-core/commands/init.js +114 -0
  46. package/dist/src/faf-core/commands/init.js.map +1 -0
  47. package/dist/src/faf-core/commands/innit.d.ts +7 -0
  48. package/dist/src/faf-core/commands/innit.js +13 -0
  49. package/dist/src/faf-core/commands/innit.js.map +1 -0
  50. package/dist/src/faf-core/commands/migrate.d.ts +15 -0
  51. package/dist/src/faf-core/commands/migrate.js +86 -0
  52. package/dist/src/faf-core/commands/migrate.js.map +1 -0
  53. package/dist/src/faf-core/commands/quick.d.ts +16 -0
  54. package/dist/src/faf-core/commands/quick.js +184 -0
  55. package/dist/src/faf-core/commands/quick.js.map +1 -0
  56. package/dist/src/faf-core/commands/score.d.ts +47 -0
  57. package/dist/src/faf-core/commands/score.js +49 -0
  58. package/dist/src/faf-core/commands/score.js.map +1 -0
  59. package/dist/src/faf-core/commands/sync.d.ts +16 -0
  60. package/dist/src/faf-core/commands/sync.js +210 -0
  61. package/dist/src/faf-core/commands/sync.js.map +1 -0
  62. package/dist/src/faf-core/commands/update.d.ts +12 -0
  63. package/dist/src/faf-core/commands/update.js +46 -0
  64. package/dist/src/faf-core/commands/update.js.map +1 -0
  65. package/dist/src/faf-core/commands/validate.d.ts +21 -0
  66. package/dist/src/faf-core/commands/validate.js +81 -0
  67. package/dist/src/faf-core/commands/validate.js.map +1 -0
  68. package/dist/src/faf-core/compiler/faf-compiler.d.ts +138 -0
  69. package/dist/src/faf-core/compiler/faf-compiler.js +794 -0
  70. package/dist/src/faf-core/compiler/faf-compiler.js.map +1 -0
  71. package/dist/src/faf-core/engines/dependency-tsa.d.ts +88 -0
  72. package/dist/src/faf-core/engines/dependency-tsa.js +361 -0
  73. package/dist/src/faf-core/engines/dependency-tsa.js.map +1 -0
  74. package/dist/src/faf-core/engines/fab-formats-processor.d.ts +166 -0
  75. package/dist/src/faf-core/engines/fab-formats-processor.js +1274 -0
  76. package/dist/src/faf-core/engines/fab-formats-processor.js.map +1 -0
  77. package/dist/src/faf-core/engines/faf-dna.d.ts +159 -0
  78. package/dist/src/faf-core/engines/faf-dna.js +554 -0
  79. package/dist/src/faf-core/engines/faf-dna.js.map +1 -0
  80. package/dist/src/faf-core/engines/relentless-context-extractor.d.ts +100 -0
  81. package/dist/src/faf-core/engines/relentless-context-extractor.js +625 -0
  82. package/dist/src/faf-core/engines/relentless-context-extractor.js.map +1 -0
  83. package/dist/src/faf-core/fix-once/colors.d.ts +104 -0
  84. package/dist/src/faf-core/fix-once/colors.js +236 -0
  85. package/dist/src/faf-core/fix-once/colors.js.map +1 -0
  86. package/dist/src/faf-core/fix-once/types.d.ts +257 -0
  87. package/dist/src/faf-core/fix-once/types.js +26 -0
  88. package/dist/src/faf-core/fix-once/types.js.map +1 -0
  89. package/dist/src/faf-core/fix-once/yaml.d.ts +57 -0
  90. package/dist/src/faf-core/fix-once/yaml.js +172 -0
  91. package/dist/src/faf-core/fix-once/yaml.js.map +1 -0
  92. package/dist/src/faf-core/generators/faf-generator-championship.d.ts +16 -0
  93. package/dist/src/faf-core/generators/faf-generator-championship.js +462 -0
  94. package/dist/src/faf-core/generators/faf-generator-championship.js.map +1 -0
  95. package/dist/src/faf-core/utils/balance-visualizer.d.ts +37 -0
  96. package/dist/src/faf-core/utils/balance-visualizer.js +197 -0
  97. package/dist/src/faf-core/utils/balance-visualizer.js.map +1 -0
  98. package/dist/src/faf-core/utils/championship-style.d.ts +109 -0
  99. package/dist/src/faf-core/utils/championship-style.js +219 -0
  100. package/dist/src/faf-core/utils/championship-style.js.map +1 -0
  101. package/dist/src/faf-core/utils/chrome-extension-detector.d.ts +73 -0
  102. package/dist/src/faf-core/utils/chrome-extension-detector.js +268 -0
  103. package/dist/src/faf-core/utils/chrome-extension-detector.js.map +1 -0
  104. package/dist/src/faf-core/utils/fafignore-parser.d.ts +20 -0
  105. package/dist/src/faf-core/utils/fafignore-parser.js +178 -0
  106. package/dist/src/faf-core/utils/fafignore-parser.js.map +1 -0
  107. package/dist/src/faf-core/utils/file-utils.d.ts +112 -0
  108. package/dist/src/faf-core/utils/file-utils.js +846 -0
  109. package/dist/src/faf-core/utils/file-utils.js.map +1 -0
  110. package/dist/src/faf-core/utils/native-file-finder.d.ts +115 -0
  111. package/dist/src/faf-core/utils/native-file-finder.js +211 -0
  112. package/dist/src/faf-core/utils/native-file-finder.js.map +1 -0
  113. package/dist/src/faf-core/utils/platform-detector.d.ts +30 -0
  114. package/dist/src/faf-core/utils/platform-detector.js +218 -0
  115. package/dist/src/faf-core/utils/platform-detector.js.map +1 -0
  116. package/dist/src/faf-core/utils/technical-credit.d.ts +35 -0
  117. package/dist/src/faf-core/utils/technical-credit.js +286 -0
  118. package/dist/src/faf-core/utils/technical-credit.js.map +1 -0
  119. package/dist/src/faf-core/utils/yaml-generator.d.ts +41 -0
  120. package/dist/src/faf-core/utils/yaml-generator.js +360 -0
  121. package/dist/src/faf-core/utils/yaml-generator.js.map +1 -0
  122. package/dist/src/handlers/behavioral-instruction.d.ts +16 -0
  123. package/dist/src/handlers/behavioral-instruction.js +43 -0
  124. package/dist/src/handlers/behavioral-instruction.js.map +1 -0
  125. package/dist/src/handlers/championship-tools.d.ts +113 -0
  126. package/dist/src/handlers/championship-tools.js +2602 -0
  127. package/dist/src/handlers/championship-tools.js.map +1 -0
  128. package/dist/src/handlers/engine-adapter.d.ts +28 -0
  129. package/dist/src/handlers/engine-adapter.js +603 -0
  130. package/dist/src/handlers/engine-adapter.js.map +1 -0
  131. package/dist/src/handlers/fileHandler.d.ts +36 -0
  132. package/dist/src/handlers/fileHandler.js +246 -0
  133. package/dist/src/handlers/fileHandler.js.map +1 -0
  134. package/dist/src/handlers/resources.d.ts +18 -0
  135. package/dist/src/handlers/resources.js +78 -0
  136. package/dist/src/handlers/resources.js.map +1 -0
  137. package/dist/src/handlers/tool-registry.d.ts +23 -0
  138. package/dist/src/handlers/tool-registry.js +68 -0
  139. package/dist/src/handlers/tool-registry.js.map +1 -0
  140. package/dist/src/handlers/tool-types.d.ts +167 -0
  141. package/dist/src/handlers/tool-types.js +7 -0
  142. package/dist/src/handlers/tool-types.js.map +1 -0
  143. package/dist/src/handlers/tools.d.ts +25 -0
  144. package/dist/src/handlers/tools.js +1168 -0
  145. package/dist/src/handlers/tools.js.map +1 -0
  146. package/dist/src/index.d.ts +2 -0
  147. package/dist/src/index.js +17 -0
  148. package/dist/src/index.js.map +1 -0
  149. package/dist/src/server.d.ts +28 -0
  150. package/dist/src/server.js +179 -0
  151. package/dist/src/server.js.map +1 -0
  152. package/dist/src/test-all-functions.d.ts +15 -0
  153. package/dist/src/test-all-functions.js +163 -0
  154. package/dist/src/test-all-functions.js.map +1 -0
  155. package/dist/src/types/mcp-tools.d.ts +53 -0
  156. package/dist/src/types/mcp-tools.js +77 -0
  157. package/dist/src/types/mcp-tools.js.map +1 -0
  158. package/dist/src/types/project-types.d.ts +22 -0
  159. package/dist/src/types/project-types.js +85 -0
  160. package/dist/src/types/project-types.js.map +1 -0
  161. package/dist/src/types/slots.d.ts +39 -0
  162. package/dist/src/types/slots.js +162 -0
  163. package/dist/src/types/slots.js.map +1 -0
  164. package/dist/src/types/tool-visibility.d.ts +36 -0
  165. package/dist/src/types/tool-visibility.js +510 -0
  166. package/dist/src/types/tool-visibility.js.map +1 -0
  167. package/dist/src/utils/auto-path-detection.d.ts +26 -0
  168. package/dist/src/utils/auto-path-detection.js +198 -0
  169. package/dist/src/utils/auto-path-detection.js.map +1 -0
  170. package/dist/src/utils/championship-format.d.ts +30 -0
  171. package/dist/src/utils/championship-format.js +79 -0
  172. package/dist/src/utils/championship-format.js.map +1 -0
  173. package/dist/src/utils/cli-detector.d.ts +20 -0
  174. package/dist/src/utils/cli-detector.js +230 -0
  175. package/dist/src/utils/cli-detector.js.map +1 -0
  176. package/dist/src/utils/display-protocol.d.ts +57 -0
  177. package/dist/src/utils/display-protocol.js +131 -0
  178. package/dist/src/utils/display-protocol.js.map +1 -0
  179. package/dist/src/utils/faf-file-finder.d.ts +59 -0
  180. package/dist/src/utils/faf-file-finder.js +139 -0
  181. package/dist/src/utils/faf-file-finder.js.map +1 -0
  182. package/dist/src/utils/fuzzy-detector.d.ts +56 -0
  183. package/dist/src/utils/fuzzy-detector.js +221 -0
  184. package/dist/src/utils/fuzzy-detector.js.map +1 -0
  185. package/dist/src/utils/path-resolver.d.ts +51 -0
  186. package/dist/src/utils/path-resolver.js +214 -0
  187. package/dist/src/utils/path-resolver.js.map +1 -0
  188. package/dist/src/utils/type-guards.d.ts +9 -0
  189. package/dist/src/utils/type-guards.js +27 -0
  190. package/dist/src/utils/type-guards.js.map +1 -0
  191. package/dist/src/utils/username-detector.d.ts +27 -0
  192. package/dist/src/utils/username-detector.js +90 -0
  193. package/dist/src/utils/username-detector.js.map +1 -0
  194. package/dist/src/utils/visual-style.d.ts +62 -0
  195. package/dist/src/utils/visual-style.js +164 -0
  196. package/dist/src/utils/visual-style.js.map +1 -0
  197. package/dist/src/version.d.ts +9 -0
  198. package/dist/src/version.js +37 -0
  199. package/dist/src/version.js.map +1 -0
  200. package/package.json +114 -0
  201. package/scripts/discord-sync-curated.js +233 -0
  202. package/scripts/discord-sync-final.js +218 -0
  203. package/scripts/discord-sync-simple.js +175 -0
  204. package/scripts/discord-sync-working.js +187 -0
  205. package/scripts/discord-sync.js +181 -0
  206. package/scripts/postinstall.js +46 -0
  207. package/skill/SKILL.md +385 -0
@@ -0,0 +1,846 @@
1
+ "use strict";
2
+ /**
3
+ * 📁 File Utilities
4
+ * Helper functions for finding and working with .faf files
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.findFafFile = findFafFile;
11
+ exports.fileExists = fileExists;
12
+ exports.getFileModTime = getFileModTime;
13
+ exports.findPackageJson = findPackageJson;
14
+ exports.findPyprojectToml = findPyprojectToml;
15
+ exports.findRequirementsTxt = findRequirementsTxt;
16
+ exports.findTsConfig = findTsConfig;
17
+ exports.analyzeTsConfig = analyzeTsConfig;
18
+ exports.findN8nWorkflows = findN8nWorkflows;
19
+ exports.findMakeScenarios = findMakeScenarios;
20
+ exports.findOpalMiniApps = findOpalMiniApps;
21
+ exports.findOpenAIAssistants = findOpenAIAssistants;
22
+ exports.detectProjectType = detectProjectType;
23
+ exports.daysSinceModified = daysSinceModified;
24
+ exports.detectPythonProjectType = detectPythonProjectType;
25
+ exports.detectPythonPatterns = detectPythonPatterns;
26
+ const fs_1 = require("fs");
27
+ const path_1 = __importDefault(require("path"));
28
+ const native_file_finder_js_1 = require("./native-file-finder.js");
29
+ const fafignore_parser_1 = require("./fafignore-parser");
30
+ /**
31
+ * Find project.faf file in current directory or parent directories
32
+ *
33
+ * v3.0.0: ONLY supports project.faf (no legacy .faf support)
34
+ */
35
+ async function findFafFile(startDir = process.cwd()) {
36
+ let currentDir = path_1.default.resolve(startDir);
37
+ // Check up to 10 parent directories to avoid infinite loops
38
+ for (let i = 0; i < 10; i++) {
39
+ try {
40
+ const projectFafPath = path_1.default.join(currentDir, 'project.faf');
41
+ // Check if project.faf exists and is a file
42
+ if (await fileExists(projectFafPath)) {
43
+ const stats = await fs_1.promises.stat(projectFafPath);
44
+ if (stats.isFile()) {
45
+ return projectFafPath;
46
+ }
47
+ }
48
+ // v3.0.0: Support legacy .faf with migration suggestion
49
+ const legacyFafPath = path_1.default.join(currentDir, '.faf');
50
+ if (await fileExists(legacyFafPath)) {
51
+ const stats = await fs_1.promises.stat(legacyFafPath);
52
+ if (stats.isFile()) {
53
+ console.warn('\n💡 Using legacy .faf file. Run "faf migrate" to upgrade to project.faf (<1 second)\n');
54
+ return legacyFafPath;
55
+ }
56
+ }
57
+ // Move to parent directory
58
+ const parentDir = path_1.default.dirname(currentDir);
59
+ if (parentDir === currentDir) {
60
+ // Reached filesystem root
61
+ break;
62
+ }
63
+ currentDir = parentDir;
64
+ }
65
+ catch {
66
+ // Skip this directory if we can't read it
67
+ const parentDir = path_1.default.dirname(currentDir);
68
+ if (parentDir === currentDir) {
69
+ break;
70
+ }
71
+ currentDir = parentDir;
72
+ }
73
+ }
74
+ return null;
75
+ }
76
+ /**
77
+ * Check if file exists and is readable
78
+ */
79
+ async function fileExists(filePath) {
80
+ try {
81
+ await fs_1.promises.access(filePath, fs_1.promises.constants.F_OK | fs_1.promises.constants.R_OK);
82
+ return true;
83
+ }
84
+ catch {
85
+ return false;
86
+ }
87
+ }
88
+ /**
89
+ * Get file modification time
90
+ */
91
+ async function getFileModTime(filePath) {
92
+ try {
93
+ const stats = await fs_1.promises.stat(filePath);
94
+ return stats.mtime;
95
+ }
96
+ catch {
97
+ return null;
98
+ }
99
+ }
100
+ /**
101
+ * Find package.json in project
102
+ */
103
+ async function findPackageJson(startDir = process.cwd()) {
104
+ let currentDir = path_1.default.resolve(startDir); // Fix: resolve to absolute path
105
+ while (currentDir !== path_1.default.dirname(currentDir)) {
106
+ const packagePath = path_1.default.join(currentDir, "package.json");
107
+ if (await fileExists(packagePath)) {
108
+ return packagePath;
109
+ }
110
+ currentDir = path_1.default.dirname(currentDir);
111
+ }
112
+ return null;
113
+ }
114
+ /**
115
+ * Find pyproject.toml in project (Python Poetry/PEP 518)
116
+ */
117
+ async function findPyprojectToml(startDir = process.cwd()) {
118
+ let currentDir = path_1.default.resolve(startDir); // Fix: resolve to absolute path
119
+ while (currentDir !== path_1.default.dirname(currentDir)) {
120
+ const pyprojectPath = path_1.default.join(currentDir, "pyproject.toml");
121
+ if (await fileExists(pyprojectPath)) {
122
+ return pyprojectPath;
123
+ }
124
+ currentDir = path_1.default.dirname(currentDir);
125
+ }
126
+ return null;
127
+ }
128
+ /**
129
+ * Find requirements.txt in project (Python pip)
130
+ */
131
+ async function findRequirementsTxt(startDir = process.cwd()) {
132
+ let currentDir = path_1.default.resolve(startDir); // Fix: resolve to absolute path
133
+ while (currentDir !== path_1.default.dirname(currentDir)) {
134
+ const requirementsPath = path_1.default.join(currentDir, "requirements.txt");
135
+ if (await fileExists(requirementsPath)) {
136
+ return requirementsPath;
137
+ }
138
+ currentDir = path_1.default.dirname(currentDir);
139
+ }
140
+ return null;
141
+ }
142
+ /**
143
+ * Find tsconfig.json in project (TypeScript)
144
+ */
145
+ async function findTsConfig(startDir = process.cwd()) {
146
+ let currentDir = path_1.default.resolve(startDir); // Fix: resolve to absolute path
147
+ while (currentDir !== path_1.default.dirname(currentDir)) {
148
+ const tsconfigPath = path_1.default.join(currentDir, "tsconfig.json");
149
+ if (await fileExists(tsconfigPath)) {
150
+ return tsconfigPath;
151
+ }
152
+ currentDir = path_1.default.dirname(currentDir);
153
+ }
154
+ return null;
155
+ }
156
+ /**
157
+ * Analyze tsconfig.json for F1-Inspired TypeScript intelligence
158
+ */
159
+ async function analyzeTsConfig(filePath) {
160
+ try {
161
+ const content = await fs_1.promises.readFile(filePath, "utf-8");
162
+ // Strip comments from JSON (tsconfig.json often has comments)
163
+ const cleanedContent = content
164
+ .replace(/\/\*[\s\S]*?\*\//g, "") // Remove /* */ comments
165
+ .replace(/\/\/.*$/gm, ""); // Remove // comments
166
+ const config = JSON.parse(cleanedContent);
167
+ const compilerOptions = config.compilerOptions || {};
168
+ // Detect F1-Inspired engineering quality
169
+ const strictnessLevel = calculateStrictnessLevel(compilerOptions);
170
+ const frameworkIntegration = detectFrameworkIntegration(compilerOptions, config);
171
+ const performanceOptimizations = detectPerformanceConfig(compilerOptions);
172
+ return {
173
+ target: compilerOptions.target || "ES5",
174
+ module: compilerOptions.module || "CommonJS",
175
+ moduleResolution: compilerOptions.moduleResolution || "node",
176
+ strict: compilerOptions.strict || false,
177
+ strictnessLevel,
178
+ frameworkIntegration,
179
+ performanceOptimizations,
180
+ includes: config.include || [],
181
+ excludes: config.exclude || [],
182
+ engineeringQuality: assessEngineeringQuality(compilerOptions),
183
+ };
184
+ }
185
+ catch {
186
+ return null;
187
+ }
188
+ }
189
+ /**
190
+ * Detect n8n workflow files in directory
191
+ */
192
+ async function findN8nWorkflows(projectDir = process.cwd()) {
193
+ const workflows = [];
194
+ try {
195
+ const files = await fs_1.promises.readdir(projectDir);
196
+ for (const file of files) {
197
+ if (file.endsWith('.json') && !file.includes('package')) {
198
+ try {
199
+ const filePath = path_1.default.join(projectDir, file);
200
+ const content = await fs_1.promises.readFile(filePath, 'utf-8');
201
+ const json = JSON.parse(content);
202
+ // Check if it's an n8n workflow (has nodes, connections, and name)
203
+ if (json.nodes && Array.isArray(json.nodes) &&
204
+ json.connections && typeof json.connections === 'object' &&
205
+ json.name && typeof json.name === 'string') {
206
+ workflows.push(file);
207
+ }
208
+ }
209
+ catch {
210
+ // Not valid JSON or not n8n format, skip
211
+ }
212
+ }
213
+ }
214
+ }
215
+ catch {
216
+ // Directory read error, return empty
217
+ }
218
+ return workflows;
219
+ }
220
+ /**
221
+ * Find Make.com scenario files in a project directory
222
+ *
223
+ * Detects Make.com blueprint JSON files by checking for:
224
+ * - name string (scenario name)
225
+ * - flow array (modules/steps)
226
+ * - metadata object (scenario metadata)
227
+ *
228
+ * @param projectDir - Directory to search (defaults to cwd)
229
+ * @returns Array of Make.com scenario file names
230
+ */
231
+ async function findMakeScenarios(projectDir = process.cwd()) {
232
+ const scenarios = [];
233
+ try {
234
+ const files = await fs_1.promises.readdir(projectDir);
235
+ for (const file of files) {
236
+ if (file.endsWith('.json') && !file.includes('package')) {
237
+ try {
238
+ const filePath = path_1.default.join(projectDir, file);
239
+ const content = await fs_1.promises.readFile(filePath, 'utf-8');
240
+ const json = JSON.parse(content);
241
+ // Check if it's a Make.com blueprint (has name, flow array, and metadata)
242
+ if (json.name && typeof json.name === 'string' &&
243
+ json.flow && Array.isArray(json.flow) &&
244
+ json.metadata && typeof json.metadata === 'object') {
245
+ scenarios.push(file);
246
+ }
247
+ }
248
+ catch {
249
+ // Not valid JSON or not Make format, skip
250
+ }
251
+ }
252
+ }
253
+ }
254
+ catch {
255
+ // Directory read error, return empty
256
+ }
257
+ return scenarios;
258
+ }
259
+ /**
260
+ * Find Google Opal mini-app files in a project directory
261
+ *
262
+ * Detects Opal mini-app JSON files by checking for:
263
+ * - steps array (mini-app steps)
264
+ * - model string (AI model used)
265
+ *
266
+ * @param projectDir - Directory to search (defaults to cwd)
267
+ * @returns Array of Opal mini-app file names
268
+ */
269
+ async function findOpalMiniApps(projectDir = process.cwd()) {
270
+ const miniApps = [];
271
+ try {
272
+ const files = await fs_1.promises.readdir(projectDir);
273
+ for (const file of files) {
274
+ if (file.endsWith('.json') && !file.includes('package')) {
275
+ try {
276
+ const filePath = path_1.default.join(projectDir, file);
277
+ const content = await fs_1.promises.readFile(filePath, 'utf-8');
278
+ const json = JSON.parse(content);
279
+ // Check if it's an Opal mini-app (has steps and model)
280
+ if (json.steps && Array.isArray(json.steps) &&
281
+ json.model && typeof json.model === 'string') {
282
+ miniApps.push(file);
283
+ }
284
+ }
285
+ catch {
286
+ // Not valid JSON or not Opal format, skip
287
+ }
288
+ }
289
+ }
290
+ }
291
+ catch {
292
+ // Directory read error, return empty
293
+ }
294
+ return miniApps;
295
+ }
296
+ /**
297
+ * Find OpenAI Assistant files in a project directory
298
+ *
299
+ * Detects OpenAI Assistant JSON files (OpenAPI 3.x schemas) by checking for:
300
+ * - openapi string (OpenAPI version)
301
+ * - paths object (API endpoints/actions)
302
+ *
303
+ * @param projectDir - Directory to search (defaults to cwd)
304
+ * @returns Array of OpenAI Assistant file names
305
+ */
306
+ async function findOpenAIAssistants(projectDir = process.cwd()) {
307
+ const assistants = [];
308
+ try {
309
+ const files = await fs_1.promises.readdir(projectDir);
310
+ for (const file of files) {
311
+ if (file.endsWith('.json') && !file.includes('package')) {
312
+ try {
313
+ const filePath = path_1.default.join(projectDir, file);
314
+ const content = await fs_1.promises.readFile(filePath, 'utf-8');
315
+ const json = JSON.parse(content);
316
+ // Check if it's an OpenAI Assistant schema (has openapi and paths)
317
+ if (json.openapi && typeof json.openapi === 'string' &&
318
+ json.paths && typeof json.paths === 'object') {
319
+ assistants.push(file);
320
+ }
321
+ }
322
+ catch {
323
+ // Not valid JSON or not OpenAI format, skip
324
+ }
325
+ }
326
+ }
327
+ }
328
+ catch {
329
+ // Directory read error, return empty
330
+ }
331
+ return assistants;
332
+ }
333
+ /**
334
+ * Detect project type from files and structure
335
+ *
336
+ * CHAMPIONSHIP DETECTION STRATEGY:
337
+ * 1. 😽 TURBO-CAT: Format discovery (finds config files)
338
+ * 2. 🛂 TSA: Dependency intelligence (analyzes actual usage)
339
+ * 3. Cross-reference both engines for definitive answer
340
+ * 4. Fallback to file patterns if engines unavailable
341
+ *
342
+ * Goal: Championship-grade detection using existing engines
343
+ */
344
+ async function detectProjectType(projectDir = process.cwd()) {
345
+ // PHASE 1: TURBO-CAT + TSA CHAMPIONSHIP DETECTION
346
+ // ============================================================================
347
+ try {
348
+ // Try to use TSA for smart dependency analysis (if package.json exists)
349
+ const packageJsonPath = path_1.default.join(projectDir, "package.json");
350
+ if (await fileExists(packageJsonPath)) {
351
+ try {
352
+ // Dynamic import to avoid circular dependencies and performance impact
353
+ const { DependencyTSA } = await import('../engines/dependency-tsa.js');
354
+ const tsa = new DependencyTSA(projectDir);
355
+ const report = await tsa.inspect();
356
+ // Analyze CORE dependencies (>10 imports = actually used)
357
+ const coreDeps = report.inspections
358
+ .filter((i) => i.status === 'CORE')
359
+ .map((i) => i.package);
360
+ const activeDeps = report.inspections
361
+ .filter((i) => i.status === 'ACTIVE')
362
+ .map((i) => i.package);
363
+ // Read package.json for structural hints
364
+ const packageContent = await fs_1.promises.readFile(packageJsonPath, "utf-8");
365
+ const packageData = JSON.parse(packageContent);
366
+ // Check for TypeScript
367
+ const hasTypeScript = await fileExists(path_1.default.join(projectDir, "tsconfig.json")) ||
368
+ coreDeps.includes('typescript') ||
369
+ activeDeps.includes('typescript');
370
+ // PRIORITY 1: CLI DETECTION (package.json.bin is DEFINITIVE)
371
+ if (packageData.bin) {
372
+ return hasTypeScript ? "cli-ts" : "cli";
373
+ }
374
+ // Secondary CLI check using TSA intelligence
375
+ const cliDeps = ['commander', 'yargs', 'oclif', 'inquirer'];
376
+ const hasCliCore = coreDeps.some((dep) => cliDeps.includes(dep));
377
+ const hasCliActive = activeDeps.some((dep) => cliDeps.includes(dep));
378
+ if (hasCliCore || hasCliActive) {
379
+ return hasTypeScript ? "cli-ts" : "cli";
380
+ }
381
+ // PRIORITY 2: FULLSTACK (based on CORE usage)
382
+ if (coreDeps.includes('next') || coreDeps.includes('@next/core')) {
383
+ return hasTypeScript ? "fullstack-ts" : "fullstack";
384
+ }
385
+ if (coreDeps.includes('nuxt') || coreDeps.includes('@nuxt/core')) {
386
+ return hasTypeScript ? "fullstack-ts" : "fullstack";
387
+ }
388
+ if (coreDeps.includes('@sveltejs/kit')) {
389
+ return hasTypeScript ? "svelte-ts" : "svelte";
390
+ }
391
+ // PRIORITY 3: FRONTEND (based on CORE usage)
392
+ if (coreDeps.includes('react') || coreDeps.includes('react-dom')) {
393
+ return hasTypeScript ? "react-ts" : "react";
394
+ }
395
+ if (coreDeps.includes('vue') || coreDeps.includes('@vue/core')) {
396
+ return hasTypeScript ? "vue-ts" : "vue";
397
+ }
398
+ if (coreDeps.includes('svelte')) {
399
+ return hasTypeScript ? "svelte-ts" : "svelte";
400
+ }
401
+ if (coreDeps.includes('angular') || coreDeps.includes('@angular/core')) {
402
+ return "angular";
403
+ }
404
+ // PRIORITY 4: BACKEND/API (based on CORE usage)
405
+ const backendFrameworks = ['express', 'fastify', 'koa', 'hapi'];
406
+ if (coreDeps.some((dep) => backendFrameworks.includes(dep))) {
407
+ return hasTypeScript ? "node-api-ts" : "node-api";
408
+ }
409
+ // If TSA worked but found nothing definitive, continue to fallback
410
+ }
411
+ catch (tsaError) {
412
+ // TSA failed or not available, continue to fallback detection
413
+ }
414
+ }
415
+ }
416
+ catch {
417
+ // TURBO-CAT/TSA unavailable, use fallback detection
418
+ }
419
+ // PHASE 2: FALLBACK DETECTION (when engines unavailable)
420
+ // ============================================================================
421
+ // TypeScript detection - check for tsconfig.json
422
+ const tsconfigPath = path_1.default.join(projectDir, "tsconfig.json");
423
+ let hasTypeScript = false;
424
+ if (await fileExists(tsconfigPath)) {
425
+ hasTypeScript = true;
426
+ }
427
+ // Check for package.json (fallback to naive dependency checking)
428
+ const packageJsonPath = path_1.default.join(projectDir, "package.json");
429
+ if (await fileExists(packageJsonPath)) {
430
+ try {
431
+ const packageContent = await fs_1.promises.readFile(packageJsonPath, "utf-8");
432
+ const packageData = JSON.parse(packageContent);
433
+ // Check dependencies for framework indicators (NAIVE - no usage analysis)
434
+ const deps = {
435
+ ...packageData.dependencies,
436
+ ...packageData.devDependencies,
437
+ };
438
+ // Detect TypeScript in dependencies
439
+ if (deps.typescript ||
440
+ deps["@types/node"] ||
441
+ Object.keys(deps).some((dep) => dep.startsWith("@types/"))) {
442
+ hasTypeScript = true;
443
+ }
444
+ // CLI detection (structural only, no TSA intelligence)
445
+ if (packageData.bin) {
446
+ return hasTypeScript ? "cli-ts" : "cli";
447
+ }
448
+ const hasCliDeps = deps.commander || deps.yargs || deps.oclif || deps.inquirer;
449
+ const hasCliKeywords = packageData.keywords?.includes('cli') ||
450
+ packageData.keywords?.includes('command-line');
451
+ const hasCliName = packageData.name?.includes('cli');
452
+ if (hasCliDeps || hasCliKeywords || hasCliName) {
453
+ return hasTypeScript ? "cli-ts" : "cli";
454
+ }
455
+ // Framework detection (naive - just checks if dependency exists)
456
+ if (deps.next || deps["@next/core"]) {
457
+ return hasTypeScript ? "fullstack-ts" : "fullstack";
458
+ }
459
+ if (deps.nuxt || deps["@nuxt/core"]) {
460
+ return hasTypeScript ? "fullstack-ts" : "fullstack";
461
+ }
462
+ if (deps["@sveltejs/kit"]) {
463
+ return hasTypeScript ? "svelte-ts" : "svelte";
464
+ }
465
+ if (deps.react || deps["react-dom"]) {
466
+ return hasTypeScript ? "react-ts" : "react";
467
+ }
468
+ if (deps.vue || deps["@vue/core"]) {
469
+ return hasTypeScript ? "vue-ts" : "vue";
470
+ }
471
+ if (deps.svelte) {
472
+ return hasTypeScript ? "svelte-ts" : "svelte";
473
+ }
474
+ if (deps.angular || deps["@angular/core"]) {
475
+ return "angular";
476
+ }
477
+ if (deps.express || deps.fastify || deps.koa || deps.hapi) {
478
+ return hasTypeScript ? "node-api-ts" : "node-api";
479
+ }
480
+ }
481
+ catch {
482
+ // Continue with file-based detection
483
+ }
484
+ }
485
+ // PHASE 3: PYTHON DETECTION (check for Python-specific files)
486
+ // ============================================================================
487
+ const pythonType = await detectPythonProjectType(projectDir);
488
+ if (pythonType !== "latest-idea") {
489
+ return pythonType;
490
+ }
491
+ // PHASE 3: FILE-BASED DETECTION (when package.json unavailable or inconclusive)
492
+ // ============================================================================
493
+ const ignorePatterns = await (0, fafignore_parser_1.parseFafIgnore)(projectDir);
494
+ // File-based detection - using native file finder (NO GLOB!)
495
+ const files = await native_file_finder_js_1.globReplacements.allSource(projectDir, {
496
+ ignore: ignorePatterns.filter((p) => !p.startsWith("*.")) // Remove *.ext patterns
497
+ });
498
+ // ============================================================================
499
+ // PRIORITY 5: PYTHON FILE DETECTION (fallback when no pyproject.toml/requirements.txt)
500
+ // ============================================================================
501
+ if (files.some((f) => f.endsWith(".py"))) {
502
+ const pythonPatternType = await detectPythonPatterns(projectDir, files.filter((f) => f.endsWith(".py")));
503
+ if (pythonPatternType !== "python-generic") {
504
+ return pythonPatternType;
505
+ }
506
+ return "python-generic";
507
+ }
508
+ // ============================================================================
509
+ // PRIORITY 6: FRAMEWORK FILE PATTERNS (when no package.json found)
510
+ // ============================================================================
511
+ // TypeScript file detection
512
+ if (files.some((f) => f.endsWith(".ts") && !f.endsWith(".d.ts"))) {
513
+ hasTypeScript = true;
514
+ }
515
+ // Check for framework-specific file extensions
516
+ const hasSvelteFiles = files.some((f) => f.endsWith(".svelte"));
517
+ const hasReactFiles = files.some((f) => f.endsWith(".jsx") || f.endsWith(".tsx"));
518
+ const hasVueFiles = files.some((f) => f.endsWith(".vue"));
519
+ if (hasSvelteFiles) {
520
+ return hasTypeScript ? "svelte-ts" : "svelte";
521
+ }
522
+ if (hasReactFiles) {
523
+ return hasTypeScript ? "react-ts" : "react";
524
+ }
525
+ if (hasVueFiles) {
526
+ return hasTypeScript ? "vue-ts" : "vue";
527
+ }
528
+ // ============================================================================
529
+ // PRIORITY 7: STATIC HTML DETECTION (no package.json, has HTML/CSS)
530
+ // ============================================================================
531
+ const hasIndexHtml = files.some((f) => f.endsWith('index.html') || f === 'index.html');
532
+ const hasCssFiles = files.some((f) => f.endsWith('.css'));
533
+ const hasHtmlFiles = files.some((f) => f.endsWith('.html'));
534
+ // Check for package.json ONLY in project directory (not parent directories)
535
+ const projectPackageJson = path_1.default.join(projectDir, 'package.json');
536
+ const hasProjectPackageJson = await fileExists(projectPackageJson);
537
+ // Detect static HTML: index.html without package.json in project dir + (CSS files OR other HTML files)
538
+ if (hasIndexHtml && !hasProjectPackageJson && (hasCssFiles || hasHtmlFiles)) {
539
+ return 'static-html';
540
+ }
541
+ // ============================================================================
542
+ // PRIORITY 8: PURE TYPESCRIPT PROJECT (has .ts files but no framework)
543
+ // ============================================================================
544
+ if (hasTypeScript) {
545
+ return "typescript";
546
+ }
547
+ // ============================================================================
548
+ // FINAL FALLBACK: Unknown/early-stage project
549
+ // ============================================================================
550
+ return "latest-idea";
551
+ }
552
+ /**
553
+ * Calculate days since file was modified
554
+ */
555
+ function daysSinceModified(date) {
556
+ const now = new Date();
557
+ const diffTime = Math.abs(now.getTime() - date.getTime());
558
+ return Math.ceil(diffTime / (1000 * 60 * 60 * 24));
559
+ }
560
+ /**
561
+ * Detect Python project type using dependency files (Option A)
562
+ */
563
+ async function detectPythonProjectType(projectDir) {
564
+ // Priority order: pyproject.toml > requirements.txt
565
+ const pyprojectPath = await findPyprojectToml(projectDir);
566
+ if (pyprojectPath) {
567
+ const framework = await analyzePyprojectToml(pyprojectPath);
568
+ if (framework) {
569
+ return framework;
570
+ }
571
+ }
572
+ const requirementsPath = await findRequirementsTxt(projectDir);
573
+ if (requirementsPath) {
574
+ const framework = await analyzeRequirementsTxt(requirementsPath);
575
+ if (framework) {
576
+ return framework;
577
+ }
578
+ }
579
+ return "latest-idea";
580
+ }
581
+ /**
582
+ * Analyze pyproject.toml for Python frameworks
583
+ */
584
+ async function analyzePyprojectToml(filePath) {
585
+ try {
586
+ const content = await fs_1.promises.readFile(filePath, "utf-8");
587
+ // Simple string-based detection for now (could use TOML parser later)
588
+ if (content.includes("fastapi")) {
589
+ return "python-fastapi";
590
+ }
591
+ if (content.includes("django")) {
592
+ return "python-django";
593
+ }
594
+ if (content.includes("flask")) {
595
+ return "python-flask";
596
+ }
597
+ if (content.includes("starlette")) {
598
+ return "python-starlette";
599
+ }
600
+ // If it has Python dependencies but no specific framework
601
+ if (content.includes("python = ")) {
602
+ return "python-generic";
603
+ }
604
+ return null;
605
+ }
606
+ catch {
607
+ return null;
608
+ }
609
+ }
610
+ /**
611
+ * Analyze requirements.txt for Python frameworks
612
+ */
613
+ async function analyzeRequirementsTxt(filePath) {
614
+ try {
615
+ const content = await fs_1.promises.readFile(filePath, "utf-8");
616
+ if (content.includes("fastapi")) {
617
+ return "python-fastapi";
618
+ }
619
+ if (content.includes("django")) {
620
+ return "python-django";
621
+ }
622
+ if (content.includes("flask")) {
623
+ return "python-flask";
624
+ }
625
+ if (content.includes("starlette")) {
626
+ return "python-starlette";
627
+ }
628
+ // Any Python packages detected
629
+ if (content.trim().length > 0) {
630
+ return "python-generic";
631
+ }
632
+ return null;
633
+ }
634
+ catch {
635
+ return null;
636
+ }
637
+ }
638
+ /**
639
+ * Detect Python frameworks using code patterns (Option B)
640
+ */
641
+ async function detectPythonPatterns(projectDir, pythonFiles) {
642
+ try {
643
+ // Check main Python files first (main.py, app.py, api.py)
644
+ const mainFiles = pythonFiles.filter((f) => f.includes("main.py") || f.includes("app.py") || f.includes("api.py"));
645
+ const filesToCheck = mainFiles.length > 0 ? mainFiles : pythonFiles.slice(0, 5);
646
+ for (const file of filesToCheck) {
647
+ const filePath = path_1.default.join(projectDir, file);
648
+ try {
649
+ const content = await fs_1.promises.readFile(filePath, "utf-8");
650
+ // FastAPI patterns
651
+ if (content.includes("from fastapi import") ||
652
+ content.includes("FastAPI()")) {
653
+ return "python-fastapi";
654
+ }
655
+ // Django patterns
656
+ if (content.includes("from django.") ||
657
+ content.includes("django.http")) {
658
+ return "python-django";
659
+ }
660
+ // Flask patterns
661
+ if (content.includes("from flask import") ||
662
+ content.includes("Flask(")) {
663
+ return "python-flask";
664
+ }
665
+ // Starlette patterns
666
+ if (content.includes("from starlette.") ||
667
+ content.includes("Starlette(")) {
668
+ return "python-starlette";
669
+ }
670
+ }
671
+ catch {
672
+ continue;
673
+ }
674
+ }
675
+ return "python-generic";
676
+ }
677
+ catch {
678
+ return "python-generic";
679
+ }
680
+ }
681
+ /**
682
+ * Calculate TypeScript strictness level for F1-Inspired quality assessment
683
+ */
684
+ function calculateStrictnessLevel(compilerOptions) {
685
+ let strictnessScore = 0;
686
+ // Basic strictness
687
+ if (compilerOptions.strict) {
688
+ strictnessScore += 2;
689
+ }
690
+ if (compilerOptions.noImplicitAny) {
691
+ strictnessScore += 1;
692
+ }
693
+ if (compilerOptions.strictNullChecks) {
694
+ strictnessScore += 1;
695
+ }
696
+ // Advanced strictness
697
+ if (compilerOptions.exactOptionalPropertyTypes) {
698
+ strictnessScore += 2;
699
+ }
700
+ if (compilerOptions.noUncheckedIndexedAccess) {
701
+ strictnessScore += 2;
702
+ }
703
+ if (compilerOptions.noImplicitReturns) {
704
+ strictnessScore += 1;
705
+ }
706
+ if (compilerOptions.noFallthroughCasesInSwitch) {
707
+ strictnessScore += 1;
708
+ }
709
+ if (compilerOptions.noUnusedLocals) {
710
+ strictnessScore += 1;
711
+ }
712
+ if (compilerOptions.noUnusedParameters) {
713
+ strictnessScore += 1;
714
+ }
715
+ // F1-Inspired ultra-strict
716
+ if (compilerOptions.allowUnreachableCode === false) {
717
+ strictnessScore += 1;
718
+ }
719
+ if (compilerOptions.allowUnusedLabels === false) {
720
+ strictnessScore += 1;
721
+ }
722
+ if (compilerOptions.noPropertyAccessFromIndexSignature) {
723
+ strictnessScore += 1;
724
+ }
725
+ if (compilerOptions.verbatimModuleSyntax) {
726
+ strictnessScore += 1;
727
+ }
728
+ if (strictnessScore >= 12) {
729
+ return "f1_inspired";
730
+ }
731
+ if (strictnessScore >= 8) {
732
+ return "ultra_strict";
733
+ }
734
+ if (strictnessScore >= 4) {
735
+ return "strict";
736
+ }
737
+ return "basic";
738
+ }
739
+ /**
740
+ * Detect framework integration patterns
741
+ */
742
+ function detectFrameworkIntegration(compilerOptions, config) {
743
+ const includes = config.include || [];
744
+ const includesStr = includes.join(" ");
745
+ // Svelte detection
746
+ if (includesStr.includes("svelte") || config.extends?.includes("svelte")) {
747
+ if (compilerOptions.verbatimModuleSyntax) {
748
+ return "svelte_5_runes_native";
749
+ }
750
+ return "svelte_native";
751
+ }
752
+ // React detection
753
+ if (compilerOptions.jsx) {
754
+ if (compilerOptions.jsx === "react-jsx") {
755
+ return "react_17_native";
756
+ }
757
+ return "react_native";
758
+ }
759
+ // Next.js detection
760
+ if (config.extends?.includes("next")) {
761
+ return "nextjs_native";
762
+ }
763
+ // Vue detection
764
+ if (includesStr.includes("vue")) {
765
+ return "vue_native";
766
+ }
767
+ // Node.js detection
768
+ if (compilerOptions.moduleResolution === "NodeNext") {
769
+ return "nodejs_native";
770
+ }
771
+ if (compilerOptions.module === "NodeNext") {
772
+ return "nodejs_esm_native";
773
+ }
774
+ // Pure TypeScript project detection
775
+ if (compilerOptions.target &&
776
+ compilerOptions.module &&
777
+ !compilerOptions.jsx) {
778
+ return "pure_typescript";
779
+ }
780
+ return "standard";
781
+ }
782
+ /**
783
+ * Detect performance optimizations
784
+ */
785
+ function detectPerformanceConfig(compilerOptions) {
786
+ const optimizations = [];
787
+ if (compilerOptions.target && compilerOptions.target.includes("2022")) {
788
+ optimizations.push("modern_target_es2022");
789
+ }
790
+ if (compilerOptions.moduleResolution === "NodeNext") {
791
+ optimizations.push("nodejs_native_modules");
792
+ }
793
+ if (compilerOptions.verbatimModuleSyntax) {
794
+ optimizations.push("verbatim_module_syntax");
795
+ }
796
+ if (compilerOptions.isolatedModules) {
797
+ optimizations.push("isolated_modules");
798
+ }
799
+ if (compilerOptions.skipLibCheck) {
800
+ optimizations.push("skip_lib_check");
801
+ }
802
+ if (compilerOptions.allowImportingTsExtensions) {
803
+ optimizations.push("ts_extension_imports");
804
+ }
805
+ return optimizations;
806
+ }
807
+ /**
808
+ * Assess overall engineering quality based on configuration
809
+ */
810
+ function assessEngineeringQuality(compilerOptions) {
811
+ let qualityScore = 0;
812
+ // Quality indicators
813
+ if (compilerOptions.declaration) {
814
+ qualityScore += 1;
815
+ }
816
+ if (compilerOptions.declarationMap) {
817
+ qualityScore += 1;
818
+ }
819
+ if (compilerOptions.sourceMap) {
820
+ qualityScore += 1;
821
+ }
822
+ if (compilerOptions.forceConsistentCasingInFileNames) {
823
+ qualityScore += 1;
824
+ }
825
+ if (compilerOptions.removeComments === false) {
826
+ qualityScore += 1;
827
+ } // Keeping docs
828
+ // F1-Inspired indicators
829
+ if (compilerOptions.exactOptionalPropertyTypes) {
830
+ qualityScore += 2;
831
+ }
832
+ if (compilerOptions.noUncheckedIndexedAccess) {
833
+ qualityScore += 2;
834
+ }
835
+ if (compilerOptions.verbatimModuleSyntax) {
836
+ qualityScore += 2;
837
+ }
838
+ if (qualityScore >= 8) {
839
+ return "f1_inspired";
840
+ }
841
+ if (qualityScore >= 5) {
842
+ return "professional";
843
+ }
844
+ return "standard";
845
+ }
846
+ //# sourceMappingURL=file-utils.js.map