claude-memory-layer 1.0.26 → 1.0.28
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/.env.example +7 -0
- package/AGENTS.md +11 -0
- package/README.md +184 -41
- package/benchmarks/replay/anonymized-real-sessions.json +48 -0
- package/dist/cli/index.js +10097 -6003
- package/dist/cli/index.js.map +4 -4
- package/dist/core/index.js +9745 -5587
- package/dist/core/index.js.map +4 -4
- package/dist/hooks/post-tool-use.js +6545 -5270
- package/dist/hooks/post-tool-use.js.map +4 -4
- package/dist/hooks/semantic-daemon.js +6646 -5354
- package/dist/hooks/semantic-daemon.js.map +4 -4
- package/dist/hooks/session-end.js +6618 -5347
- package/dist/hooks/session-end.js.map +4 -4
- package/dist/hooks/session-start.js +6619 -5354
- package/dist/hooks/session-start.js.map +4 -4
- package/dist/hooks/stop.js +6614 -5325
- package/dist/hooks/stop.js.map +4 -4
- package/dist/hooks/user-prompt-submit.js +6702 -5356
- package/dist/hooks/user-prompt-submit.js.map +4 -4
- package/dist/index.js +13537 -0
- package/dist/index.js.map +7 -0
- package/dist/mcp/index.js +20770 -0
- package/dist/mcp/index.js.map +7 -0
- package/dist/server/api/index.js +6632 -5319
- package/dist/server/api/index.js.map +4 -4
- package/dist/server/index.js +6667 -5340
- package/dist/server/index.js.map +4 -4
- package/dist/services/memory-service.js +6568 -5350
- package/dist/services/memory-service.js.map +4 -4
- package/dist/ui/assets/js/bootstrap.js +244 -0
- package/dist/ui/assets/js/chat.js +373 -0
- package/dist/ui/assets/js/disclosure.js +232 -0
- package/dist/ui/assets/js/modals.js +298 -0
- package/dist/ui/assets/js/overview.js +655 -0
- package/dist/ui/assets/js/state.js +72 -0
- package/dist/ui/assets/js/views.js +468 -0
- package/dist/ui/index.html +43 -1
- package/dist/ui/index.ts +3 -0
- package/dist/ui/style.css +222 -0
- package/docs/ARCHITECTURE_COMPARISON_AND_RECOMMENDATIONS.md +627 -0
- package/docs/HERMES_MEMORY_INGESTION_ANALYSIS.md +440 -0
- package/docs/MEMORY_USEFULNESS_AUDIT.md +371 -0
- package/docs/MEMORY_USEFULNESS_AUDIT_RAW.json +80 -0
- package/docs/MEMSEARCH_PROJECT_STRUCTURE_ANALYSIS.md +333 -0
- package/docs/PRODUCT_VALIDATION_MATRIX.md +82 -0
- package/docs/PROJECT_STRUCTURE_ANALYSIS.md +421 -0
- package/docs/REFACTORING_MILESTONES_AND_ISSUES.md +501 -0
- package/docs/REFACTORING_PLAN_THIN_CORE.md +414 -0
- package/docs/REFERENCE_PROJECT_ANALYSES.md +25 -0
- package/docs/SUPERLOCALMEMORY_PROJECT_STRUCTURE_ANALYSIS.md +452 -0
- package/docs/TARGET_ARCHITECTURE_AND_FOLDER_STRUCTURE.md +446 -0
- package/docs/architecture/comparison-index.md +47 -0
- package/docs/reports/codex-real-data-validation-20260505T040447Z.md +46 -0
- package/package.json +9 -5
- package/scripts/build.ts +25 -8
- package/scripts/generate-session-qrels.ts +126 -0
- package/scripts/replay-retrieval-benchmark.ts +69 -0
- package/specs/thin-core-refactor/context.md +275 -0
- package/specs/thin-core-refactor/plan.md +536 -0
- package/specs/thin-core-refactor/spec.md +465 -0
- package/src/adapters/claude/capture/index.ts +3 -0
- package/src/adapters/claude/context/index.ts +3 -0
- package/src/adapters/claude/hooks/index.ts +21 -0
- package/src/adapters/claude/hooks/post-tool-use.ts +239 -0
- package/src/adapters/claude/hooks/prompt-injection-policy.ts +104 -0
- package/src/adapters/claude/hooks/semantic-daemon-client.ts +209 -0
- package/src/adapters/claude/hooks/semantic-daemon.ts +283 -0
- package/src/adapters/claude/hooks/session-end.ts +59 -0
- package/src/adapters/claude/hooks/session-start.ts +73 -0
- package/src/adapters/claude/hooks/stop.ts +128 -0
- package/src/adapters/claude/hooks/user-prompt-submit.ts +361 -0
- package/src/adapters/claude/index.ts +4 -0
- package/src/adapters/claude/transcript/index.ts +4 -0
- package/src/adapters/claude/transcript/transcript-reader.ts +57 -0
- package/src/adapters/claude/transcript/turn-reconstructor.ts +65 -0
- package/src/apps/cli/claude-settings-hooks.ts +138 -0
- package/src/apps/cli/codex-import-runner.ts +125 -0
- package/src/apps/cli/codex-validation-output.ts +95 -0
- package/src/apps/cli/hermes-import-runner.ts +130 -0
- package/src/apps/cli/hermes-validation-output.ts +91 -0
- package/src/apps/cli/index.ts +1731 -0
- package/src/apps/cli/mcp-install.ts +106 -0
- package/src/apps/cli/retrieval-disclosure-output.ts +196 -0
- package/src/apps/dashboard/assets/js/bootstrap.js +244 -0
- package/src/apps/dashboard/assets/js/chat.js +373 -0
- package/src/apps/dashboard/assets/js/disclosure.js +232 -0
- package/src/apps/dashboard/assets/js/modals.js +298 -0
- package/src/apps/dashboard/assets/js/overview.js +655 -0
- package/src/apps/dashboard/assets/js/state.js +72 -0
- package/src/apps/dashboard/assets/js/views.js +468 -0
- package/src/{ui → apps/dashboard}/index.html +43 -1
- package/src/apps/dashboard/index.ts +3 -0
- package/src/{ui → apps/dashboard}/style.css +222 -0
- package/src/apps/index.ts +5 -0
- package/src/apps/server/api/chat.ts +244 -0
- package/src/apps/server/api/citations.ts +105 -0
- package/src/apps/server/api/events.ts +137 -0
- package/src/apps/server/api/health.ts +53 -0
- package/src/apps/server/api/index.ts +26 -0
- package/src/apps/server/api/projects.ts +74 -0
- package/src/apps/server/api/search.ts +184 -0
- package/src/apps/server/api/sessions.ts +115 -0
- package/src/apps/server/api/stats.ts +723 -0
- package/src/apps/server/api/turns.ts +143 -0
- package/src/apps/server/api/utils.ts +65 -0
- package/src/apps/server/index.ts +111 -0
- package/src/cli/index.ts +2 -1311
- package/src/cli/retrieval-disclosure-output.ts +2 -0
- package/src/compat/index.ts +5 -0
- package/src/core/derive/fact-deriver.ts +170 -0
- package/src/core/derive/index.ts +2 -0
- package/src/core/derive/summary-deriver.ts +76 -0
- package/src/core/embedder.ts +4 -152
- package/src/core/engine/embedding-maintenance-service.ts +187 -0
- package/src/core/engine/endless-memory-services.ts +4 -0
- package/src/core/engine/index.ts +19 -0
- package/src/core/engine/memory-engine-services.ts +170 -0
- package/src/core/engine/memory-ingest-service.ts +317 -0
- package/src/core/engine/memory-query-service.ts +173 -0
- package/src/core/engine/memory-runtime-service.ts +162 -0
- package/src/core/engine/memory-service-composition.ts +231 -0
- package/src/core/engine/retrieval-analytics-service.ts +181 -0
- package/src/core/engine/retrieval-disclosure-service.ts +420 -0
- package/src/core/engine/retrieval-orchestrator.ts +377 -0
- package/src/core/engine/retrieval-services.ts +176 -0
- package/src/core/engine/shared-memory-services.ts +4 -0
- package/src/core/entity-repo.ts +1 -3
- package/src/core/event-store.ts +3 -3
- package/src/core/evidence-aligner.ts +2 -2
- package/src/core/external-market-context.ts +582 -0
- package/src/core/graduation.ts +2 -3
- package/src/core/index.ts +21 -0
- package/src/core/matcher.ts +2 -4
- package/src/core/model/memory-fact.ts +30 -0
- package/src/core/model/memory-rule.ts +14 -0
- package/src/core/model/memory-summary.ts +21 -0
- package/src/core/model/raw-event.ts +28 -0
- package/src/core/model/retrieval-result.ts +35 -0
- package/src/core/privacy/filter.ts +21 -10
- package/src/core/product-validation-matrix.ts +314 -0
- package/src/core/progressive-retriever.ts +1 -2
- package/src/core/registry/project-path.ts +54 -0
- package/src/core/registry/session-registry.ts +69 -0
- package/src/core/replay-evaluator.ts +625 -0
- package/src/core/retrieval-benchmark.ts +117 -0
- package/src/core/retrieval-quality.ts +109 -0
- package/src/core/retriever.ts +53 -15
- package/src/core/session-qrels.ts +360 -0
- package/src/core/shared-event-store.ts +1 -1
- package/src/core/sqlite-event-store.ts +35 -11
- package/src/core/task/blocker-resolver.ts +2 -2
- package/src/core/task/task-resolver.ts +0 -1
- package/src/core/vector-outbox.ts +1 -10
- package/src/core/vector-worker.ts +1 -1
- package/src/extensions/endless-memory/endless-memory-services.ts +350 -0
- package/src/extensions/endless-memory/index.ts +1 -0
- package/src/extensions/index.ts +5 -0
- package/src/extensions/mcp/handlers.ts +960 -0
- package/src/extensions/mcp/index.ts +48 -0
- package/src/extensions/mcp/tools.ts +252 -0
- package/src/extensions/shared-memory/index.ts +1 -0
- package/src/extensions/shared-memory/shared-memory-services.ts +211 -0
- package/src/extensions/vector/embedder.ts +197 -0
- package/src/extensions/vector/index.ts +1 -0
- package/src/hooks/post-tool-use.ts +3 -236
- package/src/hooks/semantic-daemon-client.ts +1 -208
- package/src/hooks/semantic-daemon.ts +6 -271
- package/src/hooks/session-end.ts +4 -79
- package/src/hooks/session-start.ts +4 -73
- package/src/hooks/stop.ts +3 -173
- package/src/hooks/user-prompt-submit.ts +3 -338
- package/src/index.ts +13 -0
- package/src/mcp/handlers.ts +2 -212
- package/src/mcp/index.ts +3 -46
- package/src/mcp/tools.ts +2 -78
- package/src/server/api/chat.ts +2 -244
- package/src/server/api/citations.ts +2 -105
- package/src/server/api/events.ts +2 -137
- package/src/server/api/health.ts +2 -53
- package/src/server/api/index.ts +2 -26
- package/src/server/api/projects.ts +2 -74
- package/src/server/api/search.ts +2 -102
- package/src/server/api/sessions.ts +2 -115
- package/src/server/api/stats.ts +2 -724
- package/src/server/api/turns.ts +2 -143
- package/src/server/api/utils.ts +2 -46
- package/src/server/index.ts +2 -100
- package/src/services/bootstrap-organizer.ts +46 -26
- package/src/services/codex-session-history-importer.ts +521 -29
- package/src/services/hermes-session-history-importer.ts +733 -0
- package/src/services/memory-service-config.ts +36 -0
- package/src/services/memory-service-registry.ts +150 -0
- package/src/services/memory-service.ts +211 -1325
- package/src/services/session-history-importer.ts +58 -14
- package/tests/README.md +23 -0
- package/tests/adapters/claude/claude-semantic-daemon-adapter.test.ts +54 -0
- package/tests/adapters/claude/claude-transcript-reconstructor.test.ts +98 -0
- package/tests/adapters/claude-hook-prompt-injection-policy.test.ts +99 -0
- package/tests/apps/app-layer-boundary.test.ts +48 -0
- package/tests/apps/claude-settings-hooks.test.ts +107 -0
- package/tests/apps/cli-disclosure-output.test.ts +212 -0
- package/tests/apps/codex-import-runner.test.ts +99 -0
- package/tests/apps/codex-validation-output.test.ts +100 -0
- package/tests/apps/hermes-import-runner.test.ts +99 -0
- package/tests/apps/mcp-install-command.test.ts +59 -0
- package/tests/apps/package-build-entrypoints.test.ts +30 -0
- package/tests/apps/search-api-disclosure.test.ts +162 -0
- package/tests/apps/stats-api-lightweight.test.ts +67 -0
- package/tests/apps/ui-disclosure-output.test.ts +140 -0
- package/tests/{bootstrap-organizer.test.ts → core/bootstrap-organizer.test.ts} +1 -1
- package/tests/{canonical-key.test.ts → core/canonical-key.test.ts} +1 -1
- package/tests/core/codex-session-history-importer-validation.test.ts +185 -0
- package/tests/{consolidation-worker.test.ts → core/consolidation-worker.test.ts} +2 -2
- package/tests/core/embedding-maintenance-service.test.ts +282 -0
- package/tests/{evidence-aligner.test.ts → core/evidence-aligner.test.ts} +1 -1
- package/tests/core/external-market-context.test.ts +209 -0
- package/tests/core/fact-deriver.test.ts +79 -0
- package/tests/core/hermes-session-history-importer-validation.test.ts +609 -0
- package/tests/{ingest-interceptor.test.ts → core/ingest-interceptor.test.ts} +1 -1
- package/tests/{markdown-mirror.test.ts → core/markdown-mirror.test.ts} +2 -2
- package/tests/{matcher.test.ts → core/matcher.test.ts} +1 -1
- package/tests/{md-mirror.test.ts → core/md-mirror.test.ts} +2 -2
- package/tests/core/memory-engine-services.test.ts +240 -0
- package/tests/core/memory-ingest-service.test.ts +296 -0
- package/tests/core/memory-query-service.test.ts +129 -0
- package/tests/core/memory-runtime-service.test.ts +201 -0
- package/tests/core/memory-service-composition.test.ts +192 -0
- package/tests/core/memory-service-config.test.ts +41 -0
- package/tests/core/memory-service-facade.test.ts +30 -0
- package/tests/core/memory-service-registry.test.ts +206 -0
- package/tests/core/product-validation-matrix.test.ts +61 -0
- package/tests/core/project-registry.test.ts +78 -0
- package/tests/core/replay-evaluator.test.ts +181 -0
- package/tests/core/retrieval-analytics-service.test.ts +210 -0
- package/tests/core/retrieval-benchmark.test.ts +93 -0
- package/tests/core/retrieval-disclosure-service.test.ts +264 -0
- package/tests/core/retrieval-orchestrator.test.ts +403 -0
- package/tests/core/retrieval-quality.test.ts +31 -0
- package/tests/core/retrieval-services.test.ts +185 -0
- package/tests/{retriever-fallback-chain.test.ts → core/retriever-fallback-chain.test.ts} +3 -3
- package/tests/{retriever-strategy-scope.test.ts → core/retriever-strategy-scope.test.ts} +70 -3
- package/tests/{retriever.memu-adoption.test.ts → core/retriever.memu-adoption.test.ts} +3 -3
- package/tests/core/session-history-importer-filter.test.ts +78 -0
- package/tests/core/session-qrels.test.ts +250 -0
- package/tests/{sqlite-event-store-replication.test.ts → core/sqlite-event-store-replication.test.ts} +36 -1
- package/tests/core/summary-deriver.test.ts +66 -0
- package/tests/extensions/embedder-warning-suppression.test.ts +53 -0
- package/tests/extensions/endless-memory-extension-boundary.test.ts +17 -0
- package/tests/extensions/endless-memory-services.test.ts +325 -0
- package/tests/extensions/mcp-context-tools.test.ts +905 -0
- package/tests/extensions/mcp-extension-boundary.test.ts +21 -0
- package/tests/extensions/mcp-package-build.test.ts +22 -0
- package/tests/extensions/mcp-project-aware-tools.test.ts +102 -0
- package/tests/extensions/shared-memory-extension-boundary.test.ts +24 -0
- package/tests/extensions/shared-memory-services.test.ts +309 -0
- package/tests/extensions/vector-extension-boundary.test.ts +21 -0
- package/.claude/settings.local.json +0 -25
- package/.npm-cache/_cacache/content-v2/sha512/04/76/c098f88dfe584a2b80870bff7421b05d17d3d9ee1027f77772332a22d3f93a9a57101a2855107f6ad82077a818bba912b2bc317f2361b5ddb09ad284d9ce +0 -0
- package/.npm-cache/_cacache/content-v2/sha512/60/25/d2ecd39cfc7cab58351162814be77f935c6d6491c10c3745d456da7ddb2117ffd90c10e53fe3c0f1ed16b403307841543634504398b16ee4e6b6dd8e0c45 +0 -0
- package/.npm-cache/_cacache/index-v5/2b/9a/7f8f40206ed8a2e0a84efaa953ccaed1f5d001e14b931083f2e7a0738007 +0 -2
- package/.npm-cache/_cacache/index-v5/2e/d9/fcfa5c6a6abdc2a3644ab84a95936047298c465a2f47ee03db8f7fe1e946 +0 -3
- package/.npm-cache/_cacache/index-v5/a9/42/e519633356d12d3d2f19da66a8301016d496c8f5c3e0554124aaa62dc043 +0 -2
- package/.npm-cache/_logs/2026-02-26T12_04_52_729Z-debug-0.log +0 -256
- package/.npm-cache/_logs/2026-02-26T12_05_36_835Z-debug-0.log +0 -18
- package/.npm-cache/_logs/2026-02-26T12_05_45_982Z-debug-0.log +0 -32
- package/.npm-cache/_logs/2026-02-26T12_05_48_515Z-debug-0.log +0 -260
- package/.npm-cache/_logs/2026-02-26T12_05_53_567Z-debug-0.log +0 -69
- package/.npm-cache/_update-notifier-last-checked +0 -0
- package/bootstrap-kb/decisions/decisions.md +0 -244
- package/bootstrap-kb/glossary/glossary.md +0 -46
- package/bootstrap-kb/modules/.claude-plugin.md +0 -22
- package/bootstrap-kb/modules/agents.md.md +0 -15
- package/bootstrap-kb/modules/claude.md.md +0 -15
- package/bootstrap-kb/modules/context.md.md +0 -15
- package/bootstrap-kb/modules/docs.md +0 -18
- package/bootstrap-kb/modules/handoff.md.md +0 -15
- package/bootstrap-kb/modules/package-lock.json.md +0 -15
- package/bootstrap-kb/modules/package.json.md +0 -15
- package/bootstrap-kb/modules/plan.md.md +0 -15
- package/bootstrap-kb/modules/readme.md.md +0 -15
- package/bootstrap-kb/modules/scripts.md +0 -26
- package/bootstrap-kb/modules/spec.md.md +0 -15
- package/bootstrap-kb/modules/specs.md +0 -20
- package/bootstrap-kb/modules/src.md +0 -51
- package/bootstrap-kb/modules/tests.md +0 -42
- package/bootstrap-kb/modules/tsconfig.json.md +0 -15
- package/bootstrap-kb/modules/vitest.config.ts.md +0 -15
- package/bootstrap-kb/overview/overview.md +0 -40
- package/bootstrap-kb/sources/manifest.json +0 -950
- package/bootstrap-kb/sources/manifest.md +0 -227
- package/bootstrap-kb/timeline/timeline.md +0 -57
- package/claude-memory-layer-1.0.14.tgz +0 -0
- package/d.sh +0 -3
- package/deploy.sh +0 -3
- package/dist/ui/app.js +0 -2101
- package/memory/.claude-plugin/commands/2026-02-25.md +0 -263
- package/memory/_index.md +0 -418
- package/memory/agent_response/uncategorized/2026-02-26.md +0 -176
- package/memory/agent_response/uncategorized/2026-03-03.md +0 -14
- package/memory/agent_response/uncategorized/2026-03-04.md +0 -1421
- package/memory/agent_response/uncategorized/2026-03-05.md +0 -48
- package/memory/default/uncategorized/2026-02-25.md +0 -4839
- package/memory/session_summary/uncategorized/2026-02-26.md +0 -13
- package/memory/session_summary/uncategorized/2026-03-03.md +0 -5
- package/memory/session_summary/uncategorized/2026-03-04.md +0 -50
- package/memory/specs/20260207-dashboard-upgrade/2026-02-25.md +0 -142
- package/memory/specs/citations-system/2026-02-25.md +0 -1121
- package/memory/specs/endless-mode/2026-02-25.md +0 -1392
- package/memory/specs/entity-edge-model/2026-02-25.md +0 -1263
- package/memory/specs/evidence-aligner-v2/2026-02-25.md +0 -1028
- package/memory/specs/mcp-desktop-integration/2026-02-25.md +0 -1334
- package/memory/specs/post-tool-use-hook/2026-02-25.md +0 -1164
- package/memory/specs/private-tags/2026-02-25.md +0 -1057
- package/memory/specs/progressive-disclosure/2026-02-25.md +0 -1436
- package/memory/specs/task-entity-system/2026-02-25.md +0 -924
- package/memory/specs/vector-outbox-v2/2026-02-25.md +0 -1510
- package/memory/specs/web-viewer-ui/2026-02-25.md +0 -1709
- package/memory/tool_observation/uncategorized/2026-02-26.md +0 -209
- package/memory/tool_observation/uncategorized/2026-03-03.md +0 -21
- package/memory/tool_observation/uncategorized/2026-03-04.md +0 -1033
- package/memory/tool_observation/uncategorized/2026-03-05.md +0 -29
- package/memory/user_prompt/uncategorized/2026-02-26.md +0 -25
- package/memory/user_prompt/uncategorized/2026-03-04.md +0 -634
- package/specs/optional-duckdb/context.md +0 -77
- package/specs/optional-duckdb/plan.md +0 -142
- package/specs/optional-duckdb/spec.md +0 -35
- package/src/ui/app.js +0 -2101
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import * as path from 'node:path';
|
|
5
|
+
import {
|
|
6
|
+
buildSessionQrelsFixtureFromJsonl,
|
|
7
|
+
collectClaudeSessionJsonlFiles,
|
|
8
|
+
summarizeSessionQrelsFixture,
|
|
9
|
+
type SessionQrelsNoMatchQueryInput
|
|
10
|
+
} from '../src/core/session-qrels.js';
|
|
11
|
+
|
|
12
|
+
const args = process.argv.slice(2);
|
|
13
|
+
|
|
14
|
+
void main(args);
|
|
15
|
+
|
|
16
|
+
async function main(argv: string[]): Promise<void> {
|
|
17
|
+
const sessions: string[] = [];
|
|
18
|
+
const sessionDirs: string[] = [];
|
|
19
|
+
let outPath = '';
|
|
20
|
+
let summaryOutPath = '';
|
|
21
|
+
let name = 'session-qrels-fixture';
|
|
22
|
+
let ks = [1, 3, 5];
|
|
23
|
+
let maxQueries: number | undefined;
|
|
24
|
+
let maxFiles: number | undefined;
|
|
25
|
+
let minBytes = 0;
|
|
26
|
+
let redactContent = false;
|
|
27
|
+
let includeSubagents = false;
|
|
28
|
+
const noMatchQueries: SessionQrelsNoMatchQueryInput[] = [];
|
|
29
|
+
|
|
30
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
31
|
+
const arg = argv[i];
|
|
32
|
+
if (arg === '--session') {
|
|
33
|
+
const value = argv[++i];
|
|
34
|
+
if (value) sessions.push(value);
|
|
35
|
+
} else if (arg === '--sessions-dir' || arg === '--session-dir') {
|
|
36
|
+
const value = argv[++i];
|
|
37
|
+
if (value) sessionDirs.push(value);
|
|
38
|
+
} else if (arg === '--out') {
|
|
39
|
+
outPath = argv[++i] ?? '';
|
|
40
|
+
} else if (arg === '--summary-out') {
|
|
41
|
+
summaryOutPath = argv[++i] ?? '';
|
|
42
|
+
} else if (arg === '--name') {
|
|
43
|
+
name = argv[++i] ?? name;
|
|
44
|
+
} else if (arg === '--ks') {
|
|
45
|
+
ks = (argv[++i] ?? '').split(',').map((value) => Number(value.trim())).filter(Number.isFinite);
|
|
46
|
+
} else if (arg === '--max-queries') {
|
|
47
|
+
const parsed = Number(argv[++i]);
|
|
48
|
+
maxQueries = Number.isFinite(parsed) ? parsed : undefined;
|
|
49
|
+
} else if (arg === '--max-files') {
|
|
50
|
+
const parsed = Number(argv[++i]);
|
|
51
|
+
maxFiles = Number.isFinite(parsed) ? parsed : undefined;
|
|
52
|
+
} else if (arg === '--min-bytes') {
|
|
53
|
+
const parsed = Number(argv[++i]);
|
|
54
|
+
minBytes = Number.isFinite(parsed) ? parsed : minBytes;
|
|
55
|
+
} else if (arg === '--redact-content') {
|
|
56
|
+
redactContent = true;
|
|
57
|
+
} else if (arg === '--include-subagents') {
|
|
58
|
+
includeSubagents = true;
|
|
59
|
+
} else if (arg === '--no-match-query' || arg === '--negative-query') {
|
|
60
|
+
const query = argv[++i];
|
|
61
|
+
if (query) noMatchQueries.push({ query });
|
|
62
|
+
} else if (arg === '--no-match-forbidden-ids' || arg === '--negative-forbidden-ids') {
|
|
63
|
+
const value = argv[++i] ?? '';
|
|
64
|
+
const forbiddenIds = value.split(',').map((id) => id.trim()).filter(Boolean);
|
|
65
|
+
const last = noMatchQueries[noMatchQueries.length - 1];
|
|
66
|
+
if (last) last.forbiddenIds = forbiddenIds;
|
|
67
|
+
} else if (!arg.startsWith('--')) {
|
|
68
|
+
sessions.push(arg);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
for (const sessionDir of sessionDirs) {
|
|
73
|
+
const discovered = await collectClaudeSessionJsonlFiles(expandUserPath(sessionDir), {
|
|
74
|
+
includeSubagents,
|
|
75
|
+
maxFiles,
|
|
76
|
+
minBytes
|
|
77
|
+
});
|
|
78
|
+
sessions.push(...discovered);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const uniqueSessions = Array.from(new Set(sessions.map(expandUserPath)));
|
|
82
|
+
|
|
83
|
+
if (uniqueSessions.length === 0) {
|
|
84
|
+
console.error('Usage: tsx scripts/generate-session-qrels.ts --session <claude.jsonl> [--session <more.jsonl>] [--sessions-dir ~/.claude/projects] [--max-files 50] [--out fixture.json] [--summary-out summary.json] [--ks 1,3,5] [--redact-content] [--no-match-query "query" --no-match-forbidden-ids id1,id2]');
|
|
85
|
+
process.exit(2);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (!redactContent) {
|
|
89
|
+
console.error('WARNING: generated qrels include raw user prompts and assistant responses. Review before committing or sharing, or pass --redact-content for shareable metadata.');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const generatedAt = new Date().toISOString();
|
|
93
|
+
const jsonl = (await Promise.all(uniqueSessions.map((session) => readFile(session, 'utf8')))).join('\n');
|
|
94
|
+
const fixture = buildSessionQrelsFixtureFromJsonl(jsonl, {
|
|
95
|
+
name,
|
|
96
|
+
ks,
|
|
97
|
+
maxQueries,
|
|
98
|
+
redactContent,
|
|
99
|
+
sourceFileCount: uniqueSessions.length,
|
|
100
|
+
rawContentIncluded: !redactContent,
|
|
101
|
+
generatedAt,
|
|
102
|
+
noMatchQueries
|
|
103
|
+
});
|
|
104
|
+
const output = `${JSON.stringify(fixture, null, 2)}\n`;
|
|
105
|
+
const summary = summarizeSessionQrelsFixture(fixture);
|
|
106
|
+
|
|
107
|
+
if (outPath) {
|
|
108
|
+
await mkdir(path.dirname(expandUserPath(outPath)), { recursive: true });
|
|
109
|
+
await writeFile(expandUserPath(outPath), output, 'utf8');
|
|
110
|
+
} else {
|
|
111
|
+
process.stdout.write(output);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (summaryOutPath) {
|
|
115
|
+
await mkdir(path.dirname(expandUserPath(summaryOutPath)), { recursive: true });
|
|
116
|
+
await writeFile(expandUserPath(summaryOutPath), `${JSON.stringify(summary, null, 2)}\n`, 'utf8');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
console.error(`Generated ${summary.queryCount} qrels from ${uniqueSessions.length} Claude JSONL file(s).`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function expandUserPath(value: string): string {
|
|
123
|
+
if (value === '~') return homedir();
|
|
124
|
+
if (value.startsWith('~/')) return path.join(homedir(), value.slice(2));
|
|
125
|
+
return value;
|
|
126
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import {
|
|
5
|
+
evaluateReplayFixture,
|
|
6
|
+
formatReplayEvaluationMarkdown,
|
|
7
|
+
type ReplayEvaluationFixture
|
|
8
|
+
} from '../src/core/replay-evaluator.js';
|
|
9
|
+
import type { RetrievalStrategy } from '../src/core/retriever.js';
|
|
10
|
+
|
|
11
|
+
const args = process.argv.slice(2);
|
|
12
|
+
|
|
13
|
+
void main(args);
|
|
14
|
+
|
|
15
|
+
async function main(argv: string[]): Promise<void> {
|
|
16
|
+
let fixturePath = path.join('benchmarks', 'replay', 'anonymized-real-sessions.json');
|
|
17
|
+
let outPath = '';
|
|
18
|
+
let format: 'json' | 'markdown' = 'json';
|
|
19
|
+
let includePerQuery = true;
|
|
20
|
+
let strategy: RetrievalStrategy | undefined;
|
|
21
|
+
let topK: number | undefined;
|
|
22
|
+
let minScore: number | undefined;
|
|
23
|
+
let positionalFixtureConsumed = false;
|
|
24
|
+
|
|
25
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
26
|
+
const arg = argv[i];
|
|
27
|
+
if (arg === '--fixture') {
|
|
28
|
+
fixturePath = argv[++i] ?? fixturePath;
|
|
29
|
+
} else if (arg === '--out' || arg === '--report-out') {
|
|
30
|
+
outPath = argv[++i] ?? '';
|
|
31
|
+
} else if (arg === '--format') {
|
|
32
|
+
const parsed = argv[++i];
|
|
33
|
+
if (parsed === 'markdown' || parsed === 'json') format = parsed;
|
|
34
|
+
} else if (arg === '--no-per-query') {
|
|
35
|
+
includePerQuery = false;
|
|
36
|
+
} else if (arg === '--strategy') {
|
|
37
|
+
const parsed = argv[++i];
|
|
38
|
+
if (parsed === 'auto' || parsed === 'fast' || parsed === 'deep') strategy = parsed;
|
|
39
|
+
} else if (arg === '--top-k' || arg === '--topK') {
|
|
40
|
+
const parsed = Number(argv[++i]);
|
|
41
|
+
topK = Number.isFinite(parsed) ? parsed : undefined;
|
|
42
|
+
} else if (arg === '--min-score') {
|
|
43
|
+
const parsed = Number(argv[++i]);
|
|
44
|
+
minScore = Number.isFinite(parsed) ? parsed : undefined;
|
|
45
|
+
} else if (!arg.startsWith('--') && !positionalFixtureConsumed) {
|
|
46
|
+
fixturePath = arg;
|
|
47
|
+
positionalFixtureConsumed = true;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const fixture = JSON.parse(await readFile(fixturePath, 'utf8')) as ReplayEvaluationFixture;
|
|
52
|
+
const report = await evaluateReplayFixture(fixture, {
|
|
53
|
+
includePerQuery,
|
|
54
|
+
topK,
|
|
55
|
+
retrievalOptions: {
|
|
56
|
+
...(strategy ? { strategy } : {}),
|
|
57
|
+
...(minScore !== undefined ? { minScore } : {})
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
const output = format === 'markdown'
|
|
61
|
+
? formatReplayEvaluationMarkdown(report, { qrelsPath: fixturePath })
|
|
62
|
+
: `${JSON.stringify(report, null, 2)}\n`;
|
|
63
|
+
|
|
64
|
+
if (outPath) {
|
|
65
|
+
await writeFile(outPath, output, 'utf8');
|
|
66
|
+
} else {
|
|
67
|
+
process.stdout.write(output);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# Thin Core Refactor Context
|
|
2
|
+
|
|
3
|
+
> **Version**: 1.0.0
|
|
4
|
+
> **Created**: 2026-04-30
|
|
5
|
+
|
|
6
|
+
## 1. 배경
|
|
7
|
+
|
|
8
|
+
`claude-memory-layer`는 본래 Claude Code용 메모리 플러그인/레이어로 출발했지만, 현재는 다음을 모두 품고 있다.
|
|
9
|
+
|
|
10
|
+
- hook-based memory capture
|
|
11
|
+
- SQLite primary event storage
|
|
12
|
+
- vector indexing and retrieval
|
|
13
|
+
- markdown mirror
|
|
14
|
+
- local dashboard and REST API
|
|
15
|
+
- shared memory concepts
|
|
16
|
+
- optional Mongo sync
|
|
17
|
+
- continuity / working set / consolidated memories
|
|
18
|
+
- partial MCP surface
|
|
19
|
+
|
|
20
|
+
이 자체는 강점이다. 하지만 시간이 지나며 **코어 엔진과 확장 기능의 경계가 흐려지고 있다.**
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 2. 현재 구조의 핵심 특징
|
|
25
|
+
|
|
26
|
+
### 2.1 강점
|
|
27
|
+
|
|
28
|
+
1. **Claude lifecycle에 깊게 붙어 있음**
|
|
29
|
+
- SessionStart / UserPromptSubmit / PostToolUse / Stop / SessionEnd를 통한 풍부한 capture 가능
|
|
30
|
+
|
|
31
|
+
2. **실전적인 retrieval**
|
|
32
|
+
- vector + keyword + fallback chain + progressive retrieval + semantic daemon
|
|
33
|
+
|
|
34
|
+
3. **프로젝트 격리 설계**
|
|
35
|
+
- project hash 기반 local storage isolation
|
|
36
|
+
|
|
37
|
+
4. **운영 관찰성**
|
|
38
|
+
- dashboard, health, retrieval traces, helpfulness signals
|
|
39
|
+
|
|
40
|
+
### 2.2 약점
|
|
41
|
+
|
|
42
|
+
1. **`MemoryService` 비대화**
|
|
43
|
+
- orchestration을 넘어 multi-subsystem god service에 가까워짐
|
|
44
|
+
|
|
45
|
+
2. **source of truth ambiguity 위험**
|
|
46
|
+
- SQLite / LanceDB / markdown / shared / Mongo sync의 관계가 신규 독자에게 즉시 명확하지 않음
|
|
47
|
+
|
|
48
|
+
3. **문서 drift**
|
|
49
|
+
- docs와 실제 코드가 일부 어긋남
|
|
50
|
+
|
|
51
|
+
4. **확장 기능의 코어 침투**
|
|
52
|
+
- shared / continuity / analytics / vector concerns가 코어 경계 안에 많이 들어와 있음
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 3. 외부 레퍼런스에서 얻은 시사점
|
|
57
|
+
|
|
58
|
+
## 3.1 memsearch에서 얻은 시사점
|
|
59
|
+
|
|
60
|
+
`memsearch`의 가장 큰 장점은 **코어가 작고 선명하다**는 점이다.
|
|
61
|
+
|
|
62
|
+
배울 점:
|
|
63
|
+
1. **source of truth가 분명함**
|
|
64
|
+
- markdown canonical, vector index derived
|
|
65
|
+
|
|
66
|
+
2. **plugin/adaptation 분리**
|
|
67
|
+
- core library와 platform integration이 비교적 분리됨
|
|
68
|
+
|
|
69
|
+
3. **progressive disclosure UX**
|
|
70
|
+
- search → expand → transcript drill-down
|
|
71
|
+
|
|
72
|
+
4. **incremental / deterministic indexing 관점**
|
|
73
|
+
- stable chunk IDs
|
|
74
|
+
|
|
75
|
+
해석:
|
|
76
|
+
- `claude-memory-layer`는 memsearch처럼 단순해질 필요는 없지만,
|
|
77
|
+
- 최소한 **코어를 다시 설명 가능한 단위로 줄이는 discipline**은 배워야 한다.
|
|
78
|
+
|
|
79
|
+
## 3.2 superlocalmemory에서 얻은 시사점
|
|
80
|
+
|
|
81
|
+
`superlocalmemory`는 엄청 강력하지만 매우 큰 플랫폼이다.
|
|
82
|
+
|
|
83
|
+
가져올 만한 개념:
|
|
84
|
+
1. **raw memory vs atomic facts 분리**
|
|
85
|
+
2. **SQLite 중심 로컬 엔진 철학**
|
|
86
|
+
3. **검색 결과 explainability**
|
|
87
|
+
4. **lightweight feedback loop**
|
|
88
|
+
|
|
89
|
+
가져오지 말아야 할 것:
|
|
90
|
+
1. full platform sprawl
|
|
91
|
+
2. 너무 넓은 MCP/mesh/systems surface
|
|
92
|
+
3. 한 repo에 너무 많은 제품 축을 동시에 키우는 방식
|
|
93
|
+
|
|
94
|
+
해석:
|
|
95
|
+
- `claude-memory-layer`는 superlocalmemory처럼 모든 방향으로 커지기보다,
|
|
96
|
+
- 거기서 **좋은 모델링 개념만 선택적으로 흡수**해야 한다.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 4. 왜 thin-core 방향인가
|
|
101
|
+
|
|
102
|
+
thin-core 방향은 단순히 “코드를 예쁘게 나누자”는 얘기가 아니다.
|
|
103
|
+
|
|
104
|
+
이 방향이 필요한 이유는 다음과 같다.
|
|
105
|
+
|
|
106
|
+
### 4.1 유지보수 속도 회복
|
|
107
|
+
기능이 많을수록, 새로운 기능 추가보다 “어디에 넣어야 하는지” 결정 비용이 커진다.
|
|
108
|
+
경계를 다시 세우지 않으면 개발 속도가 급격히 느려진다.
|
|
109
|
+
|
|
110
|
+
### 4.2 오류 격리
|
|
111
|
+
vector, hooks, shared memory, dashboard, MCP 문제가 모두 core 문제처럼 보이면 디버깅이 어려워진다.
|
|
112
|
+
|
|
113
|
+
### 4.3 테스트 구조 단순화
|
|
114
|
+
core / adapter / extension / app이 분리되면,
|
|
115
|
+
각 계층 테스트 목적이 분명해진다.
|
|
116
|
+
|
|
117
|
+
### 4.4 제품 집중력 유지
|
|
118
|
+
현재 프로젝트의 가장 큰 강점은 “Claude 특화 memory experience”다.
|
|
119
|
+
이를 유지하려면 오히려 코어를 가볍게 만들어 adapter 경쟁력을 살려야 한다.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 5. 새 구조의 개념적 역할
|
|
124
|
+
|
|
125
|
+
### Core
|
|
126
|
+
이 시스템이 **반드시** 해야 하는 일만 맡는다.
|
|
127
|
+
|
|
128
|
+
- raw events 저장
|
|
129
|
+
- facts/summaries derivation
|
|
130
|
+
- retrieval
|
|
131
|
+
- source tracing
|
|
132
|
+
- registry
|
|
133
|
+
- journal projection
|
|
134
|
+
|
|
135
|
+
### Adapter (Claude)
|
|
136
|
+
Claude Code라는 외부 시스템과 대화하는 법을 안다.
|
|
137
|
+
|
|
138
|
+
- hook payload
|
|
139
|
+
- transcript parsing
|
|
140
|
+
- tool capture policy
|
|
141
|
+
- additionalContext formatting
|
|
142
|
+
|
|
143
|
+
### Extensions
|
|
144
|
+
있으면 좋은 기능들.
|
|
145
|
+
|
|
146
|
+
- vector acceleration
|
|
147
|
+
- analytics
|
|
148
|
+
- shared memory
|
|
149
|
+
- Mongo sync
|
|
150
|
+
- MCP
|
|
151
|
+
- continuity systems
|
|
152
|
+
|
|
153
|
+
### Apps
|
|
154
|
+
사용자-facing entrypoints.
|
|
155
|
+
|
|
156
|
+
- CLI
|
|
157
|
+
- server
|
|
158
|
+
- dashboard
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## 6. 핵심 도메인 재정의 이유
|
|
163
|
+
|
|
164
|
+
### 6.1 RawEvent
|
|
165
|
+
현재 시스템은 대화/툴/세션 마커가 모두 비슷한 흐름으로 다뤄지지만, conceptual model은 충분히 분명하지 않다.
|
|
166
|
+
|
|
167
|
+
RawEvent를 분리하면:
|
|
168
|
+
- ingest가 단순해지고
|
|
169
|
+
- 원본 보존이 쉬워지고
|
|
170
|
+
- source tracing이 쉬워진다.
|
|
171
|
+
|
|
172
|
+
### 6.2 MemoryFact
|
|
173
|
+
검색 시스템이 진짜 필요로 하는 것은 항상 전체 transcript가 아니다.
|
|
174
|
+
작고 검색 가능한 fact unit이 더 실용적이다.
|
|
175
|
+
|
|
176
|
+
분리 효과:
|
|
177
|
+
- retrieval 품질 향상
|
|
178
|
+
- future reranking 확장 쉬움
|
|
179
|
+
- code-aware anchor 연결 쉬움
|
|
180
|
+
|
|
181
|
+
### 6.3 MemorySummary
|
|
182
|
+
session/project continuity는 중요하지만 raw event와 같은 층에 두면 혼란스럽다.
|
|
183
|
+
요약을 별도 층으로 두면:
|
|
184
|
+
- low-token retrieval
|
|
185
|
+
- dashboard readability
|
|
186
|
+
- export/journal readability
|
|
187
|
+
가 좋아진다.
|
|
188
|
+
|
|
189
|
+
### 6.4 MemoryRule
|
|
190
|
+
반복되는 선호/관례는 단순 fact가 아니다.
|
|
191
|
+
별도 개념으로 두는 편이 장기적으로 낫다.
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## 7. 저장 계층 역할 정리 배경
|
|
196
|
+
|
|
197
|
+
현재는 “실제로 뭐가 원본이고 뭐가 파생인지”를 코드를 다 읽어야 이해된다.
|
|
198
|
+
이건 좋지 않다.
|
|
199
|
+
|
|
200
|
+
권장 해석:
|
|
201
|
+
- **SQLite** = authoritative store
|
|
202
|
+
- **Markdown journal** = 사람이 읽는 canonical projection
|
|
203
|
+
- **LanceDB** = disposable acceleration layer
|
|
204
|
+
- **shared/Mongo** = replication/extension
|
|
205
|
+
|
|
206
|
+
이 정리가 있으면:
|
|
207
|
+
- 운영 판단이 쉬워지고
|
|
208
|
+
- 장애 복구가 쉬워지고
|
|
209
|
+
- 문서가 정직해진다.
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## 8. retrieval UX를 왜 제품화해야 하나
|
|
214
|
+
|
|
215
|
+
현재 retrieval 능력 자체는 이미 꽤 좋다.
|
|
216
|
+
문제는 그것이 사용자/개발자에게 **명확한 mental model**로 전달되지 않는다는 점이다.
|
|
217
|
+
|
|
218
|
+
memsearch의 시사점:
|
|
219
|
+
- search
|
|
220
|
+
- expand
|
|
221
|
+
- transcript/source
|
|
222
|
+
|
|
223
|
+
이 3단 구조는 매우 이해하기 쉽다.
|
|
224
|
+
|
|
225
|
+
`claude-memory-layer`도 이를 도입하면:
|
|
226
|
+
- CLI가 더 명확해지고
|
|
227
|
+
- API가 더 깔끔해지고
|
|
228
|
+
- dashboard도 더 설명 가능해진다.
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## 9. 코드 레벨 이행 전략 배경
|
|
233
|
+
|
|
234
|
+
완전 재작성은 위험하다.
|
|
235
|
+
이 프로젝트는 이미 훅/CLI/server/dashboard가 연결되어 있어 regression 위험이 크다.
|
|
236
|
+
|
|
237
|
+
따라서 다음 전략이 적합하다.
|
|
238
|
+
|
|
239
|
+
### Strangler migration
|
|
240
|
+
1. 새 경계 먼저 만든다
|
|
241
|
+
2. 새 타입 먼저 도입한다
|
|
242
|
+
3. 기존 facade는 유지한다
|
|
243
|
+
4. 내부 구현만 조금씩 새 서비스로 대체한다
|
|
244
|
+
5. 마지막에 legacy wrapper를 줄인다
|
|
245
|
+
|
|
246
|
+
이 전략의 장점:
|
|
247
|
+
- 작은 커밋 가능
|
|
248
|
+
- revert 쉬움
|
|
249
|
+
- 기능 중단 최소화
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## 10. 성공 시 기대 상태
|
|
254
|
+
|
|
255
|
+
리팩터링이 성공하면 다음이 가능해야 한다.
|
|
256
|
+
|
|
257
|
+
1. 신규 개발자가 구조를 빠르게 설명할 수 있다.
|
|
258
|
+
2. vector index가 없어도 core memory는 쓸 수 있다.
|
|
259
|
+
3. Claude hooks는 강력하지만 core와 느슨하게 결합된다.
|
|
260
|
+
4. shared/MCP/continuity를 끄거나 발전시켜도 core에 미치는 영향이 작다.
|
|
261
|
+
5. 향후 code-aware memory anchor나 lightweight graph를 안전하게 넣을 수 있다.
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## 11. 최종 맥락 요약
|
|
266
|
+
|
|
267
|
+
이번 리팩터링은 기능 축소 프로젝트가 아니다.
|
|
268
|
+
|
|
269
|
+
정확히는:
|
|
270
|
+
- **코어를 다시 작게 정의하고**
|
|
271
|
+
- **Claude 특화 강점은 더 분명하게 살리고**
|
|
272
|
+
- **무거운 기능은 올바른 곳으로 이동시키는 프로젝트**다.
|
|
273
|
+
|
|
274
|
+
즉, 이 작업은 구조 미화가 아니라,
|
|
275
|
+
`claude-memory-layer`를 앞으로도 계속 빠르게 발전시킬 수 있게 만드는 **장기 유지보수 투자**다.
|