@phren/cli 0.0.28 → 0.0.32
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/mcp/dist/capabilities/cli.js +2 -5
- package/mcp/dist/capabilities/mcp.js +5 -8
- package/mcp/dist/capabilities/types.js +2 -5
- package/mcp/dist/capabilities/vscode.js +2 -5
- package/mcp/dist/capabilities/web-ui.js +2 -5
- package/mcp/dist/{cli-actions.js → cli/actions.js} +22 -21
- package/mcp/dist/{cli.js → cli/cli.js} +13 -13
- package/mcp/dist/{cli-config.js → cli/config.js} +9 -9
- package/mcp/dist/{cli-extract.js → cli/extract.js} +8 -8
- package/mcp/dist/{cli-govern.js → cli/govern.js} +10 -9
- package/mcp/dist/{cli-graph.js → cli/graph.js} +10 -9
- package/mcp/dist/{cli-hooks-citations.js → cli/hooks-citations.js} +2 -2
- package/mcp/dist/{cli-hooks-context.js → cli/hooks-context.js} +23 -23
- package/mcp/dist/{cli-hooks-globs.js → cli/hooks-globs.js} +4 -4
- package/mcp/dist/{cli-hooks-output.js → cli/hooks-output.js} +9 -10
- package/mcp/dist/{cli-hooks-session.js → cli/hooks-session.js} +42 -57
- package/mcp/dist/{cli-hooks.js → cli/hooks.js} +27 -26
- package/mcp/dist/{cli-namespaces.js → cli/namespaces.js} +25 -24
- package/mcp/dist/{cli-ops.js → cli/ops.js} +9 -9
- package/mcp/dist/{cli-search.js → cli/search.js} +8 -7
- package/mcp/dist/cli-hooks-git.js +243 -0
- package/mcp/dist/cli-hooks-prompt.js +319 -0
- package/mcp/dist/cli-hooks-session-handlers.js +349 -0
- package/mcp/dist/cli-hooks-stop.js +557 -0
- package/mcp/dist/{content-archive.js → content/archive.js} +8 -9
- package/mcp/dist/{content-citation.js → content/citation.js} +5 -5
- package/mcp/dist/{content-dedup.js → content/dedup.js} +9 -12
- package/mcp/dist/{content-learning.js → content/learning.js} +12 -12
- package/mcp/dist/{content-validate.js → content/validate.js} +5 -5
- package/mcp/dist/{core-finding.js → core/finding.js} +4 -4
- package/mcp/dist/{core-project.js → core/project.js} +4 -4
- package/mcp/dist/{core-search.js → core/search.js} +2 -2
- package/mcp/dist/{data-access.js → data/access.js} +131 -13
- package/mcp/dist/{data-tasks.js → data/tasks.js} +7 -5
- package/mcp/dist/embedding.js +9 -14
- package/mcp/dist/entrypoint.js +11 -11
- package/mcp/dist/{finding-context.js → finding/context.js} +2 -2
- package/mcp/dist/{finding-impact.js → finding/impact.js} +3 -3
- package/mcp/dist/{finding-journal.js → finding/journal.js} +4 -4
- package/mcp/dist/{finding-lifecycle.js → finding/lifecycle.js} +4 -4
- package/mcp/dist/{governance-audit.js → governance/audit.js} +2 -2
- package/mcp/dist/{governance-locks.js → governance/locks.js} +14 -9
- package/mcp/dist/{governance-policy.js → governance/policy.js} +10 -12
- package/mcp/dist/{governance-rbac.js → governance/rbac.js} +3 -3
- package/mcp/dist/{governance-scores.js → governance/scores.js} +8 -10
- package/mcp/dist/hooks.js +39 -31
- package/mcp/dist/index-query.js +4 -1
- package/mcp/dist/index.js +53 -29
- package/mcp/dist/{init-config.js → init/config.js} +6 -6
- package/mcp/dist/{init.js → init/init.js} +28 -29
- package/mcp/dist/{init-preferences.js → init/preferences.js} +3 -3
- package/mcp/dist/{init-setup.js → init/setup.js} +17 -19
- package/mcp/dist/{init-shared.js → init/shared.js} +3 -3
- package/mcp/dist/init-bootstrap.js +68 -0
- package/mcp/dist/init-detect.js +38 -0
- package/mcp/dist/init-dryrun.js +55 -0
- package/mcp/dist/init-env.js +114 -0
- package/mcp/dist/init-fresh.js +239 -0
- package/mcp/dist/init-hooks.js +26 -0
- package/mcp/dist/init-mcp.js +65 -0
- package/mcp/dist/init-migrate.js +51 -0
- package/mcp/dist/init-modes.js +135 -0
- package/mcp/dist/init-npm.js +37 -0
- package/mcp/dist/init-project-local.js +99 -0
- package/mcp/dist/init-semantic.js +48 -0
- package/mcp/dist/init-types.js +1 -0
- package/mcp/dist/init-uninstall.js +482 -0
- package/mcp/dist/init-update.js +96 -0
- package/mcp/dist/init-walkthrough-merge.js +90 -0
- package/mcp/dist/init-walkthrough.js +529 -0
- package/mcp/dist/{link-checksums.js → link/checksums.js} +5 -5
- package/mcp/dist/{link-context.js → link/context.js} +4 -4
- package/mcp/dist/{link-doctor.js → link/doctor.js} +20 -22
- package/mcp/dist/{link.js → link/link.js} +26 -31
- package/mcp/dist/{link-skills.js → link/skills.js} +10 -10
- package/mcp/dist/logger.js +11 -3
- package/mcp/dist/phren-art.js +0 -6
- package/mcp/dist/phren-paths.js +30 -12
- package/mcp/dist/proactivity.js +2 -2
- package/mcp/dist/profile-store.js +5 -6
- package/mcp/dist/project-config.js +2 -2
- package/mcp/dist/project-topics.js +1 -1
- package/mcp/dist/query-correlation.js +1 -1
- package/mcp/dist/{session-checkpoints.js → session/checkpoints.js} +3 -3
- package/mcp/dist/{session-utils.js → session/utils.js} +1 -1
- package/mcp/dist/{shared-content.js → shared/content.js} +7 -7
- package/mcp/dist/{shared-data-utils.js → shared/data-utils.js} +3 -3
- package/mcp/dist/{shared-embedding-cache.js → shared/embedding-cache.js} +3 -3
- package/mcp/dist/{shared-fragment-graph.js → shared/fragment-graph.js} +15 -24
- package/mcp/dist/shared/governance.js +4 -0
- package/mcp/dist/{shared-index.js → shared/index.js} +92 -123
- package/mcp/dist/{shared-ollama.js → shared/ollama.js} +2 -2
- package/mcp/dist/{shared-retrieval.js → shared/retrieval.js} +16 -21
- package/mcp/dist/{shared-search-fallback.js → shared/search-fallback.js} +17 -20
- package/mcp/dist/{shared-sqljs.js → shared/sqljs.js} +3 -3
- package/mcp/dist/{shared-vector-index.js → shared/vector-index.js} +3 -3
- package/mcp/dist/shared.js +4 -59
- package/mcp/dist/{shell-entry.js → shell/entry.js} +6 -6
- package/mcp/dist/{shell-input.js → shell/input.js} +13 -13
- package/mcp/dist/{shell-palette.js → shell/palette.js} +3 -3
- package/mcp/dist/{shell-render.js → shell/render.js} +1 -1
- package/mcp/dist/{shell.js → shell/shell.js} +11 -11
- package/mcp/dist/{shell-state-store.js → shell/state-store.js} +5 -5
- package/mcp/dist/{shell-view-list.js → shell/view-list.js} +1 -1
- package/mcp/dist/{shell-view.js → shell/view.js} +13 -13
- package/mcp/dist/{skill-files.js → skill/files.js} +9 -9
- package/mcp/dist/{skill-registry.js → skill/registry.js} +4 -4
- package/mcp/dist/{skill-state.js → skill/state.js} +1 -1
- package/mcp/dist/startup-embedding.js +2 -2
- package/mcp/dist/status.js +15 -14
- package/mcp/dist/{tasks-github.js → task/github.js} +2 -2
- package/mcp/dist/{task-hygiene.js → task/hygiene.js} +4 -4
- package/mcp/dist/{task-lifecycle.js → task/lifecycle.js} +7 -7
- package/mcp/dist/telemetry.js +3 -4
- package/mcp/dist/tool-registry.js +29 -17
- package/mcp/dist/tools/config.js +515 -0
- package/mcp/dist/{mcp-data.js → tools/data.js} +8 -10
- package/mcp/dist/{mcp-extract-facts.js → tools/extract-facts.js} +6 -6
- package/mcp/dist/{mcp-extract.js → tools/extract.js} +6 -6
- package/mcp/dist/{mcp-finding.js → tools/finding.js} +97 -124
- package/mcp/dist/{mcp-graph.js → tools/graph.js} +11 -14
- package/mcp/dist/{mcp-hooks.js → tools/hooks.js} +6 -6
- package/mcp/dist/{mcp-memory.js → tools/memory.js} +5 -5
- package/mcp/dist/{mcp-ops.js → tools/ops.js} +169 -71
- package/mcp/dist/{mcp-search.js → tools/search.js} +19 -23
- package/mcp/dist/{mcp-session.js → tools/session.js} +48 -23
- package/mcp/dist/{mcp-skills.js → tools/skills.js} +33 -35
- package/mcp/dist/{mcp-tasks.js → tools/tasks.js} +155 -282
- package/mcp/dist/{memory-ui-data.js → ui/data.js} +31 -17
- package/mcp/dist/{memory-ui.js → ui/memory-ui.js} +3 -3
- package/mcp/dist/{memory-ui-page.js → ui/page.js} +4 -6
- package/mcp/dist/{memory-ui-server.js → ui/server.js} +30 -22
- package/mcp/dist/update.js +2 -2
- package/mcp/dist/utils.js +51 -11
- package/package.json +2 -2
- package/scripts/preuninstall.mjs +31 -0
- package/starter/global/CLAUDE.md +3 -2
- package/mcp/dist/mcp-config.js +0 -551
- package/mcp/dist/shared-governance.js +0 -4
- /package/mcp/dist/{content-metadata.js → content/metadata.js} +0 -0
- /package/mcp/dist/{shared-stemmer.js → shared/stemmer.js} +0 -0
- /package/mcp/dist/{shell-types.js → shell/types.js} +0 -0
- /package/mcp/dist/{mcp-types.js → tools/types.js} +0 -0
- /package/mcp/dist/{memory-ui-assets.js → ui/assets.js} +0 -0
- /package/mcp/dist/{memory-ui-graph.js → ui/graph.js} +0 -0
- /package/mcp/dist/{memory-ui-scripts.js → ui/scripts.js} +0 -0
- /package/mcp/dist/{memory-ui-styles.js → ui/styles.js} +0 -0
|
@@ -3,21 +3,22 @@ import * as path from "path";
|
|
|
3
3
|
import * as os from "os";
|
|
4
4
|
import * as crypto from "crypto";
|
|
5
5
|
import { globSync } from "glob";
|
|
6
|
-
import { debugLog, appendIndexEvent, getProjectDirs, collectNativeMemoryFiles, runtimeFile, homeDir, readRootManifest, } from "
|
|
7
|
-
import { getIndexPolicy, withFileLock } from "./
|
|
8
|
-
import { stripTaskDoneSection } from "./
|
|
9
|
-
import { isInactiveFindingLine } from "
|
|
10
|
-
import { invalidateDfCache } from "./
|
|
11
|
-
import { errorMessage } from "
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
export {
|
|
19
|
-
export {
|
|
20
|
-
export {
|
|
6
|
+
import { debugLog, appendIndexEvent, getProjectDirs, collectNativeMemoryFiles, runtimeFile, homeDir, readRootManifest, } from "../shared.js";
|
|
7
|
+
import { getIndexPolicy, withFileLock } from "./governance.js";
|
|
8
|
+
import { stripTaskDoneSection } from "./content.js";
|
|
9
|
+
import { isInactiveFindingLine } from "../finding/lifecycle.js";
|
|
10
|
+
import { invalidateDfCache } from "./search-fallback.js";
|
|
11
|
+
import { errorMessage } from "../utils.js";
|
|
12
|
+
import { logger } from "../logger.js";
|
|
13
|
+
import { beginUserFragmentBuildCache, endUserFragmentBuildCache, extractAndLinkFragments, ensureGlobalEntitiesTable, } from "./fragment-graph.js";
|
|
14
|
+
import { bootstrapSqlJs } from "./sqljs.js";
|
|
15
|
+
import { getProjectOwnershipMode, getProjectSourcePath, readProjectConfig } from "../project-config.js";
|
|
16
|
+
import { buildSourceDocKey, queryDocBySourceKey, queryDocRows, } from "../index-query.js";
|
|
17
|
+
import { classifyTopicForText, readProjectTopics, } from "../project-topics.js";
|
|
18
|
+
export { porterStem } from "./stemmer.js";
|
|
19
|
+
export { cosineFallback } from "./search-fallback.js";
|
|
20
|
+
export { queryFragmentLinks, queryFragmentLinks as queryEntityLinks, getFragmentBoostDocs, getFragmentBoostDocs as getEntityBoostDocs, ensureGlobalEntitiesTable, queryCrossProjectFragments, logFragmentMiss, logFragmentMiss as logEntityMiss, extractFragmentNames, extractFragmentNames as extractEntityNames, } from "./fragment-graph.js";
|
|
21
|
+
export { buildSourceDocKey, decodeFiniteNumber, decodeStringRow, extractSnippet, getDocSourceKey, normalizeMemoryId, queryDocBySourceKey, queryDocRows, queryRows, rowToDoc, rowToDocWithRowid, } from "../index-query.js";
|
|
21
22
|
// ── Async embedding queue ───────────────────────────────────────────────────
|
|
22
23
|
const _embQueue = new Map();
|
|
23
24
|
let _embTimer = null;
|
|
@@ -32,8 +33,8 @@ function scheduleEmbedding(phrenPath, docPath, content) {
|
|
|
32
33
|
async function _drainEmbQueue() {
|
|
33
34
|
if (_embQueue.size === 0)
|
|
34
35
|
return;
|
|
35
|
-
const { embedText, getEmbeddingModel } = await import("./
|
|
36
|
-
const { getEmbeddingCache } = await import("./
|
|
36
|
+
const { embedText, getEmbeddingModel } = await import("./ollama.js");
|
|
37
|
+
const { getEmbeddingCache } = await import("./embedding-cache.js");
|
|
37
38
|
const entries = [..._embQueue.entries()];
|
|
38
39
|
_embQueue.clear();
|
|
39
40
|
// Group by phrenPath so we flush each cache once after all its entries are set.
|
|
@@ -49,8 +50,7 @@ async function _drainEmbQueue() {
|
|
|
49
50
|
await cache.load();
|
|
50
51
|
}
|
|
51
52
|
catch (err) {
|
|
52
|
-
|
|
53
|
-
process.stderr.write(`[phren] embeddingQueue cacheLoad: ${errorMessage(err)}\n`);
|
|
53
|
+
logger.debug("embeddingQueue cacheLoad", errorMessage(err));
|
|
54
54
|
}
|
|
55
55
|
const model = getEmbeddingModel();
|
|
56
56
|
for (const { docPath, content } of docs) {
|
|
@@ -62,16 +62,14 @@ async function _drainEmbQueue() {
|
|
|
62
62
|
cache.set(docPath, getEmbeddingModel(), vec);
|
|
63
63
|
}
|
|
64
64
|
catch (err) {
|
|
65
|
-
|
|
66
|
-
process.stderr.write(`[phren] embeddingQueue embedText: ${errorMessage(err)}\n`);
|
|
65
|
+
logger.debug("embeddingQueue embedText", errorMessage(err));
|
|
67
66
|
}
|
|
68
67
|
}
|
|
69
68
|
try {
|
|
70
69
|
await cache.flush();
|
|
71
70
|
}
|
|
72
71
|
catch (err) {
|
|
73
|
-
|
|
74
|
-
process.stderr.write(`[phren] embeddingQueue cacheFlush: ${errorMessage(err)}\n`);
|
|
72
|
+
logger.debug("embeddingQueue cacheFlush", errorMessage(err));
|
|
75
73
|
}
|
|
76
74
|
}
|
|
77
75
|
}
|
|
@@ -133,8 +131,7 @@ function _resolveImportsRecursive(content, phrenPath, seen, depth) {
|
|
|
133
131
|
normalized = fs.realpathSync.native(resolved);
|
|
134
132
|
}
|
|
135
133
|
catch (err) {
|
|
136
|
-
|
|
137
|
-
process.stderr.write(`[phren] resolveImports realpath: ${errorMessage(err)}\n`);
|
|
134
|
+
logger.debug("resolveImports realpath", errorMessage(err));
|
|
138
135
|
return `<!-- @import not found: ${trimmed} -->`;
|
|
139
136
|
}
|
|
140
137
|
let normalizedGlobalRoot = globalRoot;
|
|
@@ -158,8 +155,7 @@ function _resolveImportsRecursive(content, phrenPath, seen, depth) {
|
|
|
158
155
|
return _resolveImportsRecursive(imported, phrenPath, childSeen, depth + 1);
|
|
159
156
|
}
|
|
160
157
|
catch (err) {
|
|
161
|
-
|
|
162
|
-
process.stderr.write(`[phren] resolveImports fileRead: ${errorMessage(err)}\n`);
|
|
158
|
+
logger.debug("resolveImports fileRead", errorMessage(err));
|
|
163
159
|
return `<!-- @import error: ${trimmed} -->`;
|
|
164
160
|
}
|
|
165
161
|
});
|
|
@@ -180,8 +176,7 @@ function touchSentinel(phrenPath) {
|
|
|
180
176
|
fs.writeFileSync(sentinelPath, Date.now().toString());
|
|
181
177
|
}
|
|
182
178
|
catch (err) {
|
|
183
|
-
|
|
184
|
-
process.stderr.write(`[phren] touchSentinel: ${errorMessage(err)}\n`);
|
|
179
|
+
logger.debug("touchSentinel", errorMessage(err));
|
|
185
180
|
}
|
|
186
181
|
}
|
|
187
182
|
function computePhrenHash(phrenPath, profile, preGlobbed) {
|
|
@@ -197,8 +192,7 @@ function computePhrenHash(phrenPath, profile, preGlobbed) {
|
|
|
197
192
|
hash.update(`${f}:${stat.mtimeMs}:${stat.size}`);
|
|
198
193
|
}
|
|
199
194
|
catch (err) {
|
|
200
|
-
|
|
201
|
-
process.stderr.write(`[phren] computePhrenHash skip: ${errorMessage(err)}\n`);
|
|
195
|
+
logger.debug("computePhrenHash skip", errorMessage(err));
|
|
202
196
|
}
|
|
203
197
|
}
|
|
204
198
|
for (const configPath of topicConfigEntries) {
|
|
@@ -207,8 +201,7 @@ function computePhrenHash(phrenPath, profile, preGlobbed) {
|
|
|
207
201
|
hash.update(`topic-config:${configPath}:${stat.mtimeMs}:${stat.size}`);
|
|
208
202
|
}
|
|
209
203
|
catch (err) {
|
|
210
|
-
|
|
211
|
-
process.stderr.write(`[phren] computePhrenHash topicConfig: ${errorMessage(err)}\n`);
|
|
204
|
+
logger.debug("computePhrenHash topicConfig", errorMessage(err));
|
|
212
205
|
}
|
|
213
206
|
}
|
|
214
207
|
}
|
|
@@ -239,8 +232,7 @@ function computePhrenHash(phrenPath, profile, preGlobbed) {
|
|
|
239
232
|
}
|
|
240
233
|
}
|
|
241
234
|
catch (err) {
|
|
242
|
-
|
|
243
|
-
process.stderr.write(`[phren] computePhrenHash globDir: ${errorMessage(err)}\n`);
|
|
235
|
+
logger.debug("computePhrenHash globDir", errorMessage(err));
|
|
244
236
|
}
|
|
245
237
|
}
|
|
246
238
|
files.sort();
|
|
@@ -250,8 +242,7 @@ function computePhrenHash(phrenPath, profile, preGlobbed) {
|
|
|
250
242
|
hash.update(`${f}:${stat.mtimeMs}:${stat.size}`);
|
|
251
243
|
}
|
|
252
244
|
catch (err) {
|
|
253
|
-
|
|
254
|
-
process.stderr.write(`[phren] computePhrenHash skip: ${errorMessage(err)}\n`);
|
|
245
|
+
logger.debug("computePhrenHash skip", errorMessage(err));
|
|
255
246
|
}
|
|
256
247
|
}
|
|
257
248
|
for (const configPath of topicConfigEntries) {
|
|
@@ -260,8 +251,7 @@ function computePhrenHash(phrenPath, profile, preGlobbed) {
|
|
|
260
251
|
hash.update(`topic-config:${configPath}:${stat.mtimeMs}:${stat.size}`);
|
|
261
252
|
}
|
|
262
253
|
catch (err) {
|
|
263
|
-
|
|
264
|
-
process.stderr.write(`[phren] computePhrenHash topicConfig: ${errorMessage(err)}\n`);
|
|
254
|
+
logger.debug("computePhrenHash topicConfig", errorMessage(err));
|
|
265
255
|
}
|
|
266
256
|
}
|
|
267
257
|
}
|
|
@@ -271,8 +261,7 @@ function computePhrenHash(phrenPath, profile, preGlobbed) {
|
|
|
271
261
|
hash.update(`native:${mem.fullPath}:${stat.mtimeMs}:${stat.size}`);
|
|
272
262
|
}
|
|
273
263
|
catch (err) {
|
|
274
|
-
|
|
275
|
-
process.stderr.write(`[phren] computePhrenHash skip: ${errorMessage(err)}\n`);
|
|
264
|
+
logger.debug("computePhrenHash skip", errorMessage(err));
|
|
276
265
|
}
|
|
277
266
|
}
|
|
278
267
|
// Include global/ files (pulled via @import) so changes invalidate the cache
|
|
@@ -286,8 +275,7 @@ function computePhrenHash(phrenPath, profile, preGlobbed) {
|
|
|
286
275
|
hash.update(`global:${f}:${stat.mtimeMs}:${stat.size}`);
|
|
287
276
|
}
|
|
288
277
|
catch (err) {
|
|
289
|
-
|
|
290
|
-
process.stderr.write(`[phren] computePhrenHash skip: ${errorMessage(err)}\n`);
|
|
278
|
+
logger.debug("computePhrenHash skip", errorMessage(err));
|
|
291
279
|
}
|
|
292
280
|
}
|
|
293
281
|
}
|
|
@@ -299,8 +287,7 @@ function computePhrenHash(phrenPath, profile, preGlobbed) {
|
|
|
299
287
|
hash.update(`manual-links:${stat.mtimeMs}:${stat.size}`);
|
|
300
288
|
}
|
|
301
289
|
catch (err) {
|
|
302
|
-
|
|
303
|
-
process.stderr.write(`[phren] computePhrenHash skip: ${errorMessage(err)}\n`);
|
|
290
|
+
logger.debug("computePhrenHash skip", errorMessage(err));
|
|
304
291
|
}
|
|
305
292
|
}
|
|
306
293
|
const indexPolicyPath = path.join(phrenPath, ".config", "index-policy.json");
|
|
@@ -310,8 +297,7 @@ function computePhrenHash(phrenPath, profile, preGlobbed) {
|
|
|
310
297
|
hash.update(`index-policy-file:${stat.mtimeMs}:${stat.size}`);
|
|
311
298
|
}
|
|
312
299
|
catch (err) {
|
|
313
|
-
|
|
314
|
-
process.stderr.write(`[phren] computePhrenHash skip: ${errorMessage(err)}\n`);
|
|
300
|
+
logger.debug("computePhrenHash skip", errorMessage(err));
|
|
315
301
|
}
|
|
316
302
|
}
|
|
317
303
|
if (profile)
|
|
@@ -334,8 +320,7 @@ function loadHashMap(phrenPath) {
|
|
|
334
320
|
}
|
|
335
321
|
}
|
|
336
322
|
catch (err) {
|
|
337
|
-
|
|
338
|
-
process.stderr.write(`[phren] loadHashMap: ${errorMessage(err)}\n`);
|
|
323
|
+
logger.debug("loadHashMap", errorMessage(err));
|
|
339
324
|
}
|
|
340
325
|
return { hashes: {} };
|
|
341
326
|
}
|
|
@@ -355,8 +340,7 @@ function saveHashMap(phrenPath, hashes) {
|
|
|
355
340
|
existing = data.hashes;
|
|
356
341
|
}
|
|
357
342
|
catch (err) {
|
|
358
|
-
|
|
359
|
-
process.stderr.write(`[phren] saveHashMap readExisting: ${errorMessage(err)}\n`);
|
|
343
|
+
logger.debug("saveHashMap readExisting", errorMessage(err));
|
|
360
344
|
}
|
|
361
345
|
const merged = { ...existing, ...hashes };
|
|
362
346
|
// Remove entries for paths that no longer exist on disk
|
|
@@ -494,8 +478,7 @@ function insertFileIntoIndex(db, entry, phrenPath, opts) {
|
|
|
494
478
|
return true;
|
|
495
479
|
}
|
|
496
480
|
catch (err) {
|
|
497
|
-
|
|
498
|
-
process.stderr.write(`[phren] insertFileIntoIndex: ${errorMessage(err)}\n`);
|
|
481
|
+
logger.debug("insertFileIntoIndex", errorMessage(err));
|
|
499
482
|
return false;
|
|
500
483
|
}
|
|
501
484
|
}
|
|
@@ -575,8 +558,7 @@ function deleteEntityLinksForDocPath(db, phrenPath, docPath, fallbackProject, fa
|
|
|
575
558
|
db.run("DELETE FROM global_entities WHERE doc_key = ?", [sourceDoc]);
|
|
576
559
|
}
|
|
577
560
|
catch (err) {
|
|
578
|
-
|
|
579
|
-
process.stderr.write(`[phren] deleteEntityLinksForDocPath globalEntities: ${errorMessage(err)}\n`);
|
|
561
|
+
logger.debug("deleteEntityLinksForDocPath globalEntities", errorMessage(err));
|
|
580
562
|
}
|
|
581
563
|
}
|
|
582
564
|
/**
|
|
@@ -591,15 +573,13 @@ export function updateFileInIndex(db, filePath, phrenPath) {
|
|
|
591
573
|
deleteEntityLinksForDocPath(db, phrenPath, resolvedPath);
|
|
592
574
|
}
|
|
593
575
|
catch (err) {
|
|
594
|
-
|
|
595
|
-
process.stderr.write(`[phren] updateFileInIndex deleteEntityLinks: ${errorMessage(err)}\n`);
|
|
576
|
+
logger.debug("updateFileInIndex deleteEntityLinks", errorMessage(err));
|
|
596
577
|
}
|
|
597
578
|
try {
|
|
598
579
|
db.run("DELETE FROM docs WHERE path = ?", [resolvedPath]);
|
|
599
580
|
}
|
|
600
581
|
catch (err) {
|
|
601
|
-
|
|
602
|
-
process.stderr.write(`[phren] updateFileInIndex deleteDocs: ${errorMessage(err)}\n`);
|
|
582
|
+
logger.debug("updateFileInIndex deleteDocs", errorMessage(err));
|
|
603
583
|
}
|
|
604
584
|
// Re-insert if file still exists
|
|
605
585
|
if (fs.existsSync(resolvedPath)) {
|
|
@@ -618,8 +598,7 @@ export function updateFileInIndex(db, filePath, phrenPath) {
|
|
|
618
598
|
extractAndLinkFragments(db, content, getEntrySourceDocKey(entry, phrenPath), phrenPath);
|
|
619
599
|
}
|
|
620
600
|
catch (err) {
|
|
621
|
-
|
|
622
|
-
process.stderr.write(`[phren] updateFileInIndex entityExtraction: ${errorMessage(err)}\n`);
|
|
601
|
+
logger.debug("updateFileInIndex entityExtraction", errorMessage(err));
|
|
623
602
|
}
|
|
624
603
|
}
|
|
625
604
|
}
|
|
@@ -630,22 +609,20 @@ export function updateFileInIndex(db, filePath, phrenPath) {
|
|
|
630
609
|
saveHashMap(phrenPath, hashData.hashes);
|
|
631
610
|
}
|
|
632
611
|
catch (err) {
|
|
633
|
-
|
|
634
|
-
process.stderr.write(`[phren] updateFileInIndex hashMap: ${errorMessage(err)}\n`);
|
|
612
|
+
logger.debug("updateFileInIndex hashMap", errorMessage(err));
|
|
635
613
|
}
|
|
636
614
|
}
|
|
637
615
|
else {
|
|
638
616
|
// Remove stale embedding if file was deleted
|
|
639
617
|
void (async () => {
|
|
640
618
|
try {
|
|
641
|
-
const { getEmbeddingCache } = await import("./
|
|
619
|
+
const { getEmbeddingCache } = await import("./embedding-cache.js");
|
|
642
620
|
const c = getEmbeddingCache(phrenPath);
|
|
643
621
|
c.delete(resolvedPath);
|
|
644
622
|
await c.flush();
|
|
645
623
|
}
|
|
646
624
|
catch (err) {
|
|
647
|
-
|
|
648
|
-
process.stderr.write(`[phren] updateFileInIndex embeddingDelete: ${errorMessage(err)}\n`);
|
|
625
|
+
logger.debug("updateFileInIndex embeddingDelete", errorMessage(err));
|
|
649
626
|
}
|
|
650
627
|
})();
|
|
651
628
|
}
|
|
@@ -664,8 +641,7 @@ function readHashSentinel(phrenPath) {
|
|
|
664
641
|
}
|
|
665
642
|
}
|
|
666
643
|
catch (err) {
|
|
667
|
-
|
|
668
|
-
process.stderr.write(`[phren] readHashSentinel: ${errorMessage(err)}\n`);
|
|
644
|
+
logger.debug("readHashSentinel", errorMessage(err));
|
|
669
645
|
}
|
|
670
646
|
return null;
|
|
671
647
|
}
|
|
@@ -675,8 +651,7 @@ function writeHashSentinel(phrenPath, hash) {
|
|
|
675
651
|
fs.writeFileSync(sentinelPath, JSON.stringify({ hash, computedAt: Date.now() }));
|
|
676
652
|
}
|
|
677
653
|
catch (err) {
|
|
678
|
-
|
|
679
|
-
process.stderr.write(`[phren] writeHashSentinel: ${errorMessage(err)}\n`);
|
|
654
|
+
logger.debug("writeHashSentinel", errorMessage(err));
|
|
680
655
|
}
|
|
681
656
|
}
|
|
682
657
|
function isSentinelFresh(phrenPath, sentinel) {
|
|
@@ -693,8 +668,7 @@ function isSentinelFresh(phrenPath, sentinel) {
|
|
|
693
668
|
return false;
|
|
694
669
|
}
|
|
695
670
|
catch (err) {
|
|
696
|
-
|
|
697
|
-
process.stderr.write(`[phren] isSentinelFresh statDir: ${errorMessage(err)}\n`);
|
|
671
|
+
logger.debug("isSentinelFresh statDir", errorMessage(err));
|
|
698
672
|
}
|
|
699
673
|
}
|
|
700
674
|
return true;
|
|
@@ -715,8 +689,7 @@ function loadCachedEntityGraph(db, graphPath, allFiles, phrenPath) {
|
|
|
715
689
|
return fs.statSync(f.fullPath).mtimeMs > graphMtime;
|
|
716
690
|
}
|
|
717
691
|
catch (err) {
|
|
718
|
-
|
|
719
|
-
process.stderr.write(`[phren] loadCachedEntityGraph statFile: ${errorMessage(err)}\n`);
|
|
692
|
+
logger.debug("loadCachedEntityGraph statFile", errorMessage(err));
|
|
720
693
|
return true;
|
|
721
694
|
}
|
|
722
695
|
});
|
|
@@ -743,8 +716,7 @@ function loadCachedEntityGraph(db, graphPath, allFiles, phrenPath) {
|
|
|
743
716
|
db.run("INSERT OR IGNORE INTO global_entities (entity, project, doc_key) VALUES (?, ?, ?)", [entity, project, docKey]);
|
|
744
717
|
}
|
|
745
718
|
catch (err) {
|
|
746
|
-
|
|
747
|
-
process.stderr.write(`[phren] loadCachedEntityGraph globalEntitiesInsert2: ${errorMessage(err)}\n`);
|
|
719
|
+
logger.debug("loadCachedEntityGraph globalEntitiesInsert2", errorMessage(err));
|
|
748
720
|
}
|
|
749
721
|
}
|
|
750
722
|
}
|
|
@@ -762,23 +734,20 @@ function loadCachedEntityGraph(db, graphPath, allFiles, phrenPath) {
|
|
|
762
734
|
db.run("INSERT OR IGNORE INTO global_entities (entity, project, doc_key) VALUES (?, ?, ?)", [name, proj, sourceDoc]);
|
|
763
735
|
}
|
|
764
736
|
catch (err) {
|
|
765
|
-
|
|
766
|
-
process.stderr.write(`[phren] loadCachedEntityGraph globalEntitiesInsert: ${errorMessage(err)}\n`);
|
|
737
|
+
logger.debug("loadCachedEntityGraph globalEntitiesInsert", errorMessage(err));
|
|
767
738
|
}
|
|
768
739
|
}
|
|
769
740
|
}
|
|
770
741
|
}
|
|
771
742
|
catch (err) {
|
|
772
|
-
|
|
773
|
-
process.stderr.write(`[phren] entityGraph globalEntitiesRestore: ${errorMessage(err)}\n`);
|
|
743
|
+
logger.debug("entityGraph globalEntitiesRestore", errorMessage(err));
|
|
774
744
|
}
|
|
775
745
|
}
|
|
776
746
|
return true;
|
|
777
747
|
}
|
|
778
748
|
}
|
|
779
749
|
catch (err) {
|
|
780
|
-
|
|
781
|
-
process.stderr.write(`[phren] entityGraph cacheLoad: ${errorMessage(err)}\n`);
|
|
750
|
+
logger.debug("entityGraph cacheLoad", errorMessage(err));
|
|
782
751
|
}
|
|
783
752
|
return false;
|
|
784
753
|
}
|
|
@@ -797,8 +766,7 @@ function mergeManualLinks(db, phrenPath) {
|
|
|
797
766
|
// Validate: skip manual links whose sourceDoc no longer exists in the index
|
|
798
767
|
const docCheck = queryDocBySourceKey(db, phrenPath, link.sourceDoc);
|
|
799
768
|
if (!docCheck) {
|
|
800
|
-
|
|
801
|
-
process.stderr.write(`[phren] manualLinks: pruning stale link to "${link.sourceDoc}"\n`);
|
|
769
|
+
logger.debug("manualLinks", `pruning stale link to "${link.sourceDoc}"`);
|
|
802
770
|
pruned = true;
|
|
803
771
|
continue;
|
|
804
772
|
}
|
|
@@ -819,14 +787,12 @@ function mergeManualLinks(db, phrenPath) {
|
|
|
819
787
|
db.run("INSERT OR IGNORE INTO global_entities (entity, project, doc_key) VALUES (?, ?, ?)", [link.entity, projectMatch[1], link.sourceDoc]);
|
|
820
788
|
}
|
|
821
789
|
catch (err) {
|
|
822
|
-
|
|
823
|
-
process.stderr.write(`[phren] manualLinks globalEntities: ${errorMessage(err)}\n`);
|
|
790
|
+
logger.debug("manualLinks globalEntities", errorMessage(err));
|
|
824
791
|
}
|
|
825
792
|
}
|
|
826
793
|
}
|
|
827
794
|
catch (err) {
|
|
828
|
-
|
|
829
|
-
process.stderr.write(`[phren] manualLinks entry: ${errorMessage(err)}\n`);
|
|
795
|
+
logger.debug("manualLinks entry", errorMessage(err));
|
|
830
796
|
}
|
|
831
797
|
}
|
|
832
798
|
// Rewrite manual-links.json if stale entries were pruned
|
|
@@ -839,14 +805,12 @@ function mergeManualLinks(db, phrenPath) {
|
|
|
839
805
|
});
|
|
840
806
|
}
|
|
841
807
|
catch (err) {
|
|
842
|
-
|
|
843
|
-
process.stderr.write(`[phren] manualLinks prune write: ${errorMessage(err)}\n`);
|
|
808
|
+
logger.debug("manualLinks prune write", errorMessage(err));
|
|
844
809
|
}
|
|
845
810
|
}
|
|
846
811
|
}
|
|
847
812
|
catch (err) {
|
|
848
|
-
|
|
849
|
-
process.stderr.write(`[phren] mergeManualLinks: ${errorMessage(err)}\n`);
|
|
813
|
+
logger.debug("mergeManualLinks", errorMessage(err));
|
|
850
814
|
}
|
|
851
815
|
}
|
|
852
816
|
async function buildIndexImpl(phrenPath, profile) {
|
|
@@ -859,8 +823,7 @@ async function buildIndexImpl(phrenPath, profile) {
|
|
|
859
823
|
userSuffix = String(os.userInfo().uid);
|
|
860
824
|
}
|
|
861
825
|
catch (err) {
|
|
862
|
-
|
|
863
|
-
process.stderr.write(`[phren] buildIndexImpl userInfo: ${errorMessage(err)}\n`);
|
|
826
|
+
logger.debug("buildIndexImpl userInfo", errorMessage(err));
|
|
864
827
|
userSuffix = crypto.createHash("sha1").update(homeDir()).digest("hex").slice(0, 12);
|
|
865
828
|
}
|
|
866
829
|
const cacheDir = path.join(os.tmpdir(), `phren-fts-${userSuffix}`);
|
|
@@ -965,8 +928,7 @@ async function buildIndexImpl(phrenPath, profile) {
|
|
|
965
928
|
}
|
|
966
929
|
}
|
|
967
930
|
catch (err) {
|
|
968
|
-
|
|
969
|
-
process.stderr.write(`[phren] buildIndex hashFile: ${errorMessage(err)}\n`);
|
|
931
|
+
logger.debug("buildIndex hashFile", errorMessage(err));
|
|
970
932
|
}
|
|
971
933
|
}
|
|
972
934
|
// Check for files missing from the index (deleted files)
|
|
@@ -1001,28 +963,24 @@ async function buildIndexImpl(phrenPath, profile) {
|
|
|
1001
963
|
deleteEntityLinksForDocPath(db, phrenPath, missingPath);
|
|
1002
964
|
}
|
|
1003
965
|
catch (err) {
|
|
1004
|
-
|
|
1005
|
-
process.stderr.write(`[phren] buildIndex deleteEntityLinksForMissing: ${errorMessage(err)}\n`);
|
|
966
|
+
logger.debug("buildIndex deleteEntityLinksForMissing", errorMessage(err));
|
|
1006
967
|
}
|
|
1007
968
|
try {
|
|
1008
969
|
db.run("DELETE FROM docs WHERE path = ?", [missingPath]);
|
|
1009
970
|
}
|
|
1010
971
|
catch (err) {
|
|
1011
|
-
|
|
1012
|
-
process.stderr.write(`[phren] buildIndex deleteDocForMissing: ${errorMessage(err)}\n`);
|
|
972
|
+
logger.debug("buildIndex deleteDocForMissing", errorMessage(err));
|
|
1013
973
|
}
|
|
1014
974
|
}
|
|
1015
975
|
db.run("COMMIT");
|
|
1016
976
|
}
|
|
1017
977
|
catch (err) {
|
|
1018
|
-
|
|
1019
|
-
process.stderr.write(`[phren] buildIndex incrementalDeleteCommit: ${errorMessage(err)}\n`);
|
|
978
|
+
logger.debug("buildIndex incrementalDeleteCommit", errorMessage(err));
|
|
1020
979
|
try {
|
|
1021
980
|
db.run("ROLLBACK");
|
|
1022
981
|
}
|
|
1023
982
|
catch (e2) {
|
|
1024
|
-
|
|
1025
|
-
process.stderr.write(`[phren] buildIndex incrementalDeleteRollback: ${e2 instanceof Error ? e2.message : String(e2)}\n`);
|
|
983
|
+
logger.debug("buildIndex incrementalDeleteRollback", e2 instanceof Error ? e2.message : String(e2));
|
|
1026
984
|
}
|
|
1027
985
|
}
|
|
1028
986
|
let updatedCount = 0;
|
|
@@ -1058,8 +1016,7 @@ async function buildIndexImpl(phrenPath, profile) {
|
|
|
1058
1016
|
db.run("ROLLBACK");
|
|
1059
1017
|
}
|
|
1060
1018
|
catch (e2) {
|
|
1061
|
-
|
|
1062
|
-
process.stderr.write(`[phren] buildIndex perFileRollback: ${e2 instanceof Error ? e2.message : String(e2)}\n`);
|
|
1019
|
+
logger.debug("buildIndex perFileRollback", e2 instanceof Error ? e2.message : String(e2));
|
|
1063
1020
|
}
|
|
1064
1021
|
throw err;
|
|
1065
1022
|
}
|
|
@@ -1073,8 +1030,7 @@ async function buildIndexImpl(phrenPath, profile) {
|
|
|
1073
1030
|
fs.writeFileSync(cacheFile, db.export());
|
|
1074
1031
|
}
|
|
1075
1032
|
catch (err) {
|
|
1076
|
-
|
|
1077
|
-
process.stderr.write(`[phren] buildIndex incrementalCacheSave: ${errorMessage(err)}\n`);
|
|
1033
|
+
logger.debug("buildIndex incrementalCacheSave", errorMessage(err));
|
|
1078
1034
|
}
|
|
1079
1035
|
const incMs = Date.now() - t0;
|
|
1080
1036
|
debugLog(`Incremental FTS update: ${updatedCount} changed, ${missingFromIndex.length} removed in ${incMs}ms`);
|
|
@@ -1131,8 +1087,7 @@ async function buildIndexImpl(phrenPath, profile) {
|
|
|
1131
1087
|
newHashes[entry.fullPath] = hashFileContent(entry.fullPath);
|
|
1132
1088
|
}
|
|
1133
1089
|
catch (err) {
|
|
1134
|
-
|
|
1135
|
-
process.stderr.write(`[phren] computePhrenHash skip: ${errorMessage(err)}\n`);
|
|
1090
|
+
logger.debug("computePhrenHash skip", errorMessage(err));
|
|
1136
1091
|
}
|
|
1137
1092
|
if (insertFileIntoIndex(db, entry, phrenPath, { scheduleEmbeddings: true })) {
|
|
1138
1093
|
fileCount++;
|
|
@@ -1159,8 +1114,7 @@ async function buildIndexImpl(phrenPath, profile) {
|
|
|
1159
1114
|
fs.writeFileSync(graphPath, JSON.stringify({ entities: entityRows, links: linkRows, globalEntities: globalEntityRows, ts: Date.now() }));
|
|
1160
1115
|
}
|
|
1161
1116
|
catch (err) {
|
|
1162
|
-
|
|
1163
|
-
process.stderr.write(`[phren] buildIndex entityGraphPersist: ${errorMessage(err)}\n`);
|
|
1117
|
+
logger.debug("buildIndex entityGraphPersist", errorMessage(err));
|
|
1164
1118
|
}
|
|
1165
1119
|
}
|
|
1166
1120
|
// Always merge manual links (survive rebuild)
|
|
@@ -1192,8 +1146,7 @@ async function buildIndexImpl(phrenPath, profile) {
|
|
|
1192
1146
|
fs.unlinkSync(path.join(cacheDir, f));
|
|
1193
1147
|
}
|
|
1194
1148
|
catch (err) {
|
|
1195
|
-
|
|
1196
|
-
process.stderr.write(`[phren] buildIndex staleCacheCleanup: ${errorMessage(err)}\n`);
|
|
1149
|
+
logger.debug("buildIndex staleCacheCleanup", errorMessage(err));
|
|
1197
1150
|
}
|
|
1198
1151
|
}
|
|
1199
1152
|
debugLog(`Saved FTS index cache (${hash.slice(0, 8)}) — total ${Date.now() - t0}ms`);
|
|
@@ -1229,8 +1182,7 @@ function isRebuildLockHeld(phrenPath) {
|
|
|
1229
1182
|
return Date.now() - stat.mtimeMs <= staleThreshold;
|
|
1230
1183
|
}
|
|
1231
1184
|
catch (err) {
|
|
1232
|
-
|
|
1233
|
-
process.stderr.write(`[phren] isRebuildLockHeld stat: ${errorMessage(err)}\n`);
|
|
1185
|
+
logger.debug("isRebuildLockHeld stat", errorMessage(err));
|
|
1234
1186
|
return false;
|
|
1235
1187
|
}
|
|
1236
1188
|
}
|
|
@@ -1241,8 +1193,7 @@ async function loadIndexSnapshotOrEmpty(phrenPath, profile) {
|
|
|
1241
1193
|
userSuffix = String(os.userInfo().uid);
|
|
1242
1194
|
}
|
|
1243
1195
|
catch (err) {
|
|
1244
|
-
|
|
1245
|
-
process.stderr.write(`[phren] loadIndexSnapshotOrEmpty userInfo: ${errorMessage(err)}\n`);
|
|
1196
|
+
logger.debug("loadIndexSnapshotOrEmpty userInfo", errorMessage(err));
|
|
1246
1197
|
userSuffix = crypto.createHash("sha1").update(homeDir()).digest("hex").slice(0, 12);
|
|
1247
1198
|
}
|
|
1248
1199
|
const cacheDir = path.join(os.tmpdir(), `phren-fts-${userSuffix}`);
|
|
@@ -1257,7 +1208,27 @@ async function loadIndexSnapshotOrEmpty(phrenPath, profile) {
|
|
|
1257
1208
|
debugLog(`Failed to open cached FTS snapshot while rebuild lock held: ${errorMessage(err)}`);
|
|
1258
1209
|
}
|
|
1259
1210
|
}
|
|
1260
|
-
|
|
1211
|
+
// Before returning empty, try to load any stale-but-usable cache file
|
|
1212
|
+
try {
|
|
1213
|
+
if (fs.existsSync(cacheDir)) {
|
|
1214
|
+
const cacheFiles = fs.readdirSync(cacheDir)
|
|
1215
|
+
.filter(f => f.endsWith(".db"))
|
|
1216
|
+
.map(f => ({ name: f, mtime: fs.statSync(path.join(cacheDir, f)).mtimeMs }))
|
|
1217
|
+
.sort((a, b) => b.mtime - a.mtime);
|
|
1218
|
+
for (const cf of cacheFiles) {
|
|
1219
|
+
try {
|
|
1220
|
+
const staleDb = new SQL.Database(fs.readFileSync(path.join(cacheDir, cf.name)));
|
|
1221
|
+
debugLog(`FTS rebuild in progress; falling back to stale cache: ${cf.name}`);
|
|
1222
|
+
return staleDb;
|
|
1223
|
+
}
|
|
1224
|
+
catch { /* try next */ }
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
catch (err) {
|
|
1229
|
+
debugLog(`Failed to scan stale FTS caches: ${errorMessage(err)}`);
|
|
1230
|
+
}
|
|
1231
|
+
debugLog("FTS rebuild already in progress; no usable cache found, returning empty snapshot");
|
|
1261
1232
|
return createEmptyIndexDb(SQL);
|
|
1262
1233
|
}
|
|
1263
1234
|
// Serialize concurrent in-process buildIndex calls to prevent SQLite corruption
|
|
@@ -1342,8 +1313,7 @@ export function findFtsCacheForPath(phrenPath, profile) {
|
|
|
1342
1313
|
userSuffix = String(os.userInfo().uid);
|
|
1343
1314
|
}
|
|
1344
1315
|
catch (err) {
|
|
1345
|
-
|
|
1346
|
-
process.stderr.write(`[phren] findFtsCacheForPath userInfo: ${errorMessage(err)}\n`);
|
|
1316
|
+
logger.debug("findFtsCacheForPath userInfo", errorMessage(err));
|
|
1347
1317
|
userSuffix = crypto.createHash("sha1").update(homeDir()).digest("hex").slice(0, 12);
|
|
1348
1318
|
}
|
|
1349
1319
|
const cacheDir = path.join(os.tmpdir(), `phren-fts-${userSuffix}`);
|
|
@@ -1357,8 +1327,7 @@ export function findFtsCacheForPath(phrenPath, profile) {
|
|
|
1357
1327
|
}
|
|
1358
1328
|
}
|
|
1359
1329
|
catch (err) {
|
|
1360
|
-
|
|
1361
|
-
process.stderr.write(`[phren] findFtsCacheForPath: ${errorMessage(err)}\n`);
|
|
1330
|
+
logger.debug("findFtsCacheForPath", errorMessage(err));
|
|
1362
1331
|
}
|
|
1363
1332
|
return { exists: false };
|
|
1364
1333
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { debugLog } from "
|
|
1
|
+
import { debugLog } from "../shared.js";
|
|
2
2
|
const DEFAULT_OLLAMA_URL = "http://localhost:11434";
|
|
3
3
|
const DEFAULT_EMBEDDING_MODEL = "nomic-embed-text";
|
|
4
4
|
const DEFAULT_EXTRACT_MODEL = "llama3.2";
|
|
@@ -178,4 +178,4 @@ export async function generateText(prompt, model, url) {
|
|
|
178
178
|
return null;
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
|
-
export { cosineSimilarity } from "
|
|
181
|
+
export { cosineSimilarity } from "../embedding.js";
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
// shared-retrieval.ts — shared retrieval core used by hooks and MCP search.
|
|
2
|
-
import { getQualityMultiplier, entryScoreKey, } from "./
|
|
3
|
-
import { queryDocRows, queryRows, cosineFallback, extractSnippet, getDocSourceKey, getEntityBoostDocs, decodeFiniteNumber, rowToDocWithRowid, buildIndex, } from "./
|
|
4
|
-
import { filterTrustedFindingsDetailed, } from "./
|
|
5
|
-
import { parseCitationComment } from "
|
|
6
|
-
import { getHighImpactFindings } from "
|
|
7
|
-
import { buildFtsQueryVariants, buildRelaxedFtsQuery, isFeatureEnabled, STOP_WORDS, errorMessage } from "
|
|
2
|
+
import { getQualityMultiplier, entryScoreKey, } from "./governance.js";
|
|
3
|
+
import { queryDocRows, queryRows, cosineFallback, extractSnippet, getDocSourceKey, getEntityBoostDocs, decodeFiniteNumber, rowToDocWithRowid, buildIndex, } from "./index.js";
|
|
4
|
+
import { filterTrustedFindingsDetailed, } from "./content.js";
|
|
5
|
+
import { parseCitationComment } from "../content/citation.js";
|
|
6
|
+
import { getHighImpactFindings } from "../finding/impact.js";
|
|
7
|
+
import { buildFtsQueryVariants, buildRelaxedFtsQuery, isFeatureEnabled, STOP_WORDS, errorMessage } from "../utils.js";
|
|
8
|
+
import { logger } from "../logger.js";
|
|
8
9
|
import * as fs from "fs";
|
|
9
10
|
import * as path from "path";
|
|
10
|
-
import { getProjectGlobBoost } from "
|
|
11
|
-
import { vectorFallback, deterministicSeed } from "./
|
|
12
|
-
import { getOllamaUrl, getCloudEmbeddingUrl } from "./
|
|
13
|
-
import { keywordFallbackSearch } from "
|
|
14
|
-
import { debugLog } from "
|
|
11
|
+
import { getProjectGlobBoost } from "../cli/hooks-globs.js";
|
|
12
|
+
import { vectorFallback, deterministicSeed } from "./search-fallback.js";
|
|
13
|
+
import { getOllamaUrl, getCloudEmbeddingUrl } from "./ollama.js";
|
|
14
|
+
import { keywordFallbackSearch } from "../core/search.js";
|
|
15
|
+
import { debugLog } from "../shared.js";
|
|
15
16
|
// ── Scoring constants ─────────────────────────────────────────────────────────
|
|
16
17
|
/** Number of docs sampled for token-overlap semantic fallback search. */
|
|
17
18
|
const SEMANTIC_FALLBACK_SAMPLE_LIMIT = 100;
|
|
@@ -383,8 +384,7 @@ export async function searchDocumentsAsync(db, safeQuery, prompt, keywords, dete
|
|
|
383
384
|
}
|
|
384
385
|
catch (err) {
|
|
385
386
|
// Vector search failure is non-fatal — return sync result
|
|
386
|
-
|
|
387
|
-
process.stderr.write(`[phren] hybridSearch vectorFallback: ${errorMessage(err)}\n`);
|
|
387
|
+
logger.debug("hybridSearch vectorFallback", errorMessage(err));
|
|
388
388
|
return syncResult;
|
|
389
389
|
}
|
|
390
390
|
}
|
|
@@ -483,9 +483,7 @@ export async function searchKnowledgeRows(db, options) {
|
|
|
483
483
|
}
|
|
484
484
|
}
|
|
485
485
|
catch (err) {
|
|
486
|
-
|
|
487
|
-
process.stderr.write(`[phren] vectorFallback: ${errorMessage(err)}\n`);
|
|
488
|
-
}
|
|
486
|
+
logger.debug("vectorFallback", errorMessage(err));
|
|
489
487
|
}
|
|
490
488
|
}
|
|
491
489
|
return { safeQuery, rows, usedFallback };
|
|
@@ -523,9 +521,7 @@ export async function searchFederatedStores(localPhrenPath, options) {
|
|
|
523
521
|
}
|
|
524
522
|
}
|
|
525
523
|
catch (err) {
|
|
526
|
-
|
|
527
|
-
process.stderr.write(`[phren] federatedSearch storePath=${storePath}: ${errorMessage(err)}\n`);
|
|
528
|
-
}
|
|
524
|
+
logger.debug(`federatedSearch storePath=${storePath}`, errorMessage(err));
|
|
529
525
|
// Federation errors are non-fatal — continue with other stores
|
|
530
526
|
}
|
|
531
527
|
}
|
|
@@ -771,8 +767,7 @@ export function markStaleCitations(snippet) {
|
|
|
771
767
|
}
|
|
772
768
|
}
|
|
773
769
|
catch (err) {
|
|
774
|
-
|
|
775
|
-
process.stderr.write(`[phren] applyCitationAnnotations fileRead: ${errorMessage(err)}\n`);
|
|
770
|
+
logger.debug("applyCitationAnnotations fileRead", errorMessage(err));
|
|
776
771
|
stale = true;
|
|
777
772
|
}
|
|
778
773
|
}
|