cf-doctor 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +161 -0
  3. package/bin/cf-doctor.js +18 -0
  4. package/dist/doctor.d.ts +21 -0
  5. package/dist/doctor.d.ts.map +1 -0
  6. package/dist/doctor.js +33 -0
  7. package/dist/doctor.js.map +1 -0
  8. package/dist/index.d.ts +9 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +9 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/mcp-server.d.ts +12 -0
  13. package/dist/mcp-server.d.ts.map +1 -0
  14. package/dist/mcp-server.js +200 -0
  15. package/dist/mcp-server.js.map +1 -0
  16. package/dist/patches/apply.d.ts +7 -0
  17. package/dist/patches/apply.d.ts.map +1 -0
  18. package/dist/patches/apply.js +51 -0
  19. package/dist/patches/apply.js.map +1 -0
  20. package/dist/persistence/episodes.d.ts +42 -0
  21. package/dist/persistence/episodes.d.ts.map +1 -0
  22. package/dist/persistence/episodes.js +160 -0
  23. package/dist/persistence/episodes.js.map +1 -0
  24. package/dist/persistence/index.d.ts +4 -0
  25. package/dist/persistence/index.d.ts.map +1 -0
  26. package/dist/persistence/index.js +4 -0
  27. package/dist/persistence/index.js.map +1 -0
  28. package/dist/persistence/q-table.d.ts +42 -0
  29. package/dist/persistence/q-table.d.ts.map +1 -0
  30. package/dist/persistence/q-table.js +138 -0
  31. package/dist/persistence/q-table.js.map +1 -0
  32. package/dist/persistence/sona.d.ts +45 -0
  33. package/dist/persistence/sona.d.ts.map +1 -0
  34. package/dist/persistence/sona.js +142 -0
  35. package/dist/persistence/sona.js.map +1 -0
  36. package/package.json +63 -0
  37. package/patches/README.md +68 -0
  38. package/patches/neural-index.patch +8 -0
  39. package/patches/quick-test.patch +25 -0
  40. package/patches/sona-integration.patch +76 -0
  41. package/patches/version-bridge.patch +30 -0
  42. package/scripts/cf-doctor.sh +684 -0
  43. package/tests/run-all-tests.sh +32 -0
  44. package/tests/test-01-doctor-passes.sh +43 -0
  45. package/tests/test-02-mcp-init.sh +36 -0
  46. package/tests/test-03-agent-spawn-no-ruvector.sh +84 -0
  47. package/tests/test-04-agent-spawn-with-ruvector.sh +37 -0
  48. package/tests/test-05-learning-persists.sh +94 -0
  49. package/tests/test-06-hooks-version-bridge.sh +82 -0
  50. package/tests/test-helpers.sh +88 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 FoxFlow Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,161 @@
1
+ # cf-doctor
2
+
3
+ > Setup validator, auto-fixer, and learning persistence for [claude-flow](https://github.com/ruvnet/claude-flow) + [ruvector](https://github.com/ruvnet/ruvector) integration.
4
+
5
+ Fixes the top integration-layer bugs that prevent claude-flow and ruvector from working together on Linux/Ubuntu.
6
+
7
+ ## Features
8
+
9
+ - **Environment validation** — Checks Node.js, pnpm, Rust, @claude-flow/cli, MCP handshake, @ruvector packages, database drivers
10
+ - **Auto-fix mode** — Installs missing packages, creates directories, generates config
11
+ - **Learning persistence** — Q-learning tables, SONA patterns, and episode history survive restarts
12
+ - **MCP server** — Use as a Claude Code MCP server for integrated tooling
13
+ - **Git patches** — Ready-to-apply fixes for broken @ruvector imports in claude-flow
14
+
15
+ ## Quick Start
16
+
17
+ ### CLI
18
+
19
+ ```bash
20
+ # Install globally
21
+ npm install -g cf-doctor
22
+
23
+ # Run diagnostic
24
+ cf-doctor
25
+
26
+ # Auto-fix issues
27
+ cf-doctor --fix
28
+
29
+ # JSON output (for CI)
30
+ cf-doctor --json
31
+ ```
32
+
33
+ ### As MCP Server (Claude Code)
34
+
35
+ Add to your `claude_desktop_config.json`:
36
+
37
+ ```json
38
+ {
39
+ "mcpServers": {
40
+ "cf-doctor": {
41
+ "command": "node",
42
+ "args": ["node_modules/cf-doctor/dist/mcp-server.js"]
43
+ }
44
+ }
45
+ }
46
+ ```
47
+
48
+ This exposes 5 tools to Claude:
49
+ - `cf_doctor_check` — Run environment validation
50
+ - `cf_doctor_fix` — Auto-fix environment issues
51
+ - `cf_recall_episodes` — Search past agent episodes by similarity
52
+ - `cf_store_episode` — Store agent episode for future recall
53
+ - `cf_q_update` — Update Q-learning state
54
+
55
+ ### As Library
56
+
57
+ ```typescript
58
+ import { runDoctor, recallRelevantEpisodes, PersistentSonaEngine } from 'cf-doctor';
59
+
60
+ // Run diagnostic programmatically
61
+ const result = runDoctor();
62
+ console.log(result.counts); // { green: 7, yellow: 1, red: 1 }
63
+
64
+ // Recall relevant past episodes
65
+ const episodes = recallRelevantEpisodes('fix authentication bug', 3);
66
+
67
+ // Persistent SONA engine
68
+ const sona = new PersistentSonaEngine();
69
+ await sona.store('auth-pattern', { type: 'jwt', refresh: true });
70
+ ```
71
+
72
+ ### One-liner Install
73
+
74
+ ```bash
75
+ curl -fsSL https://raw.githubusercontent.com/foxflow/cf-doctor/main/install.sh | bash
76
+ ```
77
+
78
+ ## What It Fixes
79
+
80
+ | Bug | Impact | Fix |
81
+ |-----|--------|-----|
82
+ | `@ruvector/sona` static import crashes | Neural module unusable without WASM | Dynamic import + mock fallback |
83
+ | `@ruvector/attention` static import | Performance tests crash | Dynamic import + mock |
84
+ | claude-flow v2/v3 version mismatch | ruvector hooks fail silently | Auto-detect version, adjust CLI args |
85
+ | Q-learning state lost on restart | Agents don't learn from experience | File-based persistence with atomic writes |
86
+ | SONA patterns lost on restart | Pattern recognition resets every session | JSON persistence with debounced saves |
87
+ | No episode recall | New agents start from scratch | TF-IDF similarity search over past episodes |
88
+
89
+ ## Applying Git Patches
90
+
91
+ To fix the source imports directly in your clone:
92
+
93
+ ```bash
94
+ # claude-flow patches
95
+ cd claude-flow
96
+ git apply node_modules/cf-doctor/patches/sona-integration.patch
97
+ git apply node_modules/cf-doctor/patches/neural-index.patch
98
+ git apply node_modules/cf-doctor/patches/quick-test.patch
99
+
100
+ # ruvector patch
101
+ cd ruvector
102
+ git apply node_modules/cf-doctor/patches/version-bridge.patch
103
+ ```
104
+
105
+ Or programmatically:
106
+
107
+ ```typescript
108
+ import { applyPatches } from 'cf-doctor/patches';
109
+ const results = applyPatches('/path/to/claude-flow', 'claude-flow');
110
+ ```
111
+
112
+ ## Traffic Light Output
113
+
114
+ ```
115
+ cf-doctor — claude-flow + ruvector installation validator
116
+
117
+ ── Prerequisites ──
118
+ ✅ Node.js 22.11.0
119
+ ✅ pnpm 9.15.0
120
+ ⚠️ Rust not installed (optional)
121
+
122
+ ── Installation Validation ──
123
+ ✅ @claude-flow/cli v3.1.0
124
+ ✅ MCP handshake OK
125
+
126
+ ── @ruvector Packages ──
127
+ ⚠️ 0/8 installed (all using mock fallback)
128
+
129
+ ── Environment ──
130
+ ✅ Directories OK
131
+ ✅ Database: sql.js (WASM)
132
+ ✅ Config generated
133
+
134
+ ╔═══════════════════════════════════╗
135
+ ║ Result: READY (2 warnings) ║
136
+ ╚═══════════════════════════════════╝
137
+ ```
138
+
139
+ ## Claude Code Skills
140
+
141
+ Drop the skills into your project:
142
+
143
+ ```bash
144
+ cp -r node_modules/cf-doctor/skills/ .claude/skills/
145
+ ```
146
+
147
+ Then use `/cf-doctor`, `/cf-patch`, or `/cf-learn` in Claude Code.
148
+
149
+ ## Development
150
+
151
+ ```bash
152
+ git clone https://github.com/foxflow/cf-doctor
153
+ cd cf-doctor
154
+ npm install
155
+ npm run build
156
+ npm test
157
+ ```
158
+
159
+ ## License
160
+
161
+ MIT
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { fileURLToPath } from 'url';
4
+ import { dirname, join } from 'path';
5
+ import { execFileSync } from 'child_process';
6
+
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = dirname(__filename);
9
+ const scriptPath = join(__dirname, '..', 'scripts', 'cf-doctor.sh');
10
+
11
+ try {
12
+ execFileSync('bash', [scriptPath, ...process.argv.slice(2)], {
13
+ stdio: 'inherit',
14
+ env: { ...process.env },
15
+ });
16
+ } catch (err) {
17
+ process.exit(err.status || 1);
18
+ }
@@ -0,0 +1,21 @@
1
+ export interface CheckResult {
2
+ status: 'green' | 'yellow' | 'red';
3
+ detail: string;
4
+ }
5
+ export interface DoctorResult {
6
+ result: 'READY' | 'READY_WITH_WARNINGS' | 'NOT_READY';
7
+ counts: {
8
+ green: number;
9
+ yellow: number;
10
+ red: number;
11
+ };
12
+ checks: Record<string, CheckResult>;
13
+ summary: Array<{
14
+ status: string;
15
+ label: string;
16
+ }>;
17
+ }
18
+ export declare function runDoctor(options?: {
19
+ fix?: boolean;
20
+ }): DoctorResult;
21
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,OAAO,GAAG,qBAAqB,GAAG,WAAW,CAAC;IACtD,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACvD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACpC,OAAO,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnD;AAED,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,YAAY,CAwBnE"}
package/dist/doctor.js ADDED
@@ -0,0 +1,33 @@
1
+ import { execFileSync } from 'child_process';
2
+ import { fileURLToPath } from 'url';
3
+ import { dirname, join } from 'path';
4
+ const __filename = fileURLToPath(import.meta.url);
5
+ const __dirname = dirname(__filename);
6
+ export function runDoctor(options) {
7
+ const scriptPath = join(__dirname, '..', 'scripts', 'cf-doctor.sh');
8
+ const args = ['--json'];
9
+ if (options?.fix)
10
+ args.push('--fix');
11
+ try {
12
+ const output = execFileSync('bash', [scriptPath, ...args], {
13
+ encoding: 'utf-8',
14
+ timeout: 30000,
15
+ env: { ...process.env },
16
+ });
17
+ return JSON.parse(output);
18
+ }
19
+ catch (err) {
20
+ // cf-doctor exits 1 on RED checks but still produces valid JSON
21
+ const execErr = err;
22
+ if (execErr.stdout) {
23
+ try {
24
+ return JSON.parse(execErr.stdout);
25
+ }
26
+ catch {
27
+ // Fall through
28
+ }
29
+ }
30
+ throw new Error(`cf-doctor failed: ${execErr.message ?? 'unknown error'}`);
31
+ }
32
+ }
33
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAErC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AActC,MAAM,UAAU,SAAS,CAAC,OAA2B;IACnD,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IACxB,IAAI,OAAO,EAAE,GAAG;QAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAErC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,EAAE;YACzD,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,KAAK;YACd,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE;SACxB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAiB,CAAC;IAC5C,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,gEAAgE;QAChE,MAAM,OAAO,GAAG,GAA4C,CAAC;QAC7D,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAiB,CAAC;YACpD,CAAC;YAAC,MAAM,CAAC;gBACP,eAAe;YACjB,CAAC;QACH,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,qBAAqB,OAAO,CAAC,OAAO,IAAI,eAAe,EAAE,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * cf-doctor — Setup validator and learning persistence for claude-flow + ruvector
3
+ */
4
+ export { runDoctor, type DoctorResult, type CheckResult } from './doctor.js';
5
+ export { startMCPServer } from './mcp-server.js';
6
+ export { loadQTable, saveQTable, updateQValue, getBestAction, epsilonGreedyAction, } from './persistence/q-table.js';
7
+ export { PersistentSonaEngine, loadSonaPatterns, saveSonaPatterns, registerSonaExitHandler, } from './persistence/sona.js';
8
+ export { saveEpisode, loadEpisodes, recallRelevantEpisodes, formatEpisodesAsContext, } from './persistence/episodes.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EACL,UAAU,EACV,UAAU,EACV,YAAY,EACZ,aAAa,EACb,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,WAAW,EACX,YAAY,EACZ,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,2BAA2B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * cf-doctor — Setup validator and learning persistence for claude-flow + ruvector
3
+ */
4
+ export { runDoctor } from './doctor.js';
5
+ export { startMCPServer } from './mcp-server.js';
6
+ export { loadQTable, saveQTable, updateQValue, getBestAction, epsilonGreedyAction, } from './persistence/q-table.js';
7
+ export { PersistentSonaEngine, loadSonaPatterns, saveSonaPatterns, registerSonaExitHandler, } from './persistence/sona.js';
8
+ export { saveEpisode, loadEpisodes, recallRelevantEpisodes, formatEpisodesAsContext, } from './persistence/episodes.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAuC,MAAM,aAAa,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EACL,UAAU,EACV,UAAU,EACV,YAAY,EACZ,aAAa,EACb,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,WAAW,EACX,YAAY,EACZ,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,2BAA2B,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * MCP Server for cf-doctor
3
+ *
4
+ * Exposes tools:
5
+ * - cf_doctor_check: Run environment validation
6
+ * - cf_doctor_fix: Auto-fix environment issues
7
+ * - cf_recall_episodes: Search past agent episodes
8
+ * - cf_store_episode: Store a new agent episode
9
+ * - cf_q_update: Update Q-learning state
10
+ */
11
+ export declare function startMCPServer(): void;
12
+ //# sourceMappingURL=mcp-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAwMH,wBAAgB,cAAc,IAAI,IAAI,CAsBrC"}
@@ -0,0 +1,200 @@
1
+ /**
2
+ * MCP Server for cf-doctor
3
+ *
4
+ * Exposes tools:
5
+ * - cf_doctor_check: Run environment validation
6
+ * - cf_doctor_fix: Auto-fix environment issues
7
+ * - cf_recall_episodes: Search past agent episodes
8
+ * - cf_store_episode: Store a new agent episode
9
+ * - cf_q_update: Update Q-learning state
10
+ */
11
+ import { fileURLToPath } from 'url';
12
+ import { createInterface } from 'readline';
13
+ import { runDoctor } from './doctor.js';
14
+ import { recallRelevantEpisodes, saveEpisode, formatEpisodesAsContext } from './persistence/episodes.js';
15
+ import { loadQTable, saveQTable, updateQValue } from './persistence/q-table.js';
16
+ const TOOLS = [
17
+ {
18
+ name: 'cf_doctor_check',
19
+ description: 'Run cf-doctor environment validation. Returns GREEN/YELLOW/RED status for each check.',
20
+ inputSchema: {
21
+ type: 'object',
22
+ properties: {},
23
+ },
24
+ },
25
+ {
26
+ name: 'cf_doctor_fix',
27
+ description: 'Run cf-doctor with --fix flag to auto-repair environment issues.',
28
+ inputSchema: {
29
+ type: 'object',
30
+ properties: {},
31
+ },
32
+ },
33
+ {
34
+ name: 'cf_recall_episodes',
35
+ description: 'Search past agent episodes by text similarity. Returns relevant episodes for context.',
36
+ inputSchema: {
37
+ type: 'object',
38
+ properties: {
39
+ context: { type: 'string', description: 'Text describing what the agent needs to do' },
40
+ topK: { type: 'number', description: 'Number of episodes to return (default: 5)' },
41
+ },
42
+ required: ['context'],
43
+ },
44
+ },
45
+ {
46
+ name: 'cf_store_episode',
47
+ description: 'Store a new agent episode for future recall.',
48
+ inputSchema: {
49
+ type: 'object',
50
+ properties: {
51
+ agentId: { type: 'string', description: 'Agent identifier' },
52
+ input: { type: 'string', description: 'Task description' },
53
+ outcome: { type: 'string', description: 'What happened' },
54
+ reward: { type: 'number', description: 'Success score (-1 to 1)' },
55
+ taskId: { type: 'string', description: 'Optional task ID' },
56
+ },
57
+ required: ['agentId', 'input', 'outcome', 'reward'],
58
+ },
59
+ },
60
+ {
61
+ name: 'cf_q_update',
62
+ description: 'Update Q-learning table with a state-action-reward observation.',
63
+ inputSchema: {
64
+ type: 'object',
65
+ properties: {
66
+ state: { type: 'string', description: 'Current state identifier' },
67
+ action: { type: 'string', description: 'Action taken' },
68
+ reward: { type: 'number', description: 'Reward received' },
69
+ },
70
+ required: ['state', 'action', 'reward'],
71
+ },
72
+ },
73
+ ];
74
+ function handleRequest(req) {
75
+ const id = req.id ?? 0;
76
+ const { method, params } = req;
77
+ switch (method) {
78
+ case 'initialize':
79
+ return {
80
+ jsonrpc: '2.0',
81
+ id,
82
+ result: {
83
+ protocolVersion: '2024-11-05',
84
+ capabilities: { tools: {} },
85
+ serverInfo: { name: 'cf-doctor', version: '1.0.0' },
86
+ },
87
+ };
88
+ case 'tools/list':
89
+ return { jsonrpc: '2.0', id, result: { tools: TOOLS } };
90
+ case 'tools/call': {
91
+ const toolName = (params?.name ?? '');
92
+ const toolArgs = (params?.arguments ?? {});
93
+ switch (toolName) {
94
+ case 'cf_doctor_check': {
95
+ const result = runDoctor();
96
+ return {
97
+ jsonrpc: '2.0',
98
+ id,
99
+ result: {
100
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
101
+ },
102
+ };
103
+ }
104
+ case 'cf_doctor_fix': {
105
+ const result = runDoctor({ fix: true });
106
+ return {
107
+ jsonrpc: '2.0',
108
+ id,
109
+ result: {
110
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
111
+ },
112
+ };
113
+ }
114
+ case 'cf_recall_episodes': {
115
+ const episodes = recallRelevantEpisodes(toolArgs.context, toolArgs.topK || 5);
116
+ const formatted = formatEpisodesAsContext(episodes);
117
+ return {
118
+ jsonrpc: '2.0',
119
+ id,
120
+ result: {
121
+ content: [{ type: 'text', text: formatted || 'No relevant episodes found.' }],
122
+ },
123
+ };
124
+ }
125
+ case 'cf_store_episode': {
126
+ saveEpisode({
127
+ id: `ep-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
128
+ agentId: toolArgs.agentId,
129
+ taskId: toolArgs.taskId,
130
+ input: toolArgs.input,
131
+ outcome: toolArgs.outcome,
132
+ reward: toolArgs.reward,
133
+ timestamp: Date.now(),
134
+ });
135
+ return {
136
+ jsonrpc: '2.0',
137
+ id,
138
+ result: {
139
+ content: [{ type: 'text', text: 'Episode stored successfully.' }],
140
+ },
141
+ };
142
+ }
143
+ case 'cf_q_update': {
144
+ const table = loadQTable();
145
+ const entry = updateQValue(table, toolArgs.state, toolArgs.action, toolArgs.reward);
146
+ saveQTable(table, table.size);
147
+ return {
148
+ jsonrpc: '2.0',
149
+ id,
150
+ result: {
151
+ content: [{ type: 'text', text: `Q-value updated: ${entry.action} = ${entry.value.toFixed(4)} (visits: ${entry.visits})` }],
152
+ },
153
+ };
154
+ }
155
+ default:
156
+ return {
157
+ jsonrpc: '2.0',
158
+ id,
159
+ error: { code: -32601, message: `Unknown tool: ${toolName}` },
160
+ };
161
+ }
162
+ }
163
+ case 'notifications/initialized':
164
+ return { jsonrpc: '2.0', id, result: {} };
165
+ default:
166
+ return {
167
+ jsonrpc: '2.0',
168
+ id,
169
+ error: { code: -32601, message: `Method not found: ${method}` },
170
+ };
171
+ }
172
+ }
173
+ export function startMCPServer() {
174
+ const rl = createInterface({ input: process.stdin });
175
+ rl.on('line', (line) => {
176
+ try {
177
+ const req = JSON.parse(line);
178
+ const response = handleRequest(req);
179
+ // Don't respond to notifications (no id)
180
+ if (req.id !== undefined) {
181
+ process.stdout.write(JSON.stringify(response) + '\n');
182
+ }
183
+ }
184
+ catch {
185
+ const errorResp = {
186
+ jsonrpc: '2.0',
187
+ id: 0,
188
+ error: { code: -32700, message: 'Parse error' },
189
+ };
190
+ process.stdout.write(JSON.stringify(errorResp) + '\n');
191
+ }
192
+ });
193
+ rl.on('close', () => process.exit(0));
194
+ }
195
+ // If run directly, start MCP server
196
+ const currentFile = fileURLToPath(import.meta.url);
197
+ if (process.argv[1] && currentFile.endsWith(process.argv[1].replace(/\\/g, '/'))) {
198
+ startMCPServer();
199
+ }
200
+ //# sourceMappingURL=mcp-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface PatchResult {
2
+ name: string;
3
+ applied: boolean;
4
+ error?: string;
5
+ }
6
+ export declare function applyPatches(repoPath: string, target?: 'claude-flow' | 'ruvector' | 'all'): PatchResult[];
7
+ //# sourceMappingURL=apply.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/patches/apply.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAYD,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,aAAa,GAAG,UAAU,GAAG,KAAa,GACjD,WAAW,EAAE,CAoCf"}
@@ -0,0 +1,51 @@
1
+ import { execFileSync } from 'child_process';
2
+ import { existsSync } from 'fs';
3
+ import { fileURLToPath } from 'url';
4
+ import { dirname, join } from 'path';
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = dirname(__filename);
7
+ const PATCHES_DIR = join(__dirname, '..', '..', 'patches');
8
+ const CLAUDE_FLOW_PATCHES = [
9
+ 'sona-integration.patch',
10
+ 'neural-index.patch',
11
+ 'quick-test.patch',
12
+ ];
13
+ const RUVECTOR_PATCHES = [
14
+ 'version-bridge.patch',
15
+ ];
16
+ export function applyPatches(repoPath, target = 'all') {
17
+ const results = [];
18
+ const patches = target === 'claude-flow' ? CLAUDE_FLOW_PATCHES
19
+ : target === 'ruvector' ? RUVECTOR_PATCHES
20
+ : [...CLAUDE_FLOW_PATCHES, ...RUVECTOR_PATCHES];
21
+ for (const patchFile of patches) {
22
+ const patchPath = join(PATCHES_DIR, patchFile);
23
+ if (!existsSync(patchPath)) {
24
+ results.push({ name: patchFile, applied: false, error: 'Patch file not found' });
25
+ continue;
26
+ }
27
+ try {
28
+ // Dry run first
29
+ execFileSync('git', ['apply', '--check', patchPath], {
30
+ cwd: repoPath,
31
+ encoding: 'utf-8',
32
+ });
33
+ // Apply for real
34
+ execFileSync('git', ['apply', patchPath], {
35
+ cwd: repoPath,
36
+ encoding: 'utf-8',
37
+ });
38
+ results.push({ name: patchFile, applied: true });
39
+ }
40
+ catch (err) {
41
+ const execErr = err;
42
+ results.push({
43
+ name: patchFile,
44
+ applied: false,
45
+ error: execErr.stderr || execErr.message || 'Unknown error',
46
+ });
47
+ }
48
+ }
49
+ return results;
50
+ }
51
+ //# sourceMappingURL=apply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/patches/apply.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAErC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;AAQ3D,MAAM,mBAAmB,GAAG;IAC1B,wBAAwB;IACxB,oBAAoB;IACpB,kBAAkB;CACnB,CAAC;AAEF,MAAM,gBAAgB,GAAG;IACvB,sBAAsB;CACvB,CAAC;AAEF,MAAM,UAAU,YAAY,CAC1B,QAAgB,EAChB,SAA6C,KAAK;IAElD,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,MAAM,OAAO,GAAG,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,mBAAmB;QAC5D,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,gBAAgB;YAC1C,CAAC,CAAC,CAAC,GAAG,mBAAmB,EAAE,GAAG,gBAAgB,CAAC,CAAC;IAElD,KAAK,MAAM,SAAS,IAAI,OAAO,EAAE,CAAC;QAChC,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QAC/C,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC,CAAC;YACjF,SAAS;QACX,CAAC;QAED,IAAI,CAAC;YACH,gBAAgB;YAChB,YAAY,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE;gBACnD,GAAG,EAAE,QAAQ;gBACb,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;YACH,iBAAiB;YACjB,YAAY,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE;gBACxC,GAAG,EAAE,QAAQ;gBACb,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,OAAO,GAAG,GAA4C,CAAC;YAC7D,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,OAAO,IAAI,eAAe;aAC5D,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Episode Recall with TF-IDF Similarity
3
+ *
4
+ * Searches past agent episodes by text similarity to provide
5
+ * relevant context to newly spawned agents.
6
+ */
7
+ export interface Episode {
8
+ id: string;
9
+ agentId: string;
10
+ taskId?: string;
11
+ input: string;
12
+ outcome: string;
13
+ reward: number;
14
+ timestamp: number;
15
+ metadata?: Record<string, unknown>;
16
+ }
17
+ export interface EpisodeStore {
18
+ version: 1;
19
+ episodes: Episode[];
20
+ idf: Record<string, number>;
21
+ lastRecomputed: number;
22
+ }
23
+ export declare function loadEpisodes(): Episode[];
24
+ export declare function saveEpisode(episode: Episode): void;
25
+ /**
26
+ * Recall episodes relevant to the given context using TF-IDF similarity.
27
+ *
28
+ * @param context - Text describing what the agent needs to do
29
+ * @param topK - Number of episodes to return (default: 5)
30
+ * @param minSimilarity - Minimum similarity threshold (default: 0.1)
31
+ * @returns Array of relevant episodes sorted by similarity (descending)
32
+ */
33
+ export declare function recallRelevantEpisodes(context: string, topK?: number, minSimilarity?: number): Array<Episode & {
34
+ similarity: number;
35
+ }>;
36
+ /**
37
+ * Format episodes as context string for injection into agent prompts.
38
+ */
39
+ export declare function formatEpisodesAsContext(episodes: Array<Episode & {
40
+ similarity: number;
41
+ }>): string;
42
+ //# sourceMappingURL=episodes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"episodes.d.ts","sourceRoot":"","sources":["../../src/persistence/episodes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,CAAC,CAAC;IACX,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;CACxB;AAoFD,wBAAgB,YAAY,IAAI,OAAO,EAAE,CAcxC;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+BlD;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAU,EAChB,aAAa,GAAE,MAAY,GAC1B,KAAK,CAAC,OAAO,GAAG;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CA+BzC;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,KAAK,CAAC,OAAO,GAAG;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,GAChD,MAAM,CAeR"}