tachibot-mcp 2.0.2

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 (214) hide show
  1. package/.env.example +260 -0
  2. package/CHANGELOG.md +54 -0
  3. package/CODE_OF_CONDUCT.md +56 -0
  4. package/CONTRIBUTING.md +54 -0
  5. package/Dockerfile +36 -0
  6. package/LICENSE +644 -0
  7. package/README.md +201 -0
  8. package/SECURITY.md +95 -0
  9. package/dist/personality/komaai-expressions.js +12 -0
  10. package/dist/profiles/balanced.json +33 -0
  11. package/dist/profiles/code_focus.json +33 -0
  12. package/dist/profiles/full.json +33 -0
  13. package/dist/profiles/minimal.json +33 -0
  14. package/dist/profiles/research_power.json +33 -0
  15. package/dist/scripts/build-profiles.js +46 -0
  16. package/dist/src/application/services/focus/FocusModeRegistry.js +46 -0
  17. package/dist/src/application/services/focus/FocusTool.service.js +109 -0
  18. package/dist/src/application/services/focus/ModeRegistry.js +46 -0
  19. package/dist/src/application/services/focus/modes/focus-deep.mode.js +27 -0
  20. package/dist/src/application/services/focus/modes/status.mode.js +50 -0
  21. package/dist/src/application/services/focus/modes/tachibot-status.mode.js +50 -0
  22. package/dist/src/collaborative-orchestrator.js +391 -0
  23. package/dist/src/config/model-constants.js +188 -0
  24. package/dist/src/config/model-defaults.js +57 -0
  25. package/dist/src/config/model-preferences.js +382 -0
  26. package/dist/src/config/timeout-config.js +130 -0
  27. package/dist/src/config.js +173 -0
  28. package/dist/src/domain/interfaces/IFocusMode.js +5 -0
  29. package/dist/src/domain/interfaces/IProvider.js +6 -0
  30. package/dist/src/domain/interfaces/ITool.js +5 -0
  31. package/dist/src/focus-deep.js +245 -0
  32. package/dist/src/infrastructure/ascii/art/robots.ascii.js +16 -0
  33. package/dist/src/mcp-client.js +90 -0
  34. package/dist/src/memory/index.js +17 -0
  35. package/dist/src/memory/memory-config.js +135 -0
  36. package/dist/src/memory/memory-interface.js +174 -0
  37. package/dist/src/memory/memory-manager.js +383 -0
  38. package/dist/src/memory/providers/devlog-provider.js +385 -0
  39. package/dist/src/memory/providers/hybrid-provider.js +399 -0
  40. package/dist/src/memory/providers/local-provider.js +388 -0
  41. package/dist/src/memory/providers/mem0-provider.js +337 -0
  42. package/dist/src/modes/architect.js +477 -0
  43. package/dist/src/modes/auditor.js +362 -0
  44. package/dist/src/modes/challenger.js +841 -0
  45. package/dist/src/modes/code-reviewer.js +382 -0
  46. package/dist/src/modes/commit-guardian.js +424 -0
  47. package/dist/src/modes/documentation-writer.js +572 -0
  48. package/dist/src/modes/scout.js +587 -0
  49. package/dist/src/modes/shared/helpers/challenger-helpers.js +454 -0
  50. package/dist/src/modes/shared/helpers/index.js +17 -0
  51. package/dist/src/modes/shared/helpers/scout-helpers.js +270 -0
  52. package/dist/src/modes/shared/helpers/verifier-helpers.js +332 -0
  53. package/dist/src/modes/test-architect.js +767 -0
  54. package/dist/src/modes/verifier.js +378 -0
  55. package/dist/src/monitoring/performance-monitor.js +435 -0
  56. package/dist/src/optimization/batch-executor.js +121 -0
  57. package/dist/src/optimization/context-pruner.js +196 -0
  58. package/dist/src/optimization/cost-monitor.js +338 -0
  59. package/dist/src/optimization/index.js +65 -0
  60. package/dist/src/optimization/model-router.js +264 -0
  61. package/dist/src/optimization/result-cache.js +114 -0
  62. package/dist/src/optimization/token-optimizer.js +257 -0
  63. package/dist/src/optimization/token-tracker.js +118 -0
  64. package/dist/src/orchestrator-instructions.js +128 -0
  65. package/dist/src/orchestrator-lite.js +139 -0
  66. package/dist/src/orchestrator.js +191 -0
  67. package/dist/src/orchestrators/collaborative/interfaces/IToolExecutionEngine.js +1 -0
  68. package/dist/src/orchestrators/collaborative/interfaces/IToolExecutionStrategy.js +5 -0
  69. package/dist/src/orchestrators/collaborative/interfaces/IVisualizationRenderer.js +1 -0
  70. package/dist/src/orchestrators/collaborative/registries/ModelProviderRegistry.js +95 -0
  71. package/dist/src/orchestrators/collaborative/registries/ToolAdapterRegistry.js +64 -0
  72. package/dist/src/orchestrators/collaborative/services/tool-execution/ToolExecutionService.js +502 -0
  73. package/dist/src/orchestrators/collaborative/services/visualization/VisualizationService.js +206 -0
  74. package/dist/src/orchestrators/collaborative/types/session-types.js +5 -0
  75. package/dist/src/profiles/balanced.js +37 -0
  76. package/dist/src/profiles/code_focus.js +37 -0
  77. package/dist/src/profiles/debug_intensive.js +59 -0
  78. package/dist/src/profiles/full.js +37 -0
  79. package/dist/src/profiles/minimal.js +37 -0
  80. package/dist/src/profiles/research_code.js +59 -0
  81. package/dist/src/profiles/research_power.js +37 -0
  82. package/dist/src/profiles/types.js +5 -0
  83. package/dist/src/profiles/workflow_builder.js +53 -0
  84. package/dist/src/prompt-engineer-lite.js +78 -0
  85. package/dist/src/prompt-engineer.js +399 -0
  86. package/dist/src/reasoning-chain.js +508 -0
  87. package/dist/src/sequential-thinking.js +291 -0
  88. package/dist/src/server-diagnostic.js +74 -0
  89. package/dist/src/server-raw.js +158 -0
  90. package/dist/src/server-simple.js +58 -0
  91. package/dist/src/server.js +514 -0
  92. package/dist/src/session/session-logger.js +617 -0
  93. package/dist/src/session/session-manager.js +571 -0
  94. package/dist/src/session/session-tools.js +400 -0
  95. package/dist/src/tools/advanced-modes.js +200 -0
  96. package/dist/src/tools/claude-integration.js +356 -0
  97. package/dist/src/tools/consolidated/ai-router.js +174 -0
  98. package/dist/src/tools/consolidated/ai-tool.js +48 -0
  99. package/dist/src/tools/consolidated/brainstorm-tool.js +87 -0
  100. package/dist/src/tools/consolidated/environment-detector.js +80 -0
  101. package/dist/src/tools/consolidated/index.js +50 -0
  102. package/dist/src/tools/consolidated/search-tool.js +110 -0
  103. package/dist/src/tools/consolidated/workflow-tool.js +238 -0
  104. package/dist/src/tools/gemini-tools.js +329 -0
  105. package/dist/src/tools/grok-enhanced.js +376 -0
  106. package/dist/src/tools/grok-tools.js +299 -0
  107. package/dist/src/tools/lmstudio-tools.js +223 -0
  108. package/dist/src/tools/openai-tools.js +498 -0
  109. package/dist/src/tools/openrouter-tools.js +317 -0
  110. package/dist/src/tools/optimized-wrapper.js +204 -0
  111. package/dist/src/tools/perplexity-tools.js +294 -0
  112. package/dist/src/tools/pingpong-tool.js +343 -0
  113. package/dist/src/tools/qwen-wrapper.js +74 -0
  114. package/dist/src/tools/tool-router.js +444 -0
  115. package/dist/src/tools/unified-ai-provider.js +260 -0
  116. package/dist/src/tools/workflow-runner.js +425 -0
  117. package/dist/src/tools/workflow-validator-tool.js +107 -0
  118. package/dist/src/types.js +23 -0
  119. package/dist/src/utils/input-validator.js +130 -0
  120. package/dist/src/utils/model-router.js +91 -0
  121. package/dist/src/utils/progress-stream.js +255 -0
  122. package/dist/src/utils/provider-router.js +88 -0
  123. package/dist/src/utils/smart-api-client.js +146 -0
  124. package/dist/src/utils/table-builder.js +218 -0
  125. package/dist/src/utils/timestamp-formatter.js +134 -0
  126. package/dist/src/utils/tool-compressor.js +257 -0
  127. package/dist/src/utils/tool-config.js +201 -0
  128. package/dist/src/validators/dependency-graph-validator.js +147 -0
  129. package/dist/src/validators/interpolation-validator.js +222 -0
  130. package/dist/src/validators/output-usage-validator.js +151 -0
  131. package/dist/src/validators/syntax-validator.js +102 -0
  132. package/dist/src/validators/tool-registry-validator.js +123 -0
  133. package/dist/src/validators/tool-types.js +97 -0
  134. package/dist/src/validators/types.js +8 -0
  135. package/dist/src/validators/workflow-validator.js +134 -0
  136. package/dist/src/visualizer-lite.js +42 -0
  137. package/dist/src/visualizer.js +179 -0
  138. package/dist/src/workflows/circuit-breaker.js +199 -0
  139. package/dist/src/workflows/custom-workflows.js +451 -0
  140. package/dist/src/workflows/engine/AutoSynthesizer.js +97 -0
  141. package/dist/src/workflows/engine/StepParameterResolver.js +74 -0
  142. package/dist/src/workflows/engine/VariableInterpolator.js +123 -0
  143. package/dist/src/workflows/engine/WorkflowDiscovery.js +125 -0
  144. package/dist/src/workflows/engine/WorkflowExecutionEngine.js +485 -0
  145. package/dist/src/workflows/engine/WorkflowExecutor.js +113 -0
  146. package/dist/src/workflows/engine/WorkflowFileManager.js +244 -0
  147. package/dist/src/workflows/engine/WorkflowHelpers.js +114 -0
  148. package/dist/src/workflows/engine/WorkflowOutputFormatter.js +83 -0
  149. package/dist/src/workflows/engine/events/WorkflowEventBus.js +132 -0
  150. package/dist/src/workflows/engine/events/interfaces/IEventBus.js +5 -0
  151. package/dist/src/workflows/engine/handlers/ErrorRecoveryHandler.js +162 -0
  152. package/dist/src/workflows/engine/handlers/PromptEnhancementHandler.js +115 -0
  153. package/dist/src/workflows/engine/handlers/SessionPersistenceHandler.js +167 -0
  154. package/dist/src/workflows/engine/handlers/StepExecutionHandler.js +231 -0
  155. package/dist/src/workflows/engine/handlers/ToolInvocationHandler.js +46 -0
  156. package/dist/src/workflows/engine/interfaces/IAutoSynthesizer.js +5 -0
  157. package/dist/src/workflows/engine/interfaces/IStepParameterResolver.js +5 -0
  158. package/dist/src/workflows/engine/interfaces/IVariableInterpolator.js +5 -0
  159. package/dist/src/workflows/engine/interfaces/IWorkflowDiscovery.js +4 -0
  160. package/dist/src/workflows/engine/interfaces/IWorkflowFileManager.js +5 -0
  161. package/dist/src/workflows/engine/interfaces/IWorkflowOutputFormatter.js +5 -0
  162. package/dist/src/workflows/engine/state/WorkflowStateMachine.js +194 -0
  163. package/dist/src/workflows/engine/state/interfaces/IStateMachine.js +17 -0
  164. package/dist/src/workflows/fallback-strategies.js +373 -0
  165. package/dist/src/workflows/message-queue.js +455 -0
  166. package/dist/src/workflows/model-router.js +189 -0
  167. package/dist/src/workflows/orchestrator-examples.js +174 -0
  168. package/dist/src/workflows/orchestrator-integration.js +200 -0
  169. package/dist/src/workflows/self-healing.js +524 -0
  170. package/dist/src/workflows/tool-mapper.js +407 -0
  171. package/dist/src/workflows/tool-orchestrator.js +796 -0
  172. package/dist/src/workflows/workflow-engine.js +573 -0
  173. package/dist/src/workflows/workflow-parser.js +283 -0
  174. package/dist/src/workflows/workflow-types.js +95 -0
  175. package/dist/src/workflows.js +568 -0
  176. package/dist/test-workflow-file-output.js +93 -0
  177. package/docs/API_KEYS.md +570 -0
  178. package/docs/CLAUDE_CODE_SETUP.md +181 -0
  179. package/docs/CLAUDE_DESKTOP_MANUAL.md +127 -0
  180. package/docs/CONFIGURATION.md +745 -0
  181. package/docs/FOCUS_MODES.md +240 -0
  182. package/docs/INSTALLATION_BOTH.md +145 -0
  183. package/docs/TERMS.md +352 -0
  184. package/docs/TOOLS_REFERENCE.md +1622 -0
  185. package/docs/TOOL_PARAMETERS.md +496 -0
  186. package/docs/TOOL_PROFILES.md +236 -0
  187. package/docs/WORKFLOWS.md +987 -0
  188. package/docs/WORKFLOW_OUTPUT.md +198 -0
  189. package/docs/WORKFLOW_PROGRESS_TRACKING.md +305 -0
  190. package/docs/workflows/design-brainstorm.md +335 -0
  191. package/package.json +97 -0
  192. package/profiles/balanced.json +37 -0
  193. package/profiles/code_focus.json +37 -0
  194. package/profiles/debug_intensive.json +34 -0
  195. package/profiles/full.json +37 -0
  196. package/profiles/minimal.json +37 -0
  197. package/profiles/research_power.json +37 -0
  198. package/profiles/workflow_builder.json +37 -0
  199. package/smithery.yaml +66 -0
  200. package/start.sh +8 -0
  201. package/tools.config.json +81 -0
  202. package/tsconfig.json +18 -0
  203. package/workflows/accessibility-code-audit.yaml +92 -0
  204. package/workflows/code-architecture-review.yaml +202 -0
  205. package/workflows/code-review.yaml +142 -0
  206. package/workflows/core/iterative-problem-solver.yaml +283 -0
  207. package/workflows/creative-brainstorm-yaml.yaml +215 -0
  208. package/workflows/pingpong.yaml +141 -0
  209. package/workflows/system/README.md +412 -0
  210. package/workflows/system/challenger.yaml +175 -0
  211. package/workflows/system/scout.yaml +164 -0
  212. package/workflows/system/verifier.yaml +133 -0
  213. package/workflows/ultra-creative-brainstorm.yaml +318 -0
  214. package/workflows/ux-research-flow.yaml +92 -0
@@ -0,0 +1,399 @@
1
+ /**
2
+ * Hybrid Memory Provider
3
+ * Combines multiple memory providers with fallback and sync capabilities
4
+ */
5
+ import { BaseMemoryProvider } from '../memory-interface.js';
6
+ import { createMem0Provider } from './mem0-provider.js';
7
+ import { createDevLogProvider } from './devlog-provider.js';
8
+ import { createLocalProvider } from './local-provider.js';
9
+ /**
10
+ * Hybrid provider implementation
11
+ */
12
+ export class HybridProvider extends BaseMemoryProvider {
13
+ constructor(config) {
14
+ super();
15
+ this.name = 'hybrid';
16
+ this.primaryProvider = null;
17
+ this.fallbackProvider = null;
18
+ this.syncInterval = null;
19
+ this.syncQueue = new Map();
20
+ this.isSyncing = false;
21
+ this.config = {
22
+ syncInterval: config.syncInterval || 60000, // Default 1 minute
23
+ preferPrimaryFor: config.preferPrimaryFor || ['team', 'global'],
24
+ ...config
25
+ };
26
+ }
27
+ async doInitialize() {
28
+ try {
29
+ // Initialize primary provider
30
+ this.primaryProvider = await this.createProvider(this.config.primary);
31
+ if (!this.primaryProvider) {
32
+ throw new Error(`Failed to create primary provider: ${this.config.primary}`);
33
+ }
34
+ // Initialize fallback provider
35
+ this.fallbackProvider = await this.createProvider(this.config.fallback);
36
+ if (!this.fallbackProvider) {
37
+ throw new Error(`Failed to create fallback provider: ${this.config.fallback}`);
38
+ }
39
+ // Set up sync interval if enabled
40
+ if (this.config.syncInterval && this.config.syncInterval > 0) {
41
+ this.startSync();
42
+ }
43
+ console.error(`Hybrid provider initialized with primary=${this.config.primary}, fallback=${this.config.fallback}`);
44
+ }
45
+ catch (error) {
46
+ console.error('Failed to initialize hybrid provider:', error);
47
+ throw error;
48
+ }
49
+ }
50
+ async store(item) {
51
+ const preferPrimary = this.shouldUsePrimary(item.tier);
52
+ let primaryId = null;
53
+ let fallbackId = null;
54
+ // Try primary first if preferred
55
+ if (preferPrimary && this.primaryProvider) {
56
+ try {
57
+ if (await this.primaryProvider.isAvailable()) {
58
+ primaryId = await this.primaryProvider.store(item);
59
+ }
60
+ }
61
+ catch (error) {
62
+ console.warn(`Primary provider store failed: ${error}`);
63
+ }
64
+ }
65
+ // Always store in fallback for redundancy
66
+ if (this.fallbackProvider) {
67
+ try {
68
+ fallbackId = await this.fallbackProvider.store(item);
69
+ }
70
+ catch (error) {
71
+ console.error(`Fallback provider store failed: ${error}`);
72
+ if (!primaryId)
73
+ throw error; // Fail if both failed
74
+ }
75
+ }
76
+ // Try primary if not already tried and fallback succeeded
77
+ if (!preferPrimary && !primaryId && fallbackId && this.primaryProvider) {
78
+ try {
79
+ if (await this.primaryProvider.isAvailable()) {
80
+ primaryId = await this.primaryProvider.store(item);
81
+ }
82
+ }
83
+ catch (error) {
84
+ // Non-critical, we have fallback
85
+ console.warn(`Primary provider store failed (non-critical): ${error}`);
86
+ }
87
+ }
88
+ // Queue for sync if only stored in one provider
89
+ if ((primaryId && !fallbackId) || (!primaryId && fallbackId)) {
90
+ this.syncQueue.set(item.id, item);
91
+ }
92
+ // Update metrics
93
+ this.metrics.totalItems++;
94
+ this.metrics.itemsByTier[item.tier]++;
95
+ return primaryId || fallbackId || item.id;
96
+ }
97
+ async retrieve(query) {
98
+ const results = new Map();
99
+ // Try primary provider
100
+ if (this.primaryProvider && await this.primaryProvider.isAvailable()) {
101
+ try {
102
+ const primaryItems = await this.primaryProvider.retrieve(query);
103
+ primaryItems.forEach(item => results.set(item.id, item));
104
+ }
105
+ catch (error) {
106
+ console.warn(`Primary provider retrieve failed: ${error}`);
107
+ }
108
+ }
109
+ // Try fallback provider
110
+ if (this.fallbackProvider) {
111
+ try {
112
+ const fallbackItems = await this.fallbackProvider.retrieve(query);
113
+ fallbackItems.forEach(item => {
114
+ // Merge with primary results, primary takes precedence
115
+ if (!results.has(item.id)) {
116
+ results.set(item.id, item);
117
+ }
118
+ });
119
+ }
120
+ catch (error) {
121
+ console.error(`Fallback provider retrieve failed: ${error}`);
122
+ if (results.size === 0)
123
+ throw error; // Fail if both failed
124
+ }
125
+ }
126
+ return Array.from(results.values());
127
+ }
128
+ async retrieveContext(query) {
129
+ // Try primary first
130
+ if (this.primaryProvider && await this.primaryProvider.isAvailable()) {
131
+ try {
132
+ return await this.primaryProvider.retrieveContext(query);
133
+ }
134
+ catch (error) {
135
+ console.warn(`Primary provider context retrieval failed: ${error}`);
136
+ }
137
+ }
138
+ // Fallback
139
+ if (this.fallbackProvider) {
140
+ try {
141
+ return await this.fallbackProvider.retrieveContext(query);
142
+ }
143
+ catch (error) {
144
+ console.error(`Fallback provider context retrieval failed: ${error}`);
145
+ throw error;
146
+ }
147
+ }
148
+ // Return empty context if both failed
149
+ return {
150
+ items: [],
151
+ synthesis: '',
152
+ relevanceScore: 0,
153
+ tokenCount: 0,
154
+ sources: {
155
+ session: 0,
156
+ working: 0,
157
+ project: 0,
158
+ team: 0,
159
+ global: 0
160
+ }
161
+ };
162
+ }
163
+ async update(id, updates) {
164
+ let primarySuccess = false;
165
+ let fallbackSuccess = false;
166
+ // Update in both providers
167
+ if (this.primaryProvider && await this.primaryProvider.isAvailable()) {
168
+ try {
169
+ primarySuccess = await this.primaryProvider.update(id, updates);
170
+ }
171
+ catch (error) {
172
+ console.warn(`Primary provider update failed: ${error}`);
173
+ }
174
+ }
175
+ if (this.fallbackProvider) {
176
+ try {
177
+ fallbackSuccess = await this.fallbackProvider.update(id, updates);
178
+ }
179
+ catch (error) {
180
+ console.warn(`Fallback provider update failed: ${error}`);
181
+ }
182
+ }
183
+ return primarySuccess || fallbackSuccess;
184
+ }
185
+ async delete(id) {
186
+ let primarySuccess = false;
187
+ let fallbackSuccess = false;
188
+ // Delete from both providers
189
+ if (this.primaryProvider && await this.primaryProvider.isAvailable()) {
190
+ try {
191
+ primarySuccess = await this.primaryProvider.delete(id);
192
+ }
193
+ catch (error) {
194
+ console.warn(`Primary provider delete failed: ${error}`);
195
+ }
196
+ }
197
+ if (this.fallbackProvider) {
198
+ try {
199
+ fallbackSuccess = await this.fallbackProvider.delete(id);
200
+ }
201
+ catch (error) {
202
+ console.warn(`Fallback provider delete failed: ${error}`);
203
+ }
204
+ }
205
+ if (primarySuccess || fallbackSuccess) {
206
+ this.metrics.totalItems--;
207
+ // Remove from sync queue if present
208
+ this.syncQueue.delete(id);
209
+ }
210
+ return primarySuccess || fallbackSuccess;
211
+ }
212
+ async semanticSearch(text, limit, threshold) {
213
+ const results = new Map();
214
+ // Try primary if it supports semantic search
215
+ if (this.primaryProvider && 'semanticSearch' in this.primaryProvider) {
216
+ try {
217
+ const items = await this.primaryProvider.semanticSearch(text, limit, threshold);
218
+ items.forEach((item) => results.set(item.id, item));
219
+ }
220
+ catch (error) {
221
+ console.warn(`Primary provider semantic search failed: ${error}`);
222
+ }
223
+ }
224
+ // Try fallback if it supports semantic search
225
+ if (this.fallbackProvider && 'semanticSearch' in this.fallbackProvider) {
226
+ try {
227
+ const items = await this.fallbackProvider.semanticSearch(text, limit, threshold);
228
+ items.forEach((item) => {
229
+ if (!results.has(item.id)) {
230
+ results.set(item.id, item);
231
+ }
232
+ });
233
+ }
234
+ catch (error) {
235
+ console.warn(`Fallback provider semantic search failed: ${error}`);
236
+ }
237
+ }
238
+ return Array.from(results.values()).slice(0, limit);
239
+ }
240
+ async cleanup() {
241
+ let totalCleaned = 0;
242
+ // Cleanup both providers
243
+ if (this.primaryProvider) {
244
+ try {
245
+ totalCleaned += await this.primaryProvider.cleanup();
246
+ }
247
+ catch (error) {
248
+ console.warn(`Primary provider cleanup failed: ${error}`);
249
+ }
250
+ }
251
+ if (this.fallbackProvider) {
252
+ try {
253
+ totalCleaned += await this.fallbackProvider.cleanup();
254
+ }
255
+ catch (error) {
256
+ console.warn(`Fallback provider cleanup failed: ${error}`);
257
+ }
258
+ }
259
+ return totalCleaned;
260
+ }
261
+ async export() {
262
+ const allItems = new Map();
263
+ // Export from both providers
264
+ if (this.primaryProvider) {
265
+ try {
266
+ const items = await this.primaryProvider.export();
267
+ items.forEach(item => allItems.set(item.id, item));
268
+ }
269
+ catch (error) {
270
+ console.warn(`Primary provider export failed: ${error}`);
271
+ }
272
+ }
273
+ if (this.fallbackProvider) {
274
+ try {
275
+ const items = await this.fallbackProvider.export();
276
+ items.forEach(item => {
277
+ if (!allItems.has(item.id)) {
278
+ allItems.set(item.id, item);
279
+ }
280
+ });
281
+ }
282
+ catch (error) {
283
+ console.warn(`Fallback provider export failed: ${error}`);
284
+ }
285
+ }
286
+ return Array.from(allItems.values());
287
+ }
288
+ async import(items) {
289
+ let totalImported = 0;
290
+ // Import to both providers
291
+ if (this.primaryProvider) {
292
+ try {
293
+ totalImported = await this.primaryProvider.import(items);
294
+ }
295
+ catch (error) {
296
+ console.warn(`Primary provider import failed: ${error}`);
297
+ }
298
+ }
299
+ if (this.fallbackProvider) {
300
+ try {
301
+ await this.fallbackProvider.import(items);
302
+ }
303
+ catch (error) {
304
+ console.warn(`Fallback provider import failed: ${error}`);
305
+ }
306
+ }
307
+ return totalImported;
308
+ }
309
+ async isAvailable() {
310
+ const primaryAvailable = this.primaryProvider ?
311
+ await this.primaryProvider.isAvailable() : false;
312
+ const fallbackAvailable = this.fallbackProvider ?
313
+ await this.fallbackProvider.isAvailable() : false;
314
+ return primaryAvailable || fallbackAvailable;
315
+ }
316
+ async close() {
317
+ // Stop sync
318
+ if (this.syncInterval) {
319
+ clearInterval(this.syncInterval);
320
+ this.syncInterval = null;
321
+ }
322
+ // Perform final sync
323
+ await this.performSync();
324
+ // Close providers
325
+ if (this.primaryProvider) {
326
+ await this.primaryProvider.close();
327
+ }
328
+ if (this.fallbackProvider) {
329
+ await this.fallbackProvider.close();
330
+ }
331
+ await super.close();
332
+ }
333
+ /**
334
+ * Helper methods
335
+ */
336
+ async createProvider(type) {
337
+ const config = global.memoryConfig || {};
338
+ switch (type) {
339
+ case 'mem0':
340
+ return await createMem0Provider(config.mem0 || {});
341
+ case 'devlog':
342
+ return await createDevLogProvider(config.devlog || {});
343
+ case 'local':
344
+ return await createLocalProvider(config.local || {
345
+ storageType: 'json',
346
+ path: './.focus-memory-hybrid',
347
+ maxSizeMB: 100
348
+ });
349
+ default:
350
+ throw new Error(`Unknown provider type: ${type}`);
351
+ }
352
+ }
353
+ shouldUsePrimary(tier) {
354
+ return this.config.preferPrimaryFor?.includes(tier) || false;
355
+ }
356
+ startSync() {
357
+ this.syncInterval = setInterval(() => {
358
+ this.performSync().catch(console.error);
359
+ }, this.config.syncInterval);
360
+ }
361
+ async performSync() {
362
+ if (this.isSyncing || this.syncQueue.size === 0)
363
+ return;
364
+ this.isSyncing = true;
365
+ const itemsToSync = Array.from(this.syncQueue.values());
366
+ for (const item of itemsToSync) {
367
+ try {
368
+ // Check if item exists in both providers
369
+ const primaryHas = this.primaryProvider ?
370
+ (await this.primaryProvider.retrieve({ text: item.id, limit: 1 })).length > 0 : false;
371
+ const fallbackHas = this.fallbackProvider ?
372
+ (await this.fallbackProvider.retrieve({ text: item.id, limit: 1 })).length > 0 : false;
373
+ // Sync to missing provider
374
+ if (!primaryHas && this.primaryProvider && await this.primaryProvider.isAvailable()) {
375
+ await this.primaryProvider.store(item);
376
+ }
377
+ if (!fallbackHas && this.fallbackProvider) {
378
+ await this.fallbackProvider.store(item);
379
+ }
380
+ // Remove from queue if synced
381
+ if (primaryHas || fallbackHas) {
382
+ this.syncQueue.delete(item.id);
383
+ }
384
+ }
385
+ catch (error) {
386
+ console.warn(`Failed to sync item ${item.id}: ${error}`);
387
+ }
388
+ }
389
+ this.isSyncing = false;
390
+ }
391
+ }
392
+ /**
393
+ * Factory function to create hybrid provider
394
+ */
395
+ export async function createHybridProvider(config) {
396
+ const provider = new HybridProvider(config);
397
+ await provider.initialize();
398
+ return provider;
399
+ }