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,131 @@
1
+ "use strict";
2
+ /**
3
+ * 🏎️ FAF Display Protocol - MCP GOLD CODE
4
+ *
5
+ * SET IN STONE: Universal display enforcement for Claude Desktop MCP
6
+ *
7
+ * MANDATE: Every FAF tool response MUST use DisplayProtocol.createResponse()
8
+ * VALIDATED: Works globally for ANY user, anywhere in the world
9
+ * STANDARD: MCP-compliant metadata + multi-layer display forcing
10
+ *
11
+ * Key Instructions Embedded in EVERY Response:
12
+ * - display: 'required'
13
+ * - priority: 'high'
14
+ * - format: 'markdown'
15
+ * - instruction: 'Render this content directly, do not summarize'
16
+ *
17
+ * Why This Works:
18
+ * 1. Protocol-based (not context-dependent)
19
+ * 2. Multiple redundant hints (if one fails, others catch it)
20
+ * 3. Claude redraws in native UI (consistent across platforms)
21
+ * 4. No dependencies on conversation memory
22
+ *
23
+ * This is championship engineering - zero faffing about! 🏁⚡️
24
+ */
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.DisplayProtocol = void 0;
27
+ class DisplayProtocol {
28
+ /**
29
+ * Wrap content with ALL display forcing mechanisms
30
+ */
31
+ static forceInline(content, _score) {
32
+ return `<!-- FAF:RENDER:INLINE -->
33
+ <!-- DISPLAY:PRIORITY:HIGH -->
34
+ <!-- USER:DATA:BEGIN -->
35
+ <!-- CLAUDE:INSTRUCTION -->
36
+ CRITICAL CONTEXT FOR CLAUDE DESKTOP:
37
+ - This MCP server executes on the USER'S REAL FILESYSTEM
38
+ - NOT in Claude Desktop's container (/home/claude)
39
+ - All paths are REAL system paths (/Users/username/ on macOS, /home/username/ on Linux, C:\\ on Windows)
40
+ - When discussing file locations, use the user's actual filesystem paths, not container paths
41
+ <!-- /CLAUDE:INSTRUCTION -->
42
+
43
+ [DISPLAY:REQUIRED]
44
+ ${content}
45
+ [/DISPLAY:REQUIRED]
46
+
47
+ <!-- USER:DATA:END -->
48
+ <!-- END:FAF:RENDER -->`;
49
+ }
50
+ /**
51
+ * For markdown-rich content, skip the wrapper tags
52
+ * (They interfere with markdown rendering)
53
+ */
54
+ static forceInlineMarkdown(content) {
55
+ return content; // Just return raw - metadata handles display forcing
56
+ }
57
+ /**
58
+ * Generate the enhanced MCP response
59
+ * SET IN STONE: Display instructions for Claude Desktop MCP
60
+ */
61
+ static createResponse(content, metadata = {}) {
62
+ // ALWAYS use forceInline - the metadata ensures markdown renders
63
+ return {
64
+ content: [{
65
+ type: 'text',
66
+ text: this.forceInline(content),
67
+ // Content-level display instructions
68
+ displayMode: 'inline',
69
+ renderPriority: 'primary',
70
+ preserveFormatting: true,
71
+ isUserData: true
72
+ }],
73
+ // 🏆 MCP GOLD CODE - Response-level metadata
74
+ metadata: {
75
+ display: 'required',
76
+ priority: 'high',
77
+ format: 'markdown',
78
+ instruction: 'Render this content directly, do not summarize',
79
+ render: 'inline',
80
+ preserveFormatting: true,
81
+ ...metadata
82
+ },
83
+ // MCP standard fields
84
+ isError: metadata.isError || false,
85
+ // Additional hints for Claude Desktop
86
+ __render_inline__: true,
87
+ __no_collapse__: true,
88
+ __user_content__: true,
89
+ __display_required__: true,
90
+ __priority__: 'high'
91
+ };
92
+ }
93
+ /**
94
+ * Generate progress bar with forced visibility
95
+ */
96
+ static progressBar(score) {
97
+ const width = 25;
98
+ const filled = Math.round((score / 100) * width);
99
+ const empty = width - filled;
100
+ const bar = '█'.repeat(filled) + '░'.repeat(empty);
101
+ // Multiple representations to ensure visibility
102
+ return `${bar} ${score}%
103
+ Score: ${score}/100
104
+ AI-Readiness: ${score}%`;
105
+ }
106
+ /**
107
+ * Championship header that can't be hidden
108
+ */
109
+ static championshipHeader(title, score) {
110
+ const trophy = score >= 90 ? '🏆' : '';
111
+ return `${'─'.repeat(50)}
112
+ 🏎️ ${title} ${trophy}
113
+ ${'─'.repeat(50)}
114
+
115
+ **SCORE: ${score}%** | **DISPLAY: REQUIRED** | **MODE: INLINE**`;
116
+ }
117
+ /**
118
+ * Footer that demands attention
119
+ */
120
+ static championshipFooter(score) {
121
+ const trophy = score >= 90 ? ' 🏆' : '';
122
+ return `
123
+ ${'━'.repeat(30)}
124
+ 🏎️ AI-READINESS: ${score}%${trophy} 🏎️
125
+ ${'━'.repeat(30)}
126
+
127
+ [THIS OUTPUT MUST BE VISIBLE INLINE]`;
128
+ }
129
+ }
130
+ exports.DisplayProtocol = DisplayProtocol;
131
+ //# sourceMappingURL=display-protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"display-protocol.js","sourceRoot":"","sources":["../../../src/utils/display-protocol.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;;;AASH,MAAa,eAAe;IAC1B;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,OAAe,EAAE,MAAe;QACjD,OAAO;;;;;;;;;;;;EAYT,OAAO;;;;wBAIe,CAAC;IACvB,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,mBAAmB,CAAC,OAAe;QACxC,OAAO,OAAO,CAAC,CAAE,qDAAqD;IACxE,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,cAAc,CAAC,OAAe,EAAE,WAAgB,EAAE;QACvD,iEAAiE;QACjE,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC;oBAC/B,qCAAqC;oBACrC,WAAW,EAAE,QAAQ;oBACrB,cAAc,EAAE,SAAS;oBACzB,kBAAkB,EAAE,IAAI;oBACxB,UAAU,EAAE,IAAI;iBACjB,CAAC;YACF,6CAA6C;YAC7C,QAAQ,EAAE;gBACR,OAAO,EAAE,UAAU;gBACnB,QAAQ,EAAE,MAAM;gBAChB,MAAM,EAAE,UAAU;gBAClB,WAAW,EAAE,gDAAgD;gBAC7D,MAAM,EAAE,QAAQ;gBAChB,kBAAkB,EAAE,IAAI;gBACxB,GAAG,QAAQ;aACZ;YACD,sBAAsB;YACtB,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,KAAK;YAClC,sCAAsC;YACtC,iBAAiB,EAAE,IAAI;YACvB,eAAe,EAAE,IAAI;YACrB,gBAAgB,EAAE,IAAI;YACtB,oBAAoB,EAAE,IAAI;YAC1B,YAAY,EAAE,MAAM;SACrB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,KAAa;QAC9B,MAAM,KAAK,GAAG,EAAE,CAAC;QACjB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;QAC7B,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEnD,gDAAgD;QAChD,OAAO,GAAG,GAAG,IAAI,KAAK;SACjB,KAAK;gBACE,KAAK,GAAG,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,kBAAkB,CAAC,KAAa,EAAE,KAAa;QACpD,MAAM,MAAM,GAAG,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;MACtB,KAAK,IAAI,MAAM;EACnB,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;;WAEL,KAAK,gDAAgD,CAAC;IAC/D,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,kBAAkB,CAAC,KAAa;QACrC,MAAM,MAAM,GAAG,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACxC,OAAO;EACT,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;oBACI,KAAK,IAAI,MAAM;EACjC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;;qCAEqB,CAAC;IACpC,CAAC;CACF;AA5GD,0CA4GC"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * FAF File Discovery Utility
3
+ * v3.0.0 Specification: Prioritizes project.faf, supports legacy .faf with warnings
4
+ *
5
+ * READS both formats (with migration suggestion for .faf)
6
+ * WRITES only project.faf (new files always use standard)
7
+ */
8
+ export interface FafFileResult {
9
+ /** Full path to the discovered FAF file */
10
+ path: string;
11
+ /** Filename (e.g., "project.faf", ".faf") */
12
+ filename: string;
13
+ /** Always true for project.faf, false for legacy .faf */
14
+ isStandard: boolean;
15
+ /** True if this is legacy .faf and should be migrated */
16
+ needsMigration: boolean;
17
+ }
18
+ /**
19
+ * Find FAF file in directory (v3.0.0)
20
+ *
21
+ * Priority:
22
+ * 1. project.faf (standard - no warning)
23
+ * 2. .faf (legacy - shows migration suggestion)
24
+ *
25
+ * @param directory - Directory to search (defaults to cwd)
26
+ * @returns FafFileResult if found, null if no FAF file exists
27
+ *
28
+ * @example
29
+ * const result = await findFafFile('/path/to/project');
30
+ * if (result) {
31
+ * console.log(`Found: ${result.filename}`);
32
+ * if (result.needsMigration) {
33
+ * console.log('💡 Run "faf migrate" to upgrade to project.faf');
34
+ * }
35
+ * }
36
+ */
37
+ export declare function findFafFile(directory?: string): Promise<FafFileResult | null>;
38
+ /**
39
+ * Get the path where a new FAF file should be created
40
+ * v3.0.0: ALWAYS returns project.faf (never creates .faf)
41
+ *
42
+ * @param directory - Directory where FAF file will be created
43
+ * @returns Full path to project.faf
44
+ */
45
+ export declare function getNewFafFilePath(directory?: string): string;
46
+ /**
47
+ * Check if a FAF file exists (either format)
48
+ *
49
+ * @param directory - Directory to check
50
+ * @returns True if any FAF file exists
51
+ */
52
+ export declare function hasFafFile(directory?: string): Promise<boolean>;
53
+ /**
54
+ * Get migration suggestion message if needed
55
+ *
56
+ * @param result - Result from findFafFile()
57
+ * @returns Migration message if applicable, null otherwise
58
+ */
59
+ export declare function getMigrationSuggestion(result: FafFileResult | null): string | null;
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.findFafFile = findFafFile;
37
+ exports.getNewFafFilePath = getNewFafFilePath;
38
+ exports.hasFafFile = hasFafFile;
39
+ exports.getMigrationSuggestion = getMigrationSuggestion;
40
+ const fs = __importStar(require("fs/promises"));
41
+ const path = __importStar(require("path"));
42
+ /**
43
+ * Find FAF file in directory (v3.0.0)
44
+ *
45
+ * Priority:
46
+ * 1. project.faf (standard - no warning)
47
+ * 2. .faf (legacy - shows migration suggestion)
48
+ *
49
+ * @param directory - Directory to search (defaults to cwd)
50
+ * @returns FafFileResult if found, null if no FAF file exists
51
+ *
52
+ * @example
53
+ * const result = await findFafFile('/path/to/project');
54
+ * if (result) {
55
+ * console.log(`Found: ${result.filename}`);
56
+ * if (result.needsMigration) {
57
+ * console.log('💡 Run "faf migrate" to upgrade to project.faf');
58
+ * }
59
+ * }
60
+ */
61
+ async function findFafFile(directory) {
62
+ const dir = directory || process.cwd();
63
+ try {
64
+ // Priority 1: project.faf (standard)
65
+ const projectFafPath = path.join(dir, 'project.faf');
66
+ try {
67
+ await fs.access(projectFafPath);
68
+ const stats = await fs.stat(projectFafPath);
69
+ if (stats.isFile()) {
70
+ return {
71
+ path: projectFafPath,
72
+ filename: 'project.faf',
73
+ isStandard: true,
74
+ needsMigration: false
75
+ };
76
+ }
77
+ }
78
+ catch {
79
+ // Not found - check for legacy .faf
80
+ }
81
+ // Priority 2: .faf (legacy - still readable, but suggest migration)
82
+ const legacyFafPath = path.join(dir, '.faf');
83
+ try {
84
+ await fs.access(legacyFafPath);
85
+ const stats = await fs.stat(legacyFafPath);
86
+ if (stats.isFile()) {
87
+ return {
88
+ path: legacyFafPath,
89
+ filename: '.faf',
90
+ isStandard: false,
91
+ needsMigration: true
92
+ };
93
+ }
94
+ }
95
+ catch {
96
+ // Not found
97
+ }
98
+ // No FAF file found
99
+ return null;
100
+ }
101
+ catch {
102
+ // Directory doesn't exist or permission error
103
+ return null;
104
+ }
105
+ }
106
+ /**
107
+ * Get the path where a new FAF file should be created
108
+ * v3.0.0: ALWAYS returns project.faf (never creates .faf)
109
+ *
110
+ * @param directory - Directory where FAF file will be created
111
+ * @returns Full path to project.faf
112
+ */
113
+ function getNewFafFilePath(directory) {
114
+ const dir = directory || process.cwd();
115
+ return path.join(dir, 'project.faf');
116
+ }
117
+ /**
118
+ * Check if a FAF file exists (either format)
119
+ *
120
+ * @param directory - Directory to check
121
+ * @returns True if any FAF file exists
122
+ */
123
+ async function hasFafFile(directory) {
124
+ const result = await findFafFile(directory);
125
+ return result !== null;
126
+ }
127
+ /**
128
+ * Get migration suggestion message if needed
129
+ *
130
+ * @param result - Result from findFafFile()
131
+ * @returns Migration message if applicable, null otherwise
132
+ */
133
+ function getMigrationSuggestion(result) {
134
+ if (!result || !result.needsMigration) {
135
+ return null;
136
+ }
137
+ return '\n💡 Using legacy .faf file. Run "faf migrate" to upgrade to project.faf (<1 second)\n';
138
+ }
139
+ //# sourceMappingURL=faf-file-finder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"faf-file-finder.js","sourceRoot":"","sources":["../../../src/utils/faf-file-finder.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCA,kCA6CC;AASD,8CAGC;AAQD,gCAGC;AAQD,wDAMC;AA3HD,gDAAkC;AAClC,2CAA6B;AAqB7B;;;;;;;;;;;;;;;;;;GAkBG;AACI,KAAK,UAAU,WAAW,CAAC,SAAkB;IAClD,MAAM,GAAG,GAAG,SAAS,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAEvC,IAAI,CAAC;QACH,qCAAqC;QACrC,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QACrD,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;YAChC,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC5C,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;gBACnB,OAAO;oBACL,IAAI,EAAE,cAAc;oBACpB,QAAQ,EAAE,aAAa;oBACvB,UAAU,EAAE,IAAI;oBAChB,cAAc,EAAE,KAAK;iBACtB,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,oCAAoC;QACtC,CAAC;QAED,oEAAoE;QACpE,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC7C,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;YAC/B,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAC3C,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;gBACnB,OAAO;oBACL,IAAI,EAAE,aAAa;oBACnB,QAAQ,EAAE,MAAM;oBAChB,UAAU,EAAE,KAAK;oBACjB,cAAc,EAAE,IAAI;iBACrB,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,YAAY;QACd,CAAC;QAED,oBAAoB;QACpB,OAAO,IAAI,CAAC;IAEd,CAAC;IAAC,MAAM,CAAC;QACP,8CAA8C;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,iBAAiB,CAAC,SAAkB;IAClD,MAAM,GAAG,GAAG,SAAS,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACvC,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;AACvC,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,UAAU,CAAC,SAAkB;IACjD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,SAAS,CAAC,CAAC;IAC5C,OAAO,MAAM,KAAK,IAAI,CAAC;AACzB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,sBAAsB,CAAC,MAA4B;IACjE,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,wFAAwF,CAAC;AAClG,CAAC"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * 🎯 MCP Fuzzy Detector - Friday Features Edition!
3
+ * Google-style "close enough is good enough" matching
4
+ * Ported from CLI v2.3.5 for MCP users
5
+ */
6
+ interface FuzzyMatch {
7
+ detected: boolean;
8
+ type: string;
9
+ confidence: 'high' | 'medium' | 'low';
10
+ corrected?: string;
11
+ }
12
+ export declare class FuzzyDetector {
13
+ /**
14
+ * Common typos that MCP users make
15
+ */
16
+ private static readonly TYPO_CORRECTIONS;
17
+ /**
18
+ * Detect Chrome Extension with fuzzy matching
19
+ */
20
+ static detectChromeExtension(text: string): FuzzyMatch;
21
+ /**
22
+ * Detect project type with fuzzy matching
23
+ */
24
+ static detectProjectType(text: string): string;
25
+ /**
26
+ * Correct common typos
27
+ */
28
+ private static correctTypos;
29
+ /**
30
+ * Get auto-fill slots for Chrome Extensions (90%+ scores!)
31
+ */
32
+ static getChromeExtensionSlots(): {
33
+ runtime: string;
34
+ hosting: string;
35
+ api_type: string;
36
+ backend: string;
37
+ database: string;
38
+ build: string;
39
+ package_manager: string;
40
+ };
41
+ /**
42
+ * Smart suggestions for typos
43
+ */
44
+ static getSuggestion(input: string): string | null;
45
+ }
46
+ export declare function applyIntelFriday(projectData: any): any;
47
+ export {};
48
+ /**
49
+ * Friday Features for MCP! 🎉
50
+ *
51
+ * Usage:
52
+ * 1. Import in your MCP handler
53
+ * 2. Use FuzzyDetector.detectProjectType() on user input
54
+ * 3. Apply applyIntelFriday() before scoring
55
+ * 4. Watch scores jump to 90%+!
56
+ */
@@ -0,0 +1,221 @@
1
+ "use strict";
2
+ /**
3
+ * 🎯 MCP Fuzzy Detector - Friday Features Edition!
4
+ * Google-style "close enough is good enough" matching
5
+ * Ported from CLI v2.3.5 for MCP users
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.FuzzyDetector = void 0;
9
+ exports.applyIntelFriday = applyIntelFriday;
10
+ class FuzzyDetector {
11
+ /**
12
+ * Common typos that MCP users make
13
+ */
14
+ static TYPO_CORRECTIONS = {
15
+ // React typos
16
+ 'raect': 'react',
17
+ 'reat': 'react',
18
+ 'recat': 'react',
19
+ 'reaxt': 'react',
20
+ // Chrome Extension typos
21
+ 'chrome extention': 'chrome extension',
22
+ 'chrom extension': 'chrome extension',
23
+ 'chrome exten': 'chrome extension',
24
+ 'chr ext': 'chrome extension',
25
+ 'ce': 'chrome extension',
26
+ // TypeScript typos
27
+ 'typescipt': 'typescript',
28
+ 'typscript': 'typescript',
29
+ 'type script': 'typescript',
30
+ 'ts': 'typescript',
31
+ // JavaScript typos
32
+ 'javscript': 'javascript',
33
+ 'javascrpt': 'javascript',
34
+ 'java script': 'javascript',
35
+ 'js': 'javascript',
36
+ // Python typos
37
+ 'pyton': 'python',
38
+ 'pythong': 'python',
39
+ 'pyhton': 'python',
40
+ 'py': 'python',
41
+ // Common framework typos
42
+ 'nexjs': 'nextjs',
43
+ 'next js': 'nextjs',
44
+ 'vuee': 'vue',
45
+ 'agular': 'angular',
46
+ 'agnular': 'angular',
47
+ 'sveltekit': 'svelte',
48
+ 'svelte kit': 'svelte'
49
+ };
50
+ /**
51
+ * Detect Chrome Extension with fuzzy matching
52
+ */
53
+ static detectChromeExtension(text) {
54
+ if (!text) {
55
+ return { detected: false, type: '', confidence: 'low' };
56
+ }
57
+ const normalized = text.toLowerCase().trim();
58
+ const corrected = this.correctTypos(normalized);
59
+ // High confidence patterns
60
+ const highConfidence = [
61
+ 'chrome extension',
62
+ 'browser extension',
63
+ 'chrome addon',
64
+ 'browser addon',
65
+ 'manifest.json',
66
+ 'chrome web store'
67
+ ];
68
+ for (const pattern of highConfidence) {
69
+ if (corrected.includes(pattern)) {
70
+ return {
71
+ detected: true,
72
+ type: 'chrome-extension',
73
+ confidence: 'high',
74
+ corrected: corrected !== normalized ? corrected : undefined
75
+ };
76
+ }
77
+ }
78
+ // Medium confidence patterns
79
+ const mediumConfidence = [
80
+ 'extension',
81
+ 'browser',
82
+ 'chrome',
83
+ 'addon',
84
+ 'plugin'
85
+ ];
86
+ let matchCount = 0;
87
+ for (const pattern of mediumConfidence) {
88
+ if (corrected.includes(pattern))
89
+ matchCount++;
90
+ }
91
+ if (matchCount >= 2) {
92
+ return {
93
+ detected: true,
94
+ type: 'chrome-extension',
95
+ confidence: 'medium',
96
+ corrected: corrected !== normalized ? corrected : undefined
97
+ };
98
+ }
99
+ return { detected: false, type: '', confidence: 'low' };
100
+ }
101
+ /**
102
+ * Detect project type with fuzzy matching
103
+ */
104
+ static detectProjectType(text) {
105
+ if (!text)
106
+ return 'general';
107
+ const normalized = text.toLowerCase().trim();
108
+ const corrected = this.correctTypos(normalized);
109
+ // Check for Chrome Extension first (Friday Feature!)
110
+ const chromeCheck = this.detectChromeExtension(normalized);
111
+ if (chromeCheck.detected) {
112
+ return 'chrome-extension';
113
+ }
114
+ // React/Next.js
115
+ if (corrected.includes('react') || corrected.includes('next')) {
116
+ return 'react';
117
+ }
118
+ // Vue/Nuxt
119
+ if (corrected.includes('vue') || corrected.includes('nuxt')) {
120
+ return 'vue';
121
+ }
122
+ // Svelte/SvelteKit
123
+ if (corrected.includes('svelte')) {
124
+ return 'svelte';
125
+ }
126
+ // Angular
127
+ if (corrected.includes('angular')) {
128
+ return 'angular';
129
+ }
130
+ // Python frameworks
131
+ if (corrected.includes('fastapi'))
132
+ return 'python-fastapi';
133
+ if (corrected.includes('django'))
134
+ return 'python-django';
135
+ if (corrected.includes('flask'))
136
+ return 'python-flask';
137
+ // API/Backend
138
+ if (corrected.includes('api') || corrected.includes('backend')) {
139
+ return 'node-api';
140
+ }
141
+ // CLI
142
+ if (corrected.includes('cli') || corrected.includes('command')) {
143
+ return 'cli-tool';
144
+ }
145
+ // Mobile
146
+ if (corrected.includes('mobile') || corrected.includes('ios') || corrected.includes('android')) {
147
+ return 'mobile';
148
+ }
149
+ return 'general';
150
+ }
151
+ /**
152
+ * Correct common typos
153
+ */
154
+ static correctTypos(text) {
155
+ let corrected = text;
156
+ for (const [typo, correction] of Object.entries(this.TYPO_CORRECTIONS)) {
157
+ const regex = new RegExp(`\\b${typo}\\b`, 'gi');
158
+ corrected = corrected.replace(regex, correction);
159
+ }
160
+ return corrected;
161
+ }
162
+ /**
163
+ * Get auto-fill slots for Chrome Extensions (90%+ scores!)
164
+ */
165
+ static getChromeExtensionSlots() {
166
+ return {
167
+ runtime: 'Chrome/Browser',
168
+ hosting: 'Chrome Web Store',
169
+ api_type: 'Chrome Extension APIs',
170
+ backend: 'Service Worker',
171
+ database: 'chrome.storage API',
172
+ build: 'Webpack/Vite',
173
+ package_manager: 'npm'
174
+ };
175
+ }
176
+ /**
177
+ * Smart suggestions for typos
178
+ */
179
+ static getSuggestion(input) {
180
+ const corrected = this.correctTypos(input.toLowerCase());
181
+ if (corrected !== input.toLowerCase()) {
182
+ return corrected;
183
+ }
184
+ return null;
185
+ }
186
+ }
187
+ exports.FuzzyDetector = FuzzyDetector;
188
+ // Intel-Friday: Simple IF statements adding massive value!
189
+ function applyIntelFriday(projectData) {
190
+ // IF: Chrome Extension detected → Auto-fill 7 slots for 90%+ score
191
+ if (projectData.project_type === 'chrome-extension' ||
192
+ FuzzyDetector.detectChromeExtension(projectData.description || '').detected) {
193
+ const chromeSlots = FuzzyDetector.getChromeExtensionSlots();
194
+ return {
195
+ ...projectData,
196
+ ...chromeSlots,
197
+ _friday_feature: 'Chrome Extension auto-filled! 🎯'
198
+ };
199
+ }
200
+ // IF: React detected → Add common React patterns
201
+ if (projectData.framework?.includes('react')) {
202
+ projectData.state_management = projectData.state_management || 'React Context/Redux';
203
+ projectData.css_framework = projectData.css_framework || 'Tailwind CSS';
204
+ }
205
+ // IF: Python detected → Add common Python patterns
206
+ if (projectData.language?.includes('python')) {
207
+ projectData.package_manager = 'pip';
208
+ projectData.runtime = 'Python 3.11+';
209
+ }
210
+ return projectData;
211
+ }
212
+ /**
213
+ * Friday Features for MCP! 🎉
214
+ *
215
+ * Usage:
216
+ * 1. Import in your MCP handler
217
+ * 2. Use FuzzyDetector.detectProjectType() on user input
218
+ * 3. Apply applyIntelFriday() before scoring
219
+ * 4. Watch scores jump to 90%+!
220
+ */
221
+ //# sourceMappingURL=fuzzy-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fuzzy-detector.js","sourceRoot":"","sources":["../../../src/utils/fuzzy-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * 🎯 Projects Convention Path Resolver
3
+ *
4
+ * Default: ~/Projects/[project-name]/project.faf
5
+ *
6
+ * Project name inference order:
7
+ * 1. User explicit path (always wins)
8
+ * 2. User project name statement
9
+ * 3. AI inference from README, files, conversation context
10
+ * 4. Fallback to 'unnamed-project'
11
+ */
12
+ export interface ProjectContext {
13
+ readme?: string;
14
+ projectName?: string;
15
+ uploadedFiles?: string[];
16
+ conversationContext?: string;
17
+ }
18
+ export interface PathResolution {
19
+ projectPath: string;
20
+ fafFilePath: string;
21
+ projectName: string;
22
+ source: 'user-explicit' | 'user-name' | 'ai-inference' | 'fallback';
23
+ }
24
+ /**
25
+ * Get user's home directory cross-platform
26
+ */
27
+ export declare function getHomeDirectory(): string;
28
+ /**
29
+ * Get default Projects directory
30
+ */
31
+ export declare function getProjectsDirectory(): string;
32
+ /**
33
+ * Resolve project path using Projects convention
34
+ *
35
+ * @param userInput - User-provided path or project name
36
+ * @param context - Context for AI inference (README, files, etc.)
37
+ * @returns Path resolution with project directory and .faf file path
38
+ */
39
+ export declare function resolveProjectPath(userInput?: string, context?: ProjectContext): PathResolution;
40
+ /**
41
+ * Ensure Projects directory exists
42
+ */
43
+ export declare function ensureProjectsDirectory(): void;
44
+ /**
45
+ * Validate that path is on real filesystem (not container)
46
+ */
47
+ export declare function isRealFilesystemPath(inputPath: string): boolean;
48
+ /**
49
+ * Format confirmation message for user
50
+ */
51
+ export declare function formatPathConfirmation(resolution: PathResolution): string;