tlc-claude-code 2.9.2 → 2.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/server/index.js CHANGED
@@ -23,9 +23,9 @@ const { parsePlan, parseBugs } = require('./lib/plan-parser');
23
23
  const { autoProvision, stopDatabase } = require('./lib/auto-database');
24
24
  const { GlobalConfig } = require('./lib/global-config');
25
25
  const { ProjectScanner } = require('./lib/project-scanner');
26
- const { createWorkspaceRouter } = require('./lib/workspace-api');
27
- const { createMemoryApi } = require('./lib/memory-api');
28
- const { createMemoryStoreAdapter } = require('./lib/memory-store-adapter');
26
+ const { createWorkspaceRouter } = require('./lib/workspace-api');
27
+ const { createMemoryApi } = require('./lib/memory-api');
28
+ const { createMemoryStoreAdapter } = require('./lib/memory-store-adapter');
29
29
  const {
30
30
  createUserStore,
31
31
  createAuthMiddleware,
@@ -86,12 +86,11 @@ const cors = require('cors');
86
86
  app.use(cors({ origin: true, credentials: true }));
87
87
 
88
88
  // Workspace API
89
- const globalConfig = new GlobalConfig();
90
- const projectScanner = new ProjectScanner();
91
- const { observeAndRemember } = require('./lib/memory-observer');
92
- const { createServerMemoryCapture } = require('./lib/memory-hooks');
93
- const { createMemoryStoreAdapter } = require('./lib/memory-store-adapter');
94
- const { checkOllamaHealth } = require('./lib/ollama-health');
89
+ const globalConfig = new GlobalConfig();
90
+ const projectScanner = new ProjectScanner();
91
+ const { observeAndRemember } = require('./lib/memory-observer');
92
+ const { createServerMemoryCapture } = require('./lib/memory-hooks');
93
+ const { checkOllamaHealth } = require('./lib/ollama-health');
95
94
 
96
95
  // Initialize memory directory structure (non-blocking)
97
96
  (async () => {
@@ -110,72 +109,103 @@ const memoryCapture = createServerMemoryCapture({
110
109
  });
111
110
 
112
111
  // Lazy-initialized memory dependencies (ESM modules loaded async)
113
- const memoryDeps = {
114
- observeAndRemember,
115
- semanticRecall: null,
116
- vectorIndexer: null,
117
- embeddingClient: null,
118
- vectorStore: null,
119
- };
112
+ const memoryDeps = {
113
+ observeAndRemember,
114
+ contextEngine: null,
115
+ contextSearch: null,
116
+ semanticRecall: null,
117
+ vectorIndexer: null,
118
+ };
120
119
 
121
120
  // Lazy init: load ESM memory modules on first use
122
121
  let memoryInitPromise = null;
123
- async function initMemoryPipeline() {
124
- if (memoryInitPromise) return memoryInitPromise;
125
- memoryInitPromise = (async () => {
126
- try {
127
- const os = require('os');
128
- const dbPath = path.join(os.homedir(), '.tlc', 'memory', 'vectors.db');
129
-
130
- // Ensure directory exists
131
- const dbDir = path.dirname(dbPath);
132
- if (!fs.existsSync(dbDir)) {
133
- fs.mkdirSync(dbDir, { recursive: true });
134
- }
135
-
136
- const { createEmbeddingClient } = await import('./lib/embedding-client.js');
137
- const { createVectorStore } = await import('./lib/vector-store.js');
138
- const { createVectorIndexer } = await import('./lib/vector-indexer.js');
139
- const { createSemanticRecall } = await import('./lib/semantic-recall.js');
140
-
141
- memoryDeps.embeddingClient = createEmbeddingClient();
142
- memoryDeps.vectorStore = await createVectorStore({ dbPath });
143
- memoryDeps.vectorIndexer = createVectorIndexer({
144
- vectorStore: memoryDeps.vectorStore,
145
- embeddingClient: memoryDeps.embeddingClient,
146
- });
147
- memoryDeps.semanticRecall = createSemanticRecall({
148
- vectorStore: memoryDeps.vectorStore,
149
- embeddingClient: memoryDeps.embeddingClient,
150
- });
151
-
152
- console.log('[TLC] Memory pipeline initialized (vector store at', dbPath + ')');
153
- } catch (err) {
154
- console.warn('[TLC] Memory pipeline unavailable:', err.message);
155
- // Non-fatal: server works without vector store
156
- }
157
- })();
122
+ async function initMemoryPipeline() {
123
+ if (memoryInitPromise) return memoryInitPromise;
124
+ memoryInitPromise = (async () => {
125
+ try {
126
+ const dbPath = path.join(PROJECT_DIR, '.tlc', 'context.sqlite');
127
+
128
+ // Ensure directory exists
129
+ const dbDir = path.dirname(dbPath);
130
+ if (!fs.existsSync(dbDir)) {
131
+ fs.mkdirSync(dbDir, { recursive: true });
132
+ }
133
+
134
+ const [{ createContextEngine }, { createSearchPipeline }, { createSearch }, { indexProject }] = await Promise.all([
135
+ import('@tlc/context-engine'),
136
+ import('@tlc/context-engine/search-pipeline'),
137
+ import('@tlc/context-engine/retrieval/search'),
138
+ import('@tlc/context-engine/retrieval/indexer'),
139
+ ]);
140
+
141
+ const contextEngine = createContextEngine({ dbPath });
142
+ const search = createSearch({
143
+ embeddingStore: {
144
+ findSimilar(db, queryVec, options) {
145
+ return contextEngine.embeddings.findSimilar(queryVec, options);
146
+ },
147
+ },
148
+ });
149
+ const searchPipeline = createSearchPipeline({
150
+ search: (db, query, options = {}) => search(db, query, options),
151
+ });
152
+
153
+ memoryDeps.contextEngine = contextEngine;
154
+ memoryDeps.contextSearch = searchPipeline;
155
+ memoryDeps.vectorIndexer = {
156
+ indexAll: async (projectRoot) => indexProject(contextEngine.db, projectRoot),
157
+ };
158
+ memoryDeps.semanticRecall = {
159
+ recall: async (query, _context = {}, options = {}) => {
160
+ const scope = options.scope ? [options.scope] : undefined;
161
+ const results = await searchPipeline(contextEngine.db, query, {
162
+ limit: options.limit,
163
+ scopes: scope,
164
+ queryVec: options.queryVec ?? null,
165
+ });
166
+
167
+ return results.map((result) => ({
168
+ id: result.uri,
169
+ uri: result.uri,
170
+ text: result.body || result.title || '',
171
+ title: result.title || result.uri,
172
+ body: result.body || '',
173
+ score: Number.isFinite(result.score) ? result.score : 0,
174
+ type: result.source === 'context' ? 'context' : 'codedb',
175
+ source: {
176
+ sourceFile: result.uri,
177
+ provider: result.source,
178
+ },
179
+ sourceFile: result.uri,
180
+ permanent: false,
181
+ }));
182
+ },
183
+ };
184
+
185
+ console.log('[TLC] Memory pipeline initialized (context engine at', dbPath + ')');
186
+ } catch (err) {
187
+ console.warn('[TLC] Memory pipeline unavailable:', err.message);
188
+ // Non-fatal: server works without vector store
189
+ }
190
+ })();
158
191
  return memoryInitPromise;
159
192
  }
160
193
 
161
194
  // Start memory init in background (non-blocking)
162
195
  initMemoryPipeline();
163
196
 
164
- const memoryApi = createMemoryApi({
165
- semanticRecall: { recall: async (...args) => {
166
- await initMemoryPipeline();
167
- return memoryDeps.semanticRecall ? memoryDeps.semanticRecall.recall(...args) : [];
168
- }},
169
- vectorIndexer: { indexAll: async (...args) => {
170
- await initMemoryPipeline();
171
- return memoryDeps.vectorIndexer ? memoryDeps.vectorIndexer.indexAll(...args) : { indexed: 0 };
172
- }},
173
- richCapture: { processChunk: async () => ({ stored: false }) },
174
- embeddingClient: { embed: async (...args) => {
175
- await initMemoryPipeline();
176
- return memoryDeps.embeddingClient ? memoryDeps.embeddingClient.embed(...args) : [];
177
- }},
178
- memoryStore: (() => {
197
+ const memoryApi = createMemoryApi({
198
+ semanticRecall: { recall: async (...args) => {
199
+ await initMemoryPipeline();
200
+ return memoryDeps.semanticRecall ? memoryDeps.semanticRecall.recall(...args) : [];
201
+ }},
202
+ vectorIndexer: { indexAll: async (...args) => {
203
+ await initMemoryPipeline();
204
+ return memoryDeps.vectorIndexer ? memoryDeps.vectorIndexer.indexAll(...args) : { indexed: 0 };
205
+ }},
206
+ richCapture: { processChunk: async () => ({ stored: false }) },
207
+ embeddingClient: { embed: async () => [] },
208
+ memoryStore: (() => {
179
209
  const adapter = createMemoryStoreAdapter(PROJECT_DIR);
180
210
  return {
181
211
  listConversations: async () => ({ items: [], total: 0 }), // TODO Phase 74: rich conversation capture
@@ -10,6 +10,7 @@
10
10
  "dependencies": {
11
11
  "@electric-sql/pglite": "^0.3.15",
12
12
  "@electric-sql/pglite-socket": "^0.0.20",
13
+ "@tlc/context-engine": "file:../../tlc-context-engine",
13
14
  "better-sqlite3": "^12.6.2",
14
15
  "chokidar": "^3.5.3",
15
16
  "cookie-parser": "^1.4.7",
@@ -22,6 +23,7 @@
22
23
  "sqlite-vec": "^0.1.7-alpha.2",
23
24
  "ssh2": "^1.17.0",
24
25
  "sudo-prompt": "^9.2.1",
26
+ "tlc-context-engine": "^0.1.0",
25
27
  "typescript": "^5.9.3",
26
28
  "ws": "^8.14.2"
27
29
  },
@@ -33,6 +35,17 @@
33
35
  "vitest": "^4.0.18"
34
36
  }
35
37
  },
38
+ "../../tlc-context-engine": {
39
+ "version": "0.1.0",
40
+ "license": "MIT",
41
+ "devDependencies": {
42
+ "better-sqlite3": "^11.9.1",
43
+ "vitest": "^3.2.4"
44
+ },
45
+ "peerDependencies": {
46
+ "better-sqlite3": ">=11.0.0"
47
+ }
48
+ },
36
49
  "node_modules/@balena/dockerignore": {
37
50
  "version": "1.0.2",
38
51
  "resolved": "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz",
@@ -1009,6 +1022,10 @@
1009
1022
  "dev": true,
1010
1023
  "license": "MIT"
1011
1024
  },
1025
+ "node_modules/@tlc/context-engine": {
1026
+ "resolved": "../../tlc-context-engine",
1027
+ "link": true
1028
+ },
1012
1029
  "node_modules/@types/chai": {
1013
1030
  "version": "5.2.3",
1014
1031
  "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz",
@@ -3714,6 +3731,15 @@
3714
3731
  "node": ">=14.0.0"
3715
3732
  }
3716
3733
  },
3734
+ "node_modules/tlc-context-engine": {
3735
+ "version": "0.1.0",
3736
+ "resolved": "https://registry.npmjs.org/tlc-context-engine/-/tlc-context-engine-0.1.0.tgz",
3737
+ "integrity": "sha512-OhLcPBmHuAYSv3XniJPnGcyDB2RaBi8wk/TsWQAaokkX7NkYhDFWWCrVsOqHTSKNMVf1M+xx+gvUFib5qaUCXA==",
3738
+ "license": "MIT",
3739
+ "peerDependencies": {
3740
+ "better-sqlite3": ">=11.0.0"
3741
+ }
3742
+ },
3717
3743
  "node_modules/to-regex-range": {
3718
3744
  "version": "5.0.1",
3719
3745
  "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -27,6 +27,7 @@
27
27
  "sqlite-vec": "^0.1.7-alpha.2",
28
28
  "ssh2": "^1.17.0",
29
29
  "sudo-prompt": "^9.2.1",
30
+ "tlc-context-engine": "^0.1.0",
30
31
  "typescript": "^5.9.3",
31
32
  "ws": "^8.14.2"
32
33
  },