claude-memory-layer 1.1.1 → 1.1.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.
- package/dist/cli/index.js +82 -1
- package/dist/cli/index.js.map +3 -3
- package/dist/hooks/session-start.js +78 -34
- package/dist/hooks/session-start.js.map +4 -4
- package/package.json +1 -1
|
@@ -2287,12 +2287,12 @@ function getProjectStoragePath(projectPath) {
|
|
|
2287
2287
|
import Database from "better-sqlite3";
|
|
2288
2288
|
import * as fs4 from "fs";
|
|
2289
2289
|
import * as nodePath from "path";
|
|
2290
|
-
function createSQLiteDatabase(
|
|
2291
|
-
const dir = nodePath.dirname(
|
|
2290
|
+
function createSQLiteDatabase(path13, options) {
|
|
2291
|
+
const dir = nodePath.dirname(path13);
|
|
2292
2292
|
if (!fs4.existsSync(dir)) {
|
|
2293
2293
|
fs4.mkdirSync(dir, { recursive: true });
|
|
2294
2294
|
}
|
|
2295
|
-
const db = new Database(
|
|
2295
|
+
const db = new Database(path13, {
|
|
2296
2296
|
readonly: options?.readonly ?? false
|
|
2297
2297
|
});
|
|
2298
2298
|
if (!options?.readonly && (options?.walMode ?? true)) {
|
|
@@ -2948,17 +2948,17 @@ function emptyOutboxRecoveryResult() {
|
|
|
2948
2948
|
function isRecord(value) {
|
|
2949
2949
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2950
2950
|
}
|
|
2951
|
-
function getNestedRecord(root,
|
|
2951
|
+
function getNestedRecord(root, path13) {
|
|
2952
2952
|
let cursor = root;
|
|
2953
|
-
for (const key of
|
|
2953
|
+
for (const key of path13) {
|
|
2954
2954
|
if (!isRecord(cursor)) return void 0;
|
|
2955
2955
|
cursor = cursor[key];
|
|
2956
2956
|
}
|
|
2957
2957
|
return isRecord(cursor) ? cursor : void 0;
|
|
2958
2958
|
}
|
|
2959
|
-
function getNestedString(root,
|
|
2959
|
+
function getNestedString(root, path13) {
|
|
2960
2960
|
let cursor = root;
|
|
2961
|
-
for (const key of
|
|
2961
|
+
for (const key of path13) {
|
|
2962
2962
|
if (!isRecord(cursor)) return void 0;
|
|
2963
2963
|
cursor = cursor[key];
|
|
2964
2964
|
}
|
|
@@ -7355,12 +7355,12 @@ var GraphPathService = class {
|
|
|
7355
7355
|
}
|
|
7356
7356
|
}
|
|
7357
7357
|
}
|
|
7358
|
-
const paths = Array.from(bestByTarget.entries()).map(([key,
|
|
7358
|
+
const paths = Array.from(bestByTarget.entries()).map(([key, path13]) => ({
|
|
7359
7359
|
target: graph.node(nodeFromKey(key)),
|
|
7360
|
-
hops:
|
|
7361
|
-
totalCost:
|
|
7362
|
-
scoreContribution:
|
|
7363
|
-
steps:
|
|
7360
|
+
hops: path13.hops,
|
|
7361
|
+
totalCost: path13.totalCost,
|
|
7362
|
+
scoreContribution: path13.totalCost > 0 ? 1 / path13.totalCost : 0,
|
|
7363
|
+
steps: path13.steps
|
|
7364
7364
|
})).sort((a, b) => b.scoreContribution - a.scoreContribution || a.hops - b.hops || a.target.name.localeCompare(b.target.name)).slice(0, maxResults);
|
|
7365
7365
|
return { startNodes, effectiveMaxHops, paths };
|
|
7366
7366
|
}
|
|
@@ -10260,12 +10260,12 @@ var Retriever = class {
|
|
|
10260
10260
|
direction: "both"
|
|
10261
10261
|
});
|
|
10262
10262
|
const titleByEntityId = new Map(startNodes.map((node) => [node.entityId, node.title]));
|
|
10263
|
-
for (const
|
|
10264
|
-
if (
|
|
10265
|
-
const target = await this.eventStore.getEvent(
|
|
10263
|
+
for (const path13 of expansion.paths) {
|
|
10264
|
+
if (path13.target.type !== "event") continue;
|
|
10265
|
+
const target = await this.eventStore.getEvent(path13.target.id);
|
|
10266
10266
|
if (!target) continue;
|
|
10267
|
-
const graphPath = toRetrievalGraphPathDebug(
|
|
10268
|
-
const score = graphPathScore(
|
|
10267
|
+
const graphPath = toRetrievalGraphPathDebug(path13, titleByEntityId);
|
|
10268
|
+
const score = graphPathScore(path13, opts.hopPenalty);
|
|
10269
10269
|
const existing = byId.get(target.id);
|
|
10270
10270
|
const graphPaths = mergeGraphPaths(existing?.graphPaths ?? [], [graphPath]);
|
|
10271
10271
|
const graphLane = {
|
|
@@ -10274,7 +10274,7 @@ var Retriever = class {
|
|
|
10274
10274
|
score
|
|
10275
10275
|
};
|
|
10276
10276
|
const row = {
|
|
10277
|
-
id: existing?.id ?? `graph-path-${
|
|
10277
|
+
id: existing?.id ?? `graph-path-${path13.hops}-${target.id}`,
|
|
10278
10278
|
eventId: target.id,
|
|
10279
10279
|
content: target.content,
|
|
10280
10280
|
score: Math.max(existing?.score ?? 0, score),
|
|
@@ -10614,8 +10614,8 @@ _Context:_ ${sessionContext}`;
|
|
|
10614
10614
|
}
|
|
10615
10615
|
matchesMetadataScope(metadata, expected) {
|
|
10616
10616
|
if (!metadata) return false;
|
|
10617
|
-
return Object.entries(expected).every(([
|
|
10618
|
-
const actual =
|
|
10617
|
+
return Object.entries(expected).every(([path13, value]) => {
|
|
10618
|
+
const actual = path13.split(".").reduce((acc, key) => {
|
|
10619
10619
|
if (typeof acc !== "object" || acc === null) return void 0;
|
|
10620
10620
|
return acc[key];
|
|
10621
10621
|
}, metadata);
|
|
@@ -10666,22 +10666,22 @@ function uniqueEntityStartNodes(candidates) {
|
|
|
10666
10666
|
}
|
|
10667
10667
|
return nodes;
|
|
10668
10668
|
}
|
|
10669
|
-
function toRetrievalGraphPathDebug(
|
|
10670
|
-
const firstStep =
|
|
10669
|
+
function toRetrievalGraphPathDebug(path13, titleByEntityId) {
|
|
10670
|
+
const firstStep = path13.steps[0];
|
|
10671
10671
|
const startNode = firstStep?.direction === "incoming" ? firstStep.to : firstStep?.from;
|
|
10672
10672
|
const startEntityId = startNode?.type === "entity" ? startNode.id : "";
|
|
10673
10673
|
return {
|
|
10674
10674
|
startEntityId,
|
|
10675
10675
|
startEntityTitle: titleByEntityId.get(startEntityId) ?? startNode?.name,
|
|
10676
|
-
targetId:
|
|
10677
|
-
targetType:
|
|
10678
|
-
hops:
|
|
10679
|
-
relationPath:
|
|
10676
|
+
targetId: path13.target.id,
|
|
10677
|
+
targetType: path13.target.type,
|
|
10678
|
+
hops: path13.hops,
|
|
10679
|
+
relationPath: path13.steps.map((step) => step.relationType)
|
|
10680
10680
|
};
|
|
10681
10681
|
}
|
|
10682
|
-
function graphPathScore(
|
|
10683
|
-
const base = Math.min(0.95, Math.max(0,
|
|
10684
|
-
return Math.max(0.05, base - hopPenalty * Math.max(0,
|
|
10682
|
+
function graphPathScore(path13, hopPenalty) {
|
|
10683
|
+
const base = Math.min(0.95, Math.max(0, path13.scoreContribution));
|
|
10684
|
+
return Math.max(0.05, base - hopPenalty * Math.max(0, path13.hops - 1));
|
|
10685
10685
|
}
|
|
10686
10686
|
function clampGraphHops(maxHops) {
|
|
10687
10687
|
if (!Number.isFinite(maxHops)) return 2;
|
|
@@ -10689,14 +10689,14 @@ function clampGraphHops(maxHops) {
|
|
|
10689
10689
|
}
|
|
10690
10690
|
function mergeGraphPaths(existing, incoming) {
|
|
10691
10691
|
const byKey = /* @__PURE__ */ new Map();
|
|
10692
|
-
for (const
|
|
10693
|
-
const key = [
|
|
10694
|
-
if (!byKey.has(key)) byKey.set(key,
|
|
10692
|
+
for (const path13 of [...existing, ...incoming]) {
|
|
10693
|
+
const key = [path13.startEntityId, path13.targetType, path13.targetId, path13.hops, ...path13.relationPath].join("\0");
|
|
10694
|
+
if (!byKey.has(key)) byKey.set(key, path13);
|
|
10695
10695
|
}
|
|
10696
10696
|
return [...byKey.values()].sort((a, b) => a.hops - b.hops || compareStable(graphPathSignature(a), graphPathSignature(b))).slice(0, 3);
|
|
10697
10697
|
}
|
|
10698
|
-
function graphPathSignature(
|
|
10699
|
-
return [
|
|
10698
|
+
function graphPathSignature(path13) {
|
|
10699
|
+
return [path13.startEntityId, path13.targetType, path13.targetId, path13.hops, ...path13.relationPath].join("|");
|
|
10700
10700
|
}
|
|
10701
10701
|
function compareStable(a, b) {
|
|
10702
10702
|
if (a < b) return -1;
|
|
@@ -13955,6 +13955,48 @@ function sleep(ms) {
|
|
|
13955
13955
|
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
13956
13956
|
}
|
|
13957
13957
|
|
|
13958
|
+
// src/adapters/claude/hooks/tool-observation-vector-auto-heal-client.ts
|
|
13959
|
+
import { spawn as spawn2 } from "child_process";
|
|
13960
|
+
import * as fs10 from "fs";
|
|
13961
|
+
import * as path12 from "path";
|
|
13962
|
+
|
|
13963
|
+
// src/core/operations/tool-observation-vector-auto-heal.ts
|
|
13964
|
+
var TOOL_OBSERVATION_VECTOR_AUTO_HEAL_KEY = "maintenance:tool_observation_vector_prune_v1";
|
|
13965
|
+
async function needsToolObservationVectorAutoHeal(store) {
|
|
13966
|
+
const flag = await store.getEndlessConfig(TOOL_OBSERVATION_VECTOR_AUTO_HEAL_KEY);
|
|
13967
|
+
return flag === null;
|
|
13968
|
+
}
|
|
13969
|
+
|
|
13970
|
+
// src/adapters/claude/hooks/tool-observation-vector-auto-heal-client.ts
|
|
13971
|
+
function getCliScriptPath() {
|
|
13972
|
+
return path12.join(path12.dirname(new URL(import.meta.url).pathname), "..", "cli", "index.js");
|
|
13973
|
+
}
|
|
13974
|
+
async function spawnToolObservationVectorAutoHealIfNeeded(projectPath) {
|
|
13975
|
+
const storagePath = getProjectStoragePath(projectPath);
|
|
13976
|
+
const dbPath = path12.join(storagePath, "events.sqlite");
|
|
13977
|
+
if (!fs10.existsSync(dbPath)) return;
|
|
13978
|
+
let store;
|
|
13979
|
+
try {
|
|
13980
|
+
store = new SQLiteEventStore(dbPath, { readonly: true });
|
|
13981
|
+
if (!await needsToolObservationVectorAutoHeal(store)) return;
|
|
13982
|
+
} catch {
|
|
13983
|
+
return;
|
|
13984
|
+
} finally {
|
|
13985
|
+
await store?.close().catch(() => void 0);
|
|
13986
|
+
}
|
|
13987
|
+
const cliScriptPath = getCliScriptPath();
|
|
13988
|
+
if (!fs10.existsSync(cliScriptPath)) return;
|
|
13989
|
+
try {
|
|
13990
|
+
const child = spawn2(
|
|
13991
|
+
process.execPath,
|
|
13992
|
+
[cliScriptPath, "repair", "auto-heal-tool-observation-vectors", "--project", projectPath],
|
|
13993
|
+
{ detached: true, stdio: "ignore", env: process.env }
|
|
13994
|
+
);
|
|
13995
|
+
child.unref();
|
|
13996
|
+
} catch {
|
|
13997
|
+
}
|
|
13998
|
+
}
|
|
13999
|
+
|
|
13958
14000
|
// src/adapters/claude/hooks/hook-output.ts
|
|
13959
14001
|
function formatClaudeContextHookOutput(hookEventName, context) {
|
|
13960
14002
|
const output = {
|
|
@@ -13980,6 +14022,8 @@ async function main() {
|
|
|
13980
14022
|
registerSession(input.session_id, input.cwd);
|
|
13981
14023
|
ensureDaemonRunning().catch(() => {
|
|
13982
14024
|
});
|
|
14025
|
+
spawnToolObservationVectorAutoHealIfNeeded(input.cwd).catch(() => {
|
|
14026
|
+
});
|
|
13983
14027
|
const memoryService = getLightweightMemoryService(input.session_id);
|
|
13984
14028
|
try {
|
|
13985
14029
|
if (!isHookEvaluationMode()) {
|