claude-memory-layer 1.0.30 → 1.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/README.md +12 -5
- package/dist/cli/index.js +4 -3
- package/dist/cli/index.js.map +2 -2
- package/dist/core/index.js +3 -2
- package/dist/core/index.js.map +2 -2
- package/dist/hooks/post-tool-use.js +3 -2
- package/dist/hooks/post-tool-use.js.map +2 -2
- package/dist/hooks/semantic-daemon.js +3 -2
- package/dist/hooks/semantic-daemon.js.map +2 -2
- package/dist/hooks/session-end.js +3 -2
- package/dist/hooks/session-end.js.map +2 -2
- package/dist/hooks/session-start.js +3 -2
- package/dist/hooks/session-start.js.map +2 -2
- package/dist/hooks/stop.js +3 -2
- package/dist/hooks/stop.js.map +2 -2
- package/dist/hooks/user-prompt-submit.js +3 -2
- package/dist/hooks/user-prompt-submit.js.map +2 -2
- package/dist/index.js +3 -2
- package/dist/index.js.map +2 -2
- package/dist/mcp/index.js +3 -2
- package/dist/mcp/index.js.map +2 -2
- package/dist/server/api/index.js +3 -2
- package/dist/server/api/index.js.map +2 -2
- package/dist/server/index.js +3 -2
- package/dist/server/index.js.map +2 -2
- package/dist/services/memory-service.js +3 -2
- package/dist/services/memory-service.js.map +2 -2
- package/package.json +10 -3
- package/scripts/postinstall-embedding-backend.cjs +18 -16
- package/AGENTS.md +0 -71
- package/CLAUDE.md +0 -30
- package/HANDOFF.md +0 -92
- package/Memo.txt +0 -558
- package/benchmarks/replay/anonymized-real-sessions.json +0 -48
- package/config/kpi-thresholds.json +0 -7
- package/context.md +0 -636
- package/docs/ARCHITECTURE_COMPARISON_AND_RECOMMENDATIONS.md +0 -627
- package/docs/HERMES_MEMORY_INGESTION_ANALYSIS.md +0 -440
- package/docs/MCP_MEMORY_SERVICE_COMPARATIVE_REVIEW.md +0 -271
- package/docs/MEMORY_USEFULNESS_AUDIT.md +0 -371
- package/docs/MEMORY_USEFULNESS_AUDIT_RAW.json +0 -80
- package/docs/MEMSEARCH_PROJECT_STRUCTURE_ANALYSIS.md +0 -333
- package/docs/MEMU_ADOPTION.md +0 -40
- package/docs/OPERATIONS.md +0 -18
- package/docs/PRODUCT_VALIDATION_MATRIX.md +0 -82
- package/docs/PROJECT_STRUCTURE_ANALYSIS.md +0 -421
- package/docs/REFACTORING_MILESTONES_AND_ISSUES.md +0 -501
- package/docs/REFACTORING_PLAN_THIN_CORE.md +0 -414
- package/docs/REFERENCE_PROJECT_ANALYSES.md +0 -25
- package/docs/SUPERLOCALMEMORY_PROJECT_STRUCTURE_ANALYSIS.md +0 -452
- package/docs/TARGET_ARCHITECTURE_AND_FOLDER_STRUCTURE.md +0 -446
- package/docs/architecture/comparison-index.md +0 -47
- package/docs/reports/codex-real-data-validation-20260505T040447Z.md +0 -46
- package/plan.md +0 -1642
- package/scripts/build.ts +0 -159
- package/scripts/bump-patch-version.sh +0 -18
- package/scripts/delete-unknown-projects.js +0 -154
- package/scripts/fix-sync-gap.js +0 -32
- package/scripts/generate-session-qrels.ts +0 -126
- package/scripts/heartbeat-memory-orchestrator.sh +0 -28
- package/scripts/replay-retrieval-benchmark.ts +0 -69
- package/scripts/report-sync-gap.js +0 -26
- package/scripts/review-queue-auto-resolve.js +0 -21
- package/scripts/sync-gap-auto-heal.sh +0 -17
- package/spec.md +0 -624
- package/specs/20260207-dashboard-upgrade/context.md +0 -38
- package/specs/20260207-dashboard-upgrade/spec.md +0 -96
- package/specs/citations-system/context.md +0 -243
- package/specs/citations-system/plan.md +0 -495
- package/specs/citations-system/spec.md +0 -371
- package/specs/endless-mode/context.md +0 -305
- package/specs/endless-mode/plan.md +0 -620
- package/specs/endless-mode/spec.md +0 -455
- package/specs/entity-edge-model/context.md +0 -401
- package/specs/entity-edge-model/plan.md +0 -459
- package/specs/entity-edge-model/spec.md +0 -391
- package/specs/evidence-aligner-v2/context.md +0 -401
- package/specs/evidence-aligner-v2/plan.md +0 -303
- package/specs/evidence-aligner-v2/spec.md +0 -312
- package/specs/mcp-desktop-integration/context.md +0 -278
- package/specs/mcp-desktop-integration/plan.md +0 -550
- package/specs/mcp-desktop-integration/spec.md +0 -494
- package/specs/memory-utilization-improvements/context.md +0 -145
- package/specs/memory-utilization-improvements/plan.md +0 -361
- package/specs/memory-utilization-improvements/spec.md +0 -361
- package/specs/post-tool-use-hook/context.md +0 -319
- package/specs/post-tool-use-hook/plan.md +0 -469
- package/specs/post-tool-use-hook/spec.md +0 -364
- package/specs/private-tags/context.md +0 -288
- package/specs/private-tags/plan.md +0 -412
- package/specs/private-tags/spec.md +0 -345
- package/specs/progressive-disclosure/context.md +0 -346
- package/specs/progressive-disclosure/plan.md +0 -663
- package/specs/progressive-disclosure/spec.md +0 -415
- package/specs/selective-tool-observation/context.md +0 -100
- package/specs/selective-tool-observation/plan.md +0 -158
- package/specs/selective-tool-observation/spec.md +0 -127
- package/specs/task-entity-system/context.md +0 -297
- package/specs/task-entity-system/plan.md +0 -301
- package/specs/task-entity-system/spec.md +0 -314
- package/specs/thin-core-refactor/context.md +0 -275
- package/specs/thin-core-refactor/plan.md +0 -536
- package/specs/thin-core-refactor/spec.md +0 -465
- package/specs/vector-outbox-v2/context.md +0 -470
- package/specs/vector-outbox-v2/plan.md +0 -562
- package/specs/vector-outbox-v2/spec.md +0 -466
- package/specs/web-viewer-ui/context.md +0 -384
- package/specs/web-viewer-ui/plan.md +0 -797
- package/specs/web-viewer-ui/spec.md +0 -516
- package/src/adapters/claude/capture/index.ts +0 -3
- package/src/adapters/claude/context/index.ts +0 -3
- package/src/adapters/claude/hooks/index.ts +0 -21
- package/src/adapters/claude/hooks/post-tool-use.ts +0 -239
- package/src/adapters/claude/hooks/prompt-injection-policy.ts +0 -104
- package/src/adapters/claude/hooks/semantic-daemon-client.ts +0 -209
- package/src/adapters/claude/hooks/semantic-daemon.ts +0 -283
- package/src/adapters/claude/hooks/session-end.ts +0 -59
- package/src/adapters/claude/hooks/session-start.ts +0 -73
- package/src/adapters/claude/hooks/stop.ts +0 -128
- package/src/adapters/claude/hooks/user-prompt-submit.ts +0 -361
- package/src/adapters/claude/index.ts +0 -4
- package/src/adapters/claude/transcript/index.ts +0 -4
- package/src/adapters/claude/transcript/transcript-reader.ts +0 -57
- package/src/adapters/claude/transcript/turn-reconstructor.ts +0 -65
- package/src/apps/cli/claude-settings-hooks.ts +0 -138
- package/src/apps/cli/codex-import-runner.ts +0 -125
- package/src/apps/cli/codex-validation-output.ts +0 -95
- package/src/apps/cli/hermes-import-runner.ts +0 -130
- package/src/apps/cli/hermes-validation-output.ts +0 -91
- package/src/apps/cli/index.ts +0 -1735
- package/src/apps/cli/mcp-install.ts +0 -106
- package/src/apps/cli/retrieval-disclosure-output.ts +0 -196
- package/src/apps/dashboard/assets/js/bootstrap.js +0 -244
- package/src/apps/dashboard/assets/js/chat.js +0 -373
- package/src/apps/dashboard/assets/js/disclosure.js +0 -232
- package/src/apps/dashboard/assets/js/modals.js +0 -298
- package/src/apps/dashboard/assets/js/overview.js +0 -655
- package/src/apps/dashboard/assets/js/state.js +0 -72
- package/src/apps/dashboard/assets/js/views.js +0 -468
- package/src/apps/dashboard/index.html +0 -543
- package/src/apps/dashboard/index.ts +0 -3
- package/src/apps/dashboard/style.css +0 -1750
- package/src/apps/index.ts +0 -5
- package/src/apps/server/api/chat.ts +0 -244
- package/src/apps/server/api/citations.ts +0 -105
- package/src/apps/server/api/events.ts +0 -137
- package/src/apps/server/api/health.ts +0 -53
- package/src/apps/server/api/index.ts +0 -26
- package/src/apps/server/api/projects.ts +0 -74
- package/src/apps/server/api/search.ts +0 -184
- package/src/apps/server/api/sessions.ts +0 -115
- package/src/apps/server/api/stats.ts +0 -723
- package/src/apps/server/api/turns.ts +0 -143
- package/src/apps/server/api/utils.ts +0 -65
- package/src/apps/server/index.ts +0 -111
- package/src/cli/index.ts +0 -3
- package/src/cli/retrieval-disclosure-output.ts +0 -2
- package/src/compat/index.ts +0 -5
- package/src/core/canonical-key.ts +0 -186
- package/src/core/citation-generator.ts +0 -63
- package/src/core/consolidated-store.ts +0 -356
- package/src/core/consolidation-worker.ts +0 -493
- package/src/core/context-formatter.ts +0 -276
- package/src/core/continuity-manager.ts +0 -341
- package/src/core/db-wrapper.ts +0 -64
- package/src/core/derive/fact-deriver.ts +0 -170
- package/src/core/derive/index.ts +0 -2
- package/src/core/derive/summary-deriver.ts +0 -76
- package/src/core/edge-repo.ts +0 -333
- package/src/core/embedder.ts +0 -4
- package/src/core/engine/embedding-maintenance-service.ts +0 -187
- package/src/core/engine/endless-memory-services.ts +0 -4
- package/src/core/engine/index.ts +0 -19
- package/src/core/engine/memory-engine-services.ts +0 -170
- package/src/core/engine/memory-ingest-service.ts +0 -317
- package/src/core/engine/memory-query-service.ts +0 -173
- package/src/core/engine/memory-runtime-service.ts +0 -162
- package/src/core/engine/memory-service-composition.ts +0 -231
- package/src/core/engine/retrieval-analytics-service.ts +0 -181
- package/src/core/engine/retrieval-disclosure-service.ts +0 -420
- package/src/core/engine/retrieval-orchestrator.ts +0 -377
- package/src/core/engine/retrieval-services.ts +0 -176
- package/src/core/engine/shared-memory-services.ts +0 -4
- package/src/core/entity-repo.ts +0 -349
- package/src/core/event-store.ts +0 -779
- package/src/core/evidence-aligner.ts +0 -635
- package/src/core/external-market-context.ts +0 -582
- package/src/core/graduation-worker.ts +0 -171
- package/src/core/graduation.ts +0 -377
- package/src/core/index.ts +0 -64
- package/src/core/ingest-interceptor.ts +0 -80
- package/src/core/markdown-mirror.ts +0 -70
- package/src/core/matcher.ts +0 -208
- package/src/core/md-mirror.ts +0 -92
- package/src/core/metadata-extractor.ts +0 -203
- package/src/core/model/memory-fact.ts +0 -30
- package/src/core/model/memory-rule.ts +0 -14
- package/src/core/model/memory-summary.ts +0 -21
- package/src/core/model/raw-event.ts +0 -28
- package/src/core/model/retrieval-result.ts +0 -35
- package/src/core/mongo-sync-config.ts +0 -165
- package/src/core/mongo-sync-worker.ts +0 -381
- package/src/core/privacy/filter.ts +0 -190
- package/src/core/privacy/index.ts +0 -20
- package/src/core/privacy/tag-parser.ts +0 -145
- package/src/core/product-validation-matrix.ts +0 -314
- package/src/core/progressive-retriever.ts +0 -414
- package/src/core/registry/project-path.ts +0 -54
- package/src/core/registry/session-registry.ts +0 -69
- package/src/core/replay-evaluator.ts +0 -625
- package/src/core/retrieval-benchmark.ts +0 -117
- package/src/core/retrieval-quality.ts +0 -109
- package/src/core/retriever.ts +0 -800
- package/src/core/session-qrels.ts +0 -360
- package/src/core/shared-event-store.ts +0 -114
- package/src/core/shared-promoter.ts +0 -249
- package/src/core/shared-store.ts +0 -289
- package/src/core/shared-vector-store.ts +0 -203
- package/src/core/sqlite-event-store.ts +0 -1846
- package/src/core/sqlite-wrapper.ts +0 -116
- package/src/core/sync-worker.ts +0 -228
- package/src/core/tag-taxonomy.ts +0 -51
- package/src/core/task/blocker-resolver.ts +0 -333
- package/src/core/task/index.ts +0 -9
- package/src/core/task/task-matcher.ts +0 -240
- package/src/core/task/task-projector.ts +0 -358
- package/src/core/task/task-resolver.ts +0 -421
- package/src/core/turn-state.ts +0 -207
- package/src/core/types.ts +0 -952
- package/src/core/vector-outbox.ts +0 -299
- package/src/core/vector-store.ts +0 -231
- package/src/core/vector-worker.ts +0 -521
- package/src/core/working-set-store.ts +0 -257
- package/src/extensions/endless-memory/endless-memory-services.ts +0 -350
- package/src/extensions/endless-memory/index.ts +0 -1
- package/src/extensions/index.ts +0 -5
- package/src/extensions/mcp/handlers.ts +0 -960
- package/src/extensions/mcp/index.ts +0 -48
- package/src/extensions/mcp/tools.ts +0 -252
- package/src/extensions/shared-memory/index.ts +0 -1
- package/src/extensions/shared-memory/shared-memory-services.ts +0 -211
- package/src/extensions/vector/embedder.ts +0 -233
- package/src/extensions/vector/index.ts +0 -1
- package/src/hooks/post-tool-use.ts +0 -9
- package/src/hooks/semantic-daemon-client.ts +0 -1
- package/src/hooks/semantic-daemon.ts +0 -11
- package/src/hooks/session-end.ts +0 -9
- package/src/hooks/session-start.ts +0 -9
- package/src/hooks/stop.ts +0 -9
- package/src/hooks/user-prompt-submit.ts +0 -9
- package/src/index.ts +0 -13
- package/src/mcp/handlers.ts +0 -2
- package/src/mcp/index.ts +0 -4
- package/src/mcp/tools.ts +0 -2
- package/src/server/api/chat.ts +0 -2
- package/src/server/api/citations.ts +0 -2
- package/src/server/api/events.ts +0 -2
- package/src/server/api/health.ts +0 -2
- package/src/server/api/index.ts +0 -2
- package/src/server/api/projects.ts +0 -2
- package/src/server/api/search.ts +0 -2
- package/src/server/api/sessions.ts +0 -2
- package/src/server/api/stats.ts +0 -2
- package/src/server/api/turns.ts +0 -2
- package/src/server/api/utils.ts +0 -2
- package/src/server/index.ts +0 -2
- package/src/services/bootstrap-organizer.ts +0 -463
- package/src/services/codex-session-history-importer.ts +0 -966
- package/src/services/hermes-session-history-importer.ts +0 -733
- package/src/services/memory-service-config.ts +0 -36
- package/src/services/memory-service-registry.ts +0 -150
- package/src/services/memory-service.ts +0 -688
- package/src/services/session-history-importer.ts +0 -629
- package/tests/README.md +0 -23
- package/tests/adapters/claude/claude-semantic-daemon-adapter.test.ts +0 -54
- package/tests/adapters/claude/claude-transcript-reconstructor.test.ts +0 -98
- package/tests/adapters/claude-hook-prompt-injection-policy.test.ts +0 -99
- package/tests/apps/app-layer-boundary.test.ts +0 -48
- package/tests/apps/claude-settings-hooks.test.ts +0 -107
- package/tests/apps/cli-disclosure-output.test.ts +0 -212
- package/tests/apps/codex-import-runner.test.ts +0 -99
- package/tests/apps/codex-validation-output.test.ts +0 -100
- package/tests/apps/hermes-import-runner.test.ts +0 -99
- package/tests/apps/mcp-install-command.test.ts +0 -59
- package/tests/apps/package-build-entrypoints.test.ts +0 -30
- package/tests/apps/postinstall-embedding-backend.test.ts +0 -175
- package/tests/apps/search-api-disclosure.test.ts +0 -162
- package/tests/apps/stats-api-lightweight.test.ts +0 -67
- package/tests/apps/ui-disclosure-output.test.ts +0 -140
- package/tests/core/bootstrap-organizer.test.ts +0 -111
- package/tests/core/canonical-key.test.ts +0 -101
- package/tests/core/codex-session-history-importer-validation.test.ts +0 -185
- package/tests/core/consolidation-worker.test.ts +0 -75
- package/tests/core/embedding-maintenance-service.test.ts +0 -282
- package/tests/core/evidence-aligner.test.ts +0 -152
- package/tests/core/external-market-context.test.ts +0 -209
- package/tests/core/fact-deriver.test.ts +0 -79
- package/tests/core/hermes-session-history-importer-validation.test.ts +0 -609
- package/tests/core/ingest-interceptor.test.ts +0 -38
- package/tests/core/markdown-mirror.test.ts +0 -85
- package/tests/core/matcher.test.ts +0 -112
- package/tests/core/md-mirror.test.ts +0 -50
- package/tests/core/memory-engine-services.test.ts +0 -240
- package/tests/core/memory-ingest-service.test.ts +0 -296
- package/tests/core/memory-query-service.test.ts +0 -129
- package/tests/core/memory-runtime-service.test.ts +0 -201
- package/tests/core/memory-service-composition.test.ts +0 -192
- package/tests/core/memory-service-config.test.ts +0 -41
- package/tests/core/memory-service-facade.test.ts +0 -30
- package/tests/core/memory-service-registry.test.ts +0 -206
- package/tests/core/product-validation-matrix.test.ts +0 -61
- package/tests/core/project-registry.test.ts +0 -78
- package/tests/core/replay-evaluator.test.ts +0 -181
- package/tests/core/retrieval-analytics-service.test.ts +0 -210
- package/tests/core/retrieval-benchmark.test.ts +0 -93
- package/tests/core/retrieval-disclosure-service.test.ts +0 -264
- package/tests/core/retrieval-orchestrator.test.ts +0 -403
- package/tests/core/retrieval-quality.test.ts +0 -31
- package/tests/core/retrieval-services.test.ts +0 -185
- package/tests/core/retriever-fallback-chain.test.ts +0 -223
- package/tests/core/retriever-strategy-scope.test.ts +0 -164
- package/tests/core/retriever.memu-adoption.test.ts +0 -122
- package/tests/core/session-history-importer-filter.test.ts +0 -78
- package/tests/core/session-qrels.test.ts +0 -250
- package/tests/core/sqlite-event-store-replication.test.ts +0 -127
- package/tests/core/summary-deriver.test.ts +0 -66
- package/tests/extensions/embedder-warning-suppression.test.ts +0 -83
- package/tests/extensions/endless-memory-extension-boundary.test.ts +0 -17
- package/tests/extensions/endless-memory-services.test.ts +0 -325
- package/tests/extensions/mcp-context-tools.test.ts +0 -905
- package/tests/extensions/mcp-extension-boundary.test.ts +0 -21
- package/tests/extensions/mcp-package-build.test.ts +0 -22
- package/tests/extensions/mcp-project-aware-tools.test.ts +0 -102
- package/tests/extensions/shared-memory-extension-boundary.test.ts +0 -24
- package/tests/extensions/shared-memory-services.test.ts +0 -309
- package/tests/extensions/vector-extension-boundary.test.ts +0 -21
- package/tsconfig.json +0 -24
- package/vitest.config.ts +0 -15
|
@@ -1,414 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Progressive Retriever
|
|
3
|
-
* Implements 3-layer progressive disclosure for token-efficient search
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { EventStore } from './event-store.js';
|
|
7
|
-
import type { VectorStore } from './vector-store.js';
|
|
8
|
-
import type { Embedder } from './embedder.js';
|
|
9
|
-
import type {
|
|
10
|
-
SearchIndexItem,
|
|
11
|
-
TimelineItem,
|
|
12
|
-
FullDetail,
|
|
13
|
-
ProgressiveSearchResult,
|
|
14
|
-
ProgressiveDisclosureConfig,
|
|
15
|
-
MemoryEvent
|
|
16
|
-
} from './types.js';
|
|
17
|
-
import { generateCitationId } from './citation-generator.js';
|
|
18
|
-
|
|
19
|
-
export interface SmartSearchOptions {
|
|
20
|
-
topK?: number;
|
|
21
|
-
minScore?: number;
|
|
22
|
-
maxTotalTokens?: number;
|
|
23
|
-
filter?: {
|
|
24
|
-
sessionId?: string;
|
|
25
|
-
eventType?: string;
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
interface ExpansionDecision {
|
|
30
|
-
expand: boolean;
|
|
31
|
-
expandTimeline?: boolean;
|
|
32
|
-
expandDetails?: boolean;
|
|
33
|
-
ids?: string[];
|
|
34
|
-
reason: string;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const DEFAULT_CONFIG: ProgressiveDisclosureConfig = {
|
|
38
|
-
enabled: true,
|
|
39
|
-
layer1: {
|
|
40
|
-
topK: 10,
|
|
41
|
-
minScore: 0.7
|
|
42
|
-
},
|
|
43
|
-
autoExpand: {
|
|
44
|
-
enabled: true,
|
|
45
|
-
highConfidenceThreshold: 0.92,
|
|
46
|
-
scoreGapThreshold: 0.1,
|
|
47
|
-
maxAutoExpandCount: 3
|
|
48
|
-
},
|
|
49
|
-
tokenBudget: {
|
|
50
|
-
maxTotalTokens: 2000,
|
|
51
|
-
layer1PerItem: 50,
|
|
52
|
-
layer2PerItem: 40,
|
|
53
|
-
layer3PerItem: 500
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
export class ProgressiveRetriever {
|
|
58
|
-
private config: ProgressiveDisclosureConfig;
|
|
59
|
-
|
|
60
|
-
constructor(
|
|
61
|
-
private eventStore: EventStore,
|
|
62
|
-
private vectorStore: VectorStore,
|
|
63
|
-
private embedder: Embedder,
|
|
64
|
-
config?: Partial<ProgressiveDisclosureConfig>
|
|
65
|
-
) {
|
|
66
|
-
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Layer 1: Search Index (lightweight, ~50-100 tokens per result)
|
|
71
|
-
*/
|
|
72
|
-
async searchIndex(
|
|
73
|
-
query: string,
|
|
74
|
-
options?: { topK?: number; filter?: SmartSearchOptions['filter'] }
|
|
75
|
-
): Promise<SearchIndexItem[]> {
|
|
76
|
-
const topK = options?.topK ?? this.config.layer1.topK;
|
|
77
|
-
|
|
78
|
-
// Generate query embedding
|
|
79
|
-
const queryEmbedding = await this.embedder.embed(query);
|
|
80
|
-
|
|
81
|
-
// Search vector store
|
|
82
|
-
const vectorResults = await this.vectorStore.search(queryEmbedding.vector, {
|
|
83
|
-
limit: topK,
|
|
84
|
-
minScore: this.config.layer1.minScore,
|
|
85
|
-
sessionId: options?.filter?.sessionId
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
// Convert to index items with summaries
|
|
89
|
-
return vectorResults.map(r => ({
|
|
90
|
-
id: r.eventId,
|
|
91
|
-
summary: this.generateSummary(r.content),
|
|
92
|
-
score: r.score,
|
|
93
|
-
type: r.eventType as SearchIndexItem['type'],
|
|
94
|
-
timestamp: new Date(r.timestamp),
|
|
95
|
-
sessionId: r.sessionId
|
|
96
|
-
}));
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Layer 2: Timeline (context around results, ~200 tokens)
|
|
101
|
-
*/
|
|
102
|
-
async getTimeline(
|
|
103
|
-
targetIds: string[],
|
|
104
|
-
options?: { windowSize?: number }
|
|
105
|
-
): Promise<TimelineItem[]> {
|
|
106
|
-
const windowSize = options?.windowSize ?? 3;
|
|
107
|
-
const items: TimelineItem[] = [];
|
|
108
|
-
const seenIds = new Set<string>();
|
|
109
|
-
|
|
110
|
-
for (const targetId of targetIds) {
|
|
111
|
-
const event = await this.eventStore.getEvent(targetId);
|
|
112
|
-
if (!event) continue;
|
|
113
|
-
|
|
114
|
-
// Get surrounding events from same session
|
|
115
|
-
const sessionEvents = await this.eventStore.getSessionEvents(event.sessionId);
|
|
116
|
-
const eventIndex = sessionEvents.findIndex(e => e.id === targetId);
|
|
117
|
-
|
|
118
|
-
if (eventIndex === -1) continue;
|
|
119
|
-
|
|
120
|
-
const start = Math.max(0, eventIndex - windowSize);
|
|
121
|
-
const end = Math.min(sessionEvents.length, eventIndex + windowSize + 1);
|
|
122
|
-
|
|
123
|
-
for (let i = start; i < end; i++) {
|
|
124
|
-
const e = sessionEvents[i];
|
|
125
|
-
if (seenIds.has(e.id)) continue;
|
|
126
|
-
seenIds.add(e.id);
|
|
127
|
-
|
|
128
|
-
items.push({
|
|
129
|
-
id: e.id,
|
|
130
|
-
timestamp: e.timestamp,
|
|
131
|
-
type: e.eventType as TimelineItem['type'],
|
|
132
|
-
preview: this.generatePreview(e.content),
|
|
133
|
-
isTarget: e.id === targetId
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// Sort by timestamp
|
|
139
|
-
return items.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Layer 3: Full Details (complete content, ~500-1000 tokens per result)
|
|
144
|
-
*/
|
|
145
|
-
async getDetails(ids: string[]): Promise<FullDetail[]> {
|
|
146
|
-
const details: FullDetail[] = [];
|
|
147
|
-
|
|
148
|
-
for (const id of ids) {
|
|
149
|
-
const event = await this.eventStore.getEvent(id);
|
|
150
|
-
if (!event) continue;
|
|
151
|
-
|
|
152
|
-
const citationId = generateCitationId(event.id);
|
|
153
|
-
|
|
154
|
-
details.push({
|
|
155
|
-
id: event.id,
|
|
156
|
-
content: event.content,
|
|
157
|
-
type: event.eventType as FullDetail['type'],
|
|
158
|
-
timestamp: event.timestamp,
|
|
159
|
-
sessionId: event.sessionId,
|
|
160
|
-
citationId,
|
|
161
|
-
metadata: this.extractMetadata(event)
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
return details;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Smart Search: Progressive search with auto-expansion
|
|
170
|
-
*/
|
|
171
|
-
async smartSearch(
|
|
172
|
-
query: string,
|
|
173
|
-
options?: SmartSearchOptions
|
|
174
|
-
): Promise<ProgressiveSearchResult> {
|
|
175
|
-
const config = { ...this.config };
|
|
176
|
-
if (options?.maxTotalTokens) {
|
|
177
|
-
config.tokenBudget.maxTotalTokens = options.maxTotalTokens;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Layer 1: Always execute
|
|
181
|
-
const index = await this.searchIndex(query, {
|
|
182
|
-
topK: options?.topK ?? config.layer1.topK,
|
|
183
|
-
filter: options?.filter
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
const result: ProgressiveSearchResult = {
|
|
187
|
-
index,
|
|
188
|
-
meta: {
|
|
189
|
-
totalMatches: index.length,
|
|
190
|
-
expandedCount: 0,
|
|
191
|
-
estimatedTokens: this.estimateTokens(index, 'layer1')
|
|
192
|
-
}
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
// Auto-expansion decision
|
|
196
|
-
if (config.autoExpand.enabled) {
|
|
197
|
-
const decision = this.shouldAutoExpand(index, config);
|
|
198
|
-
|
|
199
|
-
if (decision.expand && decision.ids) {
|
|
200
|
-
// Expand timeline
|
|
201
|
-
if (decision.expandTimeline) {
|
|
202
|
-
result.timeline = await this.getTimeline(decision.ids);
|
|
203
|
-
result.meta.estimatedTokens += this.estimateTokens(result.timeline, 'layer2');
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// Expand details (if budget allows)
|
|
207
|
-
if (decision.expandDetails) {
|
|
208
|
-
const remainingBudget = config.tokenBudget.maxTotalTokens - result.meta.estimatedTokens;
|
|
209
|
-
const idsToExpand = this.selectWithinBudget(
|
|
210
|
-
decision.ids,
|
|
211
|
-
remainingBudget,
|
|
212
|
-
config.tokenBudget.layer3PerItem
|
|
213
|
-
);
|
|
214
|
-
|
|
215
|
-
if (idsToExpand.length > 0) {
|
|
216
|
-
result.details = await this.getDetails(idsToExpand);
|
|
217
|
-
result.meta.expandedCount = idsToExpand.length;
|
|
218
|
-
result.meta.estimatedTokens += result.details.reduce(
|
|
219
|
-
(sum, d) => sum + this.estimateTokensForText(d.content),
|
|
220
|
-
0
|
|
221
|
-
);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
result.meta.expansionReason = decision.reason;
|
|
226
|
-
} else {
|
|
227
|
-
result.meta.expansionReason = decision.reason;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
return result;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Determine whether to auto-expand results
|
|
236
|
-
*/
|
|
237
|
-
private shouldAutoExpand(
|
|
238
|
-
results: SearchIndexItem[],
|
|
239
|
-
config: ProgressiveDisclosureConfig
|
|
240
|
-
): ExpansionDecision {
|
|
241
|
-
if (results.length === 0) {
|
|
242
|
-
return { expand: false, reason: 'no_results' };
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
const topScore = results[0].score;
|
|
246
|
-
|
|
247
|
-
// Rule 1: High confidence single result
|
|
248
|
-
if (topScore >= config.autoExpand.highConfidenceThreshold && results.length === 1) {
|
|
249
|
-
return {
|
|
250
|
-
expand: true,
|
|
251
|
-
expandTimeline: true,
|
|
252
|
-
expandDetails: true,
|
|
253
|
-
ids: [results[0].id],
|
|
254
|
-
reason: 'high_confidence_single'
|
|
255
|
-
};
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// Rule 2: Clear winner with score gap
|
|
259
|
-
if (results.length >= 2) {
|
|
260
|
-
const gap = results[0].score - results[1].score;
|
|
261
|
-
if (topScore >= 0.85 && gap >= config.autoExpand.scoreGapThreshold) {
|
|
262
|
-
return {
|
|
263
|
-
expand: true,
|
|
264
|
-
expandTimeline: true,
|
|
265
|
-
expandDetails: true,
|
|
266
|
-
ids: [results[0].id],
|
|
267
|
-
reason: 'clear_winner'
|
|
268
|
-
};
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// Rule 3: Multiple high scores → timeline only
|
|
273
|
-
const highScoreCount = results.filter(r => r.score >= 0.8).length;
|
|
274
|
-
if (highScoreCount >= 3) {
|
|
275
|
-
return {
|
|
276
|
-
expand: true,
|
|
277
|
-
expandTimeline: true,
|
|
278
|
-
expandDetails: false,
|
|
279
|
-
ids: results.slice(0, 3).map(r => r.id),
|
|
280
|
-
reason: 'ambiguous_multiple_high'
|
|
281
|
-
};
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// Rule 4: Low confidence
|
|
285
|
-
if (topScore < config.layer1.minScore) {
|
|
286
|
-
return { expand: false, reason: 'low_confidence' };
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
return { expand: false, reason: 'no_expansion_rule_matched' };
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* Select IDs that fit within token budget
|
|
294
|
-
*/
|
|
295
|
-
private selectWithinBudget(
|
|
296
|
-
ids: string[],
|
|
297
|
-
budget: number,
|
|
298
|
-
perItemTokens: number
|
|
299
|
-
): string[] {
|
|
300
|
-
const maxItems = Math.floor(budget / perItemTokens);
|
|
301
|
-
return ids.slice(0, Math.max(0, maxItems));
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/**
|
|
305
|
-
* Generate a short summary for Layer 1
|
|
306
|
-
*/
|
|
307
|
-
private generateSummary(content: string, maxLength: number = 100): string {
|
|
308
|
-
// Remove code blocks
|
|
309
|
-
const withoutCode = content.replace(/```[\s\S]*?```/g, '[code]');
|
|
310
|
-
|
|
311
|
-
// Extract first sentence
|
|
312
|
-
const firstSentence = withoutCode.match(/^[^.!?]+[.!?]/)?.[0] || '';
|
|
313
|
-
|
|
314
|
-
if (firstSentence.length <= maxLength) {
|
|
315
|
-
return firstSentence.trim();
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
// Truncate at word boundary
|
|
319
|
-
return withoutCode.slice(0, maxLength).replace(/\s+\S*$/, '') + '...';
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
/**
|
|
323
|
-
* Generate a preview for Layer 2
|
|
324
|
-
*/
|
|
325
|
-
private generatePreview(content: string, maxLength: number = 200): string {
|
|
326
|
-
// Summarize code blocks
|
|
327
|
-
const withCodeSummary = content.replace(
|
|
328
|
-
/```(\w+)[\s\S]*?```/g,
|
|
329
|
-
(_, lang) => `[${lang} code]`
|
|
330
|
-
);
|
|
331
|
-
|
|
332
|
-
// Collapse whitespace
|
|
333
|
-
const singleLine = withCodeSummary.replace(/\n+/g, ' ').trim();
|
|
334
|
-
|
|
335
|
-
if (singleLine.length <= maxLength) {
|
|
336
|
-
return singleLine;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
return singleLine.slice(0, maxLength).replace(/\s+\S*$/, '') + '...';
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* Extract metadata from event
|
|
344
|
-
*/
|
|
345
|
-
private extractMetadata(event: MemoryEvent): FullDetail['metadata'] {
|
|
346
|
-
const content = event.content;
|
|
347
|
-
|
|
348
|
-
return {
|
|
349
|
-
tokenCount: this.estimateTokensForText(content),
|
|
350
|
-
hasCode: /```[\s\S]*?```/.test(content),
|
|
351
|
-
files: this.extractFiles(content),
|
|
352
|
-
tools: this.extractTools(content)
|
|
353
|
-
};
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
/**
|
|
357
|
-
* Extract file paths from content
|
|
358
|
-
*/
|
|
359
|
-
private extractFiles(content: string): string[] | undefined {
|
|
360
|
-
const filePattern = /(?:\/[\w.-]+)+\.\w+/g;
|
|
361
|
-
const matches = content.match(filePattern);
|
|
362
|
-
return matches ? [...new Set(matches)] : undefined;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
/**
|
|
366
|
-
* Extract tool names from content
|
|
367
|
-
*/
|
|
368
|
-
private extractTools(content: string): string[] | undefined {
|
|
369
|
-
const toolPattern = /\b(Read|Write|Edit|Bash|Grep|Glob|WebFetch|WebSearch)\b/g;
|
|
370
|
-
const matches = content.match(toolPattern);
|
|
371
|
-
return matches ? [...new Set(matches)] : undefined;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
/**
|
|
375
|
-
* Estimate tokens for a layer
|
|
376
|
-
*/
|
|
377
|
-
private estimateTokens(
|
|
378
|
-
items: unknown[],
|
|
379
|
-
layer: 'layer1' | 'layer2' | 'layer3'
|
|
380
|
-
): number {
|
|
381
|
-
const config = this.config.tokenBudget;
|
|
382
|
-
|
|
383
|
-
switch (layer) {
|
|
384
|
-
case 'layer1':
|
|
385
|
-
return items.length * config.layer1PerItem;
|
|
386
|
-
case 'layer2':
|
|
387
|
-
return items.length * config.layer2PerItem;
|
|
388
|
-
case 'layer3':
|
|
389
|
-
return (items as FullDetail[]).reduce(
|
|
390
|
-
(sum, item) => sum + this.estimateTokensForText(item.content),
|
|
391
|
-
0
|
|
392
|
-
);
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
/**
|
|
397
|
-
* Estimate tokens for text (~4 chars per token)
|
|
398
|
-
*/
|
|
399
|
-
private estimateTokensForText(text: string): number {
|
|
400
|
-
return Math.ceil(text.length / 4);
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
/**
|
|
405
|
-
* Create a progressive retriever instance
|
|
406
|
-
*/
|
|
407
|
-
export function createProgressiveRetriever(
|
|
408
|
-
eventStore: EventStore,
|
|
409
|
-
vectorStore: VectorStore,
|
|
410
|
-
embedder: Embedder,
|
|
411
|
-
config?: Partial<ProgressiveDisclosureConfig>
|
|
412
|
-
): ProgressiveRetriever {
|
|
413
|
-
return new ProgressiveRetriever(eventStore, vectorStore, embedder, config);
|
|
414
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Project path registry utilities.
|
|
3
|
-
*
|
|
4
|
-
* These helpers are intentionally core-level and Claude-agnostic.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import * as crypto from 'crypto';
|
|
8
|
-
import * as fs from 'fs';
|
|
9
|
-
import * as os from 'os';
|
|
10
|
-
import * as path from 'path';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Normalize and resolve a project path, handling symlinks when possible.
|
|
14
|
-
*/
|
|
15
|
-
export function normalizeProjectPath(projectPath: string): string {
|
|
16
|
-
const expanded = projectPath.startsWith('~')
|
|
17
|
-
? path.join(os.homedir(), projectPath.slice(1))
|
|
18
|
-
: projectPath;
|
|
19
|
-
|
|
20
|
-
try {
|
|
21
|
-
return fs.realpathSync(expanded);
|
|
22
|
-
} catch {
|
|
23
|
-
return path.resolve(expanded);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Generate a stable 8-character hash from a normalized project path.
|
|
29
|
-
*/
|
|
30
|
-
export function hashProjectPath(projectPath: string): string {
|
|
31
|
-
const normalizedPath = normalizeProjectPath(projectPath);
|
|
32
|
-
return crypto.createHash('sha256')
|
|
33
|
-
.update(normalizedPath)
|
|
34
|
-
.digest('hex')
|
|
35
|
-
.slice(0, 8);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Get the storage path for a project-local memory database.
|
|
40
|
-
*/
|
|
41
|
-
export function getProjectStoragePath(projectPath: string): string {
|
|
42
|
-
const hash = hashProjectPath(projectPath);
|
|
43
|
-
return path.join(os.homedir(), '.claude-code', 'memory', 'projects', hash);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Resolve either an explicit project hash or a project path into a storage path.
|
|
48
|
-
*/
|
|
49
|
-
export function resolveProjectStoragePath(projectOrHash: string): string {
|
|
50
|
-
const isHash = /^[a-f0-9]{8}$/.test(projectOrHash);
|
|
51
|
-
return isHash
|
|
52
|
-
? path.join(os.homedir(), '.claude-code', 'memory', 'projects', projectOrHash)
|
|
53
|
-
: getProjectStoragePath(projectOrHash);
|
|
54
|
-
}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Session registry for mapping Claude session IDs to project-local storage.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import * as fs from 'fs';
|
|
6
|
-
import * as os from 'os';
|
|
7
|
-
import * as path from 'path';
|
|
8
|
-
import { hashProjectPath, normalizeProjectPath } from './project-path.js';
|
|
9
|
-
|
|
10
|
-
const REGISTRY_PATH = path.join(os.homedir(), '.claude-code', 'memory', 'session-registry.json');
|
|
11
|
-
|
|
12
|
-
export interface SessionRegistryEntry {
|
|
13
|
-
projectPath: string;
|
|
14
|
-
projectHash: string;
|
|
15
|
-
registeredAt: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface SessionRegistry {
|
|
19
|
-
version: number;
|
|
20
|
-
sessions: Record<string, SessionRegistryEntry>;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function loadSessionRegistry(): SessionRegistry {
|
|
24
|
-
try {
|
|
25
|
-
if (fs.existsSync(REGISTRY_PATH)) {
|
|
26
|
-
const data = fs.readFileSync(REGISTRY_PATH, 'utf-8');
|
|
27
|
-
return JSON.parse(data);
|
|
28
|
-
}
|
|
29
|
-
} catch (error) {
|
|
30
|
-
console.error('Failed to load session registry:', error);
|
|
31
|
-
}
|
|
32
|
-
return { version: 1, sessions: {} };
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function saveSessionRegistry(registry: SessionRegistry): void {
|
|
36
|
-
const dir = path.dirname(REGISTRY_PATH);
|
|
37
|
-
if (!fs.existsSync(dir)) {
|
|
38
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const tempPath = REGISTRY_PATH + '.tmp';
|
|
42
|
-
fs.writeFileSync(tempPath, JSON.stringify(registry, null, 2));
|
|
43
|
-
fs.renameSync(tempPath, REGISTRY_PATH);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export function registerSession(sessionId: string, projectPath: string): void {
|
|
47
|
-
const registry = loadSessionRegistry();
|
|
48
|
-
|
|
49
|
-
registry.sessions[sessionId] = {
|
|
50
|
-
projectPath: normalizeProjectPath(projectPath),
|
|
51
|
-
projectHash: hashProjectPath(projectPath),
|
|
52
|
-
registeredAt: new Date().toISOString()
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const entries = Object.entries(registry.sessions);
|
|
56
|
-
if (entries.length > 1000) {
|
|
57
|
-
const sorted = entries.sort((a, b) =>
|
|
58
|
-
new Date(b[1].registeredAt).getTime() - new Date(a[1].registeredAt).getTime()
|
|
59
|
-
);
|
|
60
|
-
registry.sessions = Object.fromEntries(sorted.slice(0, 1000));
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
saveSessionRegistry(registry);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export function getSessionProject(sessionId: string): SessionRegistryEntry | null {
|
|
67
|
-
const registry = loadSessionRegistry();
|
|
68
|
-
return registry.sessions[sessionId] || null;
|
|
69
|
-
}
|