nlm-memory 0.20.1 → 0.21.12
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 +69 -12
- package/assets/replay-eval-dark.svg +26 -0
- package/assets/replay-eval-light.svg +26 -0
- package/dist/cli/digest.js +69 -4
- package/dist/cli/digest.js.map +1 -1
- package/dist/cli/nlm.d.ts +14 -0
- package/dist/cli/nlm.js +556 -71
- package/dist/cli/nlm.js.map +1 -1
- package/dist/cli/reprocess-job-adapters.d.ts +35 -0
- package/dist/cli/reprocess-job-adapters.js +80 -0
- package/dist/cli/reprocess-job-adapters.js.map +1 -0
- package/dist/cli/scope-backfill.d.ts +34 -0
- package/dist/cli/scope-backfill.js +237 -0
- package/dist/cli/scope-backfill.js.map +1 -0
- package/dist/cli/scope-coverage.d.ts +44 -0
- package/dist/cli/scope-coverage.js +208 -0
- package/dist/cli/scope-coverage.js.map +1 -0
- package/dist/cli/supersede.js +8 -7
- package/dist/cli/supersede.js.map +1 -1
- package/dist/core/actions/actions-log.d.ts +65 -8
- package/dist/core/actions/actions-log.js +134 -17
- package/dist/core/actions/actions-log.js.map +1 -1
- package/dist/core/actions/overlay.d.ts +11 -2
- package/dist/core/actions/overlay.js +18 -6
- package/dist/core/actions/overlay.js.map +1 -1
- package/dist/core/adapters/claude-code.d.ts +14 -0
- package/dist/core/adapters/claude-code.js +30 -0
- package/dist/core/adapters/claude-code.js.map +1 -1
- package/dist/core/adapters/from-source.js +11 -3
- package/dist/core/adapters/from-source.js.map +1 -1
- package/dist/core/adapters/fs-wiki-writer.d.ts +44 -0
- package/dist/core/adapters/fs-wiki-writer.js +132 -0
- package/dist/core/adapters/fs-wiki-writer.js.map +1 -0
- package/dist/core/adapters/hermes-agent.d.ts +15 -2
- package/dist/core/adapters/hermes-agent.js +57 -11
- package/dist/core/adapters/hermes-agent.js.map +1 -1
- package/dist/core/adapters/memory-wiki-writer.d.ts +8 -0
- package/dist/core/adapters/memory-wiki-writer.js +16 -0
- package/dist/core/adapters/memory-wiki-writer.js.map +1 -0
- package/dist/core/adapters/muse.d.ts +51 -0
- package/dist/core/adapters/muse.js +271 -0
- package/dist/core/adapters/muse.js.map +1 -0
- package/dist/core/adapters/opencode.d.ts +11 -4
- package/dist/core/adapters/opencode.js +41 -7
- package/dist/core/adapters/opencode.js.map +1 -1
- package/dist/core/alerts/alert-state.d.ts +17 -0
- package/dist/core/alerts/alert-state.js +45 -0
- package/dist/core/alerts/alert-state.js.map +1 -0
- package/dist/core/alerts/check-and-alert.d.ts +28 -0
- package/dist/core/alerts/check-and-alert.js +53 -0
- package/dist/core/alerts/check-and-alert.js.map +1 -0
- package/dist/core/alerts/drift-transition.d.ts +27 -0
- package/dist/core/alerts/drift-transition.js +56 -0
- package/dist/core/alerts/drift-transition.js.map +1 -0
- package/dist/core/alerts/embedder-transition.d.ts +23 -0
- package/dist/core/alerts/embedder-transition.js +40 -0
- package/dist/core/alerts/embedder-transition.js.map +1 -0
- package/dist/core/alerts/fire-alert.d.ts +24 -0
- package/dist/core/alerts/fire-alert.js +72 -0
- package/dist/core/alerts/fire-alert.js.map +1 -0
- package/dist/core/alerts/job-alert.d.ts +12 -0
- package/dist/core/alerts/job-alert.js +37 -0
- package/dist/core/alerts/job-alert.js.map +1 -0
- package/dist/core/alerts/types.d.ts +104 -0
- package/dist/core/alerts/types.js +11 -0
- package/dist/core/alerts/types.js.map +1 -0
- package/dist/core/alerts/wiki-alert.d.ts +15 -0
- package/dist/core/alerts/wiki-alert.js +31 -0
- package/dist/core/alerts/wiki-alert.js.map +1 -0
- package/dist/core/classifier/prompt.d.ts +13 -0
- package/dist/core/classifier/prompt.js +52 -2
- package/dist/core/classifier/prompt.js.map +1 -1
- package/dist/core/dataset/build-dataset.d.ts +16 -1
- package/dist/core/dataset/build-dataset.js +46 -13
- package/dist/core/dataset/build-dataset.js.map +1 -1
- package/dist/core/digest/compose.d.ts +11 -3
- package/dist/core/digest/compose.js +70 -17
- package/dist/core/digest/compose.js.map +1 -1
- package/dist/core/digest/hook-injection.d.ts +43 -0
- package/dist/core/digest/hook-injection.js +87 -0
- package/dist/core/digest/hook-injection.js.map +1 -0
- package/dist/core/digest/hook-version-parity.d.ts +31 -0
- package/dist/core/digest/hook-version-parity.js +56 -0
- package/dist/core/digest/hook-version-parity.js.map +1 -0
- package/dist/core/embedding/pg-embed-backfill.js +1 -1
- package/dist/core/embedding/pg-embed-backfill.js.map +1 -1
- package/dist/core/exemplars/capture-from-session.d.ts +2 -1
- package/dist/core/exemplars/capture-from-session.js +4 -4
- package/dist/core/exemplars/capture-from-session.js.map +1 -1
- package/dist/core/exemplars/embed-backfill.d.ts +9 -0
- package/dist/core/exemplars/embed-backfill.js +9 -1
- package/dist/core/exemplars/embed-backfill.js.map +1 -1
- package/dist/core/exemplars/extract-exemplar.d.ts +2 -0
- package/dist/core/exemplars/extract-exemplar.js +7 -1
- package/dist/core/exemplars/extract-exemplar.js.map +1 -1
- package/dist/core/exemplars/ingest-exemplar.d.ts +1 -0
- package/dist/core/exemplars/ingest-exemplar.js +1 -0
- package/dist/core/exemplars/ingest-exemplar.js.map +1 -1
- package/dist/core/exemplars/recall-code.d.ts +1 -1
- package/dist/core/exemplars/recall-code.js +2 -2
- package/dist/core/exemplars/recall-code.js.map +1 -1
- package/dist/core/facts/backfill-facts.d.ts +1 -1
- package/dist/core/facts/backfill-facts.js +4 -4
- package/dist/core/facts/backfill-facts.js.map +1 -1
- package/dist/core/facts/embed-backfill.d.ts +54 -0
- package/dist/core/facts/embed-backfill.js +109 -0
- package/dist/core/facts/embed-backfill.js.map +1 -0
- package/dist/core/facts/reconcile-facts.d.ts +42 -0
- package/dist/core/facts/reconcile-facts.js +133 -0
- package/dist/core/facts/reconcile-facts.js.map +1 -0
- package/dist/core/health/embed-failure-state.d.ts +4 -0
- package/dist/core/health/embed-failure-state.js +12 -0
- package/dist/core/health/embed-failure-state.js.map +1 -0
- package/dist/core/health/warmup-retry.d.ts +27 -0
- package/dist/core/health/warmup-retry.js +53 -0
- package/dist/core/health/warmup-retry.js.map +1 -0
- package/dist/core/health/warmup-state.d.ts +15 -0
- package/dist/core/health/warmup-state.js +15 -1
- package/dist/core/health/warmup-state.js.map +1 -1
- package/dist/core/hook/cite-memo.d.ts +11 -7
- package/dist/core/hook/cite-memo.js +25 -17
- package/dist/core/hook/cite-memo.js.map +1 -1
- package/dist/core/hook/claude-settings.d.ts +1 -1
- package/dist/core/hook/claude-settings.js +0 -1
- package/dist/core/hook/claude-settings.js.map +1 -1
- package/dist/core/hook/hook-log.d.ts +13 -2
- package/dist/core/hook/hook-log.js +16 -8
- package/dist/core/hook/hook-log.js.map +1 -1
- package/dist/core/hook/memo.d.ts +10 -6
- package/dist/core/hook/memo.js +25 -17
- package/dist/core/hook/memo.js.map +1 -1
- package/dist/core/hook/pointer-block.d.ts +8 -1
- package/dist/core/hook/pointer-block.js +17 -4
- package/dist/core/hook/pointer-block.js.map +1 -1
- package/dist/core/hook/resolve-conversation-by-query.d.ts +6 -5
- package/dist/core/hook/resolve-conversation-by-query.js +24 -12
- package/dist/core/hook/resolve-conversation-by-query.js.map +1 -1
- package/dist/core/ingest/backfill-derivables.d.ts +92 -0
- package/dist/core/ingest/backfill-derivables.js +175 -0
- package/dist/core/ingest/backfill-derivables.js.map +1 -0
- package/dist/core/ingest/ingest-session.d.ts +1 -1
- package/dist/core/ingest/ingest-session.js +23 -3
- package/dist/core/ingest/ingest-session.js.map +1 -1
- package/dist/core/ingest/reclassify-oversized.d.ts +1 -1
- package/dist/core/ingest/reclassify-oversized.js +8 -2
- package/dist/core/ingest/reclassify-oversized.js.map +1 -1
- package/dist/core/ingest/reprocess.d.ts +1 -1
- package/dist/core/ingest/reprocess.js +7 -2
- package/dist/core/ingest/reprocess.js.map +1 -1
- package/dist/core/ingest/transcript-derivables.d.ts +27 -0
- package/dist/core/ingest/transcript-derivables.js +138 -0
- package/dist/core/ingest/transcript-derivables.js.map +1 -0
- package/dist/core/jobs/job-supervisor.d.ts +168 -0
- package/dist/core/jobs/job-supervisor.js +335 -0
- package/dist/core/jobs/job-supervisor.js.map +1 -0
- package/dist/core/learner/model.d.ts +63 -0
- package/dist/core/learner/model.js +30 -0
- package/dist/core/learner/model.js.map +1 -0
- package/dist/core/learner/service.d.ts +42 -0
- package/dist/core/learner/service.js +74 -0
- package/dist/core/learner/service.js.map +1 -0
- package/dist/core/learner/summary.d.ts +28 -0
- package/dist/core/learner/summary.js +70 -0
- package/dist/core/learner/summary.js.map +1 -0
- package/dist/core/learner/validate.d.ts +18 -0
- package/dist/core/learner/validate.js +95 -0
- package/dist/core/learner/validate.js.map +1 -0
- package/dist/core/metrics/re-derivation.d.ts +31 -2
- package/dist/core/metrics/re-derivation.js +36 -4
- package/dist/core/metrics/re-derivation.js.map +1 -1
- package/dist/core/outcome/coverage.d.ts +33 -0
- package/dist/core/outcome/coverage.js +46 -0
- package/dist/core/outcome/coverage.js.map +1 -0
- package/dist/core/outcome/rollup.d.ts +33 -0
- package/dist/core/outcome/rollup.js +113 -0
- package/dist/core/outcome/rollup.js.map +1 -0
- package/dist/core/providers/provider-registry.d.ts +40 -23
- package/dist/core/providers/provider-registry.js +99 -81
- package/dist/core/providers/provider-registry.js.map +1 -1
- package/dist/core/recall/citation-log.d.ts +10 -5
- package/dist/core/recall/citation-log.js +21 -10
- package/dist/core/recall/citation-log.js.map +1 -1
- package/dist/core/recall/hook-recall-log.d.ts +7 -4
- package/dist/core/recall/hook-recall-log.js +14 -8
- package/dist/core/recall/hook-recall-log.js.map +1 -1
- package/dist/core/recall/miss-log.d.ts +7 -4
- package/dist/core/recall/miss-log.js +18 -11
- package/dist/core/recall/miss-log.js.map +1 -1
- package/dist/core/recall/query-log.d.ts +8 -5
- package/dist/core/recall/query-log.js +16 -9
- package/dist/core/recall/query-log.js.map +1 -1
- package/dist/core/recall/recall-service.d.ts +10 -1
- package/dist/core/recall/recall-service.js +31 -12
- package/dist/core/recall/recall-service.js.map +1 -1
- package/dist/core/recall/recent-log.d.ts +6 -1
- package/dist/core/recall/recent-log.js +13 -5
- package/dist/core/recall/recent-log.js.map +1 -1
- package/dist/core/recall/related-concepts.d.ts +29 -0
- package/dist/core/recall/related-concepts.js +67 -0
- package/dist/core/recall/related-concepts.js.map +1 -0
- package/dist/core/recall/related-exemplars.d.ts +1 -1
- package/dist/core/recall/related-exemplars.js +2 -2
- package/dist/core/recall/related-exemplars.js.map +1 -1
- package/dist/core/recall/related-facts.d.ts +1 -1
- package/dist/core/recall/related-facts.js +3 -3
- package/dist/core/recall/related-facts.js.map +1 -1
- package/dist/core/recall-facts/fact-query-log.d.ts +8 -4
- package/dist/core/recall-facts/fact-query-log.js +16 -8
- package/dist/core/recall-facts/fact-query-log.js.map +1 -1
- package/dist/core/recall-facts/fact-recall-service.d.ts +2 -2
- package/dist/core/recall-facts/fact-recall-service.js +13 -12
- package/dist/core/recall-facts/fact-recall-service.js.map +1 -1
- package/dist/core/scheduler/scan-once.js +15 -12
- package/dist/core/scheduler/scan-once.js.map +1 -1
- package/dist/core/scheduler/scheduler.d.ts +3 -0
- package/dist/core/scheduler/scheduler.js +45 -10
- package/dist/core/scheduler/scheduler.js.map +1 -1
- package/dist/core/scope/alias-map.d.ts +10 -0
- package/dist/core/scope/alias-map.js +41 -0
- package/dist/core/scope/alias-map.js.map +1 -0
- package/dist/core/scope/derive-scope.d.ts +8 -0
- package/dist/core/scope/derive-scope.js +54 -0
- package/dist/core/scope/derive-scope.js.map +1 -0
- package/dist/core/scope/scope-clause.d.ts +16 -0
- package/dist/core/scope/scope-clause.js +21 -0
- package/dist/core/scope/scope-clause.js.map +1 -0
- package/dist/core/scope/stamp-flag.d.ts +1 -0
- package/dist/core/scope/stamp-flag.js +4 -0
- package/dist/core/scope/stamp-flag.js.map +1 -0
- package/dist/core/signals/code-signal.d.ts +1 -0
- package/dist/core/signals/code-signal.js +1 -0
- package/dist/core/signals/code-signal.js.map +1 -1
- package/dist/core/signals/failure-mode-recall.d.ts +1 -1
- package/dist/core/signals/failure-mode-recall.js +2 -2
- package/dist/core/signals/failure-mode-recall.js.map +1 -1
- package/dist/core/signals/ingest-signal.d.ts +1 -1
- package/dist/core/signals/ingest-signal.js +3 -1
- package/dist/core/signals/ingest-signal.js.map +1 -1
- package/dist/core/signals/stamp-scope.d.ts +18 -0
- package/dist/core/signals/stamp-scope.js +28 -0
- package/dist/core/signals/stamp-scope.js.map +1 -0
- package/dist/core/sources/source-registry.d.ts +49 -28
- package/dist/core/sources/source-registry.js +113 -70
- package/dist/core/sources/source-registry.js.map +1 -1
- package/dist/core/storage/pg-code-exemplar-store.d.ts +19 -10
- package/dist/core/storage/pg-code-exemplar-store.js +62 -27
- package/dist/core/storage/pg-code-exemplar-store.js.map +1 -1
- package/dist/core/storage/pg-entity-store.d.ts +6 -1
- package/dist/core/storage/pg-entity-store.js +33 -18
- package/dist/core/storage/pg-entity-store.js.map +1 -1
- package/dist/core/storage/pg-fact-ingest.d.ts +1 -1
- package/dist/core/storage/pg-fact-ingest.js +10 -7
- package/dist/core/storage/pg-fact-ingest.js.map +1 -1
- package/dist/core/storage/pg-fact-store.d.ts +29 -17
- package/dist/core/storage/pg-fact-store.js +99 -46
- package/dist/core/storage/pg-fact-store.js.map +1 -1
- package/dist/core/storage/pg-learner-store.d.ts +27 -0
- package/dist/core/storage/pg-learner-store.js +174 -0
- package/dist/core/storage/pg-learner-store.js.map +1 -0
- package/dist/core/storage/pg-session-store.d.ts +25 -21
- package/dist/core/storage/pg-session-store.js +186 -114
- package/dist/core/storage/pg-session-store.js.map +1 -1
- package/dist/core/storage/pg-signal-store.d.ts +10 -5
- package/dist/core/storage/pg-signal-store.js +26 -13
- package/dist/core/storage/pg-signal-store.js.map +1 -1
- package/dist/core/storage/pg-storage.d.ts +4 -0
- package/dist/core/storage/pg-storage.js +6 -0
- package/dist/core/storage/pg-storage.js.map +1 -1
- package/dist/core/storage/pg-workstream-store.d.ts +17 -11
- package/dist/core/storage/pg-workstream-store.js +47 -29
- package/dist/core/storage/pg-workstream-store.js.map +1 -1
- package/dist/core/storage/sqlite-code-exemplar-store.d.ts +24 -10
- package/dist/core/storage/sqlite-code-exemplar-store.js +86 -40
- package/dist/core/storage/sqlite-code-exemplar-store.js.map +1 -1
- package/dist/core/storage/sqlite-entity-store.d.ts +8 -1
- package/dist/core/storage/sqlite-entity-store.js +46 -27
- package/dist/core/storage/sqlite-entity-store.js.map +1 -1
- package/dist/core/storage/sqlite-fact-store.d.ts +45 -19
- package/dist/core/storage/sqlite-fact-store.js +175 -64
- package/dist/core/storage/sqlite-fact-store.js.map +1 -1
- package/dist/core/storage/sqlite-learner-store.d.ts +33 -0
- package/dist/core/storage/sqlite-learner-store.js +178 -0
- package/dist/core/storage/sqlite-learner-store.js.map +1 -0
- package/dist/core/storage/sqlite-outcome-store.d.ts +104 -0
- package/dist/core/storage/sqlite-outcome-store.js +211 -0
- package/dist/core/storage/sqlite-outcome-store.js.map +1 -0
- package/dist/core/storage/sqlite-session-store.d.ts +50 -21
- package/dist/core/storage/sqlite-session-store.js +233 -149
- package/dist/core/storage/sqlite-session-store.js.map +1 -1
- package/dist/core/storage/sqlite-signal-store.d.ts +12 -5
- package/dist/core/storage/sqlite-signal-store.js +29 -15
- package/dist/core/storage/sqlite-signal-store.js.map +1 -1
- package/dist/core/storage/sqlite-storage.d.ts +4 -0
- package/dist/core/storage/sqlite-storage.js +10 -2
- package/dist/core/storage/sqlite-storage.js.map +1 -1
- package/dist/core/storage/sqlite-workstream-store.d.ts +17 -11
- package/dist/core/storage/sqlite-workstream-store.js +53 -31
- package/dist/core/storage/sqlite-workstream-store.js.map +1 -1
- package/dist/core/storage/supersedence-log.d.ts +10 -7
- package/dist/core/storage/supersedence-log.js +21 -14
- package/dist/core/storage/supersedence-log.js.map +1 -1
- package/dist/core/telemetry/probe-filter.d.ts +35 -0
- package/dist/core/telemetry/probe-filter.js +56 -0
- package/dist/core/telemetry/probe-filter.js.map +1 -0
- package/dist/core/tenancy/default-team.d.ts +6 -0
- package/dist/core/tenancy/default-team.js +7 -0
- package/dist/core/tenancy/default-team.js.map +1 -0
- package/dist/core/tenancy/hosted-mode.d.ts +9 -0
- package/dist/core/tenancy/hosted-mode.js +12 -0
- package/dist/core/tenancy/hosted-mode.js.map +1 -0
- package/dist/core/tenancy/team-auth.d.ts +16 -0
- package/dist/core/tenancy/team-auth.js +22 -0
- package/dist/core/tenancy/team-auth.js.map +1 -0
- package/dist/core/tenancy/team-token-store.d.ts +45 -0
- package/dist/core/tenancy/team-token-store.js +52 -0
- package/dist/core/tenancy/team-token-store.js.map +1 -0
- package/dist/core/tenancy/tenant-clause.d.ts +37 -0
- package/dist/core/tenancy/tenant-clause.js +11 -0
- package/dist/core/tenancy/tenant-clause.js.map +1 -0
- package/dist/core/tenancy/tenant-state-path.d.ts +28 -0
- package/dist/core/tenancy/tenant-state-path.js +49 -0
- package/dist/core/tenancy/tenant-state-path.js.map +1 -0
- package/dist/core/update-check/check.d.ts +6 -0
- package/dist/core/update-check/check.js +35 -0
- package/dist/core/update-check/check.js.map +1 -1
- package/dist/core/wiki/project.d.ts +17 -0
- package/dist/core/wiki/project.js +37 -0
- package/dist/core/wiki/project.js.map +1 -0
- package/dist/core/wiki/reconcile.d.ts +15 -0
- package/dist/core/wiki/reconcile.js +14 -0
- package/dist/core/wiki/reconcile.js.map +1 -0
- package/dist/core/wiki/render.d.ts +5 -0
- package/dist/core/wiki/render.js +84 -0
- package/dist/core/wiki/render.js.map +1 -0
- package/dist/core/wiki/rollup.d.ts +28 -0
- package/dist/core/wiki/rollup.js +91 -0
- package/dist/core/wiki/rollup.js.map +1 -0
- package/dist/core/wiki/select.d.ts +8 -0
- package/dist/core/wiki/select.js +7 -0
- package/dist/core/wiki/select.js.map +1 -0
- package/dist/core/wiki/slug.d.ts +36 -0
- package/dist/core/wiki/slug.js +71 -0
- package/dist/core/wiki/slug.js.map +1 -0
- package/dist/core/wiki/types.d.ts +37 -0
- package/dist/core/wiki/types.js +2 -0
- package/dist/core/wiki/types.js.map +1 -0
- package/dist/core/work-digest/build-work-digest.d.ts +1 -1
- package/dist/core/work-digest/build-work-digest.js +3 -3
- package/dist/core/work-digest/build-work-digest.js.map +1 -1
- package/dist/core/workstream/bind.d.ts +3 -2
- package/dist/core/workstream/bind.js +29 -10
- package/dist/core/workstream/bind.js.map +1 -1
- package/dist/core/workstream/model.d.ts +1 -0
- package/dist/core/workstream/model.js.map +1 -1
- package/dist/core/workstream/rollup.d.ts +1 -1
- package/dist/core/workstream/rollup.js +6 -6
- package/dist/core/workstream/rollup.js.map +1 -1
- package/dist/hook/hook-helpers.d.ts +14 -0
- package/dist/hook/hook-helpers.js +29 -2
- package/dist/hook/hook-helpers.js.map +1 -1
- package/dist/hook/pre-compact-hook.js +8 -5
- package/dist/hook/pre-compact-hook.js.map +1 -1
- package/dist/hook/prompt-recall-hook.d.ts +7 -3
- package/dist/hook/prompt-recall-hook.js +35 -20
- package/dist/hook/prompt-recall-hook.js.map +1 -1
- package/dist/hook/recall-over-http.d.ts +28 -3
- package/dist/hook/recall-over-http.js +58 -12
- package/dist/hook/recall-over-http.js.map +1 -1
- package/dist/hook/session-end-hook.js +7 -5
- package/dist/hook/session-end-hook.js.map +1 -1
- package/dist/hook/session-start-hook.d.ts +14 -1
- package/dist/hook/session-start-hook.js +57 -16
- package/dist/hook/session-start-hook.js.map +1 -1
- package/dist/hook/stop-hook.js +11 -8
- package/dist/hook/stop-hook.js.map +1 -1
- package/dist/http/app.d.ts +47 -3
- package/dist/http/app.js +379 -132
- package/dist/http/app.js.map +1 -1
- package/dist/install/claude-code.d.ts +17 -0
- package/dist/install/claude-code.js +44 -5
- package/dist/install/claude-code.js.map +1 -1
- package/dist/install/codex.d.ts +23 -2
- package/dist/install/codex.js +111 -14
- package/dist/install/codex.js.map +1 -1
- package/dist/install/cursor.d.ts +2 -2
- package/dist/install/cursor.js +7 -7
- package/dist/install/cursor.js.map +1 -1
- package/dist/install/hermes.d.ts +8 -0
- package/dist/install/hermes.js +28 -5
- package/dist/install/hermes.js.map +1 -1
- package/dist/install/local-source.d.ts +20 -0
- package/dist/install/local-source.js +28 -0
- package/dist/install/local-source.js.map +1 -0
- package/dist/install/mcp-block.d.ts +77 -0
- package/dist/install/mcp-block.js +99 -0
- package/dist/install/mcp-block.js.map +1 -0
- package/dist/install/pi.d.ts +26 -0
- package/dist/install/pi.js +43 -0
- package/dist/install/pi.js.map +1 -1
- package/dist/install/setup.js +6 -0
- package/dist/install/setup.js.map +1 -1
- package/dist/install/windsurf.d.ts +2 -2
- package/dist/install/windsurf.js +7 -7
- package/dist/install/windsurf.js.map +1 -1
- package/dist/llm/classifier-box.d.ts +5 -0
- package/dist/llm/classifier-box.js +5 -0
- package/dist/llm/classifier-box.js.map +1 -1
- package/dist/mcp/server.d.ts +94 -15
- package/dist/mcp/server.js +402 -79
- package/dist/mcp/server.js.map +1 -1
- package/dist/ports/clock.d.ts +12 -0
- package/dist/ports/clock.js +10 -0
- package/dist/ports/clock.js.map +1 -0
- package/dist/ports/code-exemplar-store.d.ts +13 -13
- package/dist/ports/entity-store.d.ts +5 -1
- package/dist/ports/fact-store.d.ts +0 -0
- package/dist/ports/fact-store.js +0 -0
- package/dist/ports/fact-store.js.map +1 -1
- package/dist/ports/learner-store.d.ts +80 -0
- package/dist/ports/learner-store.js +19 -0
- package/dist/ports/learner-store.js.map +1 -0
- package/dist/ports/outcome.d.ts +85 -0
- package/dist/ports/outcome.js +11 -0
- package/dist/ports/outcome.js.map +1 -0
- package/dist/ports/session-store.d.ts +20 -20
- package/dist/ports/session-store.js +5 -0
- package/dist/ports/session-store.js.map +1 -1
- package/dist/ports/signal-store.d.ts +12 -8
- package/dist/ports/spawn-child.d.ts +14 -0
- package/dist/ports/spawn-child.js +10 -0
- package/dist/ports/spawn-child.js.map +1 -0
- package/dist/ports/storage.d.ts +6 -0
- package/dist/ports/transcript-adapter.d.ts +11 -0
- package/dist/ports/wiki-writer.d.ts +19 -0
- package/dist/ports/wiki-writer.js +12 -0
- package/dist/ports/wiki-writer.js.map +1 -0
- package/dist/ports/workstream-store.d.ts +20 -12
- package/dist/shared/net.d.ts +3 -0
- package/dist/shared/net.js +4 -0
- package/dist/shared/net.js.map +1 -0
- package/dist/shared/types.d.ts +55 -0
- package/dist/shared/types.js +4 -1
- package/dist/shared/types.js.map +1 -1
- package/dist/shared/version.d.ts +9 -0
- package/dist/shared/version.js +11 -0
- package/dist/shared/version.js.map +1 -0
- package/dist/ui/assets/index-D6F3xAis.js +11 -0
- package/dist/ui/index.html +1 -1
- package/migrations/029_project_scope.sql +21 -0
- package/migrations/032_session_derivables.sql +11 -0
- package/migrations/033_actions_kind_check.sql +58 -0
- package/migrations/034_tenancy_teams_and_stamps.sql +40 -0
- package/migrations/035_tenancy_entity_rekey.sql +75 -0
- package/migrations/036_tenant_name_uniqueness.sql +59 -0
- package/migrations/037_sessions_covering_index.sql +25 -0
- package/migrations/038_sources_muse.sql +33 -0
- package/migrations/039_learner_evidence.sql +51 -0
- package/migrations/pg/030_project_scope.sql +23 -0
- package/migrations/pg/031_widen_session_edges_kind.sql +11 -0
- package/migrations/pg/032_session_derivables.sql +17 -0
- package/migrations/pg/033_actions_kind_check.sql +17 -0
- package/migrations/pg/034_tenancy.sql +77 -0
- package/migrations/pg/035_tenant_name_uniqueness.sql +15 -0
- package/migrations/pg/036_sources_muse.sql +12 -0
- package/migrations/pg/037_learner_evidence.sql +55 -0
- package/nlm/index.js +258 -59
- package/package.json +10 -5
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/scripts/prompt-recall-hook.mjs +256 -58
- package/plugin/scripts/session-start-hook.mjs +283 -55
- package/plugin/scripts/stop-hook.mjs +199 -38
- package/dist/hook/subagent-start-hook.d.ts +0 -28
- package/dist/hook/subagent-start-hook.js +0 -81
- package/dist/hook/subagent-start-hook.js.map +0 -1
- package/dist/ui/assets/index-CMpQkbQy.js +0 -11
|
@@ -1,20 +1,163 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/hook/session-start-hook.ts
|
|
4
|
-
import {
|
|
4
|
+
import { execFileSync } from "node:child_process";
|
|
5
5
|
|
|
6
6
|
// src/core/hook/hook-log.ts
|
|
7
7
|
import { appendFileSync, mkdirSync } from "node:fs";
|
|
8
|
+
import { dirname } from "node:path";
|
|
9
|
+
|
|
10
|
+
// src/core/tenancy/tenant-state-path.ts
|
|
11
|
+
import { createHash } from "node:crypto";
|
|
8
12
|
import { homedir } from "node:os";
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
|
|
15
|
+
// src/core/tenancy/default-team.ts
|
|
16
|
+
var DEFAULT_TEAM_ID = "team_local";
|
|
17
|
+
|
|
18
|
+
// src/core/tenancy/tenant-state-path.ts
|
|
19
|
+
var TENANTS_DIRNAME = "tenants";
|
|
20
|
+
var SAFE_TENANT_ID = /^[A-Za-z0-9_-]+$/;
|
|
21
|
+
function sanitizeTenantId(tenantId) {
|
|
22
|
+
if (SAFE_TENANT_ID.test(tenantId)) return tenantId;
|
|
23
|
+
const sanitized = tenantId.replace(/[^A-Za-z0-9_-]/g, "_") || "unknown";
|
|
24
|
+
const hash = createHash("sha256").update(tenantId).digest("hex").slice(0, 8);
|
|
25
|
+
return `${sanitized}_${hash}`;
|
|
26
|
+
}
|
|
27
|
+
function stateRoot() {
|
|
28
|
+
return process.env["NLM_STATE_ROOT"] || join(homedir(), ".nlm");
|
|
29
|
+
}
|
|
30
|
+
function tenantStatePath(tenantId, ...segments) {
|
|
31
|
+
const base = stateRoot();
|
|
32
|
+
if (tenantId === DEFAULT_TEAM_ID) return join(base, ...segments);
|
|
33
|
+
return join(base, TENANTS_DIRNAME, sanitizeTenantId(tenantId), ...segments);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// package.json
|
|
37
|
+
var package_default = {
|
|
38
|
+
name: "nlm-memory",
|
|
39
|
+
version: "0.21.12",
|
|
40
|
+
description: "Local-first non-linear memory operating system for AI operators.",
|
|
41
|
+
type: "module",
|
|
42
|
+
license: "Apache-2.0",
|
|
43
|
+
engines: {
|
|
44
|
+
node: ">=22.0.0"
|
|
45
|
+
},
|
|
46
|
+
repository: {
|
|
47
|
+
type: "git",
|
|
48
|
+
url: "git+https://github.com/pbmagnet4/nlm-memory.git"
|
|
49
|
+
},
|
|
50
|
+
homepage: "https://github.com/pbmagnet4/nlm-memory#readme",
|
|
51
|
+
bugs: {
|
|
52
|
+
url: "https://github.com/pbmagnet4/nlm-memory/issues"
|
|
53
|
+
},
|
|
54
|
+
keywords: [
|
|
55
|
+
"ai",
|
|
56
|
+
"memory",
|
|
57
|
+
"mcp",
|
|
58
|
+
"claude-code",
|
|
59
|
+
"codex",
|
|
60
|
+
"hermes",
|
|
61
|
+
"local-first",
|
|
62
|
+
"recall",
|
|
63
|
+
"session-memory"
|
|
64
|
+
],
|
|
65
|
+
files: [
|
|
66
|
+
"dist",
|
|
67
|
+
"migrations",
|
|
68
|
+
"fixtures",
|
|
69
|
+
"templates",
|
|
70
|
+
"plugin",
|
|
71
|
+
"plugin-hermes-agent",
|
|
72
|
+
"nlm",
|
|
73
|
+
"assets",
|
|
74
|
+
"LICENSE",
|
|
75
|
+
"README.md"
|
|
76
|
+
],
|
|
77
|
+
bin: {
|
|
78
|
+
nlm: "dist/cli/nlm.js"
|
|
79
|
+
},
|
|
80
|
+
scripts: {
|
|
81
|
+
dev: "tsx watch src/cli/nlm.ts start",
|
|
82
|
+
start: "node dist/cli/nlm.js start",
|
|
83
|
+
"build:server": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
|
|
84
|
+
"build:ui": "vite build --config src/ui/vite.config.ts",
|
|
85
|
+
"build:codex-plugin": "node scripts/build-codex-plugin.mjs",
|
|
86
|
+
"verify:codex-release": "node scripts/verify-codex-release.mjs",
|
|
87
|
+
build: "npm run build:server && npm run build:ui && npm run build:codex-plugin",
|
|
88
|
+
prepare: "[ -d src ] && npm run build || true",
|
|
89
|
+
"ui:dev": "vite --config src/ui/vite.config.ts",
|
|
90
|
+
test: "vitest run",
|
|
91
|
+
"test:watch": "vitest",
|
|
92
|
+
"test:unit": "vitest run tests/unit",
|
|
93
|
+
"test:integration": "vitest run tests/integration",
|
|
94
|
+
"test:pg": "vitest run .pg.test.ts --test-timeout=20000",
|
|
95
|
+
typecheck: "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json && tsc -p tsconfig.scripts.json",
|
|
96
|
+
"bench:longmemeval": "tsx scripts/longmemeval/run-harness.ts",
|
|
97
|
+
"bench:classifier": "tsx scripts/longmemeval/run-harness.ts --classifier",
|
|
98
|
+
"bench:compare": "tsx scripts/longmemeval/compare-classifiers.ts",
|
|
99
|
+
"eval:signals": "tsx scripts/eval/signals-eval.ts",
|
|
100
|
+
"eval:classifier": "tsx scripts/eval/classifier-eval.ts",
|
|
101
|
+
"eval:fact-recall": "tsx scripts/eval/fact-recall-eval.ts",
|
|
102
|
+
"eval:recall-impact-replay": "tsx scripts/eval/recall-impact-replay.ts",
|
|
103
|
+
"eval:code-exemplar": "tsx scripts/eval/code-exemplar-eval.ts",
|
|
104
|
+
"eval:reranker": "tsx scripts/eval/reranker-ablation.ts",
|
|
105
|
+
"eval:floor": "tsx scripts/eval/floor-calibration.ts",
|
|
106
|
+
"eval:matcher": "tsx scripts/eval/tune-matcher.ts",
|
|
107
|
+
"eval:naming": "tsx scripts/eval/tune-naming.ts",
|
|
108
|
+
"eval:rederiv-sample": "tsx scripts/eval/re-derivation-sample.ts",
|
|
109
|
+
"eval:rederiv-label": "tsx scripts/eval/re-derivation-label.ts",
|
|
110
|
+
"eval:rederiv-calibrate": "tsx scripts/eval/re-derivation-calibrate.ts"
|
|
111
|
+
},
|
|
112
|
+
dependencies: {
|
|
113
|
+
"@clack/prompts": "^1.4.0",
|
|
114
|
+
"@hono/node-server": "^2.0.3",
|
|
115
|
+
"@huggingface/transformers": "4.2.0",
|
|
116
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
117
|
+
"@toon-format/toon": "^2.3.0",
|
|
118
|
+
"better-sqlite3": "^13.0.1",
|
|
119
|
+
commander: "^15.0.0",
|
|
120
|
+
hono: "^4.6.0",
|
|
121
|
+
pg: "^8.21.0",
|
|
122
|
+
pgvector: "^0.3.0",
|
|
123
|
+
"sqlite-vec": "^0.1.6",
|
|
124
|
+
yaml: "^2.9.0",
|
|
125
|
+
zod: "^4.4.3"
|
|
126
|
+
},
|
|
127
|
+
devDependencies: {
|
|
128
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
129
|
+
"@types/node": "^22.10.0",
|
|
130
|
+
"@types/pg": "^8.20.0",
|
|
131
|
+
"@types/react": "^19.2.17",
|
|
132
|
+
"@types/react-dom": "^19.2.3",
|
|
133
|
+
"@vitejs/plugin-react": "^6.0.2",
|
|
134
|
+
esbuild: "^0.28.0",
|
|
135
|
+
react: "^19.2.7",
|
|
136
|
+
"react-dom": "^19.2.7",
|
|
137
|
+
"react-router-dom": "^6.30.3",
|
|
138
|
+
"tsc-alias": "^1.8.17",
|
|
139
|
+
tsx: "^4.19.0",
|
|
140
|
+
typescript: "^6.0.3",
|
|
141
|
+
vite: "^8.0.16",
|
|
142
|
+
vitest: "^4.1.8"
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
// src/shared/version.ts
|
|
147
|
+
var NLM_VERSION = package_default.version;
|
|
148
|
+
|
|
149
|
+
// src/core/hook/hook-log.ts
|
|
150
|
+
function logPath(tenantId) {
|
|
151
|
+
if (tenantId === DEFAULT_TEAM_ID) {
|
|
152
|
+
return process.env["NLM_HOOK_LOG"] ?? tenantStatePath(tenantId, "hook-log.jsonl");
|
|
153
|
+
}
|
|
154
|
+
return tenantStatePath(tenantId, "hook-log.jsonl");
|
|
12
155
|
}
|
|
13
|
-
function appendHookLog(entry) {
|
|
156
|
+
function appendHookLog(tenantId, entry) {
|
|
14
157
|
try {
|
|
15
|
-
const path = logPath();
|
|
158
|
+
const path = logPath(tenantId);
|
|
16
159
|
mkdirSync(dirname(path), { recursive: true });
|
|
17
|
-
appendFileSync(path, `${JSON.stringify(entry)}
|
|
160
|
+
appendFileSync(path, `${JSON.stringify({ ...entry, v: NLM_VERSION })}
|
|
18
161
|
`, "utf8");
|
|
19
162
|
} catch {
|
|
20
163
|
}
|
|
@@ -30,18 +173,20 @@ import {
|
|
|
30
173
|
statSync,
|
|
31
174
|
writeFileSync
|
|
32
175
|
} from "node:fs";
|
|
33
|
-
import { homedir as homedir2 } from "node:os";
|
|
34
176
|
import { join as join2 } from "node:path";
|
|
35
|
-
function stateDir() {
|
|
36
|
-
|
|
177
|
+
function stateDir(tenantId) {
|
|
178
|
+
if (tenantId === DEFAULT_TEAM_ID) {
|
|
179
|
+
return process.env["NLM_HOOK_STATE_DIR"] ?? tenantStatePath(tenantId, "hook-state");
|
|
180
|
+
}
|
|
181
|
+
return tenantStatePath(tenantId, "hook-state");
|
|
37
182
|
}
|
|
38
|
-
function memoPath(conversationId) {
|
|
183
|
+
function memoPath(tenantId, conversationId) {
|
|
39
184
|
const safe = conversationId.replace(/[^A-Za-z0-9_-]/g, "_") || "unknown";
|
|
40
|
-
return join2(stateDir(), `${safe}.json`);
|
|
185
|
+
return join2(stateDir(tenantId), `${safe}.json`);
|
|
41
186
|
}
|
|
42
|
-
function loadSurfaced(conversationId) {
|
|
187
|
+
function loadSurfaced(tenantId, conversationId) {
|
|
43
188
|
try {
|
|
44
|
-
const path = memoPath(conversationId);
|
|
189
|
+
const path = memoPath(tenantId, conversationId);
|
|
45
190
|
if (!existsSync(path)) return /* @__PURE__ */ new Set();
|
|
46
191
|
const parsed = JSON.parse(readFileSync(path, "utf8"));
|
|
47
192
|
if (!Array.isArray(parsed)) return /* @__PURE__ */ new Set();
|
|
@@ -50,12 +195,12 @@ function loadSurfaced(conversationId) {
|
|
|
50
195
|
return /* @__PURE__ */ new Set();
|
|
51
196
|
}
|
|
52
197
|
}
|
|
53
|
-
function recordSurfaced(conversationId, ids) {
|
|
198
|
+
function recordSurfaced(tenantId, conversationId, ids) {
|
|
54
199
|
try {
|
|
55
|
-
const merged = loadSurfaced(conversationId);
|
|
200
|
+
const merged = loadSurfaced(tenantId, conversationId);
|
|
56
201
|
for (const id of ids) merged.add(id);
|
|
57
|
-
mkdirSync2(stateDir(), { recursive: true });
|
|
58
|
-
writeFileSync(memoPath(conversationId), JSON.stringify([...merged]), "utf8");
|
|
202
|
+
mkdirSync2(stateDir(tenantId), { recursive: true });
|
|
203
|
+
writeFileSync(memoPath(tenantId, conversationId), JSON.stringify([...merged]), "utf8");
|
|
59
204
|
} catch {
|
|
60
205
|
}
|
|
61
206
|
}
|
|
@@ -81,8 +226,8 @@ function truncateSummary(s, max = 200) {
|
|
|
81
226
|
}
|
|
82
227
|
return window + " ...";
|
|
83
228
|
}
|
|
84
|
-
function formatPointerBlock(hits, facts = [], exemplars = []) {
|
|
85
|
-
if (hits.length === 0 && facts.length === 0 && exemplars.length === 0) return "";
|
|
229
|
+
function formatPointerBlock(hits, facts = [], exemplars = [], concepts = []) {
|
|
230
|
+
if (hits.length === 0 && facts.length === 0 && exemplars.length === 0 && concepts.length === 0) return "";
|
|
86
231
|
const out = [];
|
|
87
232
|
if (hits.length > 0) {
|
|
88
233
|
out.push("## Possibly-relevant prior sessions (nlm-memory)");
|
|
@@ -111,7 +256,19 @@ function formatPointerBlock(hits, facts = [], exemplars = []) {
|
|
|
111
256
|
out.push(`- [${e.outcome}] ${langPart}${e.repo} - ${truncateSummary(e.taskContext)}`);
|
|
112
257
|
}
|
|
113
258
|
}
|
|
114
|
-
|
|
259
|
+
if (concepts.length > 0) {
|
|
260
|
+
if (out.length > 0) out.push("");
|
|
261
|
+
out.push("## Learning state (nlm-memory)");
|
|
262
|
+
for (const c of concepts) {
|
|
263
|
+
const n = c.attemptCount === 1 ? "1 attempt" : `${c.attemptCount} attempts`;
|
|
264
|
+
out.push(`- [${c.status}] ${c.concept} (${n})`);
|
|
265
|
+
}
|
|
266
|
+
const nextSteps = [...new Set(concepts.map((c) => c.nextStep).filter((s) => !!s))].slice(0, 2);
|
|
267
|
+
for (const next of nextSteps) {
|
|
268
|
+
out.push(`Next: ${truncateSummary(next, 120)}`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
const tools = exemplars.length > 0 ? "NLM tools: recall_sessions (search), get_session (full transcript), recall_facts (prior decisions), get_fact_history (how a decision evolved), recall_code (pull the full code for a related exemplar), learner_summary (concept mastery + next step)." : "NLM tools: recall_sessions (search), get_session (full transcript), recall_facts (prior decisions), get_fact_history (how a decision evolved), learner_summary (concept mastery + next step).";
|
|
115
272
|
out.push(tools);
|
|
116
273
|
return out.join("\n");
|
|
117
274
|
}
|
|
@@ -123,10 +280,10 @@ function medianScore(hits) {
|
|
|
123
280
|
return sorted[Math.floor(sorted.length / 2)] ?? 0;
|
|
124
281
|
}
|
|
125
282
|
function selectHits(params) {
|
|
126
|
-
const { hits, surfaced, scoreThreshold, perFireCap, perConversationCap, relativeFloor = 0 } = params;
|
|
127
|
-
const relCut =
|
|
283
|
+
const { hits, surfaced, scoreThreshold: scoreThreshold2, perFireCap, perConversationCap, relativeFloor: relativeFloor2 = 0 } = params;
|
|
284
|
+
const relCut = relativeFloor2 > 0 ? relativeFloor2 * medianScore(hits) : 0;
|
|
128
285
|
const eligible = hits.filter(
|
|
129
|
-
(h) => h.matchScore >=
|
|
286
|
+
(h) => h.matchScore >= scoreThreshold2 && h.matchScore >= relCut && !surfaced.has(h.id)
|
|
130
287
|
);
|
|
131
288
|
const budget = Math.max(0, perConversationCap - surfaced.size);
|
|
132
289
|
const limit = Math.min(perFireCap, budget);
|
|
@@ -135,7 +292,7 @@ function selectHits(params) {
|
|
|
135
292
|
|
|
136
293
|
// src/llm/env-autoload.ts
|
|
137
294
|
import { readFileSync as readFileSync2, existsSync as existsSync2 } from "node:fs";
|
|
138
|
-
import { homedir as
|
|
295
|
+
import { homedir as homedir2 } from "node:os";
|
|
139
296
|
import { resolve } from "node:path";
|
|
140
297
|
var DEFAULT_SEARCH_PATHS = [
|
|
141
298
|
"~/.nlm/.env",
|
|
@@ -144,7 +301,7 @@ var DEFAULT_SEARCH_PATHS = [
|
|
|
144
301
|
"../../.env"
|
|
145
302
|
];
|
|
146
303
|
function expandHome(p) {
|
|
147
|
-
if (p.startsWith("~/")) return resolve(
|
|
304
|
+
if (p.startsWith("~/")) return resolve(homedir2(), p.slice(2));
|
|
148
305
|
return p;
|
|
149
306
|
}
|
|
150
307
|
function autoloadEnv(extraPaths = []) {
|
|
@@ -340,6 +497,18 @@ function extractRecallQuery(prompt) {
|
|
|
340
497
|
}
|
|
341
498
|
|
|
342
499
|
// src/hook/hook-helpers.ts
|
|
500
|
+
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync3, realpathSync } from "node:fs";
|
|
501
|
+
import { pathToFileURL } from "node:url";
|
|
502
|
+
function isMainModule(metaUrl, argv1) {
|
|
503
|
+
if (!argv1) return false;
|
|
504
|
+
let resolved;
|
|
505
|
+
try {
|
|
506
|
+
resolved = realpathSync(argv1);
|
|
507
|
+
} catch {
|
|
508
|
+
return false;
|
|
509
|
+
}
|
|
510
|
+
return metaUrl === pathToFileURL(resolved).href;
|
|
511
|
+
}
|
|
343
512
|
function readStdin() {
|
|
344
513
|
return new Promise((resolve2) => {
|
|
345
514
|
let data = "";
|
|
@@ -362,29 +531,46 @@ function hookModeFromEnv() {
|
|
|
362
531
|
return process.env["NLM_HOOK_MODE"] === "live" ? "live" : "shadow";
|
|
363
532
|
}
|
|
364
533
|
|
|
534
|
+
// src/shared/net.ts
|
|
535
|
+
var DEFAULT_NLM_PORT = "3940";
|
|
536
|
+
|
|
365
537
|
// src/hook/recall-over-http.ts
|
|
366
538
|
var RECALL_LIMIT = 5;
|
|
367
|
-
|
|
368
|
-
|
|
539
|
+
function parseRecallTimeout(raw) {
|
|
540
|
+
if (raw === void 0) return 4e3;
|
|
541
|
+
const n = Number(raw);
|
|
542
|
+
return Number.isFinite(n) && n > 0 ? n : 4e3;
|
|
543
|
+
}
|
|
544
|
+
function recallTimeoutMs() {
|
|
545
|
+
return parseRecallTimeout(process.env["NLM_HOOK_RECALL_TIMEOUT_MS"]);
|
|
546
|
+
}
|
|
547
|
+
var emptyResult = (outcome) => ({
|
|
548
|
+
hits: [],
|
|
549
|
+
facts: [],
|
|
550
|
+
exemplars: [],
|
|
551
|
+
concepts: [],
|
|
552
|
+
outcome
|
|
553
|
+
});
|
|
554
|
+
async function recallOverHttp(prompt, runtime, conversationId, mode = "keyword", source = "hook") {
|
|
369
555
|
const query = extractRecallQuery(prompt);
|
|
370
|
-
if (query === null) return
|
|
371
|
-
const portValue = process.env["NLM_PORT"] ??
|
|
556
|
+
if (query === null) return emptyResult("skipped");
|
|
557
|
+
const portValue = process.env["NLM_PORT"] ?? DEFAULT_NLM_PORT;
|
|
372
558
|
const url = (
|
|
373
559
|
// 127.0.0.1, not localhost: each hook is a fresh process with no connection
|
|
374
560
|
// reuse, and Node resolves localhost to IPv6 ::1 first — a measured ~50-300ms
|
|
375
561
|
// per-fire connect penalty vs ~3ms on the explicit IPv4 loopback.
|
|
376
|
-
`http://127.0.0.1:${portValue}/api/recall?q=${encodeURIComponent(query)}&mode=${mode}&limit=${RECALL_LIMIT}&withFacts=true&withExemplars=true` + (conversationId ? `&conversation_id=${encodeURIComponent(conversationId)}` : "")
|
|
562
|
+
`http://127.0.0.1:${portValue}/api/recall?q=${encodeURIComponent(query)}&mode=${mode}&limit=${RECALL_LIMIT}&withFacts=true&withExemplars=true&withConcepts=true` + (conversationId ? `&conversation_id=${encodeURIComponent(conversationId)}` : "")
|
|
377
563
|
);
|
|
378
564
|
try {
|
|
379
|
-
const extra = { "x-recall-source":
|
|
565
|
+
const extra = { "x-recall-source": source };
|
|
380
566
|
if (runtime) extra["x-recall-runtime"] = runtime;
|
|
381
|
-
const res = await fetchWithTimeout(url, { headers: hookAuthHeaders(extra) },
|
|
382
|
-
if (!res.ok) return
|
|
567
|
+
const res = await fetchWithTimeout(url, { headers: hookAuthHeaders(extra) }, recallTimeoutMs());
|
|
568
|
+
if (!res.ok) return emptyResult("http-error");
|
|
383
569
|
let body;
|
|
384
570
|
try {
|
|
385
571
|
body = await res.json();
|
|
386
572
|
} catch {
|
|
387
|
-
return
|
|
573
|
+
return emptyResult("http-error");
|
|
388
574
|
}
|
|
389
575
|
const hits = (body.results ?? []).map((r) => ({
|
|
390
576
|
id: r.id,
|
|
@@ -405,37 +591,47 @@ async function recallOverHttp(prompt, runtime, conversationId, mode = "keyword")
|
|
|
405
591
|
repo: e.repo,
|
|
406
592
|
taskContext: e.taskContext
|
|
407
593
|
}));
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
594
|
+
const concepts = (body.relatedConcepts ?? []).map((c) => ({
|
|
595
|
+
concept: c.concept,
|
|
596
|
+
status: c.status,
|
|
597
|
+
attemptCount: c.attemptCount,
|
|
598
|
+
nextStep: c.nextStep
|
|
599
|
+
}));
|
|
600
|
+
return { hits, facts, exemplars, concepts, outcome: "ok" };
|
|
601
|
+
} catch (err) {
|
|
602
|
+
const aborted = err instanceof Error && err.name === "AbortError";
|
|
603
|
+
return emptyResult(aborted ? "timeout" : "unreachable");
|
|
411
604
|
}
|
|
412
605
|
}
|
|
413
606
|
|
|
414
607
|
// src/hook/session-start-hook.ts
|
|
415
|
-
var
|
|
416
|
-
var
|
|
608
|
+
var scoreThreshold = () => parseScoreFloor(process.env["NLM_RECALL_SCORE_FLOOR"]);
|
|
609
|
+
var relativeFloor = () => parseRelativeFloor(process.env["NLM_RECALL_REL_FLOOR"], 0.9);
|
|
417
610
|
var PER_FIRE_CAP = 3;
|
|
418
611
|
var PER_CONVERSATION_CAP = 10;
|
|
419
|
-
var
|
|
612
|
+
var RECALL_TIMEOUT_MS = 2e3;
|
|
420
613
|
async function runHook(input, deps) {
|
|
421
614
|
let hits = [];
|
|
615
|
+
let recallOutcome = "unreachable";
|
|
422
616
|
try {
|
|
423
|
-
|
|
617
|
+
const fetched = await deps.recall(input.query, input.conversationId);
|
|
618
|
+
hits = fetched.hits;
|
|
619
|
+
recallOutcome = fetched.outcome;
|
|
424
620
|
} catch {
|
|
425
621
|
hits = [];
|
|
426
622
|
}
|
|
427
|
-
const surfaced = loadSurfaced(input.conversationId);
|
|
623
|
+
const surfaced = loadSurfaced(DEFAULT_TEAM_ID, input.conversationId);
|
|
428
624
|
const selected = selectHits({
|
|
429
625
|
hits,
|
|
430
626
|
surfaced,
|
|
431
|
-
scoreThreshold:
|
|
432
|
-
relativeFloor:
|
|
627
|
+
scoreThreshold: scoreThreshold(),
|
|
628
|
+
relativeFloor: relativeFloor(),
|
|
433
629
|
perFireCap: PER_FIRE_CAP,
|
|
434
630
|
perConversationCap: PER_CONVERSATION_CAP
|
|
435
631
|
});
|
|
436
632
|
const block = formatPointerBlock(selected);
|
|
437
633
|
const estTokens = Math.ceil(block.length / 4);
|
|
438
|
-
appendHookLog({
|
|
634
|
+
appendHookLog(DEFAULT_TEAM_ID, {
|
|
439
635
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
440
636
|
conversationId: input.conversationId,
|
|
441
637
|
promptPreview: input.query,
|
|
@@ -443,10 +639,11 @@ async function runHook(input, deps) {
|
|
|
443
639
|
hits: hits.map((h) => ({ id: h.id, score: h.matchScore })),
|
|
444
640
|
wouldInject: selected.map((h) => h.id),
|
|
445
641
|
estTokens,
|
|
446
|
-
mode: deps.mode
|
|
642
|
+
mode: deps.mode,
|
|
643
|
+
recallOutcome
|
|
447
644
|
});
|
|
448
645
|
if (deps.mode === "live" && selected.length > 0) {
|
|
449
|
-
recordSurfaced(input.conversationId, selected.map((h) => h.id));
|
|
646
|
+
recordSurfaced(DEFAULT_TEAM_ID, input.conversationId, selected.map((h) => h.id));
|
|
450
647
|
return block;
|
|
451
648
|
}
|
|
452
649
|
return "";
|
|
@@ -456,12 +653,12 @@ function composeSessionStartOutput(failureModeBlock, recallBlock) {
|
|
|
456
653
|
}
|
|
457
654
|
async function fetchFailureModeBlock(repo) {
|
|
458
655
|
if (!repo) return "";
|
|
459
|
-
const portValue = process.env["NLM_PORT"] ??
|
|
656
|
+
const portValue = process.env["NLM_PORT"] ?? DEFAULT_NLM_PORT;
|
|
460
657
|
const url = `http://127.0.0.1:${portValue}/api/signals/failure-modes?repo=${encodeURIComponent(repo)}`;
|
|
461
658
|
try {
|
|
462
659
|
const res = await fetchWithTimeout(url, {
|
|
463
660
|
headers: hookAuthHeaders({ "x-recall-source": "session-start-hook" })
|
|
464
|
-
},
|
|
661
|
+
}, RECALL_TIMEOUT_MS);
|
|
465
662
|
if (!res.ok) return "";
|
|
466
663
|
const body = await res.json();
|
|
467
664
|
return typeof body.block === "string" ? body.block : "";
|
|
@@ -469,9 +666,29 @@ async function fetchFailureModeBlock(repo) {
|
|
|
469
666
|
return "";
|
|
470
667
|
}
|
|
471
668
|
}
|
|
472
|
-
|
|
669
|
+
var GIT_TIMEOUT_MS = 300;
|
|
670
|
+
var RECENT_COMMITS = 3;
|
|
671
|
+
function git(cwd, args) {
|
|
672
|
+
try {
|
|
673
|
+
return execFileSync("git", ["-C", cwd, ...args], {
|
|
674
|
+
encoding: "utf8",
|
|
675
|
+
timeout: GIT_TIMEOUT_MS,
|
|
676
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
677
|
+
}).trim();
|
|
678
|
+
} catch {
|
|
679
|
+
return "";
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
function readGitContext(workingDirectory) {
|
|
683
|
+
if (!workingDirectory) return "";
|
|
684
|
+
const branch = git(workingDirectory, ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
685
|
+
const subjects = git(workingDirectory, ["log", `-${RECENT_COMMITS}`, "--format=%s"]);
|
|
686
|
+
const branchWords = branch === "HEAD" ? "" : branch.replace(/[/_-]+/g, " ");
|
|
687
|
+
return [branchWords, subjects.replace(/\n/g, " ")].filter(Boolean).join(" ");
|
|
688
|
+
}
|
|
689
|
+
function buildQuery(workingDirectory, projectName, gitContext) {
|
|
473
690
|
const dirTail = workingDirectory.split("/").filter(Boolean).at(-1) ?? "";
|
|
474
|
-
const parts = [dirTail, projectName].filter(Boolean);
|
|
691
|
+
const parts = [dirTail, projectName, gitContext].filter(Boolean);
|
|
475
692
|
return parts.join(" ").trim() || "session start";
|
|
476
693
|
}
|
|
477
694
|
async function main() {
|
|
@@ -482,14 +699,23 @@ async function main() {
|
|
|
482
699
|
const conversationId = typeof payload.session_id === "string" ? payload.session_id : "unknown";
|
|
483
700
|
const workingDirectory = typeof payload.cwd === "string" ? payload.cwd : typeof payload.working_directory === "string" ? payload.working_directory : "";
|
|
484
701
|
const projectName = typeof payload.project_name === "string" ? payload.project_name : "";
|
|
485
|
-
const query = buildQuery(workingDirectory, projectName);
|
|
702
|
+
const query = buildQuery(workingDirectory, projectName, readGitContext(workingDirectory));
|
|
486
703
|
const mode = hookModeFromEnv();
|
|
487
704
|
const [out, failureModes] = await Promise.all([
|
|
488
705
|
runHook(
|
|
489
706
|
{ conversationId, query },
|
|
490
707
|
{
|
|
491
708
|
mode,
|
|
492
|
-
recall: async (q, cid) =>
|
|
709
|
+
recall: async (q, cid) => {
|
|
710
|
+
const r = await recallOverHttp(
|
|
711
|
+
q,
|
|
712
|
+
"claude-code",
|
|
713
|
+
cid === "unknown" ? void 0 : cid,
|
|
714
|
+
"hybrid",
|
|
715
|
+
"session-start-hook"
|
|
716
|
+
);
|
|
717
|
+
return { hits: r.hits, outcome: r.outcome };
|
|
718
|
+
}
|
|
493
719
|
}
|
|
494
720
|
),
|
|
495
721
|
mode === "live" ? fetchFailureModeBlock(workingDirectory) : Promise.resolve("")
|
|
@@ -499,10 +725,12 @@ async function main() {
|
|
|
499
725
|
} catch {
|
|
500
726
|
}
|
|
501
727
|
}
|
|
502
|
-
if (
|
|
728
|
+
if (isMainModule(import.meta.url, process.argv[1])) {
|
|
503
729
|
void main();
|
|
504
730
|
}
|
|
505
731
|
export {
|
|
732
|
+
buildQuery,
|
|
506
733
|
composeSessionStartOutput,
|
|
734
|
+
readGitContext,
|
|
507
735
|
runHook
|
|
508
736
|
};
|