moflo 4.0.2 → 4.0.3

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 (89) hide show
  1. package/package.json +114 -110
  2. package/v3/@claude-flow/cli/dist/src/memory/memory-bridge.js +194 -81
  3. package/v3/@claude-flow/cli/dist/src/memory/memory-initializer.js +1892 -1841
  4. package/v3/@claude-flow/memory/README.md +587 -0
  5. package/v3/@claude-flow/memory/dist/agent-memory-scope.d.ts +131 -0
  6. package/v3/@claude-flow/memory/dist/agent-memory-scope.js +223 -0
  7. package/v3/@claude-flow/memory/dist/agent-memory-scope.test.d.ts +8 -0
  8. package/v3/@claude-flow/memory/dist/agent-memory-scope.test.js +463 -0
  9. package/v3/@claude-flow/memory/dist/agentdb-adapter.d.ts +165 -0
  10. package/v3/@claude-flow/memory/dist/agentdb-adapter.js +806 -0
  11. package/v3/@claude-flow/memory/dist/agentdb-backend.d.ts +214 -0
  12. package/v3/@claude-flow/memory/dist/agentdb-backend.js +844 -0
  13. package/v3/@claude-flow/memory/dist/agentdb-backend.test.d.ts +7 -0
  14. package/v3/@claude-flow/memory/dist/agentdb-backend.test.js +258 -0
  15. package/v3/@claude-flow/memory/dist/application/commands/delete-memory.command.d.ts +65 -0
  16. package/v3/@claude-flow/memory/dist/application/commands/delete-memory.command.js +129 -0
  17. package/v3/@claude-flow/memory/dist/application/commands/store-memory.command.d.ts +48 -0
  18. package/v3/@claude-flow/memory/dist/application/commands/store-memory.command.js +72 -0
  19. package/v3/@claude-flow/memory/dist/application/index.d.ts +12 -0
  20. package/v3/@claude-flow/memory/dist/application/index.js +15 -0
  21. package/v3/@claude-flow/memory/dist/application/queries/search-memory.query.d.ts +72 -0
  22. package/v3/@claude-flow/memory/dist/application/queries/search-memory.query.js +143 -0
  23. package/v3/@claude-flow/memory/dist/application/services/memory-application-service.d.ts +121 -0
  24. package/v3/@claude-flow/memory/dist/application/services/memory-application-service.js +190 -0
  25. package/v3/@claude-flow/memory/dist/auto-memory-bridge.d.ts +226 -0
  26. package/v3/@claude-flow/memory/dist/auto-memory-bridge.js +709 -0
  27. package/v3/@claude-flow/memory/dist/auto-memory-bridge.test.d.ts +8 -0
  28. package/v3/@claude-flow/memory/dist/auto-memory-bridge.test.js +754 -0
  29. package/v3/@claude-flow/memory/dist/benchmark.test.d.ts +2 -0
  30. package/v3/@claude-flow/memory/dist/benchmark.test.js +277 -0
  31. package/v3/@claude-flow/memory/dist/cache-manager.d.ts +134 -0
  32. package/v3/@claude-flow/memory/dist/cache-manager.js +407 -0
  33. package/v3/@claude-flow/memory/dist/controller-registry.d.ts +216 -0
  34. package/v3/@claude-flow/memory/dist/controller-registry.js +893 -0
  35. package/v3/@claude-flow/memory/dist/controller-registry.test.d.ts +14 -0
  36. package/v3/@claude-flow/memory/dist/controller-registry.test.js +636 -0
  37. package/v3/@claude-flow/memory/dist/database-provider.d.ts +87 -0
  38. package/v3/@claude-flow/memory/dist/database-provider.js +410 -0
  39. package/v3/@claude-flow/memory/dist/database-provider.test.d.ts +7 -0
  40. package/v3/@claude-flow/memory/dist/database-provider.test.js +285 -0
  41. package/v3/@claude-flow/memory/dist/domain/entities/memory-entry.d.ts +143 -0
  42. package/v3/@claude-flow/memory/dist/domain/entities/memory-entry.js +226 -0
  43. package/v3/@claude-flow/memory/dist/domain/index.d.ts +11 -0
  44. package/v3/@claude-flow/memory/dist/domain/index.js +12 -0
  45. package/v3/@claude-flow/memory/dist/domain/repositories/memory-repository.interface.d.ts +102 -0
  46. package/v3/@claude-flow/memory/dist/domain/repositories/memory-repository.interface.js +11 -0
  47. package/v3/@claude-flow/memory/dist/domain/services/memory-domain-service.d.ts +105 -0
  48. package/v3/@claude-flow/memory/dist/domain/services/memory-domain-service.js +297 -0
  49. package/v3/@claude-flow/memory/dist/hnsw-index.d.ts +111 -0
  50. package/v3/@claude-flow/memory/dist/hnsw-index.js +781 -0
  51. package/v3/@claude-flow/memory/dist/hnsw-lite.d.ts +23 -0
  52. package/v3/@claude-flow/memory/dist/hnsw-lite.js +168 -0
  53. package/v3/@claude-flow/memory/dist/hybrid-backend.d.ts +245 -0
  54. package/v3/@claude-flow/memory/dist/hybrid-backend.js +569 -0
  55. package/v3/@claude-flow/memory/dist/hybrid-backend.test.d.ts +8 -0
  56. package/v3/@claude-flow/memory/dist/hybrid-backend.test.js +320 -0
  57. package/v3/@claude-flow/memory/dist/index.d.ts +208 -0
  58. package/v3/@claude-flow/memory/dist/index.js +362 -0
  59. package/v3/@claude-flow/memory/dist/infrastructure/index.d.ts +17 -0
  60. package/v3/@claude-flow/memory/dist/infrastructure/index.js +16 -0
  61. package/v3/@claude-flow/memory/dist/infrastructure/repositories/hybrid-memory-repository.d.ts +66 -0
  62. package/v3/@claude-flow/memory/dist/infrastructure/repositories/hybrid-memory-repository.js +409 -0
  63. package/v3/@claude-flow/memory/dist/learning-bridge.d.ts +137 -0
  64. package/v3/@claude-flow/memory/dist/learning-bridge.js +335 -0
  65. package/v3/@claude-flow/memory/dist/learning-bridge.test.d.ts +8 -0
  66. package/v3/@claude-flow/memory/dist/learning-bridge.test.js +578 -0
  67. package/v3/@claude-flow/memory/dist/memory-graph.d.ts +100 -0
  68. package/v3/@claude-flow/memory/dist/memory-graph.js +333 -0
  69. package/v3/@claude-flow/memory/dist/memory-graph.test.d.ts +8 -0
  70. package/v3/@claude-flow/memory/dist/memory-graph.test.js +609 -0
  71. package/v3/@claude-flow/memory/dist/migration.d.ts +68 -0
  72. package/v3/@claude-flow/memory/dist/migration.js +513 -0
  73. package/v3/@claude-flow/memory/dist/persistent-sona.d.ts +144 -0
  74. package/v3/@claude-flow/memory/dist/persistent-sona.js +332 -0
  75. package/v3/@claude-flow/memory/dist/query-builder.d.ts +211 -0
  76. package/v3/@claude-flow/memory/dist/query-builder.js +438 -0
  77. package/v3/@claude-flow/memory/dist/rvf-backend.d.ts +51 -0
  78. package/v3/@claude-flow/memory/dist/rvf-backend.js +481 -0
  79. package/v3/@claude-flow/memory/dist/rvf-learning-store.d.ts +139 -0
  80. package/v3/@claude-flow/memory/dist/rvf-learning-store.js +295 -0
  81. package/v3/@claude-flow/memory/dist/rvf-migration.d.ts +45 -0
  82. package/v3/@claude-flow/memory/dist/rvf-migration.js +254 -0
  83. package/v3/@claude-flow/memory/dist/sqlite-backend.d.ts +121 -0
  84. package/v3/@claude-flow/memory/dist/sqlite-backend.js +564 -0
  85. package/v3/@claude-flow/memory/dist/sqljs-backend.d.ts +128 -0
  86. package/v3/@claude-flow/memory/dist/sqljs-backend.js +601 -0
  87. package/v3/@claude-flow/memory/dist/types.d.ts +484 -0
  88. package/v3/@claude-flow/memory/dist/types.js +58 -0
  89. package/v3/@claude-flow/memory/package.json +46 -0
package/package.json CHANGED
@@ -1,110 +1,114 @@
1
- {
2
- "name": "moflo",
3
- "version": "4.0.2",
4
- "description": "MoFlo — AI agent orchestration for Claude Code. Forked from ruflo/claude-flow with patches applied to source, plus feature-level orchestration.",
5
- "main": "dist/index.js",
6
- "type": "module",
7
- "bin": {
8
- "moflo": "./bin/cli.js",
9
- "moflo-setup": "./bin/setup-project.mjs",
10
- "claude-flow": "./bin/cli.js"
11
- },
12
- "homepage": "https://github.com/eric-cielo/moflo#readme",
13
- "bugs": {
14
- "url": "https://github.com/eric-cielo/moflo/issues"
15
- },
16
- "files": [
17
- "bin/**",
18
- "v3/@claude-flow/cli/bin/**",
19
- "v3/@claude-flow/cli/dist/**/*.js",
20
- "v3/@claude-flow/cli/dist/**/*.d.ts",
21
- "!v3/@claude-flow/cli/dist/**/*.map",
22
- "v3/@claude-flow/cli/package.json",
23
- "v3/@claude-flow/shared/dist/**/*.js",
24
- "v3/@claude-flow/shared/dist/**/*.d.ts",
25
- "!v3/@claude-flow/shared/dist/**/*.map",
26
- "v3/@claude-flow/shared/package.json",
27
- "v3/@claude-flow/guidance/dist/**/*.js",
28
- "v3/@claude-flow/guidance/dist/**/*.d.ts",
29
- "!v3/@claude-flow/guidance/dist/**/*.map",
30
- "v3/@claude-flow/guidance/package.json",
31
- ".claude-plugin/**",
32
- ".claude/**",
33
- "!.claude/**/*.db",
34
- "!.claude/**/*.map",
35
- "README.md",
36
- "LICENSE"
37
- ],
38
- "scripts": {
39
- "dev": "tsx watch src/index.ts",
40
- "build": "tsc",
41
- "build:ts": "cd v3/@claude-flow/cli && npm run build || true",
42
- "test": "vitest",
43
- "test:ui": "vitest --ui",
44
- "test:security": "vitest run v3/__tests__/security/",
45
- "lint": "cd v3/@claude-flow/cli && npm run lint || true",
46
- "security:audit": "npm audit --audit-level high",
47
- "security:fix": "npm audit fix",
48
- "security:test": "npm run test:security",
49
- "v3:domains": "npm run build:domains",
50
- "v3:swarm": "npm run start:swarm",
51
- "v3:security": "npm run security:audit && npm run security:test"
52
- },
53
- "dependencies": {
54
- "semver": "^7.6.0",
55
- "zod": "^3.22.4"
56
- },
57
- "optionalDependencies": {
58
- "@claude-flow/codex": "^3.0.0-alpha.8",
59
- "@claude-flow/plugin-gastown-bridge": "^0.1.3",
60
- "@ruvector/attention": "^0.1.3",
61
- "@ruvector/core": "^0.1.30",
62
- "@ruvector/router": "^0.1.27",
63
- "@ruvector/router-linux-x64-gnu": "^0.1.27",
64
- "@ruvector/sona": "^0.1.5",
65
- "agentdb": "^3.0.0-alpha.9",
66
- "agentic-flow": "^2.0.7"
67
- },
68
- "overrides": {
69
- "hono": ">=4.11.4"
70
- },
71
- "devDependencies": {
72
- "@openai/codex": "^0.98.0",
73
- "@types/bcrypt": "^5.0.2",
74
- "@types/node": "^20.0.0",
75
- "eslint": "^8.0.0",
76
- "tsx": "^4.21.0",
77
- "typescript": "^5.0.0",
78
- "vitest": "^1.0.0"
79
- },
80
- "engines": {
81
- "node": ">=20.0.0"
82
- },
83
- "repository": {
84
- "type": "git",
85
- "url": "https://github.com/eric-cielo/moflo.git"
86
- },
87
- "keywords": [
88
- "moflo",
89
- "claude",
90
- "claude-code",
91
- "anthropic",
92
- "ai-agents",
93
- "agent-orchestration",
94
- "mcp",
95
- "model-context-protocol",
96
- "cli",
97
- "developer-tools",
98
- "workflow",
99
- "orchestration"
100
- ],
101
- "author": {
102
- "name": "Eric Cielo",
103
- "url": "https://github.com/eric-cielo"
104
- },
105
- "license": "MIT",
106
- "publishConfig": {
107
- "access": "public",
108
- "tag": "latest"
109
- }
110
- }
1
+ {
2
+ "name": "moflo",
3
+ "version": "4.0.3",
4
+ "description": "MoFlo — AI agent orchestration for Claude Code. Forked from ruflo/claude-flow with patches applied to source, plus feature-level orchestration.",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "moflo": "bin/cli.js",
9
+ "moflo-setup": "bin/setup-project.mjs",
10
+ "claude-flow": "bin/cli.js"
11
+ },
12
+ "homepage": "https://github.com/eric-cielo/moflo#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/eric-cielo/moflo/issues"
15
+ },
16
+ "files": [
17
+ "bin/**",
18
+ "v3/@claude-flow/cli/bin/**",
19
+ "v3/@claude-flow/cli/dist/**/*.js",
20
+ "v3/@claude-flow/cli/dist/**/*.d.ts",
21
+ "!v3/@claude-flow/cli/dist/**/*.map",
22
+ "v3/@claude-flow/cli/package.json",
23
+ "v3/@claude-flow/shared/dist/**/*.js",
24
+ "v3/@claude-flow/shared/dist/**/*.d.ts",
25
+ "!v3/@claude-flow/shared/dist/**/*.map",
26
+ "v3/@claude-flow/shared/package.json",
27
+ "v3/@claude-flow/guidance/dist/**/*.js",
28
+ "v3/@claude-flow/guidance/dist/**/*.d.ts",
29
+ "!v3/@claude-flow/guidance/dist/**/*.map",
30
+ "v3/@claude-flow/guidance/package.json",
31
+ "v3/@claude-flow/memory/dist/**/*.js",
32
+ "v3/@claude-flow/memory/dist/**/*.d.ts",
33
+ "!v3/@claude-flow/memory/dist/**/*.map",
34
+ "v3/@claude-flow/memory/package.json",
35
+ ".claude-plugin/**",
36
+ ".claude/**",
37
+ "!.claude/**/*.db",
38
+ "!.claude/**/*.map",
39
+ "README.md",
40
+ "LICENSE"
41
+ ],
42
+ "scripts": {
43
+ "dev": "tsx watch src/index.ts",
44
+ "build": "tsc",
45
+ "build:ts": "cd v3/@claude-flow/cli && npm run build || true",
46
+ "test": "vitest",
47
+ "test:ui": "vitest --ui",
48
+ "test:security": "vitest run v3/__tests__/security/",
49
+ "lint": "cd v3/@claude-flow/cli && npm run lint || true",
50
+ "security:audit": "npm audit --audit-level high",
51
+ "security:fix": "npm audit fix",
52
+ "security:test": "npm run test:security",
53
+ "v3:domains": "npm run build:domains",
54
+ "v3:swarm": "npm run start:swarm",
55
+ "v3:security": "npm run security:audit && npm run security:test"
56
+ },
57
+ "dependencies": {
58
+ "semver": "^7.6.0",
59
+ "zod": "^3.22.4"
60
+ },
61
+ "optionalDependencies": {
62
+ "@claude-flow/codex": "^3.0.0-alpha.8",
63
+ "@claude-flow/plugin-gastown-bridge": "^0.1.3",
64
+ "@ruvector/attention": "^0.1.3",
65
+ "@ruvector/core": "^0.1.30",
66
+ "@ruvector/router": "^0.1.27",
67
+ "@ruvector/router-linux-x64-gnu": "^0.1.27",
68
+ "@ruvector/sona": "^0.1.5",
69
+ "agentdb": "^3.0.0-alpha.9",
70
+ "agentic-flow": "^2.0.7"
71
+ },
72
+ "overrides": {
73
+ "hono": ">=4.11.4"
74
+ },
75
+ "devDependencies": {
76
+ "@openai/codex": "^0.98.0",
77
+ "@types/bcrypt": "^5.0.2",
78
+ "@types/node": "^20.0.0",
79
+ "eslint": "^8.0.0",
80
+ "tsx": "^4.21.0",
81
+ "typescript": "^5.0.0",
82
+ "vitest": "^1.0.0"
83
+ },
84
+ "engines": {
85
+ "node": ">=20.0.0"
86
+ },
87
+ "repository": {
88
+ "type": "git",
89
+ "url": "git+https://github.com/eric-cielo/moflo.git"
90
+ },
91
+ "keywords": [
92
+ "moflo",
93
+ "claude",
94
+ "claude-code",
95
+ "anthropic",
96
+ "ai-agents",
97
+ "agent-orchestration",
98
+ "mcp",
99
+ "model-context-protocol",
100
+ "cli",
101
+ "developer-tools",
102
+ "workflow",
103
+ "orchestration"
104
+ ],
105
+ "author": {
106
+ "name": "Eric Cielo",
107
+ "url": "https://github.com/eric-cielo"
108
+ },
109
+ "license": "MIT",
110
+ "publishConfig": {
111
+ "access": "public",
112
+ "tag": "latest"
113
+ }
114
+ }
@@ -17,7 +17,35 @@
17
17
  * @module v3/cli/memory-bridge
18
18
  */
19
19
  import * as path from 'path';
20
+ import * as fs from 'fs';
20
21
  import * as crypto from 'crypto';
22
+ import { createRequire } from 'module';
23
+ import { pathToFileURL } from 'url';
24
+ // Project root resolution — handles npx running from node_modules/moflo
25
+ let _projectRoot;
26
+ function getProjectRoot() {
27
+ if (_projectRoot)
28
+ return _projectRoot;
29
+ if (process.env.CLAUDE_PROJECT_DIR) {
30
+ _projectRoot = process.env.CLAUDE_PROJECT_DIR;
31
+ return _projectRoot;
32
+ }
33
+ let dir = process.cwd();
34
+ const root = path.parse(dir).root;
35
+ while (dir !== root) {
36
+ if (fs.existsSync(path.join(dir, '.swarm', 'memory.db'))) {
37
+ _projectRoot = dir;
38
+ return _projectRoot;
39
+ }
40
+ if (fs.existsSync(path.join(dir, 'CLAUDE.md')) && fs.existsSync(path.join(dir, 'package.json'))) {
41
+ _projectRoot = dir;
42
+ return _projectRoot;
43
+ }
44
+ dir = path.dirname(dir);
45
+ }
46
+ _projectRoot = process.cwd();
47
+ return _projectRoot;
48
+ }
21
49
  // ===== Lazy singleton =====
22
50
  let registryPromise = null;
23
51
  let registryInstance = null;
@@ -28,15 +56,15 @@ let bridgeAvailable = null;
28
56
  * or the special ':memory:' path.
29
57
  */
30
58
  function getDbPath(customPath) {
31
- const swarmDir = path.resolve(process.cwd(), '.swarm');
59
+ const projectRoot = getProjectRoot();
60
+ const swarmDir = path.resolve(projectRoot, '.swarm');
32
61
  if (!customPath)
33
62
  return path.join(swarmDir, 'memory.db');
34
63
  if (customPath === ':memory:')
35
64
  return ':memory:';
36
65
  const resolved = path.resolve(customPath);
37
- // Ensure the path doesn't escape the working directory
38
- const cwd = process.cwd();
39
- if (!resolved.startsWith(cwd)) {
66
+ // Ensure the path doesn't escape the project directory
67
+ if (!resolved.startsWith(projectRoot)) {
40
68
  return path.join(swarmDir, 'memory.db'); // fallback to safe default
41
69
  }
42
70
  return resolved;
@@ -48,8 +76,10 @@ function generateId(prefix) {
48
76
  return `${prefix}_${Date.now()}_${crypto.randomBytes(8).toString('hex')}`;
49
77
  }
50
78
  /**
51
- * Lazily initialize the ControllerRegistry singleton.
52
- * Returns null if @claude-flow/memory is not available.
79
+ * Lazily initialize the ControllerRegistry singleton via @claude-flow/memory.
80
+ * Falls back to direct agentdb import if @claude-flow/memory is unavailable.
81
+ * The registry exposes .get(name), .getAgentDB(), .listControllers(), and .initialize()
82
+ * to maintain compatibility with all bridge consumers.
53
83
  */
54
84
  async function getRegistry(dbPath) {
55
85
  if (bridgeAvailable === false)
@@ -59,8 +89,75 @@ async function getRegistry(dbPath) {
59
89
  if (!registryPromise) {
60
90
  registryPromise = (async () => {
61
91
  try {
62
- const { ControllerRegistry } = await import('@claude-flow/memory');
63
- const registry = new ControllerRegistry();
92
+ // Try @claude-flow/memory ControllerRegistry first (bundled in moflo)
93
+ let memoryModule = null;
94
+ const memoryRelPath = '../../../../memory/dist/index.js';
95
+ try {
96
+ memoryModule = await import(memoryRelPath);
97
+ }
98
+ catch {
99
+ try {
100
+ const req = createRequire(path.join(getProjectRoot(), 'package.json'));
101
+ const resolved = req.resolve('@claude-flow/memory');
102
+ memoryModule = await import(pathToFileURL(resolved).href);
103
+ }
104
+ catch {
105
+ // @claude-flow/memory not available
106
+ }
107
+ }
108
+ // If @claude-flow/memory has ControllerRegistry, use it directly
109
+ if (memoryModule?.ControllerRegistry) {
110
+ const { ControllerRegistry } = memoryModule;
111
+ const registry = new ControllerRegistry();
112
+ // Suppress noisy console.log during init
113
+ const origLog = console.log;
114
+ console.log = (...args) => {
115
+ const msg = String(args[0] ?? '');
116
+ if (msg.includes('Transformers.js') ||
117
+ msg.includes('better-sqlite3') ||
118
+ msg.includes('[AgentDB]') ||
119
+ msg.includes('[HNSWLibBackend]') ||
120
+ msg.includes('RuVector graph'))
121
+ return;
122
+ origLog.apply(console, args);
123
+ };
124
+ try {
125
+ await registry.initialize({
126
+ dbPath: dbPath || getDbPath(),
127
+ dimension: 384,
128
+ });
129
+ }
130
+ finally {
131
+ console.log = origLog;
132
+ }
133
+ registryInstance = registry;
134
+ return registry;
135
+ }
136
+ // Fallback: direct agentdb import with manual adapter
137
+ let agentdbModule = null;
138
+ try {
139
+ agentdbModule = await import('agentdb');
140
+ }
141
+ catch {
142
+ try {
143
+ const req = createRequire(path.join(getProjectRoot(), 'package.json'));
144
+ const resolved = req.resolve('agentdb');
145
+ agentdbModule = await import(pathToFileURL(resolved).href);
146
+ }
147
+ catch {
148
+ // Not available
149
+ }
150
+ }
151
+ if (!agentdbModule) {
152
+ bridgeAvailable = false;
153
+ registryPromise = null;
154
+ return null;
155
+ }
156
+ const { AgentDB } = agentdbModule;
157
+ const agentdb = new AgentDB({
158
+ dbPath: dbPath || getDbPath(),
159
+ dimension: 384,
160
+ });
64
161
  // Suppress noisy console.log during init
65
162
  const origLog = console.log;
66
163
  console.log = (...args) => {
@@ -74,22 +171,38 @@ async function getRegistry(dbPath) {
74
171
  origLog.apply(console, args);
75
172
  };
76
173
  try {
77
- await registry.initialize({
78
- dbPath: dbPath || getDbPath(),
79
- dimension: 384,
80
- controllers: {
81
- reasoningBank: true,
82
- learningBridge: false,
83
- tieredCache: true,
84
- hierarchicalMemory: true,
85
- memoryConsolidation: true,
86
- memoryGraph: true, // issue #1214: enable MemoryGraph for graph-aware ranking
87
- },
88
- });
174
+ await agentdb.initialize();
89
175
  }
90
176
  finally {
91
177
  console.log = origLog;
92
178
  }
179
+ // Build a registry-compatible adapter over AgentDB
180
+ const registry = {
181
+ _agentdb: agentdb,
182
+ get(name) {
183
+ try {
184
+ return agentdb.getController(name);
185
+ }
186
+ catch {
187
+ return null;
188
+ }
189
+ },
190
+ getAgentDB() {
191
+ return agentdb;
192
+ },
193
+ listControllers() {
194
+ return [
195
+ 'reflexion', 'skills', 'reasoningBank',
196
+ 'causalGraph', 'causalRecall', 'learningSystem',
197
+ 'explainableRecall', 'nightlyLearner',
198
+ 'graphTransformer', 'mutationGuard',
199
+ 'attestationLog', 'vectorBackend'
200
+ ].filter(name => {
201
+ try { return agentdb.getController(name) != null; }
202
+ catch { return false; }
203
+ });
204
+ },
205
+ };
93
206
  registryInstance = registry;
94
207
  bridgeAvailable = true;
95
208
  return registry;
@@ -239,25 +352,25 @@ function getDb(registry) {
239
352
  const db = agentdb.database;
240
353
  // Ensure memory_entries table exists (idempotent)
241
354
  try {
242
- db.exec(`CREATE TABLE IF NOT EXISTS memory_entries (
243
- id TEXT PRIMARY KEY,
244
- key TEXT NOT NULL,
245
- namespace TEXT DEFAULT 'default',
246
- content TEXT NOT NULL,
247
- type TEXT DEFAULT 'semantic',
248
- embedding TEXT,
249
- embedding_model TEXT DEFAULT 'local',
250
- embedding_dimensions INTEGER,
251
- tags TEXT,
252
- metadata TEXT,
253
- owner_id TEXT,
254
- created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),
255
- updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),
256
- expires_at INTEGER,
257
- last_accessed_at INTEGER,
258
- access_count INTEGER DEFAULT 0,
259
- status TEXT DEFAULT 'active',
260
- UNIQUE(namespace, key)
355
+ db.exec(`CREATE TABLE IF NOT EXISTS memory_entries (
356
+ id TEXT PRIMARY KEY,
357
+ key TEXT NOT NULL,
358
+ namespace TEXT DEFAULT 'default',
359
+ content TEXT NOT NULL,
360
+ type TEXT DEFAULT 'semantic',
361
+ embedding TEXT,
362
+ embedding_model TEXT DEFAULT 'local',
363
+ embedding_dimensions INTEGER,
364
+ tags TEXT,
365
+ metadata TEXT,
366
+ owner_id TEXT,
367
+ created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),
368
+ updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),
369
+ expires_at INTEGER,
370
+ last_accessed_at INTEGER,
371
+ access_count INTEGER DEFAULT 0,
372
+ status TEXT DEFAULT 'active',
373
+ UNIQUE(namespace, key)
261
374
  )`);
262
375
  // Ensure indexes
263
376
  db.exec(`CREATE INDEX IF NOT EXISTS idx_bridge_ns ON memory_entries(namespace)`);
@@ -313,15 +426,15 @@ export async function bridgeStoreEntry(options) {
313
426
  }
314
427
  // better-sqlite3 uses synchronous .run() with positional params
315
428
  const insertSql = options.upsert
316
- ? `INSERT OR REPLACE INTO memory_entries (
317
- id, key, namespace, content, type,
318
- embedding, embedding_dimensions, embedding_model,
319
- tags, metadata, created_at, updated_at, expires_at, status
429
+ ? `INSERT OR REPLACE INTO memory_entries (
430
+ id, key, namespace, content, type,
431
+ embedding, embedding_dimensions, embedding_model,
432
+ tags, metadata, created_at, updated_at, expires_at, status
320
433
  ) VALUES (?, ?, ?, ?, 'semantic', ?, ?, ?, ?, ?, ?, ?, ?, 'active')`
321
- : `INSERT INTO memory_entries (
322
- id, key, namespace, content, type,
323
- embedding, embedding_dimensions, embedding_model,
324
- tags, metadata, created_at, updated_at, expires_at, status
434
+ : `INSERT INTO memory_entries (
435
+ id, key, namespace, content, type,
436
+ embedding, embedding_dimensions, embedding_model,
437
+ tags, metadata, created_at, updated_at, expires_at, status
325
438
  ) VALUES (?, ?, ?, ?, 'semantic', ?, ?, ?, ?, ?, ?, ?, ?, 'active')`;
326
439
  const stmt = ctx.db.prepare(insertSql);
327
440
  stmt.run(id, key, namespace, value, embeddingJson, dimensions || null, model, tags.length > 0 ? JSON.stringify(tags) : null, '{}', now, now, ttl ? now + (ttl * 1000) : null);
@@ -378,11 +491,11 @@ export async function bridgeSearchEntries(options) {
378
491
  : '';
379
492
  let rows;
380
493
  try {
381
- const stmt = ctx.db.prepare(`
382
- SELECT id, key, namespace, content, embedding
383
- FROM memory_entries
384
- WHERE status = 'active' ${nsFilter}
385
- LIMIT 1000
494
+ const stmt = ctx.db.prepare(`
495
+ SELECT id, key, namespace, content, embedding
496
+ FROM memory_entries
497
+ WHERE status = 'active' ${nsFilter}
498
+ LIMIT 1000
386
499
  `);
387
500
  rows = namespace !== 'all' ? stmt.all(namespace) : stmt.all();
388
501
  }
@@ -472,12 +585,12 @@ export async function bridgeListEntries(options) {
472
585
  // List
473
586
  const entries = [];
474
587
  try {
475
- const stmt = ctx.db.prepare(`
476
- SELECT id, key, namespace, content, embedding, access_count, created_at, updated_at
477
- FROM memory_entries
478
- WHERE status = 'active' ${nsFilter}
479
- ORDER BY updated_at DESC
480
- LIMIT ? OFFSET ?
588
+ const stmt = ctx.db.prepare(`
589
+ SELECT id, key, namespace, content, embedding, access_count, created_at, updated_at
590
+ FROM memory_entries
591
+ WHERE status = 'active' ${nsFilter}
592
+ ORDER BY updated_at DESC
593
+ LIMIT ? OFFSET ?
481
594
  `);
482
595
  const rows = stmt.all(...nsParams, limit, offset);
483
596
  for (const row of rows) {
@@ -540,11 +653,11 @@ export async function bridgeGetEntry(options) {
540
653
  }
541
654
  let row;
542
655
  try {
543
- const stmt = ctx.db.prepare(`
544
- SELECT id, key, namespace, content, embedding, access_count, created_at, updated_at, tags
545
- FROM memory_entries
546
- WHERE status = 'active' AND key = ? AND namespace = ?
547
- LIMIT 1
656
+ const stmt = ctx.db.prepare(`
657
+ SELECT id, key, namespace, content, embedding, access_count, created_at, updated_at, tags
658
+ FROM memory_entries
659
+ WHERE status = 'active' AND key = ? AND namespace = ?
660
+ LIMIT 1
548
661
  `);
549
662
  row = stmt.get(key, namespace);
550
663
  }
@@ -608,10 +721,10 @@ export async function bridgeDeleteEntry(options) {
608
721
  // Soft delete using parameterized query
609
722
  let changes = 0;
610
723
  try {
611
- const result = ctx.db.prepare(`
612
- UPDATE memory_entries
613
- SET status = 'deleted', updated_at = ?
614
- WHERE key = ? AND namespace = ? AND status = 'active'
724
+ const result = ctx.db.prepare(`
725
+ UPDATE memory_entries
726
+ SET status = 'deleted', updated_at = ?
727
+ WHERE key = ? AND namespace = ? AND status = 'active'
615
728
  `).run(Date.now(), key, namespace);
616
729
  changes = result?.changes ?? 0;
617
730
  }
@@ -756,11 +869,11 @@ export async function bridgeSearchHNSW(queryEmbedding, options, dbPath) {
756
869
  : '';
757
870
  let rows;
758
871
  try {
759
- const stmt = ctx.db.prepare(`
760
- SELECT id, key, namespace, content, embedding
761
- FROM memory_entries
762
- WHERE status = 'active' AND embedding IS NOT NULL ${nsFilter}
763
- LIMIT 10000
872
+ const stmt = ctx.db.prepare(`
873
+ SELECT id, key, namespace, content, embedding
874
+ FROM memory_entries
875
+ WHERE status = 'active' AND embedding IS NOT NULL ${nsFilter}
876
+ LIMIT 10000
764
877
  `);
765
878
  rows = nsFilter
766
879
  ? stmt.all(options.namespace)
@@ -812,12 +925,12 @@ export async function bridgeAddToHNSW(id, embedding, entry, dbPath) {
812
925
  try {
813
926
  const now = Date.now();
814
927
  const embeddingJson = JSON.stringify(embedding);
815
- ctx.db.prepare(`
816
- INSERT OR REPLACE INTO memory_entries (
817
- id, key, namespace, content, type,
818
- embedding, embedding_dimensions, embedding_model,
819
- created_at, updated_at, status
820
- ) VALUES (?, ?, ?, ?, 'semantic', ?, ?, 'Xenova/all-MiniLM-L6-v2', ?, ?, 'active')
928
+ ctx.db.prepare(`
929
+ INSERT OR REPLACE INTO memory_entries (
930
+ id, key, namespace, content, type,
931
+ embedding, embedding_dimensions, embedding_model,
932
+ created_at, updated_at, status
933
+ ) VALUES (?, ?, ?, ?, 'semantic', ?, ?, 'Xenova/all-MiniLM-L6-v2', ?, ?, 'active')
821
934
  `).run(id, entry.key, entry.namespace, entry.content, embeddingJson, embedding.length, now, now);
822
935
  return true;
823
936
  }
@@ -1085,9 +1198,9 @@ export async function bridgeRecordCausalEdge(options) {
1085
1198
  const ctx = getDb(registry);
1086
1199
  if (ctx) {
1087
1200
  try {
1088
- ctx.db.prepare(`
1089
- INSERT OR REPLACE INTO memory_entries (id, key, namespace, content, type, created_at, updated_at, status)
1090
- VALUES (?, ?, 'causal-edges', ?, 'procedural', ?, ?, 'active')
1201
+ ctx.db.prepare(`
1202
+ INSERT OR REPLACE INTO memory_entries (id, key, namespace, content, type, created_at, updated_at, status)
1203
+ VALUES (?, ?, 'causal-edges', ?, 'procedural', ?, ?, 'active')
1091
1204
  `).run(generateId('edge'), `${options.sourceId}→${options.targetId}`, JSON.stringify(options), Date.now(), Date.now());
1092
1205
  return { success: true, controller: 'bridge-fallback' };
1093
1206
  }