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,17 @@
1
+ /**
2
+ * Memory System Module
3
+ * Exports all memory-related components
4
+ */
5
+ // Core exports
6
+ export * from './memory-config.js';
7
+ export * from './memory-interface.js';
8
+ export * from './memory-manager.js';
9
+ // Provider exports
10
+ export * from './providers/local-provider.js';
11
+ export * from './providers/mem0-provider.js';
12
+ // export * from './providers/devlog-provider.js';
13
+ // export * from './providers/hybrid-provider.js';
14
+ // Main API
15
+ export { getMemoryManager, resetMemoryManager, HierarchicalMemoryManager } from './memory-manager.js';
16
+ export { DEFAULT_MEMORY_CONFIG, loadMemoryConfigFromEnv, mergeMemoryConfig, validateMemoryConfig } from './memory-config.js';
17
+ export { BaseMemoryProvider } from './memory-interface.js';
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Memory Configuration System
3
+ * Flexible memory backend configuration with support for mem0, DevLog, local, and hybrid modes
4
+ */
5
+ /**
6
+ * Default configuration
7
+ */
8
+ export const DEFAULT_MEMORY_CONFIG = {
9
+ provider: 'local',
10
+ local: {
11
+ storageType: 'json',
12
+ path: './.focus-memory',
13
+ maxSizeMB: 100,
14
+ enableCompression: true
15
+ },
16
+ tiers: {
17
+ session: true,
18
+ working: true,
19
+ project: true,
20
+ team: false,
21
+ global: false
22
+ },
23
+ maxMemoryItems: 10000,
24
+ ttlMinutes: {
25
+ session: 30,
26
+ working: 120,
27
+ project: 43200, // 30 days
28
+ team: 129600, // 90 days
29
+ global: -1 // Never expires
30
+ },
31
+ enableAutoCleanup: true,
32
+ enableMetrics: false
33
+ };
34
+ /**
35
+ * Load configuration from environment variables
36
+ */
37
+ export function loadMemoryConfigFromEnv() {
38
+ const config = {};
39
+ // Provider selection
40
+ const provider = process.env.MEMORY_PROVIDER;
41
+ if (provider) {
42
+ config.provider = provider;
43
+ }
44
+ // Mem0 configuration
45
+ if (process.env.MEM0_API_KEY) {
46
+ config.mem0 = {
47
+ apiKey: process.env.MEM0_API_KEY,
48
+ endpoint: process.env.MEM0_ENDPOINT,
49
+ userId: process.env.MEM0_USER_ID,
50
+ enableVectorSearch: process.env.MEM0_ENABLE_VECTOR !== 'false',
51
+ enableGraphMemory: process.env.MEM0_ENABLE_GRAPH !== 'false'
52
+ };
53
+ }
54
+ // DevLog configuration
55
+ if (process.env.DEVLOG_CONNECTION) {
56
+ config.devlog = {
57
+ connectionString: process.env.DEVLOG_CONNECTION,
58
+ workspace: process.env.DEVLOG_WORKSPACE,
59
+ projectId: process.env.DEVLOG_PROJECT,
60
+ enableSync: process.env.DEVLOG_SYNC !== 'false'
61
+ };
62
+ }
63
+ // Local storage configuration
64
+ if (process.env.LOCAL_STORAGE_PATH) {
65
+ config.local = {
66
+ storageType: process.env.LOCAL_STORAGE_TYPE || 'json',
67
+ path: process.env.LOCAL_STORAGE_PATH,
68
+ maxSizeMB: parseInt(process.env.LOCAL_STORAGE_MAX_MB || '100'),
69
+ enableCompression: process.env.LOCAL_STORAGE_COMPRESS !== 'false'
70
+ };
71
+ }
72
+ // Tier configuration
73
+ config.tiers = {
74
+ session: process.env.ENABLE_SESSION_MEMORY !== 'false',
75
+ working: process.env.ENABLE_WORKING_MEMORY !== 'false',
76
+ project: process.env.ENABLE_PROJECT_MEMORY !== 'false',
77
+ team: process.env.ENABLE_TEAM_MEMORY === 'true',
78
+ global: process.env.ENABLE_GLOBAL_MEMORY === 'true'
79
+ };
80
+ return config;
81
+ }
82
+ /**
83
+ * Merge configurations with defaults
84
+ */
85
+ export function mergeMemoryConfig(userConfig, envConfig = loadMemoryConfigFromEnv()) {
86
+ // Priority: userConfig > envConfig > DEFAULT_MEMORY_CONFIG
87
+ return {
88
+ ...DEFAULT_MEMORY_CONFIG,
89
+ ...envConfig,
90
+ ...userConfig,
91
+ tiers: {
92
+ ...DEFAULT_MEMORY_CONFIG.tiers,
93
+ ...(envConfig.tiers || {}),
94
+ ...(userConfig.tiers || {})
95
+ },
96
+ ttlMinutes: {
97
+ ...DEFAULT_MEMORY_CONFIG.ttlMinutes,
98
+ ...(envConfig.ttlMinutes || {}),
99
+ ...(userConfig.ttlMinutes || {})
100
+ }
101
+ };
102
+ }
103
+ /**
104
+ * Validate memory configuration
105
+ */
106
+ export function validateMemoryConfig(config) {
107
+ const errors = [];
108
+ // Validate provider-specific requirements
109
+ if (config.provider === 'mem0' && !config.mem0?.apiKey && !process.env.MEM0_API_KEY) {
110
+ errors.push('Mem0 provider requires API key (MEM0_API_KEY or config.mem0.apiKey)');
111
+ }
112
+ if (config.provider === 'devlog' && !config.devlog?.connectionString && !process.env.DEVLOG_CONNECTION) {
113
+ errors.push('DevLog provider requires connection string');
114
+ }
115
+ if (config.provider === 'local' && !config.local?.path) {
116
+ errors.push('Local provider requires storage path');
117
+ }
118
+ if (config.provider === 'hybrid') {
119
+ if (!config.hybrid?.primary || !config.hybrid?.fallback) {
120
+ errors.push('Hybrid provider requires both primary and fallback providers');
121
+ }
122
+ if (config.hybrid?.primary === config.hybrid?.fallback) {
123
+ errors.push('Hybrid primary and fallback must be different');
124
+ }
125
+ }
126
+ // Validate at least one tier is enabled
127
+ const tiersEnabled = Object.values(config.tiers).some(v => v);
128
+ if (!tiersEnabled && config.provider !== 'none') {
129
+ errors.push('At least one memory tier must be enabled');
130
+ }
131
+ return {
132
+ valid: errors.length === 0,
133
+ errors
134
+ };
135
+ }
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Memory Provider Interface
3
+ * Common interface for all memory providers (mem0, DevLog, local, etc.)
4
+ */
5
+ /**
6
+ * Abstract base class for memory providers with common functionality
7
+ */
8
+ export class BaseMemoryProvider {
9
+ constructor() {
10
+ this.initialized = false;
11
+ this.metrics = {
12
+ totalItems: 0,
13
+ itemsByTier: {
14
+ session: 0,
15
+ working: 0,
16
+ project: 0,
17
+ team: 0,
18
+ global: 0
19
+ },
20
+ totalTokens: 0,
21
+ avgRetrievalTime: 0,
22
+ hitRate: 0,
23
+ storageUsedMB: 0
24
+ };
25
+ }
26
+ async initialize() {
27
+ if (this.initialized)
28
+ return;
29
+ await this.doInitialize();
30
+ this.initialized = true;
31
+ }
32
+ async storeBatch(items) {
33
+ const ids = [];
34
+ for (const item of items) {
35
+ const id = await this.store(item);
36
+ ids.push(id);
37
+ }
38
+ return ids;
39
+ }
40
+ async retrieveContext(query) {
41
+ // Default implementation - can be overridden
42
+ const items = await this.retrieve(query);
43
+ // Apply priority weights if specified
44
+ if (query.priorityWeights) {
45
+ items.sort((a, b) => {
46
+ const scoreA = this.calculatePriorityScore(a, query.priorityWeights);
47
+ const scoreB = this.calculatePriorityScore(b, query.priorityWeights);
48
+ return scoreB - scoreA;
49
+ });
50
+ }
51
+ // Limit by context window if specified
52
+ let selectedItems = items;
53
+ if (query.contextWindow) {
54
+ selectedItems = this.limitByTokens(items, query.contextWindow);
55
+ }
56
+ // Calculate source distribution
57
+ const sources = {
58
+ session: 0,
59
+ working: 0,
60
+ project: 0,
61
+ team: 0,
62
+ global: 0
63
+ };
64
+ selectedItems.forEach(item => {
65
+ sources[item.tier]++;
66
+ });
67
+ return {
68
+ items: selectedItems,
69
+ synthesis: this.synthesizeItems(selectedItems),
70
+ relevanceScore: this.calculateRelevanceScore(selectedItems, query),
71
+ tokenCount: this.estimateTokenCount(selectedItems),
72
+ sources
73
+ };
74
+ }
75
+ async deleteMany(query) {
76
+ const items = await this.retrieve(query);
77
+ let deleted = 0;
78
+ for (const item of items) {
79
+ if (await this.delete(item.id)) {
80
+ deleted++;
81
+ }
82
+ }
83
+ return deleted;
84
+ }
85
+ async cleanup() {
86
+ // Default implementation - remove expired items
87
+ const now = new Date();
88
+ let cleaned = 0;
89
+ // This would need to be implemented based on storage backend
90
+ // For now, return 0
91
+ return cleaned;
92
+ }
93
+ async getMetrics() {
94
+ return { ...this.metrics };
95
+ }
96
+ async isAvailable() {
97
+ return this.initialized;
98
+ }
99
+ async close() {
100
+ this.initialized = false;
101
+ }
102
+ /**
103
+ * Helper methods
104
+ */
105
+ calculatePriorityScore(item, weights) {
106
+ const now = Date.now();
107
+ const age = now - item.timestamp.getTime();
108
+ const recencyScore = Math.exp(-age / (1000 * 60 * 60 * 24)); // Decay over days
109
+ const frequencyScore = Math.min(1, (item.accessCount || 0) / 10);
110
+ // Relevance would need to be calculated based on query
111
+ const relevanceScore = 0.5; // Default middle value
112
+ return (weights.recency * recencyScore +
113
+ weights.relevance * relevanceScore +
114
+ weights.frequency * frequencyScore);
115
+ }
116
+ limitByTokens(items, maxTokens) {
117
+ const selected = [];
118
+ let totalTokens = 0;
119
+ for (const item of items) {
120
+ const itemTokens = this.estimateTokens(item.content);
121
+ if (totalTokens + itemTokens <= maxTokens) {
122
+ selected.push(item);
123
+ totalTokens += itemTokens;
124
+ }
125
+ else {
126
+ break;
127
+ }
128
+ }
129
+ return selected;
130
+ }
131
+ synthesizeItems(items) {
132
+ if (items.length === 0)
133
+ return '';
134
+ // Group by tier
135
+ const byTier = {
136
+ session: [],
137
+ working: [],
138
+ project: [],
139
+ team: [],
140
+ global: []
141
+ };
142
+ items.forEach(item => {
143
+ byTier[item.tier].push(item);
144
+ });
145
+ // Create synthesis
146
+ const parts = [];
147
+ if (byTier.session.length > 0) {
148
+ parts.push(`Recent context: ${byTier.session.map(i => i.content).join('; ')}`);
149
+ }
150
+ if (byTier.project.length > 0) {
151
+ parts.push(`Project context: ${byTier.project.map(i => i.content).join('; ')}`);
152
+ }
153
+ return parts.join('\n');
154
+ }
155
+ calculateRelevanceScore(items, query) {
156
+ if (items.length === 0)
157
+ return 0;
158
+ // Simple implementation - can be enhanced
159
+ return Math.min(1, items.length / 10);
160
+ }
161
+ estimateTokenCount(items) {
162
+ return items.reduce((sum, item) => sum + this.estimateTokens(item.content), 0);
163
+ }
164
+ estimateTokens(text) {
165
+ // Rough estimate: 1 token ≈ 4 characters
166
+ return Math.ceil(text.length / 4);
167
+ }
168
+ /**
169
+ * Generate unique ID
170
+ */
171
+ generateId() {
172
+ return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
173
+ }
174
+ }
@@ -0,0 +1,383 @@
1
+ /**
2
+ * Hierarchical Memory Manager
3
+ * Orchestrates multiple memory providers and manages tier-based memory hierarchy
4
+ */
5
+ import { mergeMemoryConfig, validateMemoryConfig } from './memory-config.js';
6
+ import { LocalProvider } from './providers/local-provider.js';
7
+ import { Mem0Provider } from './providers/mem0-provider.js';
8
+ // import { DevLogProvider } from './providers/devlog-provider.js';
9
+ // import { HybridProvider } from './providers/hybrid-provider.js';
10
+ /**
11
+ * Main memory manager that coordinates all providers
12
+ */
13
+ export class HierarchicalMemoryManager {
14
+ constructor(userConfig) {
15
+ this.provider = null;
16
+ // Tier-based cleanup intervals
17
+ this.cleanupIntervals = new Map();
18
+ this.config = mergeMemoryConfig(userConfig || {});
19
+ this.sessionId = this.generateSessionId();
20
+ // Validate configuration
21
+ const validation = validateMemoryConfig(this.config);
22
+ if (!validation.valid) {
23
+ console.error('Invalid memory configuration:', validation.errors);
24
+ // Fall back to local provider
25
+ this.config.provider = 'local';
26
+ }
27
+ }
28
+ /**
29
+ * Initialize the memory manager and selected provider
30
+ */
31
+ async initialize() {
32
+ console.error(`🧠 Initializing memory manager with ${this.config.provider} provider...`);
33
+ try {
34
+ // Create the appropriate provider
35
+ this.provider = await this.createProvider();
36
+ if (!this.provider) {
37
+ console.warn('Failed to create primary provider, falling back to local storage');
38
+ this.config.provider = 'local';
39
+ this.provider = await this.createLocalProvider();
40
+ }
41
+ // Set up automatic cleanup for each tier
42
+ if (this.config.enableAutoCleanup) {
43
+ this.setupAutoCleanup();
44
+ }
45
+ console.error(`✅ Memory manager initialized with ${this.provider.name} provider`);
46
+ }
47
+ catch (error) {
48
+ console.error('Failed to initialize memory manager:', error);
49
+ throw error;
50
+ }
51
+ }
52
+ /**
53
+ * Store a memory item with automatic tier assignment
54
+ */
55
+ async store(content, tier, metadata) {
56
+ if (!this.provider) {
57
+ throw new Error('Memory manager not initialized');
58
+ }
59
+ // Auto-assign tier based on context if not provided
60
+ if (!tier) {
61
+ tier = this.inferTier(content, metadata);
62
+ }
63
+ // Check if tier is enabled
64
+ if (!this.config.tiers[tier]) {
65
+ console.warn(`Tier ${tier} is disabled, upgrading to next available tier`);
66
+ const nextTier = this.getNextAvailableTier(tier);
67
+ if (!nextTier) {
68
+ throw new Error('No memory tiers are enabled');
69
+ }
70
+ tier = nextTier;
71
+ }
72
+ const item = {
73
+ id: this.generateId(),
74
+ content,
75
+ tier,
76
+ userId: this.userId,
77
+ projectId: this.projectId,
78
+ teamId: this.teamId,
79
+ timestamp: new Date(),
80
+ metadata: {
81
+ ...metadata,
82
+ sessionId: this.sessionId
83
+ },
84
+ ttl: this.config.ttlMinutes?.[tier]
85
+ };
86
+ return await this.provider.store(item);
87
+ }
88
+ /**
89
+ * Retrieve memories with hierarchical context
90
+ */
91
+ async retrieve(query) {
92
+ if (!this.provider) {
93
+ throw new Error('Memory manager not initialized');
94
+ }
95
+ // Build query with defaults
96
+ const fullQuery = {
97
+ userId: query?.userId || this.userId,
98
+ projectId: query?.projectId || this.projectId,
99
+ teamId: query?.teamId || this.teamId,
100
+ tiers: query?.tiers || this.getEnabledTiers(),
101
+ ...query
102
+ };
103
+ return await this.provider.retrieve(fullQuery);
104
+ }
105
+ /**
106
+ * Get contextual memories with synthesis
107
+ */
108
+ async getContext(text, maxTokens, options) {
109
+ if (!this.provider) {
110
+ throw new Error('Memory manager not initialized');
111
+ }
112
+ const query = {
113
+ text,
114
+ userId: this.userId,
115
+ projectId: this.projectId,
116
+ teamId: this.teamId,
117
+ tiers: this.getEnabledTiers(),
118
+ contextWindow: maxTokens || 2000,
119
+ priorityWeights: {
120
+ recency: 0.4,
121
+ relevance: 0.5,
122
+ frequency: 0.1,
123
+ ...options?.priorityWeights
124
+ },
125
+ ...options
126
+ };
127
+ return await this.provider.retrieveContext(query);
128
+ }
129
+ /**
130
+ * Promote memory to higher tier
131
+ */
132
+ async promote(itemId, newTier) {
133
+ if (!this.provider) {
134
+ throw new Error('Memory manager not initialized');
135
+ }
136
+ // Check if new tier is enabled
137
+ if (!this.config.tiers[newTier]) {
138
+ console.warn(`Cannot promote to disabled tier ${newTier}`);
139
+ return false;
140
+ }
141
+ return await this.provider.update(itemId, {
142
+ tier: newTier,
143
+ ttl: this.config.ttlMinutes?.[newTier]
144
+ });
145
+ }
146
+ /**
147
+ * Clean up expired memories
148
+ */
149
+ async cleanup() {
150
+ if (!this.provider) {
151
+ throw new Error('Memory manager not initialized');
152
+ }
153
+ return await this.provider.cleanup();
154
+ }
155
+ /**
156
+ * Get memory metrics
157
+ */
158
+ async getMetrics() {
159
+ if (!this.provider) {
160
+ throw new Error('Memory manager not initialized');
161
+ }
162
+ return await this.provider.getMetrics();
163
+ }
164
+ /**
165
+ * Semantic search across memories
166
+ */
167
+ async search(text, limit) {
168
+ if (!this.provider) {
169
+ throw new Error('Memory manager not initialized');
170
+ }
171
+ // Use semantic search if available
172
+ if (this.provider.semanticSearch) {
173
+ return await this.provider.semanticSearch(text, limit);
174
+ }
175
+ // Fall back to text-based search
176
+ return await this.retrieve({ text, limit });
177
+ }
178
+ /**
179
+ * Export all memories
180
+ */
181
+ async export() {
182
+ if (!this.provider) {
183
+ throw new Error('Memory manager not initialized');
184
+ }
185
+ return await this.provider.export();
186
+ }
187
+ /**
188
+ * Import memories
189
+ */
190
+ async import(items) {
191
+ if (!this.provider) {
192
+ throw new Error('Memory manager not initialized');
193
+ }
194
+ return await this.provider.import(items);
195
+ }
196
+ /**
197
+ * Set context (project, user, team)
198
+ */
199
+ setContext(context) {
200
+ if (context.projectId)
201
+ this.projectId = context.projectId;
202
+ if (context.userId)
203
+ this.userId = context.userId;
204
+ if (context.teamId)
205
+ this.teamId = context.teamId;
206
+ }
207
+ /**
208
+ * Start a new session
209
+ */
210
+ newSession() {
211
+ this.sessionId = this.generateSessionId();
212
+ return this.sessionId;
213
+ }
214
+ /**
215
+ * Close and cleanup
216
+ */
217
+ async close() {
218
+ // Clear cleanup intervals
219
+ this.cleanupIntervals.forEach(interval => clearInterval(interval));
220
+ this.cleanupIntervals.clear();
221
+ // Close provider
222
+ if (this.provider) {
223
+ await this.provider.close();
224
+ this.provider = null;
225
+ }
226
+ }
227
+ /**
228
+ * Private helper methods
229
+ */
230
+ async createProvider() {
231
+ switch (this.config.provider) {
232
+ case 'mem0':
233
+ if (!this.config.mem0) {
234
+ console.error('Mem0 configuration missing');
235
+ return null;
236
+ }
237
+ try {
238
+ const provider = new Mem0Provider(this.config.mem0);
239
+ await provider.initialize();
240
+ return provider;
241
+ }
242
+ catch (error) {
243
+ console.error('Failed to create Mem0 provider:', error);
244
+ return null;
245
+ }
246
+ case 'devlog':
247
+ // TODO: Implement DevLog provider
248
+ console.warn('DevLog provider not yet implemented');
249
+ return null;
250
+ case 'local':
251
+ return await this.createLocalProvider();
252
+ case 'hybrid':
253
+ // TODO: Implement Hybrid provider
254
+ console.warn('Hybrid provider not yet implemented');
255
+ return null;
256
+ case 'none':
257
+ return null;
258
+ default:
259
+ console.warn(`Unknown provider: ${this.config.provider}`);
260
+ return null;
261
+ }
262
+ }
263
+ async createLocalProvider() {
264
+ const provider = new LocalProvider(this.config.local || {
265
+ storageType: 'json',
266
+ path: './.focus-memory',
267
+ maxSizeMB: 100
268
+ });
269
+ await provider.initialize();
270
+ return provider;
271
+ }
272
+ inferTier(content, metadata) {
273
+ // Infer based on content and metadata
274
+ if (metadata?.tier)
275
+ return metadata.tier;
276
+ // Default heuristics
277
+ const contentLength = content.length;
278
+ const hasCode = /```[\s\S]*?```/.test(content);
279
+ const hasImportantKeywords = /critical|important|remember|always|never/i.test(content);
280
+ if (hasImportantKeywords && this.config.tiers.project) {
281
+ return 'project';
282
+ }
283
+ if (hasCode && this.config.tiers.working) {
284
+ return 'working';
285
+ }
286
+ if (contentLength > 500 && this.config.tiers.working) {
287
+ return 'working';
288
+ }
289
+ return 'session';
290
+ }
291
+ getNextAvailableTier(tier) {
292
+ const tierOrder = ['session', 'working', 'project', 'team', 'global'];
293
+ const currentIndex = tierOrder.indexOf(tier);
294
+ for (let i = currentIndex + 1; i < tierOrder.length; i++) {
295
+ if (this.config.tiers[tierOrder[i]]) {
296
+ return tierOrder[i];
297
+ }
298
+ }
299
+ // Try lower tiers
300
+ for (let i = currentIndex - 1; i >= 0; i--) {
301
+ if (this.config.tiers[tierOrder[i]]) {
302
+ return tierOrder[i];
303
+ }
304
+ }
305
+ return null;
306
+ }
307
+ getEnabledTiers() {
308
+ const tiers = [];
309
+ const allTiers = ['session', 'working', 'project', 'team', 'global'];
310
+ allTiers.forEach(tier => {
311
+ if (this.config.tiers[tier]) {
312
+ tiers.push(tier);
313
+ }
314
+ });
315
+ return tiers;
316
+ }
317
+ setupAutoCleanup() {
318
+ const tiers = ['session', 'working', 'project', 'team', 'global'];
319
+ tiers.forEach(tier => {
320
+ if (this.config.tiers[tier] && this.config.ttlMinutes?.[tier]) {
321
+ const ttl = this.config.ttlMinutes[tier];
322
+ if (ttl > 0) {
323
+ // Run cleanup at 1/4 of TTL interval
324
+ const interval = Math.max(60000, (ttl * 60 * 1000) / 4); // Min 1 minute
325
+ const intervalId = setInterval(async () => {
326
+ try {
327
+ await this.cleanupTier(tier);
328
+ }
329
+ catch (error) {
330
+ console.error(`Failed to cleanup ${tier} tier:`, error);
331
+ }
332
+ }, interval);
333
+ this.cleanupIntervals.set(tier, intervalId);
334
+ }
335
+ }
336
+ });
337
+ }
338
+ async cleanupTier(tier) {
339
+ if (!this.provider)
340
+ return;
341
+ const ttl = this.config.ttlMinutes?.[tier];
342
+ if (!ttl || ttl <= 0)
343
+ return;
344
+ const cutoffDate = new Date(Date.now() - (ttl * 60 * 1000));
345
+ const query = {
346
+ tiers: [tier],
347
+ endDate: cutoffDate
348
+ };
349
+ const deleted = await this.provider.deleteMany(query);
350
+ if (deleted > 0) {
351
+ console.error(`🗑️ Cleaned up ${deleted} expired ${tier} memories`);
352
+ }
353
+ }
354
+ generateId() {
355
+ return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
356
+ }
357
+ generateSessionId() {
358
+ return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
359
+ }
360
+ }
361
+ /**
362
+ * Singleton instance
363
+ */
364
+ let memoryManager = null;
365
+ /**
366
+ * Get or create memory manager instance
367
+ */
368
+ export async function getMemoryManager(config) {
369
+ if (!memoryManager) {
370
+ memoryManager = new HierarchicalMemoryManager(config);
371
+ await memoryManager.initialize();
372
+ }
373
+ return memoryManager;
374
+ }
375
+ /**
376
+ * Reset memory manager (useful for testing)
377
+ */
378
+ export async function resetMemoryManager() {
379
+ if (memoryManager) {
380
+ await memoryManager.close();
381
+ memoryManager = null;
382
+ }
383
+ }