claude-memory-layer 2.4.16 → 2.4.17
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/README.md +2 -0
- package/dist/cli/index.js +42 -19
- package/dist/cli/index.js.map +2 -2
- package/dist/core/index.js +41 -18
- package/dist/core/index.js.map +3 -3
- package/dist/hooks/codex-session-import-worker.js +1 -1
- package/dist/hooks/codex-session-start.js +4 -4
- package/dist/hooks/codex-user-prompt-submit.js +2 -2
- package/dist/hooks/post-tool-use.js +1 -1
- package/dist/hooks/semantic-daemon.js +1 -1
- package/dist/hooks/session-end.js +1 -1
- package/dist/hooks/session-start.js +4 -4
- package/dist/hooks/stop.js +1 -1
- package/dist/hooks/user-prompt-submit.js +2 -2
- package/dist/index.js +41 -18
- package/dist/index.js.map +3 -3
- package/dist/mcp/index.js +4 -4
- package/dist/server/api/index.js +1 -1
- package/dist/server/index.js +1 -1
- package/dist/services/codex-host-ingest.js +1 -1
- package/dist/services/lesson-host-service.js +1 -1
- package/dist/services/memory-service.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -639,6 +639,8 @@ claude-memory-layer mongo-sync --watch --interval 30000 --process-after-sync --p
|
|
|
639
639
|
|
|
640
640
|
서버마다 프로젝트 경로가 달라도 됩니다. Pull된 이벤트는 이 서버의 프로젝트(`--project` 경로의 hash)로 다시 귀속되어 project-scoped 검색에 나오며, 원래 서버의 project scope와 hostname은 `metadata.mongoSync`에 남습니다. 같은 프로젝트를 모으려면 모든 서버에서 `--mongo-project`(또는 `CLAUDE_MEMORY_MONGO_PROJECT`)를 같은 값으로 지정하세요. 기본값은 경로의 마지막 폴더 이름입니다.
|
|
641
641
|
|
|
642
|
+
여러 서버가 동시에 push하면 seq를 먼저 예약한 서버의 문서가 늦게 들어올 수 있어, pull은 직전 pull보다 30분 앞부터 들어온 문서를 커서 아래까지 다시 읽습니다(이미 가진 이벤트는 건너뜀). 서버 간 시계 차이도 이 범위 안이어야 합니다.
|
|
643
|
+
|
|
642
644
|
### memU-inspired Retrieval 사용 예시
|
|
643
645
|
|
|
644
646
|
아래 예시는 SDK/서비스 레벨에서 `retrieveMemories()` 호출 시 적용되는 옵션입니다.
|
package/dist/cli/index.js
CHANGED
|
@@ -38,7 +38,7 @@ function emptyLatencyAggregate() {
|
|
|
38
38
|
return { count: 0, failedCount: 0, totalMs: 0, maxMs: 0 };
|
|
39
39
|
}
|
|
40
40
|
function runtimeVersion() {
|
|
41
|
-
const value = "2.4.
|
|
41
|
+
const value = "2.4.17"?.trim();
|
|
42
42
|
return sanitizeRuntimeVersion(value || "development");
|
|
43
43
|
}
|
|
44
44
|
function sanitizeRuntimeVersion(value) {
|
|
@@ -32157,6 +32157,7 @@ function localizePulledMetadata(doc, localProject) {
|
|
|
32157
32157
|
};
|
|
32158
32158
|
return metadata;
|
|
32159
32159
|
}
|
|
32160
|
+
var LATE_INSERT_WINDOW_MS = 30 * 60 * 1e3;
|
|
32160
32161
|
function parseIntOrZero(value) {
|
|
32161
32162
|
if (!value) return 0;
|
|
32162
32163
|
const n = parseInt(value, 10);
|
|
@@ -32283,6 +32284,7 @@ var MongoSyncWorker = class {
|
|
|
32283
32284
|
await this.events.createIndex({ projectKey: 1, seq: 1 }, { unique: true });
|
|
32284
32285
|
await this.events.createIndex({ projectKey: 1, eventId: 1 }, { unique: true });
|
|
32285
32286
|
await this.events.createIndex({ projectKey: 1, dedupeKey: 1 });
|
|
32287
|
+
await this.events.createIndex({ projectKey: 1, insertedAt: 1 });
|
|
32286
32288
|
} catch (err) {
|
|
32287
32289
|
console.warn("[MongoSyncWorker] Failed to ensure indexes (continuing):", err);
|
|
32288
32290
|
}
|
|
@@ -32365,39 +32367,60 @@ var MongoSyncWorker = class {
|
|
|
32365
32367
|
}
|
|
32366
32368
|
return pushed;
|
|
32367
32369
|
}
|
|
32370
|
+
/**
|
|
32371
|
+
* A pusher reserves its seq range before it inserts, so a document can appear below a cursor that another machine's
|
|
32372
|
+
* faster insert already moved past. Each pull therefore re-reads what was inserted shortly before the previous pull
|
|
32373
|
+
* started — import skips the events it already has — and then reads past the cursor as before. The window also
|
|
32374
|
+
* absorbs clock differences between machines (insertedAt is the pusher's clock).
|
|
32375
|
+
*/
|
|
32368
32376
|
async pullEvents() {
|
|
32369
32377
|
if (!this.events) throw new Error("Mongo not connected");
|
|
32370
32378
|
const position = await this.sqliteStore.getSyncPosition(this.pullTargetName());
|
|
32371
32379
|
let lastSeq = parseIntOrZero(position.lastEventId);
|
|
32380
|
+
const startedAt = /* @__PURE__ */ new Date();
|
|
32381
|
+
const previousPullAt = position.lastTimestamp ? new Date(position.lastTimestamp) : null;
|
|
32372
32382
|
let pulled = 0;
|
|
32383
|
+
if (lastSeq > 0 && previousPullAt && !Number.isNaN(previousPullAt.getTime())) {
|
|
32384
|
+
const since = new Date(previousPullAt.getTime() - LATE_INSERT_WINDOW_MS);
|
|
32385
|
+
let afterSeq = 0;
|
|
32386
|
+
while (true) {
|
|
32387
|
+
const docs = await this.events.find(
|
|
32388
|
+
{ projectKey: this.config.projectKey, seq: { $gt: afterSeq, $lte: lastSeq }, insertedAt: { $gte: since } },
|
|
32389
|
+
{ sort: { seq: 1 }, limit: this.config.batchSize }
|
|
32390
|
+
).toArray();
|
|
32391
|
+
if (docs.length === 0) break;
|
|
32392
|
+
pulled += await this.importPulled(docs);
|
|
32393
|
+
afterSeq = docs[docs.length - 1].seq;
|
|
32394
|
+
if (docs.length < this.config.batchSize) break;
|
|
32395
|
+
}
|
|
32396
|
+
}
|
|
32373
32397
|
while (true) {
|
|
32374
32398
|
const docs = await this.events.find(
|
|
32375
32399
|
{ projectKey: this.config.projectKey, seq: { $gt: lastSeq } },
|
|
32376
32400
|
{ sort: { seq: 1 }, limit: this.config.batchSize }
|
|
32377
32401
|
).toArray();
|
|
32378
32402
|
if (docs.length === 0) break;
|
|
32379
|
-
|
|
32380
|
-
id: d.eventId,
|
|
32381
|
-
eventType: d.eventType,
|
|
32382
|
-
sessionId: d.sessionId,
|
|
32383
|
-
timestamp: d.timestamp instanceof Date ? d.timestamp : new Date(d.timestamp),
|
|
32384
|
-
content: d.content,
|
|
32385
|
-
canonicalKey: d.canonicalKey,
|
|
32386
|
-
dedupeKey: d.dedupeKey,
|
|
32387
|
-
metadata: this.config.localProject ? localizePulledMetadata(d, this.config.localProject) : d.metadata ?? void 0
|
|
32388
|
-
}));
|
|
32389
|
-
const result = await this.sqliteStore.importEvents(events);
|
|
32390
|
-
pulled += result.inserted;
|
|
32403
|
+
pulled += await this.importPulled(docs);
|
|
32391
32404
|
lastSeq = docs[docs.length - 1].seq;
|
|
32392
|
-
await this.sqliteStore.updateSyncPosition(
|
|
32393
|
-
this.pullTargetName(),
|
|
32394
|
-
String(lastSeq),
|
|
32395
|
-
(/* @__PURE__ */ new Date()).toISOString()
|
|
32396
|
-
);
|
|
32405
|
+
await this.sqliteStore.updateSyncPosition(this.pullTargetName(), String(lastSeq), startedAt.toISOString());
|
|
32397
32406
|
if (docs.length < this.config.batchSize) break;
|
|
32398
32407
|
}
|
|
32408
|
+
await this.sqliteStore.updateSyncPosition(this.pullTargetName(), String(lastSeq), startedAt.toISOString());
|
|
32399
32409
|
return pulled;
|
|
32400
32410
|
}
|
|
32411
|
+
async importPulled(docs) {
|
|
32412
|
+
const events = docs.map((d) => ({
|
|
32413
|
+
id: d.eventId,
|
|
32414
|
+
eventType: d.eventType,
|
|
32415
|
+
sessionId: d.sessionId,
|
|
32416
|
+
timestamp: d.timestamp instanceof Date ? d.timestamp : new Date(d.timestamp),
|
|
32417
|
+
content: d.content,
|
|
32418
|
+
canonicalKey: d.canonicalKey,
|
|
32419
|
+
dedupeKey: d.dedupeKey,
|
|
32420
|
+
metadata: this.config.localProject ? localizePulledMetadata(d, this.config.localProject) : d.metadata ?? void 0
|
|
32421
|
+
}));
|
|
32422
|
+
return (await this.sqliteStore.importEvents(events)).inserted;
|
|
32423
|
+
}
|
|
32401
32424
|
};
|
|
32402
32425
|
|
|
32403
32426
|
// src/apps/cli/index.ts
|
|
@@ -37031,7 +37054,7 @@ async function runOperationCli(action, label) {
|
|
|
37031
37054
|
}
|
|
37032
37055
|
}
|
|
37033
37056
|
var program = new Command();
|
|
37034
|
-
program.name("claude-memory-layer").description("Claude Code Memory Plugin CLI").version("2.4.
|
|
37057
|
+
program.name("claude-memory-layer").description("Claude Code Memory Plugin CLI").version("2.4.17");
|
|
37035
37058
|
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) => {
|
|
37036
37059
|
try {
|
|
37037
37060
|
await runMarketContextCommand(options);
|