faf-mcp 2.3.0 → 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.
- package/CHANGELOG.md +42 -3
- package/CLAUDE.md +7 -7
- package/README.md +73 -74
- package/dist/src/faf-core/commands/bi-sync.d.ts +1 -3
- package/dist/src/faf-core/commands/bi-sync.js +21 -64
- package/dist/src/faf-core/commands/bi-sync.js.map +1 -1
- package/dist/src/faf-core/commands/sync.js.map +1 -1
- package/dist/src/faf-core/engines/dependency-tsa.js.map +1 -1
- package/dist/src/faf-core/fix-once/colors.js +1 -1
- package/dist/src/faf-core/fix-once/colors.js.map +1 -1
- package/dist/src/faf-core/parsers/agents-parser.d.ts +15 -0
- package/dist/src/faf-core/parsers/agents-parser.js +29 -123
- package/dist/src/faf-core/parsers/agents-parser.js.map +1 -1
- package/dist/src/faf-core/parsers/conductor-parser.js +1 -1
- package/dist/src/faf-core/parsers/conductor-parser.js.map +1 -1
- package/dist/src/faf-core/parsers/cursorrules-parser.d.ts +15 -0
- package/dist/src/faf-core/parsers/cursorrules-parser.js +54 -111
- package/dist/src/faf-core/parsers/cursorrules-parser.js.map +1 -1
- package/dist/src/faf-core/parsers/faf-git-generator.js +0 -1
- package/dist/src/faf-core/parsers/faf-git-generator.js.map +1 -1
- package/dist/src/faf-core/parsers/gemini-parser.d.ts +10 -0
- package/dist/src/faf-core/parsers/gemini-parser.js +19 -77
- package/dist/src/faf-core/parsers/gemini-parser.js.map +1 -1
- package/dist/src/handlers/engine-adapter.d.ts +13 -12
- package/dist/src/handlers/engine-adapter.js +124 -688
- package/dist/src/handlers/engine-adapter.js.map +1 -1
- package/dist/src/handlers/resources.d.ts +19 -1
- package/dist/src/handlers/resources.js +108 -23
- package/dist/src/handlers/resources.js.map +1 -1
- package/dist/src/handlers/skills.d.ts +70 -0
- package/dist/src/handlers/skills.js +174 -0
- package/dist/src/handlers/skills.js.map +1 -0
- package/dist/src/handlers/tools.d.ts +41 -5
- package/dist/src/handlers/tools.js +213 -258
- package/dist/src/handlers/tools.js.map +1 -1
- package/dist/src/server.d.ts +4 -0
- package/dist/src/server.js +51 -6
- package/dist/src/server.js.map +1 -1
- package/dist/src/utils/faf-cli-bridge.d.ts +2 -0
- package/dist/src/utils/faf-cli-bridge.js +16 -0
- package/dist/src/utils/faf-cli-bridge.js.map +1 -1
- package/package.json +17 -14
- package/project.faf +23 -5
- package/scripts/check-engines.mjs +53 -0
- package/scripts/run-tests.sh +54 -0
- package/scripts/sync-version.js +33 -19
- package/skills/faf-ide/SKILL.md +40 -0
- package/dist/src/config/visibility.d.ts +0 -41
- package/dist/src/config/visibility.js +0 -158
- package/dist/src/config/visibility.js.map +0 -1
- package/dist/src/faf-core/commands/audit.d.ts +0 -21
- package/dist/src/faf-core/commands/audit.js +0 -83
- package/dist/src/faf-core/commands/audit.js.map +0 -1
- package/dist/src/faf-core/commands/auto.d.ts +0 -25
- package/dist/src/faf-core/commands/auto.js +0 -74
- package/dist/src/faf-core/commands/auto.js.map +0 -1
- package/dist/src/faf-core/commands/doctor.d.ts +0 -17
- package/dist/src/faf-core/commands/doctor.js +0 -198
- package/dist/src/faf-core/commands/doctor.js.map +0 -1
- package/dist/src/faf-core/commands/enhance.d.ts +0 -46
- package/dist/src/faf-core/commands/enhance.js +0 -360
- package/dist/src/faf-core/commands/enhance.js.map +0 -1
- package/dist/src/faf-core/commands/formats.d.ts +0 -22
- package/dist/src/faf-core/commands/formats.js +0 -117
- package/dist/src/faf-core/commands/formats.js.map +0 -1
- package/dist/src/faf-core/commands/human.d.ts +0 -27
- package/dist/src/faf-core/commands/human.js +0 -183
- package/dist/src/faf-core/commands/human.js.map +0 -1
- package/dist/src/faf-core/commands/init.d.ts +0 -26
- package/dist/src/faf-core/commands/init.js +0 -114
- package/dist/src/faf-core/commands/init.js.map +0 -1
- package/dist/src/faf-core/commands/innit.d.ts +0 -7
- package/dist/src/faf-core/commands/innit.js +0 -13
- package/dist/src/faf-core/commands/innit.js.map +0 -1
- package/dist/src/faf-core/commands/migrate.d.ts +0 -15
- package/dist/src/faf-core/commands/migrate.js +0 -86
- package/dist/src/faf-core/commands/migrate.js.map +0 -1
- package/dist/src/faf-core/commands/quick.d.ts +0 -16
- package/dist/src/faf-core/commands/quick.js +0 -184
- package/dist/src/faf-core/commands/quick.js.map +0 -1
- package/dist/src/faf-core/commands/readme.d.ts +0 -47
- package/dist/src/faf-core/commands/readme.js +0 -361
- package/dist/src/faf-core/commands/readme.js.map +0 -1
- package/dist/src/faf-core/commands/score.d.ts +0 -47
- package/dist/src/faf-core/commands/score.js +0 -49
- package/dist/src/faf-core/commands/score.js.map +0 -1
- package/dist/src/faf-core/commands/update.d.ts +0 -12
- package/dist/src/faf-core/commands/update.js +0 -46
- package/dist/src/faf-core/commands/update.js.map +0 -1
- package/dist/src/faf-core/commands/validate.d.ts +0 -21
- package/dist/src/faf-core/commands/validate.js +0 -81
- package/dist/src/faf-core/commands/validate.js.map +0 -1
- package/dist/src/faf-core/compiler/faf-compiler.d.ts +0 -138
- package/dist/src/faf-core/compiler/faf-compiler.js +0 -1362
- package/dist/src/faf-core/compiler/faf-compiler.js.map +0 -1
- package/dist/src/faf-core/engines/fab-formats-processor.d.ts +0 -166
- package/dist/src/faf-core/engines/fab-formats-processor.js +0 -1274
- package/dist/src/faf-core/engines/fab-formats-processor.js.map +0 -1
- package/dist/src/faf-core/engines/faf-dna.d.ts +0 -159
- package/dist/src/faf-core/engines/faf-dna.js +0 -555
- package/dist/src/faf-core/engines/faf-dna.js.map +0 -1
- package/dist/src/faf-core/engines/relentless-context-extractor.d.ts +0 -100
- package/dist/src/faf-core/engines/relentless-context-extractor.js +0 -625
- package/dist/src/faf-core/engines/relentless-context-extractor.js.map +0 -1
- package/dist/src/faf-core/fix-once/types.d.ts +0 -257
- package/dist/src/faf-core/fix-once/types.js +0 -26
- package/dist/src/faf-core/fix-once/types.js.map +0 -1
- package/dist/src/faf-core/generators/faf-generator-championship.d.ts +0 -16
- package/dist/src/faf-core/generators/faf-generator-championship.js +0 -463
- package/dist/src/faf-core/generators/faf-generator-championship.js.map +0 -1
- package/dist/src/faf-core/inject.d.ts +0 -19
- package/dist/src/faf-core/inject.js +0 -57
- package/dist/src/faf-core/inject.js.map +0 -1
- package/dist/src/faf-core/parsers/index.d.ts +0 -12
- package/dist/src/faf-core/parsers/index.js +0 -29
- package/dist/src/faf-core/parsers/index.js.map +0 -1
- package/dist/src/faf-core/utils/balance-visualizer.d.ts +0 -37
- package/dist/src/faf-core/utils/balance-visualizer.js +0 -197
- package/dist/src/faf-core/utils/balance-visualizer.js.map +0 -1
- package/dist/src/faf-core/utils/championship-style.d.ts +0 -109
- package/dist/src/faf-core/utils/championship-style.js +0 -219
- package/dist/src/faf-core/utils/championship-style.js.map +0 -1
- package/dist/src/faf-core/utils/chrome-extension-detector.d.ts +0 -73
- package/dist/src/faf-core/utils/chrome-extension-detector.js +0 -268
- package/dist/src/faf-core/utils/chrome-extension-detector.js.map +0 -1
- package/dist/src/faf-core/utils/platform-detector.d.ts +0 -30
- package/dist/src/faf-core/utils/platform-detector.js +0 -218
- package/dist/src/faf-core/utils/platform-detector.js.map +0 -1
- package/dist/src/faf-core/utils/technical-credit.d.ts +0 -35
- package/dist/src/faf-core/utils/technical-credit.js +0 -286
- package/dist/src/faf-core/utils/technical-credit.js.map +0 -1
- package/dist/src/faf-core/utils/yaml-generator.d.ts +0 -41
- package/dist/src/faf-core/utils/yaml-generator.js +0 -360
- package/dist/src/faf-core/utils/yaml-generator.js.map +0 -1
- package/dist/src/handlers/behavioral-instruction.d.ts +0 -16
- package/dist/src/handlers/behavioral-instruction.js +0 -43
- package/dist/src/handlers/behavioral-instruction.js.map +0 -1
- package/dist/src/handlers/championship-tools.d.ts +0 -116
- package/dist/src/handlers/championship-tools.js +0 -2320
- package/dist/src/handlers/championship-tools.js.map +0 -1
- package/dist/src/handlers/cloud-handler.d.ts +0 -59
- package/dist/src/handlers/cloud-handler.js +0 -348
- package/dist/src/handlers/cloud-handler.js.map +0 -1
- package/dist/src/handlers/tool-registry.d.ts +0 -23
- package/dist/src/handlers/tool-registry.js +0 -68
- package/dist/src/handlers/tool-registry.js.map +0 -1
- package/dist/src/handlers/tool-types.d.ts +0 -167
- package/dist/src/handlers/tool-types.js +0 -7
- package/dist/src/handlers/tool-types.js.map +0 -1
- package/dist/src/test-all-functions.d.ts +0 -15
- package/dist/src/test-all-functions.js +0 -163
- package/dist/src/test-all-functions.js.map +0 -1
- package/dist/src/types/mcp-tools.d.ts +0 -53
- package/dist/src/types/mcp-tools.js +0 -77
- package/dist/src/types/mcp-tools.js.map +0 -1
- package/dist/src/types/tool-visibility.d.ts +0 -36
- package/dist/src/types/tool-visibility.js +0 -551
- package/dist/src/types/tool-visibility.js.map +0 -1
- package/dist/src/utils/auto-path-detection.d.ts +0 -26
- package/dist/src/utils/auto-path-detection.js +0 -198
- package/dist/src/utils/auto-path-detection.js.map +0 -1
- package/dist/src/utils/championship-format.d.ts +0 -30
- package/dist/src/utils/championship-format.js +0 -81
- package/dist/src/utils/championship-format.js.map +0 -1
- package/dist/src/utils/cli-detector.d.ts +0 -17
- package/dist/src/utils/cli-detector.js +0 -247
- package/dist/src/utils/cli-detector.js.map +0 -1
- package/dist/src/utils/display-protocol.d.ts +0 -57
- package/dist/src/utils/display-protocol.js +0 -131
- package/dist/src/utils/display-protocol.js.map +0 -1
- package/dist/src/utils/username-detector.d.ts +0 -27
- package/dist/src/utils/username-detector.js +0 -90
- package/dist/src/utils/username-detector.js.map +0 -1
- package/dist/src/utils/visual-style.d.ts +0 -62
- package/dist/src/utils/visual-style.js +0 -166
- package/dist/src/utils/visual-style.js.map +0 -1
- package/scripts/postinstall.js +0 -50
- 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
|
-
|
|
38
|
-
|
|
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");
|
|
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
|
-
|
|
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
|
|
@@ -126,7 +83,27 @@ class FafEngineAdapter {
|
|
|
126
83
|
if (mcpWorkingDir && fs.existsSync(mcpWorkingDir)) {
|
|
127
84
|
return mcpWorkingDir;
|
|
128
85
|
}
|
|
129
|
-
// Priority 3:
|
|
86
|
+
// Priority 3 (FIX 2026-06-30): the caller's ACTUAL working directory — the
|
|
87
|
+
// workspace an IDE / MCP host (Cursor, VS Code, Claude Desktop) launches the
|
|
88
|
+
// server in. This MUST win over the ~/Projects convention below. Previously
|
|
89
|
+
// ~/Projects was FORCED here, so every no-path tool call (faf_score, …)
|
|
90
|
+
// operated on ~/Projects instead of the project the user actually had open —
|
|
91
|
+
// the editor surface's whole value, silently broken (scored ~/Projects's
|
|
92
|
+
// stale .faf for everyone). Prefer a real FAF project (cwd contains
|
|
93
|
+
// project.faf — the path-check), else the cwd itself when it's a usable,
|
|
94
|
+
// non-root directory (so faf_init/score act on the open workspace even
|
|
95
|
+
// before a .faf exists).
|
|
96
|
+
const currentDir = process.cwd();
|
|
97
|
+
const usableCwd = currentDir !== '/' && currentDir !== '/root' && fs.existsSync(currentDir);
|
|
98
|
+
if (usableCwd && fs.existsSync(path.join(currentDir, 'project.faf'))) {
|
|
99
|
+
return currentDir;
|
|
100
|
+
}
|
|
101
|
+
if (usableCwd) {
|
|
102
|
+
return currentDir;
|
|
103
|
+
}
|
|
104
|
+
// Priority 4: ~/Projects convention — a soft landing ONLY when the host gave
|
|
105
|
+
// us no usable workspace (e.g. cwd is the filesystem root). Never overrides a
|
|
106
|
+
// real cwd above.
|
|
130
107
|
const homeDir = process.env.HOME ?? process.env.USERPROFILE;
|
|
131
108
|
if (homeDir) {
|
|
132
109
|
// Try capitalized Projects first (macOS/Windows convention)
|
|
@@ -149,632 +126,99 @@ class FafEngineAdapter {
|
|
|
149
126
|
return homeDir;
|
|
150
127
|
}
|
|
151
128
|
}
|
|
152
|
-
// Priority 4: Current directory if not root
|
|
153
|
-
const currentDir = process.cwd();
|
|
154
|
-
if (currentDir !== '/' && currentDir !== '/root' && fs.existsSync(currentDir)) {
|
|
155
|
-
return currentDir;
|
|
156
|
-
}
|
|
157
129
|
// Last resort: /tmp (should rarely happen)
|
|
158
130
|
return '/tmp';
|
|
159
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
|
+
}
|
|
160
148
|
async callEngine(command, args = []) {
|
|
161
149
|
const startTime = Date.now();
|
|
162
|
-
// Input validation
|
|
163
150
|
if (!command || typeof command !== 'string') {
|
|
164
|
-
return {
|
|
165
|
-
success: false,
|
|
166
|
-
error: 'Command must be a non-empty string',
|
|
167
|
-
duration: 0
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
// ============================================================================
|
|
171
|
-
// MK3 BUNDLED ENGINE - Direct function calls (no CLI dependency!)
|
|
172
|
-
// ============================================================================
|
|
173
|
-
// SCORE command - use bundled FafCompiler
|
|
174
|
-
if (command === 'score') {
|
|
175
|
-
try {
|
|
176
|
-
const filePath = args[0] || this.workingDirectory;
|
|
177
|
-
const result = await (0, score_js_1.scoreFafFile)(filePath, { json: true });
|
|
178
|
-
const duration = Date.now() - startTime;
|
|
179
|
-
return {
|
|
180
|
-
success: true,
|
|
181
|
-
data: result,
|
|
182
|
-
duration
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
catch (error) {
|
|
186
|
-
const duration = Date.now() - startTime;
|
|
187
|
-
const errorMessage = (0, type_guards_js_1.isError)(error) ? error.message : 'Score command failed';
|
|
188
|
-
return {
|
|
189
|
-
success: false,
|
|
190
|
-
error: errorMessage,
|
|
191
|
-
duration
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
// INIT command - use bundled init
|
|
196
|
-
if (command === 'init') {
|
|
197
|
-
try {
|
|
198
|
-
// Filter out flags to get the actual path argument
|
|
199
|
-
const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
|
|
200
|
-
const projectPath = pathArgs[0] || this.workingDirectory;
|
|
201
|
-
const force = args.includes('--force');
|
|
202
|
-
const result = await (0, init_js_1.initFafFile)(projectPath, { force });
|
|
203
|
-
const duration = Date.now() - startTime;
|
|
204
|
-
return {
|
|
205
|
-
success: result.success,
|
|
206
|
-
data: result,
|
|
207
|
-
duration
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
catch (error) {
|
|
211
|
-
const duration = Date.now() - startTime;
|
|
212
|
-
const errorMessage = (0, type_guards_js_1.isError)(error) ? error.message : 'Init command failed';
|
|
213
|
-
return {
|
|
214
|
-
success: false,
|
|
215
|
-
error: errorMessage,
|
|
216
|
-
duration
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
// AUTO command - use bundled auto (init + score)
|
|
221
|
-
if (command === 'auto') {
|
|
222
|
-
try {
|
|
223
|
-
// Filter out flags to get the actual path argument
|
|
224
|
-
const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
|
|
225
|
-
const directory = pathArgs[0] || this.workingDirectory;
|
|
226
|
-
const force = args.includes('--force');
|
|
227
|
-
const result = await (0, auto_js_1.autoCommand)(directory, { force });
|
|
228
|
-
const duration = Date.now() - startTime;
|
|
229
|
-
return {
|
|
230
|
-
success: result.success,
|
|
231
|
-
data: result,
|
|
232
|
-
duration
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
catch (error) {
|
|
236
|
-
const duration = Date.now() - startTime;
|
|
237
|
-
const errorMessage = (0, type_guards_js_1.isError)(error) ? error.message : 'Auto command failed';
|
|
238
|
-
return {
|
|
239
|
-
success: false,
|
|
240
|
-
error: errorMessage,
|
|
241
|
-
duration
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
// SYNC command - use bundled sync
|
|
246
|
-
if (command === 'sync') {
|
|
247
|
-
try {
|
|
248
|
-
const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
|
|
249
|
-
const projectPath = pathArgs[0] || this.workingDirectory;
|
|
250
|
-
const auto = args.includes('--auto');
|
|
251
|
-
const result = await (0, sync_js_1.syncFafFile)(projectPath, { auto, json: true });
|
|
252
|
-
const duration = Date.now() - startTime;
|
|
253
|
-
return {
|
|
254
|
-
success: result.success,
|
|
255
|
-
data: result,
|
|
256
|
-
duration
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
catch (error) {
|
|
260
|
-
const duration = Date.now() - startTime;
|
|
261
|
-
return {
|
|
262
|
-
success: false,
|
|
263
|
-
error: (0, type_guards_js_1.isError)(error) ? error.message : 'Sync command failed',
|
|
264
|
-
duration
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
// BI-SYNC command - use bundled bi-sync (v4.5.0: supports agents/cursor/gemini/all flags)
|
|
269
|
-
if (command === 'bi-sync' || command === 'bisync') {
|
|
270
|
-
try {
|
|
271
|
-
const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
|
|
272
|
-
const projectPath = pathArgs[0] || this.workingDirectory;
|
|
273
|
-
const result = await (0, bi_sync_js_1.syncBiDirectional)(projectPath, {
|
|
274
|
-
json: true,
|
|
275
|
-
agents: args.includes('--agents'),
|
|
276
|
-
cursor: args.includes('--cursor'),
|
|
277
|
-
gemini: args.includes('--gemini'),
|
|
278
|
-
all: args.includes('--all'),
|
|
279
|
-
});
|
|
280
|
-
const duration = Date.now() - startTime;
|
|
281
|
-
return {
|
|
282
|
-
success: result.success,
|
|
283
|
-
data: result,
|
|
284
|
-
duration
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
catch (error) {
|
|
288
|
-
const duration = Date.now() - startTime;
|
|
289
|
-
return {
|
|
290
|
-
success: false,
|
|
291
|
-
error: (0, type_guards_js_1.isError)(error) ? error.message : 'Bi-sync command failed',
|
|
292
|
-
duration
|
|
293
|
-
};
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
// FORMATS command - use bundled formats
|
|
297
|
-
if (command === 'formats') {
|
|
298
|
-
try {
|
|
299
|
-
const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
|
|
300
|
-
const projectPath = pathArgs[0] || this.workingDirectory;
|
|
301
|
-
const result = await (0, formats_js_1.formatsCommand)(projectPath, { json: true });
|
|
302
|
-
const duration = Date.now() - startTime;
|
|
303
|
-
return {
|
|
304
|
-
success: result.success,
|
|
305
|
-
data: result,
|
|
306
|
-
duration
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
catch (error) {
|
|
310
|
-
const duration = Date.now() - startTime;
|
|
311
|
-
return {
|
|
312
|
-
success: false,
|
|
313
|
-
error: (0, type_guards_js_1.isError)(error) ? error.message : 'Formats command failed',
|
|
314
|
-
duration
|
|
315
|
-
};
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
// DOCTOR command - use bundled doctor
|
|
319
|
-
if (command === 'doctor') {
|
|
320
|
-
try {
|
|
321
|
-
const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
|
|
322
|
-
const projectPath = pathArgs[0] || this.workingDirectory;
|
|
323
|
-
const result = await (0, doctor_js_1.doctorCommand)(projectPath);
|
|
324
|
-
const duration = Date.now() - startTime;
|
|
325
|
-
return {
|
|
326
|
-
success: result.success,
|
|
327
|
-
data: result,
|
|
328
|
-
duration
|
|
329
|
-
};
|
|
330
|
-
}
|
|
331
|
-
catch (error) {
|
|
332
|
-
const duration = Date.now() - startTime;
|
|
333
|
-
return {
|
|
334
|
-
success: false,
|
|
335
|
-
error: (0, type_guards_js_1.isError)(error) ? error.message : 'Doctor command failed',
|
|
336
|
-
duration
|
|
337
|
-
};
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
// VALIDATE command - use bundled validate
|
|
341
|
-
if (command === 'validate') {
|
|
342
|
-
try {
|
|
343
|
-
const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
|
|
344
|
-
const projectPath = pathArgs[0] || this.workingDirectory;
|
|
345
|
-
const result = await (0, validate_js_1.validateFafFile)(projectPath, { json: true });
|
|
346
|
-
const duration = Date.now() - startTime;
|
|
347
|
-
return {
|
|
348
|
-
success: result.success,
|
|
349
|
-
data: result,
|
|
350
|
-
duration
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
|
-
catch (error) {
|
|
354
|
-
const duration = Date.now() - startTime;
|
|
355
|
-
return {
|
|
356
|
-
success: false,
|
|
357
|
-
error: (0, type_guards_js_1.isError)(error) ? error.message : 'Validate command failed',
|
|
358
|
-
duration
|
|
359
|
-
};
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
// AUDIT command - use bundled audit
|
|
363
|
-
if (command === 'audit') {
|
|
364
|
-
try {
|
|
365
|
-
const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
|
|
366
|
-
const projectPath = pathArgs[0] || this.workingDirectory;
|
|
367
|
-
const result = await (0, audit_js_1.auditFafFile)(projectPath, { json: true });
|
|
368
|
-
const duration = Date.now() - startTime;
|
|
369
|
-
return {
|
|
370
|
-
success: result.success,
|
|
371
|
-
data: result,
|
|
372
|
-
duration
|
|
373
|
-
};
|
|
374
|
-
}
|
|
375
|
-
catch (error) {
|
|
376
|
-
const duration = Date.now() - startTime;
|
|
377
|
-
return {
|
|
378
|
-
success: false,
|
|
379
|
-
error: (0, type_guards_js_1.isError)(error) ? error.message : 'Audit command failed',
|
|
380
|
-
duration
|
|
381
|
-
};
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
// UPDATE command - use bundled update
|
|
385
|
-
if (command === 'update') {
|
|
386
|
-
try {
|
|
387
|
-
const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
|
|
388
|
-
const projectPath = pathArgs[0] || this.workingDirectory;
|
|
389
|
-
const result = await (0, update_js_1.updateFafFile)(projectPath, { json: true });
|
|
390
|
-
const duration = Date.now() - startTime;
|
|
391
|
-
return {
|
|
392
|
-
success: result.success,
|
|
393
|
-
data: result,
|
|
394
|
-
duration
|
|
395
|
-
};
|
|
396
|
-
}
|
|
397
|
-
catch (error) {
|
|
398
|
-
const duration = Date.now() - startTime;
|
|
399
|
-
return {
|
|
400
|
-
success: false,
|
|
401
|
-
error: (0, type_guards_js_1.isError)(error) ? error.message : 'Update command failed',
|
|
402
|
-
duration
|
|
403
|
-
};
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
// MIGRATE command - use bundled migrate
|
|
407
|
-
if (command === 'migrate') {
|
|
408
|
-
try {
|
|
409
|
-
const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
|
|
410
|
-
const projectPath = pathArgs[0] || this.workingDirectory;
|
|
411
|
-
const force = args.includes('--force');
|
|
412
|
-
const result = await (0, migrate_js_1.migrateFafFile)(projectPath, { force, json: true });
|
|
413
|
-
const duration = Date.now() - startTime;
|
|
414
|
-
return {
|
|
415
|
-
success: result.success,
|
|
416
|
-
data: result,
|
|
417
|
-
duration
|
|
418
|
-
};
|
|
419
|
-
}
|
|
420
|
-
catch (error) {
|
|
421
|
-
const duration = Date.now() - startTime;
|
|
422
|
-
return {
|
|
423
|
-
success: false,
|
|
424
|
-
error: (0, type_guards_js_1.isError)(error) ? error.message : 'Migrate command failed',
|
|
425
|
-
duration
|
|
426
|
-
};
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
// INNIT command - use bundled innit (British init)
|
|
430
|
-
if (command === 'innit') {
|
|
431
|
-
try {
|
|
432
|
-
const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
|
|
433
|
-
const projectPath = pathArgs[0] || this.workingDirectory;
|
|
434
|
-
const force = args.includes('--force');
|
|
435
|
-
const result = await (0, innit_js_1.innitFafFile)(projectPath, { force });
|
|
436
|
-
const duration = Date.now() - startTime;
|
|
437
|
-
return {
|
|
438
|
-
success: result.success,
|
|
439
|
-
data: result,
|
|
440
|
-
duration
|
|
441
|
-
};
|
|
442
|
-
}
|
|
443
|
-
catch (error) {
|
|
444
|
-
const duration = Date.now() - startTime;
|
|
445
|
-
return {
|
|
446
|
-
success: false,
|
|
447
|
-
error: (0, type_guards_js_1.isError)(error) ? error.message : 'Innit command failed',
|
|
448
|
-
duration
|
|
449
|
-
};
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
// QUICK command - use bundled quick
|
|
453
|
-
if (command === 'quick') {
|
|
454
|
-
try {
|
|
455
|
-
const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
|
|
456
|
-
const projectPath = pathArgs[0] || this.workingDirectory;
|
|
457
|
-
const input = pathArgs[1]; // optional input string
|
|
458
|
-
const force = args.includes('--force');
|
|
459
|
-
const json = args.includes('--json');
|
|
460
|
-
const result = await (0, quick_js_1.quickCommand)(projectPath, input, { force, json });
|
|
461
|
-
const duration = Date.now() - startTime;
|
|
462
|
-
return {
|
|
463
|
-
success: result.success,
|
|
464
|
-
data: result,
|
|
465
|
-
duration
|
|
466
|
-
};
|
|
467
|
-
}
|
|
468
|
-
catch (error) {
|
|
469
|
-
const duration = Date.now() - startTime;
|
|
470
|
-
return {
|
|
471
|
-
success: false,
|
|
472
|
-
error: (0, type_guards_js_1.isError)(error) ? error.message : 'Quick command failed',
|
|
473
|
-
duration
|
|
474
|
-
};
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
// HUMAN command - use bundled human (add/set human_context)
|
|
478
|
-
if (command === 'human' || command === 'human-add') {
|
|
479
|
-
try {
|
|
480
|
-
const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
|
|
481
|
-
const projectPath = pathArgs[0] || this.workingDirectory;
|
|
482
|
-
// Extract YAML from args if provided
|
|
483
|
-
const yamlArg = args.find(arg => arg.startsWith('--yaml='));
|
|
484
|
-
const yaml = yamlArg ? yamlArg.substring(7) : undefined;
|
|
485
|
-
// Extract field/value for single field mode
|
|
486
|
-
const fieldArg = args.find(arg => arg.startsWith('--field='));
|
|
487
|
-
const valueArg = args.find(arg => arg.startsWith('--value='));
|
|
488
|
-
const field = fieldArg ? fieldArg.substring(8) : undefined;
|
|
489
|
-
const value = valueArg ? valueArg.substring(8) : undefined;
|
|
490
|
-
const result = await (0, human_js_1.humanAddCommand)(projectPath, { yaml, field, value });
|
|
491
|
-
const duration = Date.now() - startTime;
|
|
492
|
-
return {
|
|
493
|
-
success: result.success,
|
|
494
|
-
data: result,
|
|
495
|
-
duration
|
|
496
|
-
};
|
|
497
|
-
}
|
|
498
|
-
catch (error) {
|
|
499
|
-
const duration = Date.now() - startTime;
|
|
500
|
-
return {
|
|
501
|
-
success: false,
|
|
502
|
-
error: (0, type_guards_js_1.isError)(error) ? error.message : 'Human command failed',
|
|
503
|
-
duration
|
|
504
|
-
};
|
|
505
|
-
}
|
|
151
|
+
return { success: false, error: 'Command must be a non-empty string', duration: 0 };
|
|
506
152
|
}
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
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:
|
|
515
213
|
return {
|
|
516
214
|
success: false,
|
|
517
|
-
error: '
|
|
518
|
-
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,
|
|
519
217
|
};
|
|
520
|
-
}
|
|
521
|
-
const result = await (0, human_js_1.humanSetCommand)(projectPath, field, value);
|
|
522
|
-
const duration = Date.now() - startTime;
|
|
523
|
-
return {
|
|
524
|
-
success: result.success,
|
|
525
|
-
data: result,
|
|
526
|
-
duration
|
|
527
|
-
};
|
|
528
|
-
}
|
|
529
|
-
catch (error) {
|
|
530
|
-
const duration = Date.now() - startTime;
|
|
531
|
-
return {
|
|
532
|
-
success: false,
|
|
533
|
-
error: (0, type_guards_js_1.isError)(error) ? error.message : 'Human-set command failed',
|
|
534
|
-
duration
|
|
535
|
-
};
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
// README command - extract context from README.md
|
|
539
|
-
if (command === 'readme' || command === 'readme-extract') {
|
|
540
|
-
try {
|
|
541
|
-
const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
|
|
542
|
-
const projectPath = pathArgs[0] || this.workingDirectory;
|
|
543
|
-
const result = await (0, readme_js_1.readmeExtractCommand)(projectPath);
|
|
544
|
-
const duration = Date.now() - startTime;
|
|
545
|
-
return {
|
|
546
|
-
success: result.success,
|
|
547
|
-
data: result,
|
|
548
|
-
duration
|
|
549
|
-
};
|
|
550
|
-
}
|
|
551
|
-
catch (error) {
|
|
552
|
-
const duration = Date.now() - startTime;
|
|
553
|
-
return {
|
|
554
|
-
success: false,
|
|
555
|
-
error: (0, type_guards_js_1.isError)(error) ? error.message : 'README extract command failed',
|
|
556
|
-
duration
|
|
557
|
-
};
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
// README-MERGE command - extract and merge into .faf
|
|
561
|
-
if (command === 'readme-merge') {
|
|
562
|
-
try {
|
|
563
|
-
const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
|
|
564
|
-
const projectPath = pathArgs[0] || this.workingDirectory;
|
|
565
|
-
// Check for overwrite flag
|
|
566
|
-
const overwrite = args.includes('--overwrite');
|
|
567
|
-
const result = await (0, readme_js_1.readmeMergeCommand)(projectPath, { overwrite });
|
|
568
|
-
const duration = Date.now() - startTime;
|
|
569
|
-
return {
|
|
570
|
-
success: result.success,
|
|
571
|
-
data: result,
|
|
572
|
-
duration
|
|
573
|
-
};
|
|
574
|
-
}
|
|
575
|
-
catch (error) {
|
|
576
|
-
const duration = Date.now() - startTime;
|
|
577
|
-
return {
|
|
578
|
-
success: false,
|
|
579
|
-
error: (0, type_guards_js_1.isError)(error) ? error.message : 'README merge command failed',
|
|
580
|
-
duration
|
|
581
|
-
};
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
// ============================================================================
|
|
585
|
-
// v4.5.0 INTEROP COMMANDS
|
|
586
|
-
// ============================================================================
|
|
587
|
-
// AGENTS command - import/export/sync AGENTS.md
|
|
588
|
-
if (command === 'agents') {
|
|
589
|
-
try {
|
|
590
|
-
const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
|
|
591
|
-
const projectPath = pathArgs[0] || this.workingDirectory;
|
|
592
|
-
const actionArg = args.find(arg => arg.startsWith('--action='));
|
|
593
|
-
const action = actionArg ? actionArg.substring(9) : 'sync';
|
|
594
|
-
const force = args.includes('--force');
|
|
595
|
-
const merge = args.includes('--merge');
|
|
596
|
-
let result;
|
|
597
|
-
if (action === 'import') {
|
|
598
|
-
result = await (0, agents_js_1.agentsImportCommand)(projectPath, { merge });
|
|
599
|
-
}
|
|
600
|
-
else if (action === 'export') {
|
|
601
|
-
result = await (0, agents_js_1.agentsExportCommand)(projectPath, { force });
|
|
602
|
-
}
|
|
603
|
-
else {
|
|
604
|
-
result = await (0, agents_js_1.agentsSyncCommand)(projectPath);
|
|
605
|
-
}
|
|
606
|
-
return { success: result.success, data: result, duration: Date.now() - startTime };
|
|
607
|
-
}
|
|
608
|
-
catch (error) {
|
|
609
|
-
return { success: false, error: (0, type_guards_js_1.isError)(error) ? error.message : 'Agents command failed', duration: Date.now() - startTime };
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
// CURSOR command - import/export/sync .cursorrules
|
|
613
|
-
if (command === 'cursor') {
|
|
614
|
-
try {
|
|
615
|
-
const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
|
|
616
|
-
const projectPath = pathArgs[0] || this.workingDirectory;
|
|
617
|
-
const actionArg = args.find(arg => arg.startsWith('--action='));
|
|
618
|
-
const action = actionArg ? actionArg.substring(9) : 'sync';
|
|
619
|
-
const force = args.includes('--force');
|
|
620
|
-
const merge = args.includes('--merge');
|
|
621
|
-
let result;
|
|
622
|
-
if (action === 'import') {
|
|
623
|
-
result = await (0, cursor_js_1.cursorImportCommand)(projectPath, { merge });
|
|
624
|
-
}
|
|
625
|
-
else if (action === 'export') {
|
|
626
|
-
result = await (0, cursor_js_1.cursorExportCommand)(projectPath, { force });
|
|
627
|
-
}
|
|
628
|
-
else {
|
|
629
|
-
result = await (0, cursor_js_1.cursorSyncCommand)(projectPath);
|
|
630
|
-
}
|
|
631
|
-
return { success: result.success, data: result, duration: Date.now() - startTime };
|
|
632
|
-
}
|
|
633
|
-
catch (error) {
|
|
634
|
-
return { success: false, error: (0, type_guards_js_1.isError)(error) ? error.message : 'Cursor command failed', duration: Date.now() - startTime };
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
// GEMINI command - import/export/sync GEMINI.md
|
|
638
|
-
if (command === 'gemini') {
|
|
639
|
-
try {
|
|
640
|
-
const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
|
|
641
|
-
const projectPath = pathArgs[0] || this.workingDirectory;
|
|
642
|
-
const actionArg = args.find(arg => arg.startsWith('--action='));
|
|
643
|
-
const action = actionArg ? actionArg.substring(9) : 'sync';
|
|
644
|
-
const force = args.includes('--force');
|
|
645
|
-
const merge = args.includes('--merge');
|
|
646
|
-
let result;
|
|
647
|
-
if (action === 'import') {
|
|
648
|
-
result = await (0, gemini_js_1.geminiImportCommand)(projectPath, { merge });
|
|
649
|
-
}
|
|
650
|
-
else if (action === 'export') {
|
|
651
|
-
result = await (0, gemini_js_1.geminiExportCommand)(projectPath, { force });
|
|
652
|
-
}
|
|
653
|
-
else {
|
|
654
|
-
result = await (0, gemini_js_1.geminiSyncCommand)(projectPath);
|
|
655
|
-
}
|
|
656
|
-
return { success: result.success, data: result, duration: Date.now() - startTime };
|
|
657
|
-
}
|
|
658
|
-
catch (error) {
|
|
659
|
-
return { success: false, error: (0, type_guards_js_1.isError)(error) ? error.message : 'Gemini command failed', duration: Date.now() - startTime };
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
// CONDUCTOR command - import/export conductor/
|
|
663
|
-
if (command === 'conductor') {
|
|
664
|
-
try {
|
|
665
|
-
const pathArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
|
|
666
|
-
const projectPath = pathArgs[0] || this.workingDirectory;
|
|
667
|
-
const actionArg = args.find(arg => arg.startsWith('--action='));
|
|
668
|
-
const action = actionArg ? actionArg.substring(9) : 'import';
|
|
669
|
-
const force = args.includes('--force');
|
|
670
|
-
const merge = args.includes('--merge');
|
|
671
|
-
let result;
|
|
672
|
-
if (action === 'export') {
|
|
673
|
-
result = await (0, conductor_js_1.conductorExportCommand)(projectPath, { force });
|
|
674
|
-
}
|
|
675
|
-
else {
|
|
676
|
-
result = await (0, conductor_js_1.conductorImportCommand)(projectPath, { merge });
|
|
677
|
-
}
|
|
678
|
-
return { success: result.success, data: result, duration: Date.now() - startTime };
|
|
679
|
-
}
|
|
680
|
-
catch (error) {
|
|
681
|
-
return { success: false, error: (0, type_guards_js_1.isError)(error) ? error.message : 'Conductor command failed', duration: Date.now() - startTime };
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
// GIT command - generate .faf from GitHub repo
|
|
685
|
-
if (command === 'git') {
|
|
686
|
-
try {
|
|
687
|
-
const url = args[0];
|
|
688
|
-
const outputPath = args[1]; // optional
|
|
689
|
-
if (!url) {
|
|
690
|
-
return { success: false, error: 'URL is required', duration: Date.now() - startTime };
|
|
691
|
-
}
|
|
692
|
-
const result = await (0, git_context_js_1.gitContextCommand)(url, outputPath);
|
|
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 : 'Git command failed', duration: Date.now() - startTime };
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
// ============================================================================
|
|
700
|
-
// FALLBACK: Shell out to CLI for commands not yet bundled
|
|
701
|
-
// ============================================================================
|
|
702
|
-
// Check if CLI is available
|
|
703
|
-
if (!this.detectedCliPath) {
|
|
704
|
-
const duration = Date.now() - startTime;
|
|
705
|
-
return {
|
|
706
|
-
success: false,
|
|
707
|
-
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.`,
|
|
708
|
-
duration
|
|
709
|
-
};
|
|
710
|
-
}
|
|
711
|
-
// Sanitize arguments to prevent injection
|
|
712
|
-
const sanitizedArgs = args.map(arg => typeof arg === 'string' ? arg.replace(/[;&|`$(){}[\]]/g, '') : '');
|
|
713
|
-
try {
|
|
714
|
-
// Use detected absolute path to CLI
|
|
715
|
-
const fullCommand = `"${this.detectedCliPath}" ${command} ${sanitizedArgs.join(' ')}`;
|
|
716
|
-
const { stdout, stderr } = await execAsync(fullCommand, {
|
|
717
|
-
env: getEnhancedEnv(),
|
|
718
|
-
timeout: this.timeout,
|
|
719
|
-
maxBuffer: 1024 * 1024, // 1MB buffer limit
|
|
720
|
-
cwd: this.workingDirectory
|
|
721
|
-
});
|
|
722
|
-
const duration = Date.now() - startTime;
|
|
723
|
-
if (stderr?.trim()) {
|
|
724
|
-
console.warn(`FAF CLI warning: ${stderr.trim()}`);
|
|
725
218
|
}
|
|
726
|
-
return {
|
|
727
|
-
success: true,
|
|
728
|
-
data: this.parseOutput(stdout),
|
|
729
|
-
duration
|
|
730
|
-
};
|
|
731
219
|
}
|
|
732
220
|
catch (error) {
|
|
733
|
-
|
|
734
|
-
let errorMessage = 'Unknown error occurred';
|
|
735
|
-
if ((0, type_guards_js_1.isError)(error)) {
|
|
736
|
-
errorMessage = error.message;
|
|
737
|
-
// Handle specific error codes
|
|
738
|
-
if ('code' in error) {
|
|
739
|
-
if (error.code === 'ETIMEDOUT') {
|
|
740
|
-
errorMessage = `Command timed out after ${this.timeout}ms`;
|
|
741
|
-
}
|
|
742
|
-
else if (error.code === 'ENOENT') {
|
|
743
|
-
errorMessage = `FAF CLI not found at ${this.detectedCliPath}. Please reinstall: npm install -g faf-cli`;
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
// Handle signal termination
|
|
747
|
-
if ('signal' in error && error.signal === 'SIGTERM') {
|
|
748
|
-
errorMessage = 'Command was terminated';
|
|
749
|
-
}
|
|
750
|
-
}
|
|
751
|
-
console.error(`FAF CLI error: ${errorMessage}`);
|
|
752
|
-
return {
|
|
753
|
-
success: false,
|
|
754
|
-
error: errorMessage,
|
|
755
|
-
duration
|
|
756
|
-
};
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
parseOutput(output) {
|
|
760
|
-
if (!output || output.trim() === '') {
|
|
761
|
-
return { output: '' };
|
|
762
|
-
}
|
|
763
|
-
try {
|
|
764
|
-
return JSON.parse(output);
|
|
765
|
-
}
|
|
766
|
-
catch {
|
|
767
|
-
return { output: output.trim() };
|
|
768
|
-
}
|
|
769
|
-
}
|
|
770
|
-
// Method to check if FAF CLI is available
|
|
771
|
-
async checkHealth() {
|
|
772
|
-
try {
|
|
773
|
-
const result = await this.callEngine('--version');
|
|
774
|
-
return result.success;
|
|
775
|
-
}
|
|
776
|
-
catch {
|
|
777
|
-
return false;
|
|
221
|
+
return this.failure(error, `${command} command failed`, startTime);
|
|
778
222
|
}
|
|
779
223
|
}
|
|
780
224
|
// Get the current working directory used by the adapter
|
|
@@ -800,14 +244,6 @@ class FafEngineAdapter {
|
|
|
800
244
|
getEnginePath() {
|
|
801
245
|
return this.enginePath;
|
|
802
246
|
}
|
|
803
|
-
// Get CLI detection info for debugging
|
|
804
|
-
getCliInfo() {
|
|
805
|
-
return {
|
|
806
|
-
detected: this.detectedCliPath !== null,
|
|
807
|
-
path: this.detectedCliPath || undefined,
|
|
808
|
-
version: this.cliVersion
|
|
809
|
-
};
|
|
810
|
-
}
|
|
811
247
|
}
|
|
812
248
|
exports.FafEngineAdapter = FafEngineAdapter;
|
|
813
249
|
//# sourceMappingURL=engine-adapter.js.map
|