claude-memory-layer 1.0.51 → 1.0.53
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 +111 -19
- package/dist/cli/index.js.map +3 -3
- package/dist/core/index.js +55 -4
- package/dist/core/index.js.map +2 -2
- package/dist/hooks/post-tool-use.js +55 -4
- package/dist/hooks/post-tool-use.js.map +2 -2
- package/dist/hooks/semantic-daemon.js +55 -4
- package/dist/hooks/semantic-daemon.js.map +2 -2
- package/dist/hooks/session-end.js +55 -4
- package/dist/hooks/session-end.js.map +2 -2
- package/dist/hooks/session-start.js +55 -4
- package/dist/hooks/session-start.js.map +2 -2
- package/dist/hooks/stop.js +55 -4
- package/dist/hooks/stop.js.map +2 -2
- package/dist/hooks/user-prompt-submit.js +55 -4
- package/dist/hooks/user-prompt-submit.js.map +2 -2
- package/dist/index.js +55 -4
- package/dist/index.js.map +2 -2
- package/dist/mcp/index.js +58 -7
- package/dist/mcp/index.js.map +2 -2
- package/dist/server/api/index.js +64 -5
- package/dist/server/api/index.js.map +2 -2
- package/dist/server/index.js +64 -5
- package/dist/server/index.js.map +2 -2
- package/dist/services/memory-service.js +55 -4
- package/dist/services/memory-service.js.map +2 -2
- package/dist/ui/assets/js/overview.js +9 -3
- package/dist/ui/assets/js/views.js +1 -1
- package/package.json +3 -1
package/dist/cli/index.js
CHANGED
|
@@ -2327,6 +2327,10 @@ var DEFAULT_CONFIG2 = {
|
|
|
2327
2327
|
// 5 minutes
|
|
2328
2328
|
cleanupDays: 7
|
|
2329
2329
|
};
|
|
2330
|
+
function isRetryableLanceCommitConflict(error) {
|
|
2331
|
+
const normalized = error.toLowerCase();
|
|
2332
|
+
return normalized.includes("lance") && normalized.includes("commit") && normalized.includes("conflict");
|
|
2333
|
+
}
|
|
2330
2334
|
var VectorOutbox = class {
|
|
2331
2335
|
constructor(db, config) {
|
|
2332
2336
|
this.db = db;
|
|
@@ -2431,6 +2435,16 @@ var VectorOutbox = class {
|
|
|
2431
2435
|
);
|
|
2432
2436
|
if (rows.length === 0) return;
|
|
2433
2437
|
const retryCount = rows[0].retry_count;
|
|
2438
|
+
if (isRetryableLanceCommitConflict(error)) {
|
|
2439
|
+
await dbRun(
|
|
2440
|
+
this.db,
|
|
2441
|
+
`UPDATE vector_outbox
|
|
2442
|
+
SET status = 'pending', error = ?, updated_at = ?
|
|
2443
|
+
WHERE job_id = ?`,
|
|
2444
|
+
[error, now, jobId]
|
|
2445
|
+
);
|
|
2446
|
+
return;
|
|
2447
|
+
}
|
|
2434
2448
|
const newStatus = retryCount >= this.config.maxRetries - 1 ? "failed" : "pending";
|
|
2435
2449
|
await dbRun(
|
|
2436
2450
|
this.db,
|
|
@@ -4114,6 +4128,7 @@ var SQLiteEventStore = class {
|
|
|
4114
4128
|
async getOutboxStats(options = {}) {
|
|
4115
4129
|
await this.initialize();
|
|
4116
4130
|
const thresholdMs = Number.isFinite(options.stuckThresholdMs) && (options.stuckThresholdMs ?? 0) >= 0 ? options.stuckThresholdMs : DEFAULT_OUTBOX_STUCK_THRESHOLD_MS;
|
|
4131
|
+
const maxRetries = Number.isFinite(options.maxRetries) && (options.maxRetries ?? 0) > 0 ? options.maxRetries : DEFAULT_OUTBOX_MAX_RETRIES;
|
|
4117
4132
|
const now = options.now ?? /* @__PURE__ */ new Date();
|
|
4118
4133
|
const threshold = new Date(now.getTime() - thresholdMs).toISOString();
|
|
4119
4134
|
const embeddingRows = sqliteAll(
|
|
@@ -4131,8 +4146,8 @@ var SQLiteEventStore = class {
|
|
|
4131
4146
|
if (!Number.isFinite(time)) return null;
|
|
4132
4147
|
return Math.max(0, now.getTime() - time);
|
|
4133
4148
|
};
|
|
4134
|
-
const fromRows = (rows, stuckProcessing, oldestProcessingAgeMs) => {
|
|
4135
|
-
const out = { pending: 0, processing: 0, failed: 0, total: 0, stuckProcessing, oldestProcessingAgeMs };
|
|
4149
|
+
const fromRows = (rows, stuckProcessing, oldestProcessingAgeMs, retryableFailed, quarantinedFailed) => {
|
|
4150
|
+
const out = { pending: 0, processing: 0, failed: 0, retryableFailed, quarantinedFailed, total: 0, stuckProcessing, oldestProcessingAgeMs };
|
|
4136
4151
|
for (const row of rows) {
|
|
4137
4152
|
const key = row.status;
|
|
4138
4153
|
if (key === "pending" || key === "processing" || key === "failed") {
|
|
@@ -4156,6 +4171,22 @@ var SQLiteEventStore = class {
|
|
|
4156
4171
|
FROM embedding_outbox
|
|
4157
4172
|
WHERE status = 'processing'`
|
|
4158
4173
|
);
|
|
4174
|
+
const embeddingRetryableFailed = sqliteGet(
|
|
4175
|
+
this.db,
|
|
4176
|
+
`SELECT COUNT(*) as count
|
|
4177
|
+
FROM embedding_outbox
|
|
4178
|
+
WHERE status = 'failed'
|
|
4179
|
+
AND retry_count < ?`,
|
|
4180
|
+
[maxRetries]
|
|
4181
|
+
);
|
|
4182
|
+
const embeddingQuarantinedFailed = sqliteGet(
|
|
4183
|
+
this.db,
|
|
4184
|
+
`SELECT COUNT(*) as count
|
|
4185
|
+
FROM embedding_outbox
|
|
4186
|
+
WHERE status = 'failed'
|
|
4187
|
+
AND retry_count >= ?`,
|
|
4188
|
+
[maxRetries]
|
|
4189
|
+
);
|
|
4159
4190
|
const vectorStuck = sqliteGet(
|
|
4160
4191
|
this.db,
|
|
4161
4192
|
`SELECT COUNT(*) as count
|
|
@@ -4170,16 +4201,36 @@ var SQLiteEventStore = class {
|
|
|
4170
4201
|
FROM vector_outbox
|
|
4171
4202
|
WHERE status = 'processing'`
|
|
4172
4203
|
);
|
|
4204
|
+
const vectorRetryableFailed = sqliteGet(
|
|
4205
|
+
this.db,
|
|
4206
|
+
`SELECT COUNT(*) as count
|
|
4207
|
+
FROM vector_outbox
|
|
4208
|
+
WHERE status = 'failed'
|
|
4209
|
+
AND retry_count < ?`,
|
|
4210
|
+
[maxRetries]
|
|
4211
|
+
);
|
|
4212
|
+
const vectorQuarantinedFailed = sqliteGet(
|
|
4213
|
+
this.db,
|
|
4214
|
+
`SELECT COUNT(*) as count
|
|
4215
|
+
FROM vector_outbox
|
|
4216
|
+
WHERE status = 'failed'
|
|
4217
|
+
AND retry_count >= ?`,
|
|
4218
|
+
[maxRetries]
|
|
4219
|
+
);
|
|
4173
4220
|
return {
|
|
4174
4221
|
embedding: fromRows(
|
|
4175
4222
|
embeddingRows,
|
|
4176
4223
|
Number(embeddingStuck?.count ?? 0),
|
|
4177
|
-
processingAgeMs(embeddingOldest?.oldest)
|
|
4224
|
+
processingAgeMs(embeddingOldest?.oldest),
|
|
4225
|
+
Number(embeddingRetryableFailed?.count ?? 0),
|
|
4226
|
+
Number(embeddingQuarantinedFailed?.count ?? 0)
|
|
4178
4227
|
),
|
|
4179
4228
|
vector: fromRows(
|
|
4180
4229
|
vectorRows,
|
|
4181
4230
|
Number(vectorStuck?.count ?? 0),
|
|
4182
|
-
processingAgeMs(vectorOldest?.oldest)
|
|
4231
|
+
processingAgeMs(vectorOldest?.oldest),
|
|
4232
|
+
Number(vectorRetryableFailed?.count ?? 0),
|
|
4233
|
+
Number(vectorQuarantinedFailed?.count ?? 0)
|
|
4183
4234
|
)
|
|
4184
4235
|
};
|
|
4185
4236
|
}
|
|
@@ -18384,6 +18435,8 @@ function summarizeProjectOutbox(outbox) {
|
|
|
18384
18435
|
pending: (embedding.pending || 0) + (vector.pending || 0),
|
|
18385
18436
|
processing: (embedding.processing || 0) + (vector.processing || 0),
|
|
18386
18437
|
failed: (embedding.failed || 0) + (vector.failed || 0),
|
|
18438
|
+
retryableFailed: (embedding.retryableFailed || 0) + (vector.retryableFailed || 0),
|
|
18439
|
+
quarantinedFailed: (embedding.quarantinedFailed || 0) + (vector.quarantinedFailed || 0),
|
|
18387
18440
|
stuckProcessing: (embedding.stuckProcessing || 0) + (vector.stuckProcessing || 0)
|
|
18388
18441
|
};
|
|
18389
18442
|
}
|
|
@@ -18721,8 +18774,10 @@ function aggregateOutbox(outbox) {
|
|
|
18721
18774
|
const pending = (outbox.embedding?.pending || 0) + (outbox.vector?.pending || 0);
|
|
18722
18775
|
const processing = (outbox.embedding?.processing || 0) + (outbox.vector?.processing || 0);
|
|
18723
18776
|
const failed = (outbox.embedding?.failed || 0) + (outbox.vector?.failed || 0);
|
|
18777
|
+
const retryableFailed = (outbox.embedding?.retryableFailed || 0) + (outbox.vector?.retryableFailed || 0);
|
|
18778
|
+
const quarantinedFailed = (outbox.embedding?.quarantinedFailed || 0) + (outbox.vector?.quarantinedFailed || 0);
|
|
18724
18779
|
const stuckProcessing = (outbox.embedding?.stuckProcessing || 0) + (outbox.vector?.stuckProcessing || 0);
|
|
18725
|
-
return { pending, processing, failed, stuckProcessing };
|
|
18780
|
+
return { pending, processing, failed, retryableFailed, quarantinedFailed, stuckProcessing };
|
|
18726
18781
|
}
|
|
18727
18782
|
healthRouter.get("/setup", async (c) => {
|
|
18728
18783
|
const memoryService = getLightweightServiceFromQuery(c);
|
|
@@ -18791,6 +18846,8 @@ healthRouter.get("/", async (c) => {
|
|
|
18791
18846
|
const outboxPending = outbox.embedding.pending + outbox.vector.pending;
|
|
18792
18847
|
const outboxProcessing = outbox.embedding.processing + outbox.vector.processing;
|
|
18793
18848
|
const outboxFailed = outbox.embedding.failed + outbox.vector.failed;
|
|
18849
|
+
const outboxRetryableFailed = (outbox.embedding.retryableFailed ?? 0) + (outbox.vector.retryableFailed ?? 0);
|
|
18850
|
+
const outboxQuarantinedFailed = (outbox.embedding.quarantinedFailed ?? 0) + (outbox.vector.quarantinedFailed ?? 0);
|
|
18794
18851
|
const outboxStuckProcessing = outbox.embedding.stuckProcessing + outbox.vector.stuckProcessing;
|
|
18795
18852
|
const oldestProcessingAgeMs = Math.max(
|
|
18796
18853
|
outbox.embedding.oldestProcessingAgeMs ?? 0,
|
|
@@ -18811,6 +18868,8 @@ healthRouter.get("/", async (c) => {
|
|
|
18811
18868
|
pending: outboxPending,
|
|
18812
18869
|
processing: outboxProcessing,
|
|
18813
18870
|
failed: outboxFailed,
|
|
18871
|
+
retryableFailed: outboxRetryableFailed,
|
|
18872
|
+
quarantinedFailed: outboxQuarantinedFailed,
|
|
18814
18873
|
stuckProcessing: outboxStuckProcessing,
|
|
18815
18874
|
oldestProcessingAgeMs
|
|
18816
18875
|
}
|
|
@@ -20843,38 +20902,65 @@ function resolveVectorStatusCommandOptions(options, cwd = process.cwd()) {
|
|
|
20843
20902
|
if (options.project !== void 0 && options.project.trim().length === 0) {
|
|
20844
20903
|
throw new Error("--project must not be empty");
|
|
20845
20904
|
}
|
|
20846
|
-
return { projectPath: options.project ?? cwd };
|
|
20905
|
+
return { projectPath: options.project ?? cwd, json: options.json === true };
|
|
20847
20906
|
}
|
|
20848
20907
|
function formatVectorStatusReport(input) {
|
|
20849
|
-
const
|
|
20850
|
-
const vector =
|
|
20851
|
-
const
|
|
20852
|
-
const status = totals.failed > 0 || totals.stuckProcessing > 0 ? "needs-attention" : "ok";
|
|
20853
|
-
const oldestProcessingAge = maxNullable2(embedding.oldestProcessingAgeMs, vector.oldestProcessingAgeMs);
|
|
20908
|
+
const report = buildVectorStatusReport(input);
|
|
20909
|
+
const { embedding, vector, totals } = report.outbox;
|
|
20910
|
+
const oldestProcessingAge = report.oldestProcessingAgeMs;
|
|
20854
20911
|
const lines = [
|
|
20855
20912
|
"Vector Outbox Status",
|
|
20856
20913
|
`Vector count: ${input.stats.vectorCount}`,
|
|
20857
20914
|
`Total events: ${input.stats.totalEvents}`,
|
|
20858
20915
|
"",
|
|
20859
|
-
"Queue pending processing failed stuck total oldest",
|
|
20916
|
+
"Queue pending processing failed retryable quarantined stuck total oldest",
|
|
20860
20917
|
formatQueueRow("Embedding", embedding),
|
|
20861
20918
|
formatQueueRow("Vector", vector),
|
|
20862
20919
|
formatQueueRow("Total", totals),
|
|
20863
20920
|
"",
|
|
20864
|
-
`Totals: pending=${totals.pending}, processing=${totals.processing}, failed=${totals.failed}, stuck=${totals.stuckProcessing}, total=${totals.total}`,
|
|
20921
|
+
`Totals: pending=${totals.pending}, processing=${totals.processing}, failed=${totals.failed}, retryableFailed=${totals.retryableFailed ?? 0}, quarantinedFailed=${totals.quarantinedFailed ?? 0}, stuck=${totals.stuckProcessing}, total=${totals.total}`,
|
|
20865
20922
|
`Oldest processing age: ${formatDuration2(oldestProcessingAge)}`,
|
|
20866
|
-
`Status: ${status}`
|
|
20923
|
+
`Status: ${report.status}`
|
|
20867
20924
|
];
|
|
20868
|
-
if (
|
|
20925
|
+
if (report.recommendedAction === "run-recovery") {
|
|
20869
20926
|
lines.push("", "Next step: claude-memory-layer process --dry-run-recovery");
|
|
20927
|
+
} else if (report.recommendedAction === "inspect-quarantined") {
|
|
20928
|
+
lines.push("", "Next step: inspect quarantined outbox failures; recovery has no retryable failed rows.");
|
|
20870
20929
|
}
|
|
20871
20930
|
return lines.join("\n");
|
|
20872
20931
|
}
|
|
20932
|
+
function formatVectorStatusJsonReport(input) {
|
|
20933
|
+
return JSON.stringify(buildVectorStatusReport(input), null, 2);
|
|
20934
|
+
}
|
|
20935
|
+
function buildVectorStatusReport(input) {
|
|
20936
|
+
const embedding = normalizeQueue(input.outbox.embedding);
|
|
20937
|
+
const vector = normalizeQueue(input.outbox.vector);
|
|
20938
|
+
const totals = sumQueues(embedding, vector);
|
|
20939
|
+
const status = totals.failed > 0 || totals.stuckProcessing > 0 ? "needs-attention" : "ok";
|
|
20940
|
+
const oldestProcessingAgeMs = maxNullable2(embedding.oldestProcessingAgeMs, vector.oldestProcessingAgeMs);
|
|
20941
|
+
return {
|
|
20942
|
+
storage: {
|
|
20943
|
+
totalEvents: numberOrZero(input.stats.totalEvents),
|
|
20944
|
+
vectorCount: numberOrZero(input.stats.vectorCount)
|
|
20945
|
+
},
|
|
20946
|
+
outbox: { embedding, vector, totals },
|
|
20947
|
+
status,
|
|
20948
|
+
recommendedAction: selectRecommendedAction(totals),
|
|
20949
|
+
oldestProcessingAgeMs
|
|
20950
|
+
};
|
|
20951
|
+
}
|
|
20952
|
+
function selectRecommendedAction(totals) {
|
|
20953
|
+
if ((totals.retryableFailed ?? 0) > 0 || totals.stuckProcessing > 0) return "run-recovery";
|
|
20954
|
+
if ((totals.quarantinedFailed ?? 0) > 0) return "inspect-quarantined";
|
|
20955
|
+
return "none";
|
|
20956
|
+
}
|
|
20873
20957
|
function normalizeQueue(queue) {
|
|
20874
20958
|
return {
|
|
20875
20959
|
pending: numberOrZero(queue.pending),
|
|
20876
20960
|
processing: numberOrZero(queue.processing),
|
|
20877
20961
|
failed: numberOrZero(queue.failed),
|
|
20962
|
+
retryableFailed: numberOrZero(queue.retryableFailed),
|
|
20963
|
+
quarantinedFailed: numberOrZero(queue.quarantinedFailed),
|
|
20878
20964
|
total: numberOrZero(queue.total),
|
|
20879
20965
|
stuckProcessing: numberOrZero(queue.stuckProcessing),
|
|
20880
20966
|
oldestProcessingAgeMs: Number.isFinite(queue.oldestProcessingAgeMs ?? Number.NaN) ? queue.oldestProcessingAgeMs : null
|
|
@@ -20885,6 +20971,8 @@ function sumQueues(a, b) {
|
|
|
20885
20971
|
pending: a.pending + b.pending,
|
|
20886
20972
|
processing: a.processing + b.processing,
|
|
20887
20973
|
failed: a.failed + b.failed,
|
|
20974
|
+
retryableFailed: (a.retryableFailed ?? 0) + (b.retryableFailed ?? 0),
|
|
20975
|
+
quarantinedFailed: (a.quarantinedFailed ?? 0) + (b.quarantinedFailed ?? 0),
|
|
20888
20976
|
stuckProcessing: a.stuckProcessing + b.stuckProcessing,
|
|
20889
20977
|
total: a.total + b.total,
|
|
20890
20978
|
oldestProcessingAgeMs: maxNullable2(a.oldestProcessingAgeMs, b.oldestProcessingAgeMs)
|
|
@@ -20896,6 +20984,8 @@ function formatQueueRow(label, queue) {
|
|
|
20896
20984
|
String(queue.pending).padStart(7),
|
|
20897
20985
|
String(queue.processing).padStart(11),
|
|
20898
20986
|
String(queue.failed).padStart(7),
|
|
20987
|
+
String(queue.retryableFailed ?? 0).padStart(9),
|
|
20988
|
+
String(queue.quarantinedFailed ?? 0).padStart(11),
|
|
20899
20989
|
String(queue.stuckProcessing).padStart(6),
|
|
20900
20990
|
String(queue.total).padStart(6),
|
|
20901
20991
|
formatDuration2(queue.oldestProcessingAgeMs).padStart(7)
|
|
@@ -20907,7 +20997,8 @@ function maxNullable2(a, b) {
|
|
|
20907
20997
|
return Math.max(a, b);
|
|
20908
20998
|
}
|
|
20909
20999
|
function numberOrZero(value) {
|
|
20910
|
-
|
|
21000
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return 0;
|
|
21001
|
+
return Math.floor(value);
|
|
20911
21002
|
}
|
|
20912
21003
|
function formatDuration2(ms) {
|
|
20913
21004
|
if (ms === null) return "none";
|
|
@@ -21538,7 +21629,7 @@ async function runOperationCli(action, label) {
|
|
|
21538
21629
|
}
|
|
21539
21630
|
}
|
|
21540
21631
|
var program = new Command();
|
|
21541
|
-
program.name("claude-memory-layer").description("Claude Code Memory Plugin CLI").version("1.0.
|
|
21632
|
+
program.name("claude-memory-layer").description("Claude Code Memory Plugin CLI").version("1.0.53");
|
|
21542
21633
|
program.command("market-context").description("Fetch read-only DART/FRED/Finnhub context with structured MarketContextSnapshot bull/bear/risk/catalyst analysis").option("--company <name>", "Company name for DART fallback search and report subject").option("--dart-corp-code <code>", "Exact DART corp_code for issuer-specific filings").option("--symbol <ticker>", "Listed ticker for Finnhub company profile").option("--providers <list>", "Comma-separated providers: dart,fred,finnhub").option("--fred-series <list>", "Comma-separated FRED series IDs").option("--json", "Print structured JSON including analysis.marketSnapshot").option("--no-snapshot", "Disable MarketContextSnapshot and DART company snapshot analysis").action(async (options) => {
|
|
21543
21634
|
try {
|
|
21544
21635
|
await runMarketContextCommand(options);
|
|
@@ -21752,7 +21843,7 @@ program.command("stats").description("View memory statistics").option("-p, --pro
|
|
|
21752
21843
|
process.exit(1);
|
|
21753
21844
|
}
|
|
21754
21845
|
});
|
|
21755
|
-
program.command("vector-status").description("Show aggregate vector outbox status").option("-p, --project <path>", "Project path (defaults to cwd)").action(async (options) => {
|
|
21846
|
+
program.command("vector-status").description("Show aggregate vector outbox status").option("-p, --project <path>", "Project path (defaults to cwd)").option("--json", "Print aggregate vector outbox status as JSON for automation").action(async (options) => {
|
|
21756
21847
|
let service;
|
|
21757
21848
|
try {
|
|
21758
21849
|
const vectorOptions = resolveVectorStatusCommandOptions(options);
|
|
@@ -21761,7 +21852,8 @@ program.command("vector-status").description("Show aggregate vector outbox statu
|
|
|
21761
21852
|
service.getStats(),
|
|
21762
21853
|
service.getOutboxStats()
|
|
21763
21854
|
]);
|
|
21764
|
-
|
|
21855
|
+
const rendered = vectorOptions.json ? formatVectorStatusJsonReport({ stats, outbox }) : formatVectorStatusReport({ stats, outbox });
|
|
21856
|
+
console.log(rendered);
|
|
21765
21857
|
} catch (error) {
|
|
21766
21858
|
const message = error instanceof Error && error.message.startsWith("--") ? error.message : "Vector status failed";
|
|
21767
21859
|
console.error(message);
|