faf-mcp 2.3.1 → 3.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 (177) hide show
  1. package/CHANGELOG.md +26 -3
  2. package/CLAUDE.md +6 -6
  3. package/README.md +71 -72
  4. package/dist/src/faf-core/commands/bi-sync.d.ts +1 -3
  5. package/dist/src/faf-core/commands/bi-sync.js +21 -64
  6. package/dist/src/faf-core/commands/bi-sync.js.map +1 -1
  7. package/dist/src/faf-core/commands/sync.js.map +1 -1
  8. package/dist/src/faf-core/engines/dependency-tsa.js.map +1 -1
  9. package/dist/src/faf-core/fix-once/colors.js +1 -1
  10. package/dist/src/faf-core/fix-once/colors.js.map +1 -1
  11. package/dist/src/faf-core/parsers/agents-parser.d.ts +15 -0
  12. package/dist/src/faf-core/parsers/agents-parser.js +29 -123
  13. package/dist/src/faf-core/parsers/agents-parser.js.map +1 -1
  14. package/dist/src/faf-core/parsers/conductor-parser.js +1 -1
  15. package/dist/src/faf-core/parsers/conductor-parser.js.map +1 -1
  16. package/dist/src/faf-core/parsers/cursorrules-parser.d.ts +15 -0
  17. package/dist/src/faf-core/parsers/cursorrules-parser.js +54 -111
  18. package/dist/src/faf-core/parsers/cursorrules-parser.js.map +1 -1
  19. package/dist/src/faf-core/parsers/faf-git-generator.js +0 -1
  20. package/dist/src/faf-core/parsers/faf-git-generator.js.map +1 -1
  21. package/dist/src/faf-core/parsers/gemini-parser.d.ts +10 -0
  22. package/dist/src/faf-core/parsers/gemini-parser.js +19 -77
  23. package/dist/src/faf-core/parsers/gemini-parser.js.map +1 -1
  24. package/dist/src/handlers/engine-adapter.d.ts +13 -12
  25. package/dist/src/handlers/engine-adapter.js +103 -682
  26. package/dist/src/handlers/engine-adapter.js.map +1 -1
  27. package/dist/src/handlers/resources.d.ts +19 -1
  28. package/dist/src/handlers/resources.js +108 -23
  29. package/dist/src/handlers/resources.js.map +1 -1
  30. package/dist/src/handlers/skills.d.ts +70 -0
  31. package/dist/src/handlers/skills.js +174 -0
  32. package/dist/src/handlers/skills.js.map +1 -0
  33. package/dist/src/handlers/tools.d.ts +41 -5
  34. package/dist/src/handlers/tools.js +213 -258
  35. package/dist/src/handlers/tools.js.map +1 -1
  36. package/dist/src/server.d.ts +4 -0
  37. package/dist/src/server.js +51 -6
  38. package/dist/src/server.js.map +1 -1
  39. package/dist/src/utils/faf-cli-bridge.d.ts +2 -0
  40. package/dist/src/utils/faf-cli-bridge.js +16 -0
  41. package/dist/src/utils/faf-cli-bridge.js.map +1 -1
  42. package/package.json +16 -13
  43. package/project.faf +11 -6
  44. package/scripts/check-engines.mjs +53 -0
  45. package/scripts/sync-version.js +33 -19
  46. package/skills/faf-ide/SKILL.md +40 -0
  47. package/dist/src/config/visibility.d.ts +0 -41
  48. package/dist/src/config/visibility.js +0 -158
  49. package/dist/src/config/visibility.js.map +0 -1
  50. package/dist/src/faf-core/commands/audit.d.ts +0 -21
  51. package/dist/src/faf-core/commands/audit.js +0 -83
  52. package/dist/src/faf-core/commands/audit.js.map +0 -1
  53. package/dist/src/faf-core/commands/auto.d.ts +0 -25
  54. package/dist/src/faf-core/commands/auto.js +0 -74
  55. package/dist/src/faf-core/commands/auto.js.map +0 -1
  56. package/dist/src/faf-core/commands/doctor.d.ts +0 -17
  57. package/dist/src/faf-core/commands/doctor.js +0 -198
  58. package/dist/src/faf-core/commands/doctor.js.map +0 -1
  59. package/dist/src/faf-core/commands/enhance.d.ts +0 -46
  60. package/dist/src/faf-core/commands/enhance.js +0 -360
  61. package/dist/src/faf-core/commands/enhance.js.map +0 -1
  62. package/dist/src/faf-core/commands/formats.d.ts +0 -22
  63. package/dist/src/faf-core/commands/formats.js +0 -117
  64. package/dist/src/faf-core/commands/formats.js.map +0 -1
  65. package/dist/src/faf-core/commands/human.d.ts +0 -27
  66. package/dist/src/faf-core/commands/human.js +0 -183
  67. package/dist/src/faf-core/commands/human.js.map +0 -1
  68. package/dist/src/faf-core/commands/init.d.ts +0 -26
  69. package/dist/src/faf-core/commands/init.js +0 -114
  70. package/dist/src/faf-core/commands/init.js.map +0 -1
  71. package/dist/src/faf-core/commands/innit.d.ts +0 -7
  72. package/dist/src/faf-core/commands/innit.js +0 -13
  73. package/dist/src/faf-core/commands/innit.js.map +0 -1
  74. package/dist/src/faf-core/commands/migrate.d.ts +0 -15
  75. package/dist/src/faf-core/commands/migrate.js +0 -86
  76. package/dist/src/faf-core/commands/migrate.js.map +0 -1
  77. package/dist/src/faf-core/commands/quick.d.ts +0 -16
  78. package/dist/src/faf-core/commands/quick.js +0 -184
  79. package/dist/src/faf-core/commands/quick.js.map +0 -1
  80. package/dist/src/faf-core/commands/readme.d.ts +0 -47
  81. package/dist/src/faf-core/commands/readme.js +0 -361
  82. package/dist/src/faf-core/commands/readme.js.map +0 -1
  83. package/dist/src/faf-core/commands/score.d.ts +0 -47
  84. package/dist/src/faf-core/commands/score.js +0 -49
  85. package/dist/src/faf-core/commands/score.js.map +0 -1
  86. package/dist/src/faf-core/commands/update.d.ts +0 -12
  87. package/dist/src/faf-core/commands/update.js +0 -46
  88. package/dist/src/faf-core/commands/update.js.map +0 -1
  89. package/dist/src/faf-core/commands/validate.d.ts +0 -21
  90. package/dist/src/faf-core/commands/validate.js +0 -81
  91. package/dist/src/faf-core/commands/validate.js.map +0 -1
  92. package/dist/src/faf-core/compiler/faf-compiler.d.ts +0 -138
  93. package/dist/src/faf-core/compiler/faf-compiler.js +0 -1362
  94. package/dist/src/faf-core/compiler/faf-compiler.js.map +0 -1
  95. package/dist/src/faf-core/engines/fab-formats-processor.d.ts +0 -166
  96. package/dist/src/faf-core/engines/fab-formats-processor.js +0 -1274
  97. package/dist/src/faf-core/engines/fab-formats-processor.js.map +0 -1
  98. package/dist/src/faf-core/engines/faf-dna.d.ts +0 -159
  99. package/dist/src/faf-core/engines/faf-dna.js +0 -555
  100. package/dist/src/faf-core/engines/faf-dna.js.map +0 -1
  101. package/dist/src/faf-core/engines/relentless-context-extractor.d.ts +0 -100
  102. package/dist/src/faf-core/engines/relentless-context-extractor.js +0 -625
  103. package/dist/src/faf-core/engines/relentless-context-extractor.js.map +0 -1
  104. package/dist/src/faf-core/fix-once/types.d.ts +0 -257
  105. package/dist/src/faf-core/fix-once/types.js +0 -26
  106. package/dist/src/faf-core/fix-once/types.js.map +0 -1
  107. package/dist/src/faf-core/generators/faf-generator-championship.d.ts +0 -16
  108. package/dist/src/faf-core/generators/faf-generator-championship.js +0 -463
  109. package/dist/src/faf-core/generators/faf-generator-championship.js.map +0 -1
  110. package/dist/src/faf-core/inject.d.ts +0 -19
  111. package/dist/src/faf-core/inject.js +0 -57
  112. package/dist/src/faf-core/inject.js.map +0 -1
  113. package/dist/src/faf-core/parsers/index.d.ts +0 -12
  114. package/dist/src/faf-core/parsers/index.js +0 -29
  115. package/dist/src/faf-core/parsers/index.js.map +0 -1
  116. package/dist/src/faf-core/utils/balance-visualizer.d.ts +0 -37
  117. package/dist/src/faf-core/utils/balance-visualizer.js +0 -197
  118. package/dist/src/faf-core/utils/balance-visualizer.js.map +0 -1
  119. package/dist/src/faf-core/utils/championship-style.d.ts +0 -109
  120. package/dist/src/faf-core/utils/championship-style.js +0 -219
  121. package/dist/src/faf-core/utils/championship-style.js.map +0 -1
  122. package/dist/src/faf-core/utils/chrome-extension-detector.d.ts +0 -73
  123. package/dist/src/faf-core/utils/chrome-extension-detector.js +0 -268
  124. package/dist/src/faf-core/utils/chrome-extension-detector.js.map +0 -1
  125. package/dist/src/faf-core/utils/platform-detector.d.ts +0 -30
  126. package/dist/src/faf-core/utils/platform-detector.js +0 -218
  127. package/dist/src/faf-core/utils/platform-detector.js.map +0 -1
  128. package/dist/src/faf-core/utils/technical-credit.d.ts +0 -35
  129. package/dist/src/faf-core/utils/technical-credit.js +0 -286
  130. package/dist/src/faf-core/utils/technical-credit.js.map +0 -1
  131. package/dist/src/faf-core/utils/yaml-generator.d.ts +0 -41
  132. package/dist/src/faf-core/utils/yaml-generator.js +0 -360
  133. package/dist/src/faf-core/utils/yaml-generator.js.map +0 -1
  134. package/dist/src/handlers/behavioral-instruction.d.ts +0 -16
  135. package/dist/src/handlers/behavioral-instruction.js +0 -43
  136. package/dist/src/handlers/behavioral-instruction.js.map +0 -1
  137. package/dist/src/handlers/championship-tools.d.ts +0 -116
  138. package/dist/src/handlers/championship-tools.js +0 -2320
  139. package/dist/src/handlers/championship-tools.js.map +0 -1
  140. package/dist/src/handlers/cloud-handler.d.ts +0 -59
  141. package/dist/src/handlers/cloud-handler.js +0 -348
  142. package/dist/src/handlers/cloud-handler.js.map +0 -1
  143. package/dist/src/handlers/tool-registry.d.ts +0 -23
  144. package/dist/src/handlers/tool-registry.js +0 -68
  145. package/dist/src/handlers/tool-registry.js.map +0 -1
  146. package/dist/src/handlers/tool-types.d.ts +0 -167
  147. package/dist/src/handlers/tool-types.js +0 -7
  148. package/dist/src/handlers/tool-types.js.map +0 -1
  149. package/dist/src/test-all-functions.d.ts +0 -15
  150. package/dist/src/test-all-functions.js +0 -163
  151. package/dist/src/test-all-functions.js.map +0 -1
  152. package/dist/src/types/mcp-tools.d.ts +0 -53
  153. package/dist/src/types/mcp-tools.js +0 -77
  154. package/dist/src/types/mcp-tools.js.map +0 -1
  155. package/dist/src/types/tool-visibility.d.ts +0 -36
  156. package/dist/src/types/tool-visibility.js +0 -551
  157. package/dist/src/types/tool-visibility.js.map +0 -1
  158. package/dist/src/utils/auto-path-detection.d.ts +0 -26
  159. package/dist/src/utils/auto-path-detection.js +0 -198
  160. package/dist/src/utils/auto-path-detection.js.map +0 -1
  161. package/dist/src/utils/championship-format.d.ts +0 -30
  162. package/dist/src/utils/championship-format.js +0 -81
  163. package/dist/src/utils/championship-format.js.map +0 -1
  164. package/dist/src/utils/cli-detector.d.ts +0 -17
  165. package/dist/src/utils/cli-detector.js +0 -247
  166. package/dist/src/utils/cli-detector.js.map +0 -1
  167. package/dist/src/utils/display-protocol.d.ts +0 -57
  168. package/dist/src/utils/display-protocol.js +0 -131
  169. package/dist/src/utils/display-protocol.js.map +0 -1
  170. package/dist/src/utils/username-detector.d.ts +0 -27
  171. package/dist/src/utils/username-detector.js +0 -90
  172. package/dist/src/utils/username-detector.js.map +0 -1
  173. package/dist/src/utils/visual-style.d.ts +0 -62
  174. package/dist/src/utils/visual-style.js +0 -166
  175. package/dist/src/utils/visual-style.js.map +0 -1
  176. package/scripts/postinstall.js +0 -50
  177. package/skill/SKILL.md +0 -385
@@ -34,86 +34,43 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.FafEngineAdapter = void 0;
37
- const child_process_1 = require("child_process");
38
- const util_1 = require("util");
37
+ /**
38
+ * FafEngineAdapter — routes the interop tools to their bundled, in-process
39
+ * commands.
40
+ *
41
+ * Every faf-mcp tool runs in-process: scoring, init, auto, trust, status and
42
+ * the resources go through src/utils/faf-cli-bridge.ts (the faf-cli this
43
+ * package bundles); the seven interop commands below run the vendored
44
+ * faf-core modules. Nothing shells out.
45
+ *
46
+ * History (3.0 P2): this file used to carry 22 command branches, a
47
+ * `which faf` detector that ran at every server start, and an exec fallback
48
+ * that spawned whatever binary the detector found — on machines with an
49
+ * unrelated `faf` on PATH that was a different program entirely. Only seven
50
+ * branches were ever reached by a registered tool; the rest, the detector
51
+ * and the fallback are gone (archive tag: archive/pre-p2-dead-code).
52
+ */
39
53
  const path = __importStar(require("path"));
40
54
  const fs = __importStar(require("fs"));
41
- const type_guards_js_1 = require("../utils/type-guards.js"); // ✅ FIXED: Removed unused isDefined
42
- const cli_detector_js_1 = require("../utils/cli-detector.js");
43
- const score_js_1 = require("../faf-core/commands/score.js");
44
- const init_js_1 = require("../faf-core/commands/init.js");
45
- const auto_js_1 = require("../faf-core/commands/auto.js");
55
+ const type_guards_js_1 = require("../utils/type-guards.js");
46
56
  const sync_js_1 = require("../faf-core/commands/sync.js");
47
57
  const bi_sync_js_1 = require("../faf-core/commands/bi-sync.js");
48
- const formats_js_1 = require("../faf-core/commands/formats.js");
49
- const doctor_js_1 = require("../faf-core/commands/doctor.js");
50
- const validate_js_1 = require("../faf-core/commands/validate.js");
51
- const audit_js_1 = require("../faf-core/commands/audit.js");
52
- const update_js_1 = require("../faf-core/commands/update.js");
53
- const migrate_js_1 = require("../faf-core/commands/migrate.js");
54
- const innit_js_1 = require("../faf-core/commands/innit.js");
55
- const quick_js_1 = require("../faf-core/commands/quick.js");
56
- const human_js_1 = require("../faf-core/commands/human.js");
57
- const readme_js_1 = require("../faf-core/commands/readme.js");
58
- // v4.5.0 Interop commands
59
58
  const agents_js_1 = require("../faf-core/commands/agents.js");
60
59
  const cursor_js_1 = require("../faf-core/commands/cursor.js");
61
60
  const gemini_js_1 = require("../faf-core/commands/gemini.js");
62
61
  const conductor_js_1 = require("../faf-core/commands/conductor.js");
63
62
  const git_context_js_1 = require("../faf-core/commands/git-context.js");
64
- const execAsync = (0, util_1.promisify)(child_process_1.exec);
65
- // Enhanced PATH for FAF CLI discovery
66
- const getEnhancedEnv = () => ({
67
- ...process.env,
68
- PATH: [
69
- '/usr/local/bin',
70
- '/opt/homebrew/bin',
71
- process.env.HOME ? `${process.env.HOME}/.npm/bin` : undefined,
72
- process.env.HOME ? `${process.env.HOME}/.npm-global/bin` : undefined,
73
- '/usr/bin',
74
- '/bin',
75
- process.env.PATH
76
- ].filter(Boolean).join(':')
77
- });
78
63
  class FafEngineAdapter {
79
64
  enginePath;
80
- detectedCliPath = null;
81
- cliVersion;
82
- timeout;
83
65
  workingDirectory;
84
- constructor(enginePath = 'faf', timeout = 30000) {
66
+ /**
67
+ * `enginePath` is kept for the config surface (server.ts passes it through;
68
+ * faf_debug reports it). `_timeout` was the exec fallback's — retained in
69
+ * the signature so callers do not break, unused now that nothing spawns.
70
+ */
71
+ constructor(enginePath = 'native', _timeout = 30000) {
85
72
  this.enginePath = enginePath;
86
- this.timeout = timeout;
87
73
  this.workingDirectory = this.findBestWorkingDirectory();
88
- // Auto-detect CLI on initialization
89
- this.detectCli();
90
- }
91
- detectCli() {
92
- const detection = (0, cli_detector_js_1.detectFafCli)();
93
- if (detection.found && detection.path) {
94
- this.detectedCliPath = detection.path;
95
- this.cliVersion = detection.version;
96
- // Validate version meets minimum requirement
97
- if (this.cliVersion && !(0, cli_detector_js_1.validateCliVersion)(this.cliVersion, '3.1.1')) {
98
- console.warn(`FAF CLI version ${this.cliVersion} is below minimum required version 3.1.1. Some features may not work correctly.`);
99
- }
100
- console.error(`✅ FAF CLI detected: ${this.detectedCliPath} (v${this.cliVersion || 'unknown'}) via ${detection.method}`);
101
- }
102
- else {
103
- console.error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
104
- console.error('⚠️ FAF CLI NOT DETECTED');
105
- console.error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
106
- console.error('');
107
- console.error('INSTALLATION ORDER REQUIRED:');
108
- console.error(' 1️⃣ npm install -g faf-cli (REQUIRED FIRST)');
109
- console.error(' 2️⃣ npm install -g faf-mcp (THEN THIS)');
110
- console.error('');
111
- console.error('Most MCP tools require faf-cli to be installed.');
112
- console.error('Only basic file operations will work without it.');
113
- console.error('');
114
- console.error('After installing faf-cli, restart your MCP host.');
115
- console.error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
116
- }
117
74
  }
118
75
  findBestWorkingDirectory() {
119
76
  // Priority 1: Environment variable for explicit control
@@ -172,624 +129,96 @@ class FafEngineAdapter {
172
129
  // Last resort: /tmp (should rarely happen)
173
130
  return '/tmp';
174
131
  }
132
+ /**
133
+ * Wrap a bundled command's outcome. A failed command's reason travels in
134
+ * `error` so handlers can print it — previously the bundled branches set
135
+ * only `success` and users saw "❌ undefined".
136
+ */
137
+ outcome(result, fallback, startTime) {
138
+ return {
139
+ success: result.success,
140
+ data: result,
141
+ error: result.success ? undefined : (result.message || result.error || fallback),
142
+ duration: Date.now() - startTime,
143
+ };
144
+ }
145
+ failure(error, fallback, startTime) {
146
+ return { success: false, error: (0, type_guards_js_1.isError)(error) ? error.message : fallback, duration: Date.now() - startTime };
147
+ }
175
148
  async callEngine(command, args = []) {
176
149
  const startTime = Date.now();
177
- // Input validation
178
150
  if (!command || typeof command !== 'string') {
179
- return {
180
- success: false,
181
- error: 'Command must be a non-empty string',
182
- duration: 0
183
- };
184
- }
185
- // ============================================================================
186
- // MK3 BUNDLED ENGINE - Direct function calls (no CLI dependency!)
187
- // ============================================================================
188
- // SCORE command - use bundled FafCompiler
189
- if (command === 'score') {
190
- try {
191
- const filePath = args[0] || this.workingDirectory;
192
- const result = await (0, score_js_1.scoreFafFile)(filePath, { json: true });
193
- const duration = Date.now() - startTime;
194
- return {
195
- success: true,
196
- data: result,
197
- duration
198
- };
199
- }
200
- catch (error) {
201
- const duration = Date.now() - startTime;
202
- const errorMessage = (0, type_guards_js_1.isError)(error) ? error.message : 'Score command failed';
203
- return {
204
- success: false,
205
- error: errorMessage,
206
- duration
207
- };
208
- }
209
- }
210
- // INIT command - use bundled init
211
- if (command === 'init') {
212
- try {
213
- // Filter out flags to get the actual path argument
214
- const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
215
- const projectPath = pathArgs[0] || this.workingDirectory;
216
- const force = args.includes('--force');
217
- const result = await (0, init_js_1.initFafFile)(projectPath, { force });
218
- const duration = Date.now() - startTime;
219
- return {
220
- success: result.success,
221
- data: result,
222
- duration
223
- };
224
- }
225
- catch (error) {
226
- const duration = Date.now() - startTime;
227
- const errorMessage = (0, type_guards_js_1.isError)(error) ? error.message : 'Init command failed';
228
- return {
229
- success: false,
230
- error: errorMessage,
231
- duration
232
- };
233
- }
234
- }
235
- // AUTO command - use bundled auto (init + score)
236
- if (command === 'auto') {
237
- try {
238
- // Filter out flags to get the actual path argument
239
- const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
240
- const directory = pathArgs[0] || this.workingDirectory;
241
- const force = args.includes('--force');
242
- const result = await (0, auto_js_1.autoCommand)(directory, { force });
243
- const duration = Date.now() - startTime;
244
- return {
245
- success: result.success,
246
- data: result,
247
- duration
248
- };
249
- }
250
- catch (error) {
251
- const duration = Date.now() - startTime;
252
- const errorMessage = (0, type_guards_js_1.isError)(error) ? error.message : 'Auto command failed';
253
- return {
254
- success: false,
255
- error: errorMessage,
256
- duration
257
- };
258
- }
259
- }
260
- // SYNC command - use bundled sync
261
- if (command === 'sync') {
262
- try {
263
- const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
264
- const projectPath = pathArgs[0] || this.workingDirectory;
265
- const auto = args.includes('--auto');
266
- const result = await (0, sync_js_1.syncFafFile)(projectPath, { auto, json: true });
267
- const duration = Date.now() - startTime;
268
- return {
269
- success: result.success,
270
- data: result,
271
- duration
272
- };
273
- }
274
- catch (error) {
275
- const duration = Date.now() - startTime;
276
- return {
277
- success: false,
278
- error: (0, type_guards_js_1.isError)(error) ? error.message : 'Sync command failed',
279
- duration
280
- };
281
- }
282
- }
283
- // BI-SYNC command - use bundled bi-sync (v4.5.0: supports agents/cursor/gemini/all flags)
284
- if (command === 'bi-sync' || command === 'bisync') {
285
- try {
286
- const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
287
- const projectPath = pathArgs[0] || this.workingDirectory;
288
- const result = await (0, bi_sync_js_1.syncBiDirectional)(projectPath, {
289
- json: true,
290
- agents: args.includes('--agents'),
291
- cursor: args.includes('--cursor'),
292
- gemini: args.includes('--gemini'),
293
- all: args.includes('--all'),
294
- });
295
- const duration = Date.now() - startTime;
296
- return {
297
- success: result.success,
298
- data: result,
299
- duration
300
- };
301
- }
302
- catch (error) {
303
- const duration = Date.now() - startTime;
304
- return {
305
- success: false,
306
- error: (0, type_guards_js_1.isError)(error) ? error.message : 'Bi-sync command failed',
307
- duration
308
- };
309
- }
310
- }
311
- // FORMATS command - use bundled formats
312
- if (command === 'formats') {
313
- try {
314
- const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
315
- const projectPath = pathArgs[0] || this.workingDirectory;
316
- const result = await (0, formats_js_1.formatsCommand)(projectPath, { json: true });
317
- const duration = Date.now() - startTime;
318
- return {
319
- success: result.success,
320
- data: result,
321
- duration
322
- };
323
- }
324
- catch (error) {
325
- const duration = Date.now() - startTime;
326
- return {
327
- success: false,
328
- error: (0, type_guards_js_1.isError)(error) ? error.message : 'Formats command failed',
329
- duration
330
- };
331
- }
151
+ return { success: false, error: 'Command must be a non-empty string', duration: 0 };
332
152
  }
333
- // DOCTOR command - use bundled doctor
334
- if (command === 'doctor') {
335
- try {
336
- const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
337
- const projectPath = pathArgs[0] || this.workingDirectory;
338
- const result = await (0, doctor_js_1.doctorCommand)(projectPath);
339
- const duration = Date.now() - startTime;
340
- return {
341
- success: result.success,
342
- data: result,
343
- duration
344
- };
345
- }
346
- catch (error) {
347
- const duration = Date.now() - startTime;
348
- return {
349
- success: false,
350
- error: (0, type_guards_js_1.isError)(error) ? error.message : 'Doctor command failed',
351
- duration
352
- };
353
- }
354
- }
355
- // VALIDATE command - use bundled validate
356
- if (command === 'validate') {
357
- try {
358
- const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
359
- const projectPath = pathArgs[0] || this.workingDirectory;
360
- const result = await (0, validate_js_1.validateFafFile)(projectPath, { json: true });
361
- const duration = Date.now() - startTime;
362
- return {
363
- success: result.success,
364
- data: result,
365
- duration
366
- };
367
- }
368
- catch (error) {
369
- const duration = Date.now() - startTime;
370
- return {
371
- success: false,
372
- error: (0, type_guards_js_1.isError)(error) ? error.message : 'Validate command failed',
373
- duration
374
- };
375
- }
376
- }
377
- // AUDIT command - use bundled audit
378
- if (command === 'audit') {
379
- try {
380
- const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
381
- const projectPath = pathArgs[0] || this.workingDirectory;
382
- const result = await (0, audit_js_1.auditFafFile)(projectPath, { json: true });
383
- const duration = Date.now() - startTime;
384
- return {
385
- success: result.success,
386
- data: result,
387
- duration
388
- };
389
- }
390
- catch (error) {
391
- const duration = Date.now() - startTime;
392
- return {
393
- success: false,
394
- error: (0, type_guards_js_1.isError)(error) ? error.message : 'Audit command failed',
395
- duration
396
- };
397
- }
398
- }
399
- // UPDATE command - use bundled update
400
- if (command === 'update') {
401
- try {
402
- const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
403
- const projectPath = pathArgs[0] || this.workingDirectory;
404
- const result = await (0, update_js_1.updateFafFile)(projectPath, { json: true });
405
- const duration = Date.now() - startTime;
406
- return {
407
- success: result.success,
408
- data: result,
409
- duration
410
- };
411
- }
412
- catch (error) {
413
- const duration = Date.now() - startTime;
414
- return {
415
- success: false,
416
- error: (0, type_guards_js_1.isError)(error) ? error.message : 'Update command failed',
417
- duration
418
- };
419
- }
420
- }
421
- // MIGRATE command - use bundled migrate
422
- if (command === 'migrate') {
423
- try {
424
- const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
425
- const projectPath = pathArgs[0] || this.workingDirectory;
426
- const force = args.includes('--force');
427
- const result = await (0, migrate_js_1.migrateFafFile)(projectPath, { force, json: true });
428
- const duration = Date.now() - startTime;
429
- return {
430
- success: result.success,
431
- data: result,
432
- duration
433
- };
434
- }
435
- catch (error) {
436
- const duration = Date.now() - startTime;
437
- return {
438
- success: false,
439
- error: (0, type_guards_js_1.isError)(error) ? error.message : 'Migrate command failed',
440
- duration
441
- };
442
- }
443
- }
444
- // INNIT command - use bundled innit (British init)
445
- if (command === 'innit') {
446
- try {
447
- const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
448
- const projectPath = pathArgs[0] || this.workingDirectory;
449
- const force = args.includes('--force');
450
- const result = await (0, innit_js_1.innitFafFile)(projectPath, { force });
451
- const duration = Date.now() - startTime;
452
- return {
453
- success: result.success,
454
- data: result,
455
- duration
456
- };
457
- }
458
- catch (error) {
459
- const duration = Date.now() - startTime;
460
- return {
461
- success: false,
462
- error: (0, type_guards_js_1.isError)(error) ? error.message : 'Innit command failed',
463
- duration
464
- };
465
- }
466
- }
467
- // QUICK command - use bundled quick
468
- if (command === 'quick') {
469
- try {
470
- const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
471
- const projectPath = pathArgs[0] || this.workingDirectory;
472
- const input = pathArgs[1]; // optional input string
473
- const force = args.includes('--force');
474
- const json = args.includes('--json');
475
- const result = await (0, quick_js_1.quickCommand)(projectPath, input, { force, json });
476
- const duration = Date.now() - startTime;
477
- return {
478
- success: result.success,
479
- data: result,
480
- duration
481
- };
482
- }
483
- catch (error) {
484
- const duration = Date.now() - startTime;
485
- return {
486
- success: false,
487
- error: (0, type_guards_js_1.isError)(error) ? error.message : 'Quick command failed',
488
- duration
489
- };
490
- }
491
- }
492
- // HUMAN command - use bundled human (add/set human_context)
493
- if (command === 'human' || command === 'human-add') {
494
- try {
495
- const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
496
- const projectPath = pathArgs[0] || this.workingDirectory;
497
- // Extract YAML from args if provided
498
- const yamlArg = args.find(arg => arg.startsWith('--yaml='));
499
- const yaml = yamlArg ? yamlArg.substring(7) : undefined;
500
- // Extract field/value for single field mode
501
- const fieldArg = args.find(arg => arg.startsWith('--field='));
502
- const valueArg = args.find(arg => arg.startsWith('--value='));
503
- const field = fieldArg ? fieldArg.substring(8) : undefined;
504
- const value = valueArg ? valueArg.substring(8) : undefined;
505
- const result = await (0, human_js_1.humanAddCommand)(projectPath, { yaml, field, value });
506
- const duration = Date.now() - startTime;
507
- return {
508
- success: result.success,
509
- data: result,
510
- duration
511
- };
512
- }
513
- catch (error) {
514
- const duration = Date.now() - startTime;
515
- return {
516
- success: false,
517
- error: (0, type_guards_js_1.isError)(error) ? error.message : 'Human command failed',
518
- duration
519
- };
520
- }
521
- }
522
- // HUMAN-SET command - set single field
523
- if (command === 'human-set') {
524
- try {
525
- const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
526
- const projectPath = pathArgs[0] || this.workingDirectory;
527
- const field = pathArgs[1];
528
- const value = pathArgs[2];
529
- if (!field || !value) {
153
+ const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
154
+ const projectPath = pathArgs[0] || this.workingDirectory;
155
+ const actionArg = args.find(arg => arg.startsWith('--action='));
156
+ const force = args.includes('--force');
157
+ const merge = args.includes('--merge');
158
+ try {
159
+ switch (command) {
160
+ case 'sync': {
161
+ const result = await (0, sync_js_1.syncFafFile)(projectPath, { auto: args.includes('--auto'), json: true });
162
+ return this.outcome(result, 'Sync command failed', startTime);
163
+ }
164
+ case 'bi-sync':
165
+ case 'bisync': {
166
+ const result = await (0, bi_sync_js_1.syncBiDirectional)(projectPath, {
167
+ json: true,
168
+ agents: args.includes('--agents'),
169
+ cursor: args.includes('--cursor'),
170
+ gemini: args.includes('--gemini'),
171
+ all: args.includes('--all'),
172
+ });
173
+ return this.outcome(result, 'Bi-sync command failed', startTime);
174
+ }
175
+ case 'agents': {
176
+ const action = actionArg ? actionArg.substring(9) : 'sync';
177
+ const result = action === 'import' ? await (0, agents_js_1.agentsImportCommand)(projectPath, { merge })
178
+ : action === 'export' ? await (0, agents_js_1.agentsExportCommand)(projectPath, { force })
179
+ : await (0, agents_js_1.agentsSyncCommand)(projectPath);
180
+ return this.outcome(result, 'Agents command failed', startTime);
181
+ }
182
+ case 'cursor': {
183
+ const action = actionArg ? actionArg.substring(9) : 'sync';
184
+ const result = action === 'import' ? await (0, cursor_js_1.cursorImportCommand)(projectPath, { merge })
185
+ : action === 'export' ? await (0, cursor_js_1.cursorExportCommand)(projectPath, { force })
186
+ : await (0, cursor_js_1.cursorSyncCommand)(projectPath);
187
+ return this.outcome(result, 'Cursor command failed', startTime);
188
+ }
189
+ case 'gemini': {
190
+ const action = actionArg ? actionArg.substring(9) : 'sync';
191
+ const result = action === 'import' ? await (0, gemini_js_1.geminiImportCommand)(projectPath, { merge })
192
+ : action === 'export' ? await (0, gemini_js_1.geminiExportCommand)(projectPath, { force })
193
+ : await (0, gemini_js_1.geminiSyncCommand)(projectPath);
194
+ return this.outcome(result, 'Gemini command failed', startTime);
195
+ }
196
+ case 'conductor': {
197
+ const action = actionArg ? actionArg.substring(9) : 'import';
198
+ const result = action === 'export'
199
+ ? await (0, conductor_js_1.conductorExportCommand)(projectPath, { force })
200
+ : await (0, conductor_js_1.conductorImportCommand)(projectPath, { merge });
201
+ return this.outcome(result, 'Conductor command failed', startTime);
202
+ }
203
+ case 'git': {
204
+ const url = args[0];
205
+ const outputPath = args[1]; // optional
206
+ if (!url) {
207
+ return { success: false, error: 'URL is required', duration: Date.now() - startTime };
208
+ }
209
+ const result = await (0, git_context_js_1.gitContextCommand)(url, outputPath);
210
+ return this.outcome(result, 'Git command failed', startTime);
211
+ }
212
+ default:
530
213
  return {
531
214
  success: false,
532
- error: 'Usage: human-set <field> <value>',
533
- duration: Date.now() - startTime
215
+ error: `Unknown engine command '${command}'. Every faf-mcp tool runs in-process; there is no CLI to fall back to.`,
216
+ duration: Date.now() - startTime,
534
217
  };
535
- }
536
- const result = await (0, human_js_1.humanSetCommand)(projectPath, field, value);
537
- const duration = Date.now() - startTime;
538
- return {
539
- success: result.success,
540
- data: result,
541
- duration
542
- };
543
- }
544
- catch (error) {
545
- const duration = Date.now() - startTime;
546
- return {
547
- success: false,
548
- error: (0, type_guards_js_1.isError)(error) ? error.message : 'Human-set command failed',
549
- duration
550
- };
551
- }
552
- }
553
- // README command - extract context from README.md
554
- if (command === 'readme' || command === 'readme-extract') {
555
- try {
556
- const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
557
- const projectPath = pathArgs[0] || this.workingDirectory;
558
- const result = await (0, readme_js_1.readmeExtractCommand)(projectPath);
559
- const duration = Date.now() - startTime;
560
- return {
561
- success: result.success,
562
- data: result,
563
- duration
564
- };
565
- }
566
- catch (error) {
567
- const duration = Date.now() - startTime;
568
- return {
569
- success: false,
570
- error: (0, type_guards_js_1.isError)(error) ? error.message : 'README extract command failed',
571
- duration
572
- };
573
- }
574
- }
575
- // README-MERGE command - extract and merge into .faf
576
- if (command === 'readme-merge') {
577
- try {
578
- const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
579
- const projectPath = pathArgs[0] || this.workingDirectory;
580
- // Check for overwrite flag
581
- const overwrite = args.includes('--overwrite');
582
- const result = await (0, readme_js_1.readmeMergeCommand)(projectPath, { overwrite });
583
- const duration = Date.now() - startTime;
584
- return {
585
- success: result.success,
586
- data: result,
587
- duration
588
- };
589
- }
590
- catch (error) {
591
- const duration = Date.now() - startTime;
592
- return {
593
- success: false,
594
- error: (0, type_guards_js_1.isError)(error) ? error.message : 'README merge command failed',
595
- duration
596
- };
597
- }
598
- }
599
- // ============================================================================
600
- // v4.5.0 INTEROP COMMANDS
601
- // ============================================================================
602
- // AGENTS command - import/export/sync AGENTS.md
603
- if (command === 'agents') {
604
- try {
605
- const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
606
- const projectPath = pathArgs[0] || this.workingDirectory;
607
- const actionArg = args.find(arg => arg.startsWith('--action='));
608
- const action = actionArg ? actionArg.substring(9) : 'sync';
609
- const force = args.includes('--force');
610
- const merge = args.includes('--merge');
611
- let result;
612
- if (action === 'import') {
613
- result = await (0, agents_js_1.agentsImportCommand)(projectPath, { merge });
614
- }
615
- else if (action === 'export') {
616
- result = await (0, agents_js_1.agentsExportCommand)(projectPath, { force });
617
- }
618
- else {
619
- result = await (0, agents_js_1.agentsSyncCommand)(projectPath);
620
- }
621
- return { success: result.success, data: result, duration: Date.now() - startTime };
622
- }
623
- catch (error) {
624
- return { success: false, error: (0, type_guards_js_1.isError)(error) ? error.message : 'Agents command failed', duration: Date.now() - startTime };
625
- }
626
- }
627
- // CURSOR command - import/export/sync .cursorrules
628
- if (command === 'cursor') {
629
- try {
630
- const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
631
- const projectPath = pathArgs[0] || this.workingDirectory;
632
- const actionArg = args.find(arg => arg.startsWith('--action='));
633
- const action = actionArg ? actionArg.substring(9) : 'sync';
634
- const force = args.includes('--force');
635
- const merge = args.includes('--merge');
636
- let result;
637
- if (action === 'import') {
638
- result = await (0, cursor_js_1.cursorImportCommand)(projectPath, { merge });
639
- }
640
- else if (action === 'export') {
641
- result = await (0, cursor_js_1.cursorExportCommand)(projectPath, { force });
642
- }
643
- else {
644
- result = await (0, cursor_js_1.cursorSyncCommand)(projectPath);
645
- }
646
- return { success: result.success, data: result, duration: Date.now() - startTime };
647
- }
648
- catch (error) {
649
- return { success: false, error: (0, type_guards_js_1.isError)(error) ? error.message : 'Cursor command failed', duration: Date.now() - startTime };
650
- }
651
- }
652
- // GEMINI command - import/export/sync GEMINI.md
653
- if (command === 'gemini') {
654
- try {
655
- const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
656
- const projectPath = pathArgs[0] || this.workingDirectory;
657
- const actionArg = args.find(arg => arg.startsWith('--action='));
658
- const action = actionArg ? actionArg.substring(9) : 'sync';
659
- const force = args.includes('--force');
660
- const merge = args.includes('--merge');
661
- let result;
662
- if (action === 'import') {
663
- result = await (0, gemini_js_1.geminiImportCommand)(projectPath, { merge });
664
- }
665
- else if (action === 'export') {
666
- result = await (0, gemini_js_1.geminiExportCommand)(projectPath, { force });
667
- }
668
- else {
669
- result = await (0, gemini_js_1.geminiSyncCommand)(projectPath);
670
- }
671
- return { success: result.success, data: result, duration: Date.now() - startTime };
672
- }
673
- catch (error) {
674
- return { success: false, error: (0, type_guards_js_1.isError)(error) ? error.message : 'Gemini command failed', duration: Date.now() - startTime };
675
218
  }
676
219
  }
677
- // CONDUCTOR command - import/export conductor/
678
- if (command === 'conductor') {
679
- try {
680
- const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
681
- const projectPath = pathArgs[0] || this.workingDirectory;
682
- const actionArg = args.find(arg => arg.startsWith('--action='));
683
- const action = actionArg ? actionArg.substring(9) : 'import';
684
- const force = args.includes('--force');
685
- const merge = args.includes('--merge');
686
- let result;
687
- if (action === 'export') {
688
- result = await (0, conductor_js_1.conductorExportCommand)(projectPath, { force });
689
- }
690
- else {
691
- result = await (0, conductor_js_1.conductorImportCommand)(projectPath, { merge });
692
- }
693
- return { success: result.success, data: result, duration: Date.now() - startTime };
694
- }
695
- catch (error) {
696
- return { success: false, error: (0, type_guards_js_1.isError)(error) ? error.message : 'Conductor command failed', duration: Date.now() - startTime };
697
- }
698
- }
699
- // GIT command - generate .faf from GitHub repo
700
- if (command === 'git') {
701
- try {
702
- const url = args[0];
703
- const outputPath = args[1]; // optional
704
- if (!url) {
705
- return { success: false, error: 'URL is required', duration: Date.now() - startTime };
706
- }
707
- const result = await (0, git_context_js_1.gitContextCommand)(url, outputPath);
708
- return { success: result.success, data: result, duration: Date.now() - startTime };
709
- }
710
- catch (error) {
711
- return { success: false, error: (0, type_guards_js_1.isError)(error) ? error.message : 'Git command failed', duration: Date.now() - startTime };
712
- }
713
- }
714
- // ============================================================================
715
- // FALLBACK: Shell out to CLI for commands not yet bundled
716
- // ============================================================================
717
- // Check if CLI is available
718
- if (!this.detectedCliPath) {
719
- const duration = Date.now() - startTime;
720
- return {
721
- success: false,
722
- error: `FAF CLI not detected. Command '${command}' requires faf-cli.\n\nINSTALLATION ORDER:\n 1️⃣ npm install -g faf-cli\n 2️⃣ npm install -g faf-mcp\n\nAfter installing faf-cli, restart your MCP host.`,
723
- duration
724
- };
725
- }
726
- // Sanitize arguments to prevent injection
727
- const sanitizedArgs = args.map(arg => typeof arg === 'string' ? arg.replace(/[;&|`$(){}[\]]/g, '') : '');
728
- try {
729
- // Use detected absolute path to CLI
730
- const fullCommand = `"${this.detectedCliPath}" ${command} ${sanitizedArgs.join(' ')}`;
731
- const { stdout, stderr } = await execAsync(fullCommand, {
732
- env: getEnhancedEnv(),
733
- timeout: this.timeout,
734
- maxBuffer: 1024 * 1024, // 1MB buffer limit
735
- cwd: this.workingDirectory
736
- });
737
- const duration = Date.now() - startTime;
738
- if (stderr?.trim()) {
739
- console.warn(`FAF CLI warning: ${stderr.trim()}`);
740
- }
741
- return {
742
- success: true,
743
- data: this.parseOutput(stdout),
744
- duration
745
- };
746
- }
747
220
  catch (error) {
748
- const duration = Date.now() - startTime;
749
- let errorMessage = 'Unknown error occurred';
750
- if ((0, type_guards_js_1.isError)(error)) {
751
- errorMessage = error.message;
752
- // Handle specific error codes
753
- if ('code' in error) {
754
- if (error.code === 'ETIMEDOUT') {
755
- errorMessage = `Command timed out after ${this.timeout}ms`;
756
- }
757
- else if (error.code === 'ENOENT') {
758
- errorMessage = `FAF CLI not found at ${this.detectedCliPath}. Please reinstall: npm install -g faf-cli`;
759
- }
760
- }
761
- // Handle signal termination
762
- if ('signal' in error && error.signal === 'SIGTERM') {
763
- errorMessage = 'Command was terminated';
764
- }
765
- }
766
- console.error(`FAF CLI error: ${errorMessage}`);
767
- return {
768
- success: false,
769
- error: errorMessage,
770
- duration
771
- };
772
- }
773
- }
774
- parseOutput(output) {
775
- if (!output || output.trim() === '') {
776
- return { output: '' };
777
- }
778
- try {
779
- return JSON.parse(output);
780
- }
781
- catch {
782
- return { output: output.trim() };
783
- }
784
- }
785
- // Method to check if FAF CLI is available
786
- async checkHealth() {
787
- try {
788
- const result = await this.callEngine('--version');
789
- return result.success;
790
- }
791
- catch {
792
- return false;
221
+ return this.failure(error, `${command} command failed`, startTime);
793
222
  }
794
223
  }
795
224
  // Get the current working directory used by the adapter
@@ -815,14 +244,6 @@ class FafEngineAdapter {
815
244
  getEnginePath() {
816
245
  return this.enginePath;
817
246
  }
818
- // Get CLI detection info for debugging
819
- getCliInfo() {
820
- return {
821
- detected: this.detectedCliPath !== null,
822
- path: this.detectedCliPath || undefined,
823
- version: this.cliVersion
824
- };
825
- }
826
247
  }
827
248
  exports.FafEngineAdapter = FafEngineAdapter;
828
249
  //# sourceMappingURL=engine-adapter.js.map