@cortexkit/opencode-magic-context 0.41.4 → 0.42.1
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 +21 -3
- package/dist/agents/hidden-agent-registrations.d.ts +1 -3
- package/dist/agents/hidden-agent-registrations.d.ts.map +1 -1
- package/dist/agents/magic-context-prompt.d.ts +1 -1
- package/dist/agents/magic-context-prompt.d.ts.map +1 -1
- package/dist/agents/permissions.d.ts +1 -22
- package/dist/agents/permissions.d.ts.map +1 -1
- package/dist/config/agent-disable.d.ts +0 -5
- package/dist/config/agent-disable.d.ts.map +1 -1
- package/dist/config/index.d.ts +5 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/migrate-config-location.d.ts.map +1 -1
- package/dist/config/project-security.d.ts +20 -2
- package/dist/config/project-security.d.ts.map +1 -1
- package/dist/config/removed-agent-config.d.ts +8 -0
- package/dist/config/removed-agent-config.d.ts.map +1 -0
- package/dist/config/schema/magic-context.d.ts +43 -201
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/{conflict-warning-hook-ejkc9sjn.js → conflict-warning-hook-6p3xqeac.js} +3 -3
- package/dist/{derive-budgets-bc366cz8.js → derive-budgets-s2pgnnm4.js} +1 -1
- package/dist/features/builtin-commands/commands.d.ts +0 -4
- package/dist/features/builtin-commands/commands.d.ts.map +1 -1
- package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts +15 -4
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-storage.d.ts.map +1 -1
- package/dist/features/magic-context/context-authority.d.ts +31 -4
- package/dist/features/magic-context/context-authority.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/open-opencode-db.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/refresh-primers.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/retrospective-orphan-sweep.d.ts +19 -9
- package/dist/features/magic-context/dreamer/retrospective-orphan-sweep.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts +4 -0
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
- package/dist/features/magic-context/fail-closed-block.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/sweep-coordinator.d.ts.map +1 -1
- package/dist/features/magic-context/index.d.ts +0 -1
- package/dist/features/magic-context/index.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-identity.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-local.d.ts +13 -0
- package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-model-match.d.ts +41 -0
- package/dist/features/magic-context/memory/embedding-model-match.d.ts.map +1 -0
- package/dist/features/magic-context/memory/embedding-openai.d.ts +7 -20
- package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-provider.d.ts +2 -2
- package/dist/features/magic-context/memory/embedding-provider.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-synapse.d.ts +48 -14
- package/dist/features/magic-context/memory/embedding-synapse.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding.d.ts +1 -1
- package/dist/features/magic-context/memory/embedding.d.ts.map +1 -1
- package/dist/features/magic-context/memory/memory-migration.d.ts.map +1 -1
- package/dist/features/magic-context/memory/project-identity.d.ts +1 -0
- package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
- package/dist/features/magic-context/memory/promotion.d.ts +7 -1
- package/dist/features/magic-context/memory/promotion.d.ts.map +1 -1
- package/dist/features/magic-context/merged-reasoning-decisions.d.ts +6 -0
- package/dist/features/magic-context/merged-reasoning-decisions.d.ts.map +1 -0
- package/dist/features/magic-context/message-fts-rowid-map.d.ts.map +1 -1
- package/dist/features/magic-context/message-index-async.d.ts +12 -0
- package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
- package/dist/features/magic-context/message-index.d.ts.map +1 -1
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
- package/dist/features/magic-context/mural/render-trigger.d.ts +6 -0
- package/dist/features/magic-context/mural/render-trigger.d.ts.map +1 -1
- package/dist/features/magic-context/no-content-compartment.d.ts +12 -0
- package/dist/features/magic-context/no-content-compartment.d.ts.map +1 -0
- package/dist/features/magic-context/pi-content-decisions.d.ts +9 -0
- package/dist/features/magic-context/pi-content-decisions.d.ts.map +1 -0
- package/dist/features/magic-context/project-docs-hash.d.ts +4 -0
- package/dist/features/magic-context/project-docs-hash.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts +13 -4
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/protection-window.d.ts +79 -0
- package/dist/features/magic-context/protection-window.d.ts.map +1 -0
- package/dist/features/magic-context/search.d.ts.map +1 -1
- package/dist/features/magic-context/session-project-backfill.d.ts.map +1 -1
- package/dist/features/magic-context/shadow-backfill-state.d.ts +26 -0
- package/dist/features/magic-context/shadow-backfill-state.d.ts.map +1 -0
- package/dist/features/magic-context/smart-notes/compiler.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts +4 -0
- package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/storage.d.ts.map +1 -1
- package/dist/features/magic-context/storage-clone.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts +1 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-embedding-measurements.d.ts +2 -2
- package/dist/features/magic-context/storage-embedding-measurements.d.ts.map +1 -1
- package/dist/features/magic-context/storage-historian-runs.d.ts +4 -0
- package/dist/features/magic-context/storage-historian-runs.d.ts.map +1 -1
- package/dist/features/magic-context/storage-memory-mutation-log.d.ts +1 -0
- package/dist/features/magic-context/storage-memory-mutation-log.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +79 -13
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta.d.ts +1 -1
- package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
- package/dist/features/magic-context/storage-native-replay.d.ts +29 -0
- package/dist/features/magic-context/storage-native-replay.d.ts.map +1 -0
- package/dist/features/magic-context/storage-notes.d.ts +6 -0
- package/dist/features/magic-context/storage-notes.d.ts.map +1 -1
- package/dist/features/magic-context/storage-replay-document.d.ts +33 -0
- package/dist/features/magic-context/storage-replay-document.d.ts.map +1 -0
- package/dist/features/magic-context/storage-subagent-invocations.d.ts +1 -1
- package/dist/features/magic-context/storage-subagent-invocations.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tags.d.ts +19 -11
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +3 -3
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/features/magic-context/subagent-token-capture.d.ts.map +1 -1
- package/dist/features/magic-context/tagger.d.ts +13 -0
- package/dist/features/magic-context/tagger.d.ts.map +1 -1
- package/dist/features/magic-context/tool-owner-backfill.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/storage-user-memory.d.ts.map +1 -1
- package/dist/features/magic-context/workspaces.d.ts.map +1 -1
- package/dist/hooks/magic-context/apply-operations.d.ts +11 -5
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/cache-busting-signals.d.ts +9 -1
- package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -1
- package/dist/hooks/magic-context/caveman-cleanup.d.ts +1 -1
- package/dist/hooks/magic-context/caveman-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
- package/dist/hooks/magic-context/child-session-spawn.d.ts +3 -3
- package/dist/hooks/magic-context/child-session-spawn.d.ts.map +1 -1
- package/dist/hooks/magic-context/command-handler.d.ts +1 -10
- package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts +10 -21
- package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts +1 -1
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts +26 -2
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts.map +1 -1
- package/dist/hooks/magic-context/decay-render.d.ts.map +1 -1
- package/dist/hooks/magic-context/dropped-input-guard.d.ts +9 -0
- package/dist/hooks/magic-context/dropped-input-guard.d.ts.map +1 -0
- package/dist/hooks/magic-context/embed-session-state.d.ts +1 -1
- package/dist/hooks/magic-context/embed-session-state.d.ts.map +1 -1
- package/dist/hooks/magic-context/emergency-drop.d.ts +6 -1
- package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-handler.d.ts +0 -1
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-payloads.d.ts +7 -6
- package/dist/hooks/magic-context/event-payloads.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-resolvers.d.ts +1 -1
- package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
- package/dist/hooks/magic-context/execute-status.d.ts +3 -1
- package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
- package/dist/hooks/magic-context/format-embed-failure.d.ts +2 -1
- package/dist/hooks/magic-context/format-embed-failure.d.ts.map +1 -1
- package/dist/hooks/magic-context/format-embed-status.d.ts.map +1 -1
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts +7 -1
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook-handlers.d.ts +3 -1
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts +13 -4
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts +14 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/live-session-state.d.ts +1 -1
- package/dist/hooks/magic-context/lkg-slot.d.ts +34 -0
- package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
- package/dist/hooks/magic-context/maintenance-authority.d.ts +2 -2
- package/dist/hooks/magic-context/maintenance-authority.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-state-sync-timing.d.ts +21 -0
- package/dist/hooks/magic-context/module-state-sync-timing.d.ts.map +1 -0
- package/dist/hooks/magic-context/module-state-sync.d.ts +21 -7
- package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-transport.d.ts +12 -0
- package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-wire.d.ts +8 -0
- package/dist/hooks/magic-context/module-wire.d.ts.map +1 -1
- package/dist/hooks/magic-context/note-nudger.d.ts.map +1 -1
- package/dist/hooks/magic-context/persist-filtered-noise.d.ts +5 -0
- package/dist/hooks/magic-context/persist-filtered-noise.d.ts.map +1 -0
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts +6 -0
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts +18 -18
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-db.d.ts +22 -12
- package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-formatting.d.ts +8 -0
- package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts +10 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
- package/dist/hooks/magic-context/reference-retrieval.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-mode-transform.d.ts +74 -9
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/send-session-notification.d.ts +11 -10
- package/dist/hooks/magic-context/send-session-notification.d.ts.map +1 -1
- package/dist/hooks/magic-context/strip-content.d.ts +7 -0
- package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
- package/dist/hooks/magic-context/supersession-reclaim.d.ts +13 -0
- package/dist/hooks/magic-context/supersession-reclaim.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts +2 -3
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts +8 -3
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-context-state.d.ts +7 -1
- package/dist/hooks/magic-context/transform-context-state.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +11 -4
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +7 -2
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/upgrade-reminder.d.ts +7 -9
- package/dist/hooks/magic-context/upgrade-reminder.d.ts.map +1 -1
- package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
- package/dist/index-1974jvn3.js +783 -0
- package/dist/{index-0y2mcg5y.js → index-1q9kay7n.js} +18717 -16197
- package/dist/{index-4avmwfp5.js → index-36wd1d6k.js} +6 -29
- package/dist/{index-fz104x1j.js → index-jmtjh2d3.js} +3 -3
- package/dist/{index-q264erdp.js → index-nqgjwfzn.js} +70 -38
- package/dist/{index-mjv9je4e.js → index-xdtge3y2.js} +45 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6457 -5190
- package/dist/plugin/conflict-warning-hook.d.ts +5 -6
- package/dist/plugin/conflict-warning-hook.d.ts.map +1 -1
- package/dist/plugin/dream-timer.d.ts +1 -0
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/embedding-bootstrap-helpers.d.ts.map +1 -1
- package/dist/plugin/embedding-routing.d.ts +4 -1
- package/dist/plugin/embedding-routing.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +16 -2
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts +31 -1
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/plugin/rust-tool-backends.d.ts +1 -0
- package/dist/plugin/rust-tool-backends.d.ts.map +1 -1
- package/dist/plugin/tool-registry.d.ts.map +1 -1
- package/dist/{recomp-orchestrator-q98r6rga.js → recomp-orchestrator-m33b3rk9.js} +5 -5
- package/dist/{send-session-notification-hdh02wy9.js → send-session-notification-1qeqkswb.js} +6 -4
- package/dist/shared/child-session-teardown.d.ts +34 -0
- package/dist/shared/child-session-teardown.d.ts.map +1 -0
- package/dist/shared/keep-subagents.d.ts +1 -1
- package/dist/shared/keep-subagents.d.ts.map +1 -1
- package/dist/shared/model-suggestion-retry.d.ts +1 -1
- package/dist/shared/opencode-db-path.d.ts +24 -0
- package/dist/shared/opencode-db-path.d.ts.map +1 -0
- package/dist/shared/prompt-surface-runtime.d.ts +10 -5
- package/dist/shared/prompt-surface-runtime.d.ts.map +1 -1
- package/dist/shared/resolve-fallbacks.d.ts +1 -1
- package/dist/shared/rpc-types.d.ts +121 -0
- package/dist/shared/rpc-types.d.ts.map +1 -1
- package/dist/shared/sqlite.d.ts +42 -0
- package/dist/shared/sqlite.d.ts.map +1 -1
- package/dist/shared/status-detail-text.d.ts +3 -1
- package/dist/shared/status-detail-text.d.ts.map +1 -1
- package/dist/shared/status-summary.d.ts +30 -0
- package/dist/shared/status-summary.d.ts.map +1 -0
- package/dist/shared/subagent-runner.d.ts +17 -10
- package/dist/shared/subagent-runner.d.ts.map +1 -1
- package/dist/shared/tag-transcript.d.ts.map +1 -1
- package/dist/shared/tail-hygiene-status.d.ts +1 -0
- package/dist/shared/tail-hygiene-status.d.ts.map +1 -1
- package/dist/shared/transcript.d.ts +6 -0
- package/dist/shared/transcript.d.ts.map +1 -1
- package/dist/shared/user-facing-codes.d.ts +191 -0
- package/dist/shared/user-facing-codes.d.ts.map +1 -0
- package/dist/shared/window-geometry.d.ts +23 -0
- package/dist/shared/window-geometry.d.ts.map +1 -1
- package/dist/shared/write-transaction-timing.d.ts +1 -1
- package/dist/shared/write-transaction-timing.d.ts.map +1 -1
- package/dist/{storage-meta-session-dvwfw778.js → storage-meta-session-e6g0mmec.js} +2 -2
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
- package/dist/tools/ctx-memory/verification-recording.d.ts.map +1 -1
- package/dist/tools/ctx-note/constants.d.ts +1 -1
- package/dist/tools/ctx-note/constants.d.ts.map +1 -1
- package/dist/tools/ctx-note/tools.d.ts.map +1 -1
- package/dist/tools/ctx-note/types.d.ts +1 -0
- package/dist/tools/ctx-note/types.d.ts.map +1 -1
- package/dist/tools/ctx-reduce/tools.d.ts +10 -1
- package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
- package/dist/tools/ctx-search/constants.d.ts +1 -1
- package/dist/tools/ctx-search/constants.d.ts.map +1 -1
- package/dist/tools/light-descriptions.d.ts +2 -2
- package/dist/tools/light-descriptions.d.ts.map +1 -1
- package/package.json +2 -3
- package/src/agents/hidden-agent-registrations.ts +3 -15
- package/src/agents/magic-context-prompt.test.ts +7 -5
- package/src/agents/magic-context-prompt.ts +22 -30
- package/src/agents/permissions.test.ts +1 -42
- package/src/agents/permissions.ts +1 -24
- package/src/config/agent-disable.ts +5 -22
- package/src/config/index.test.ts +126 -15
- package/src/config/index.ts +41 -6
- package/src/config/latch-permanence-guard.test.ts +4 -0
- package/src/config/migrate-config-location.test.ts +39 -6
- package/src/config/migrate-config-location.ts +18 -31
- package/src/config/profiles.ts +1 -1
- package/src/config/project-security.hostile-matrix.test.ts +0 -8
- package/src/config/project-security.test.ts +21 -24
- package/src/config/project-security.ts +115 -14
- package/src/config/protected-tokens.test.ts +235 -0
- package/src/config/removed-agent-config.ts +45 -0
- package/src/config/removed-agent-source-fence.test.ts +56 -0
- package/src/config/schema/magic-context.test.ts +50 -42
- package/src/config/schema/magic-context.ts +70 -37
- package/src/shared/child-session-teardown.test.ts +218 -0
- package/src/shared/child-session-teardown.ts +66 -0
- package/src/shared/keep-subagents.ts +9 -14
- package/src/shared/model-suggestion-retry.ts +1 -1
- package/src/shared/opencode-db-path.test.ts +196 -0
- package/src/shared/opencode-db-path.ts +215 -0
- package/src/shared/prompt-surface-a1-golden.md +50 -35
- package/src/shared/prompt-surface-runtime.test.ts +28 -0
- package/src/shared/prompt-surface-runtime.ts +22 -5
- package/src/shared/resolve-fallbacks.ts +1 -1
- package/src/shared/rpc-types.ts +128 -0
- package/src/shared/session-messages-bounded.test.ts +1 -1
- package/src/shared/sqlite-import-fence.test.ts +19 -0
- package/src/shared/sqlite.test.ts +27 -1
- package/src/shared/sqlite.ts +204 -1
- package/src/shared/status-detail-text.test.ts +92 -20
- package/src/shared/status-detail-text.ts +24 -2
- package/src/shared/status-summary.ts +167 -0
- package/src/shared/subagent-runner.ts +17 -10
- package/src/shared/tag-transcript.ts +33 -21
- package/src/shared/tail-hygiene-status.ts +8 -0
- package/src/shared/transcript.ts +7 -0
- package/src/shared/user-facing-codes.test.ts +140 -0
- package/src/shared/user-facing-codes.ts +276 -0
- package/src/shared/window-geometry.test.ts +44 -0
- package/src/shared/window-geometry.ts +89 -11
- package/src/shared/write-transaction-attribution.test.ts +241 -0
- package/src/shared/write-transaction-timing.ts +2 -1
- package/src/tui/index.tsx +44 -11
- package/src/tui/slots/sidebar-content.tsx +12 -7
- package/src/tui-compiled/index.tsx +662 -649
- package/src/tui-compiled/slots/sidebar-content.tsx +301 -305
- package/dist/agents/sidekick.d.ts +0 -2
- package/dist/agents/sidekick.d.ts.map +0 -1
- package/dist/features/magic-context/defaults.d.ts +0 -2
- package/dist/features/magic-context/defaults.d.ts.map +0 -1
- package/dist/features/magic-context/sidekick/agent.d.ts +0 -14
- package/dist/features/magic-context/sidekick/agent.d.ts.map +0 -1
- package/dist/features/magic-context/sidekick/core.d.ts +0 -38
- package/dist/features/magic-context/sidekick/core.d.ts.map +0 -1
- package/dist/features/magic-context/sidekick/index.d.ts +0 -3
- package/dist/features/magic-context/sidekick/index.d.ts.map +0 -1
- package/dist/hooks/magic-context/boundary-execution.d.ts +0 -27
- package/dist/hooks/magic-context/boundary-execution.d.ts.map +0 -1
- package/dist/index-raatkvw5.js +0 -360
- package/src/agents/sidekick.ts +0 -1
- package/src/features/magic-context/defaults.ts +0 -1
|
@@ -80,6 +80,34 @@ describe("prompt-surface runtime", () => {
|
|
|
80
80
|
expect(changedModel.primaryOverride).toBe(second);
|
|
81
81
|
});
|
|
82
82
|
|
|
83
|
+
it("shares one frozen guidance epoch between the system hook and Rust adapter", () => {
|
|
84
|
+
const directory = tempDir();
|
|
85
|
+
const path = join(directory, "guidance.md");
|
|
86
|
+
const first = "## Magic Context\n\nShared first epoch";
|
|
87
|
+
const second = "## Magic Context\n\nShared second epoch";
|
|
88
|
+
writeFileSync(path, first);
|
|
89
|
+
const runtime = createPromptSurfaceRuntime({
|
|
90
|
+
userConfigDirectory: directory,
|
|
91
|
+
warn: () => undefined,
|
|
92
|
+
});
|
|
93
|
+
const systemEpochs = createPromptSurfaceGuidanceEpochCache(runtime);
|
|
94
|
+
const adapterEpochs = createPromptSurfaceGuidanceEpochCache(runtime);
|
|
95
|
+
const config = {
|
|
96
|
+
default: "full" as const,
|
|
97
|
+
guidance_override_path: "guidance.md",
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const systemInitial = systemEpochs.resolve("session", config, "provider/model");
|
|
101
|
+
writeFileSync(path, second);
|
|
102
|
+
const adapterDeferred = adapterEpochs.resolve("session", config, "provider/model");
|
|
103
|
+
expect(adapterDeferred).toBe(systemInitial);
|
|
104
|
+
expect(adapterDeferred.primaryOverride).toBe(first);
|
|
105
|
+
|
|
106
|
+
adapterEpochs.clear("session");
|
|
107
|
+
const systemNextEpoch = systemEpochs.resolve("session", config, "provider/model");
|
|
108
|
+
expect(systemNextEpoch.primaryOverride).toBe(second);
|
|
109
|
+
});
|
|
110
|
+
|
|
83
111
|
it("uses registration default, applies known overrides, and reports invalid IDs", () => {
|
|
84
112
|
const warnings: string[] = [];
|
|
85
113
|
const runtime = createPromptSurfaceRuntime({
|
|
@@ -230,18 +230,33 @@ interface GuidanceEpoch {
|
|
|
230
230
|
selection: PromptSurfaceGuidanceSelection;
|
|
231
231
|
}
|
|
232
232
|
|
|
233
|
-
|
|
234
|
-
export function createPromptSurfaceGuidanceEpochCache(runtime: PromptSurfaceRuntime): {
|
|
233
|
+
export interface PromptSurfaceGuidanceEpochCache {
|
|
235
234
|
resolve: (
|
|
236
235
|
sessionId: string,
|
|
237
236
|
config: PromptSurfaceConfig | undefined,
|
|
238
237
|
modelKey: string | undefined,
|
|
239
238
|
) => PromptSurfaceGuidanceSelection;
|
|
240
239
|
clear: (sessionId: string) => void;
|
|
241
|
-
}
|
|
242
|
-
const epochs = new Map<string, GuidanceEpoch>();
|
|
240
|
+
}
|
|
243
241
|
|
|
244
|
-
|
|
242
|
+
const guidanceEpochCacheByRuntime = new WeakMap<
|
|
243
|
+
PromptSurfaceRuntime,
|
|
244
|
+
PromptSurfaceGuidanceEpochCache
|
|
245
|
+
>();
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Freeze preset selection and materialized override bytes for one model-key epoch.
|
|
249
|
+
* Every hook using the same runtime also shares this cache, so a file edit cannot
|
|
250
|
+
* make the system hook and Rust adapter observe different bytes within one epoch.
|
|
251
|
+
*/
|
|
252
|
+
export function createPromptSurfaceGuidanceEpochCache(
|
|
253
|
+
runtime: PromptSurfaceRuntime,
|
|
254
|
+
): PromptSurfaceGuidanceEpochCache {
|
|
255
|
+
const shared = guidanceEpochCacheByRuntime.get(runtime);
|
|
256
|
+
if (shared) return shared;
|
|
257
|
+
|
|
258
|
+
const epochs = new Map<string, GuidanceEpoch>();
|
|
259
|
+
const cache: PromptSurfaceGuidanceEpochCache = {
|
|
245
260
|
resolve(sessionId, config, modelKey) {
|
|
246
261
|
const canonicalModelKey = modelKey ? piModelRefToCanonical(modelKey) : undefined;
|
|
247
262
|
const cached = epochs.get(sessionId);
|
|
@@ -257,4 +272,6 @@ export function createPromptSurfaceGuidanceEpochCache(runtime: PromptSurfaceRunt
|
|
|
257
272
|
epochs.delete(sessionId);
|
|
258
273
|
},
|
|
259
274
|
};
|
|
275
|
+
guidanceEpochCacheByRuntime.set(runtime, cache);
|
|
276
|
+
return cache;
|
|
260
277
|
}
|
|
@@ -2,7 +2,7 @@ import type { ModelInput, ResolvedModelEntry } from "./model-resolution";
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Resolve the fallback model list to attempt for a hidden-agent (historian /
|
|
5
|
-
* dreamer
|
|
5
|
+
* dreamer) call when its configured primary fails.
|
|
6
6
|
*
|
|
7
7
|
* Policy: ONLY the user's explicitly-configured `fallback_models` for this
|
|
8
8
|
* agent. There is NO builtin provider-agnostic chain — a hardcoded chain
|
package/src/shared/rpc-types.ts
CHANGED
|
@@ -7,12 +7,15 @@ import type {
|
|
|
7
7
|
DreamTaskBacklogMap,
|
|
8
8
|
DreamTaskProgress,
|
|
9
9
|
} from "../features/magic-context/dreamer/task-registry";
|
|
10
|
+
import type { SynapseLaneDescriptor } from "../features/magic-context/memory/embedding-synapse";
|
|
10
11
|
import type { ConfigParseFailure } from "./config-diagnostics";
|
|
11
12
|
import type { LoggerDiagnostics } from "./logger";
|
|
12
13
|
|
|
13
14
|
export interface TailHygieneStatus {
|
|
14
15
|
/** Tokens in active, non-protected tail content that the agent can reclaim. */
|
|
15
16
|
u: number;
|
|
17
|
+
/** Spent tool outputs contributing positive tokens to U in this baseline. */
|
|
18
|
+
reclaimableToolOutputCount?: number;
|
|
16
19
|
/** Tokens in rendered-tail content eligible for hygiene accounting in the same scan. */
|
|
17
20
|
t: number;
|
|
18
21
|
/** Reclaimable-to-eligible token ratio, clamped to 0–1 and shared by both nudge mechanisms. */
|
|
@@ -54,6 +57,8 @@ export interface SidebarSnapshot {
|
|
|
54
57
|
cacheTtl: string;
|
|
55
58
|
/** Persistent runtime failure shown directly in the sidebar when non-null. */
|
|
56
59
|
lastTransformError: string | null;
|
|
60
|
+
/** Durable history-compression failure count used to select the stable summary warning. */
|
|
61
|
+
historianFailureCount?: number;
|
|
57
62
|
lastDreamerRunAt: number | null;
|
|
58
63
|
projectIdentity: string | null;
|
|
59
64
|
compartmentTokens: number;
|
|
@@ -169,6 +174,8 @@ export interface StatusDetail extends SidebarSnapshot {
|
|
|
169
174
|
reserve: number;
|
|
170
175
|
reserveSource: "output_catalog" | "output_config" | "wall_margin" | "none";
|
|
171
176
|
geometry: "shared_upfront" | "shared_truncating" | "separate";
|
|
177
|
+
windowSource: "catalog" | "overlay" | "provider" | "detected";
|
|
178
|
+
absoluteWall: number;
|
|
172
179
|
};
|
|
173
180
|
};
|
|
174
181
|
/**
|
|
@@ -221,6 +228,12 @@ export interface StatusDetail extends SidebarSnapshot {
|
|
|
221
228
|
* (the plugin owns it), so this surface supplies the live DB value; the module
|
|
222
229
|
* surface supplies the module-store value instead.
|
|
223
230
|
*/
|
|
231
|
+
/** Search-indexing coverage and current command state for the default status summary. */
|
|
232
|
+
embedding?: {
|
|
233
|
+
state: "off" | "running" | "paused" | "stopped" | "ready" | "waiting";
|
|
234
|
+
indexed: number;
|
|
235
|
+
total: number;
|
|
236
|
+
};
|
|
224
237
|
storage_versions: {
|
|
225
238
|
/**
|
|
226
239
|
* Persisted schema version of context.db (MAX of schema_migrations).
|
|
@@ -239,12 +252,127 @@ export interface EmbedDetail {
|
|
|
239
252
|
enabled: boolean;
|
|
240
253
|
model: string;
|
|
241
254
|
provider: string;
|
|
255
|
+
synapseDescriptor?: SynapseLaneDescriptor;
|
|
242
256
|
session: { embedded: number; total: number };
|
|
243
257
|
memories: { embedded: number; total: number };
|
|
244
258
|
commits: { embedded: number; total: number; gitEnabled: boolean };
|
|
245
259
|
statusText: string;
|
|
246
260
|
}
|
|
247
261
|
|
|
262
|
+
export interface DebugProcessMemoryUsage {
|
|
263
|
+
rss: number;
|
|
264
|
+
heapTotal: number;
|
|
265
|
+
heapUsed: number;
|
|
266
|
+
external: number;
|
|
267
|
+
arrayBuffers: number;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export interface DebugSessionHolderCount {
|
|
271
|
+
sessionId: string;
|
|
272
|
+
lkgBytes: number;
|
|
273
|
+
taggerAssignments: number;
|
|
274
|
+
taggerToolAccounting: number;
|
|
275
|
+
wireRawMessages: number;
|
|
276
|
+
wireMessages: number;
|
|
277
|
+
wireContentSnapshots: number;
|
|
278
|
+
wireEstimatedBytes: number;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export interface DebugMemoryHolders {
|
|
282
|
+
lkgSlots: {
|
|
283
|
+
count: number;
|
|
284
|
+
totalBytes: number;
|
|
285
|
+
};
|
|
286
|
+
taggerCache: {
|
|
287
|
+
sessionCount: number;
|
|
288
|
+
assignmentEntries: number;
|
|
289
|
+
toolAccountingEntries: number;
|
|
290
|
+
loadSignatureEntries: number;
|
|
291
|
+
};
|
|
292
|
+
wireCache: {
|
|
293
|
+
snapshots: number;
|
|
294
|
+
rawContentSnapshots: number;
|
|
295
|
+
estimatedBytes: number;
|
|
296
|
+
};
|
|
297
|
+
compartmentMirrors: {
|
|
298
|
+
entries: number;
|
|
299
|
+
};
|
|
300
|
+
messageIndexQueue: {
|
|
301
|
+
queueLength: number;
|
|
302
|
+
reconciliationScheduled: number;
|
|
303
|
+
incrementalTimers: number;
|
|
304
|
+
pendingIncremental: number;
|
|
305
|
+
activeSessionLocks: number;
|
|
306
|
+
completedIncrementalKeys: number;
|
|
307
|
+
activeBufferMessages: number;
|
|
308
|
+
activeBufferBytes: number;
|
|
309
|
+
};
|
|
310
|
+
sessions: DebugSessionHolderCount[];
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export interface DebugSqliteConnectionMemoryStats {
|
|
314
|
+
sequence: number;
|
|
315
|
+
filename: string;
|
|
316
|
+
readonly: boolean;
|
|
317
|
+
pageSize: number | null;
|
|
318
|
+
pageCount: number | null;
|
|
319
|
+
freelistCount: number | null;
|
|
320
|
+
cacheSize: number | null;
|
|
321
|
+
cacheSizeUnit: "pages" | "kib" | null;
|
|
322
|
+
cacheUpperBoundBytes: number | null;
|
|
323
|
+
mmapSizeBytes: number | null;
|
|
324
|
+
walFileBytes: number | null;
|
|
325
|
+
shmFileBytes: number | null;
|
|
326
|
+
fts5TableCount: number | null;
|
|
327
|
+
journalMode: string | null;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
export interface DebugNativeMemoryUsage {
|
|
331
|
+
sqlite: {
|
|
332
|
+
connectionCount: number;
|
|
333
|
+
cacheUpperBoundBytes: number;
|
|
334
|
+
mmapUpperBoundBytes: number;
|
|
335
|
+
walFileBytes: number;
|
|
336
|
+
shmFileBytes: number;
|
|
337
|
+
sqliteStatusApi: "unavailable";
|
|
338
|
+
connections: DebugSqliteConnectionMemoryStats[];
|
|
339
|
+
};
|
|
340
|
+
tokenizer: {
|
|
341
|
+
loaded: boolean;
|
|
342
|
+
loadAttempted: boolean;
|
|
343
|
+
tableBytes: number | null;
|
|
344
|
+
tablePath: string | null;
|
|
345
|
+
};
|
|
346
|
+
localEmbedding: {
|
|
347
|
+
loaded: boolean;
|
|
348
|
+
providerCount: number;
|
|
349
|
+
models: string[];
|
|
350
|
+
runtimes: Array<"native" | "wasm">;
|
|
351
|
+
modelCacheBytes: number | null;
|
|
352
|
+
rssDeltaAtLoad: number;
|
|
353
|
+
externalDeltaAtLoad: number;
|
|
354
|
+
arrayBuffersDeltaAtLoad: number;
|
|
355
|
+
};
|
|
356
|
+
quickJs: {
|
|
357
|
+
loadAttempted: boolean;
|
|
358
|
+
loaded: boolean;
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
export interface DebugMemoryUsageResponse {
|
|
363
|
+
pid: number;
|
|
364
|
+
bunVersion: string;
|
|
365
|
+
memoryUsage: DebugProcessMemoryUsage;
|
|
366
|
+
native: DebugNativeMemoryUsage;
|
|
367
|
+
holders: DebugMemoryHolders;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
export interface DebugHeapSnapshotResponse extends DebugMemoryUsageResponse {
|
|
371
|
+
path: string;
|
|
372
|
+
format: "jsc" | "v8";
|
|
373
|
+
snapshotVersion?: number;
|
|
374
|
+
}
|
|
375
|
+
|
|
248
376
|
export interface RpcNotificationMessage {
|
|
249
377
|
id: number;
|
|
250
378
|
type: string;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// huge sessions (10k+ messages) which is exactly when Magic Context shines.
|
|
7
7
|
//
|
|
8
8
|
// Background: the plugin only ever needs the latest assistant message of a
|
|
9
|
-
// helper subagent (historian / dreamer /
|
|
9
|
+
// helper subagent (historian / dreamer / key-files / user-memory)
|
|
10
10
|
// or a bounded tail of the active session (conflict-warning cleanup). Both
|
|
11
11
|
// fit comfortably in `limit: 50` with massive headroom.
|
|
12
12
|
//
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
|
|
5
|
+
// `sqlite.ts` is executed directly by Node in CI's `node:sqlite` smoke and by
|
|
6
|
+
// Pi/Desktop hosts. Node's type-stripping loader does not resolve extensionless
|
|
7
|
+
// relative imports, so a static import of any sibling module breaks that path
|
|
8
|
+
// while every Bun-run test stays green (2026-09-12: master CI red for three
|
|
9
|
+
// runs after a logging import landed here). Runtime dependencies must be
|
|
10
|
+
// injected (see registerSlowWriteReporter); only type-only imports may be relative.
|
|
11
|
+
describe("sqlite.ts import fence", () => {
|
|
12
|
+
test("has no runtime-relative imports", () => {
|
|
13
|
+
const source = readFileSync(join(import.meta.dir, "sqlite.ts"), "utf8");
|
|
14
|
+
const relativeRuntimeImports = source
|
|
15
|
+
.split("\n")
|
|
16
|
+
.filter((line) => /^import\s+(?!type\s)[^;]*from\s+["']\.\.?\//.test(line));
|
|
17
|
+
expect(relativeRuntimeImports).toEqual([]);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
@@ -1,7 +1,33 @@
|
|
|
1
1
|
import { describe, expect, it } from "bun:test";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Database,
|
|
4
|
+
getSqliteMemoryStats,
|
|
5
|
+
loadSqliteModule,
|
|
6
|
+
SqliteRuntimeUnavailableError,
|
|
7
|
+
} from "./sqlite";
|
|
3
8
|
|
|
4
9
|
describe("SQLite runtime selector", () => {
|
|
10
|
+
it("reports live connection PRAGMAs and removes closed handles", () => {
|
|
11
|
+
const before = getSqliteMemoryStats().connectionCount;
|
|
12
|
+
const db = new Database(":memory:");
|
|
13
|
+
try {
|
|
14
|
+
db.exec("PRAGMA cache_size=-1024");
|
|
15
|
+
db.exec("CREATE VIRTUAL TABLE probe_fts USING fts5(content)");
|
|
16
|
+
const during = getSqliteMemoryStats();
|
|
17
|
+
expect(during.connectionCount).toBe(before + 1);
|
|
18
|
+
expect(during.connections.at(-1)).toMatchObject({
|
|
19
|
+
filename: ":memory:",
|
|
20
|
+
cacheSize: -1024,
|
|
21
|
+
cacheSizeUnit: "kib",
|
|
22
|
+
cacheUpperBoundBytes: 1024 * 1024,
|
|
23
|
+
fts5TableCount: 1,
|
|
24
|
+
});
|
|
25
|
+
} finally {
|
|
26
|
+
db.close();
|
|
27
|
+
}
|
|
28
|
+
expect(getSqliteMemoryStats().connectionCount).toBe(before);
|
|
29
|
+
});
|
|
30
|
+
|
|
5
31
|
it("wraps a missing node:sqlite module with the detected runtime and cause", async () => {
|
|
6
32
|
const cause = Object.assign(new Error("No such built-in module: node:sqlite"), {
|
|
7
33
|
code: "ERR_UNKNOWN_BUILTIN_MODULE",
|
package/src/shared/sqlite.ts
CHANGED
|
@@ -39,12 +39,28 @@
|
|
|
39
39
|
* `run()` → {changes,lastInsertRowid}) is identical and was verified directly.
|
|
40
40
|
*/
|
|
41
41
|
|
|
42
|
+
import { statSync } from "node:fs";
|
|
42
43
|
// Type import only — runtime is loaded dynamically below. @types/better-sqlite3
|
|
43
44
|
// has the richest definitions and is a structural superset of the API surface
|
|
44
45
|
// we use, so calls typed against BetterSqlite3 work under bun:sqlite and
|
|
45
46
|
// node:sqlite at runtime (both expose prepare/run/get/all/exec/close).
|
|
46
47
|
import type BetterSqlite3 from "better-sqlite3";
|
|
47
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Slow-write reporting is injected rather than imported: this module is also
|
|
51
|
+
* executed directly by Node (the `node:sqlite` smoke in CI, Pi, Desktop), and
|
|
52
|
+
* Node's type-stripping loader does not resolve extensionless imports, so any
|
|
53
|
+
* static import of the plugin's logging chain here breaks that path. The
|
|
54
|
+
* storage bootstrap registers the real reporter; until then slow privileged
|
|
55
|
+
* writes are simply not logged.
|
|
56
|
+
*/
|
|
57
|
+
type SlowWriteReporter = (site: string, transactionStartedAt: number) => void;
|
|
58
|
+
let reportSlowPrivilegedWrite: SlowWriteReporter | undefined;
|
|
59
|
+
|
|
60
|
+
export function registerSlowWriteReporter(reporter: SlowWriteReporter): void {
|
|
61
|
+
reportSlowPrivilegedWrite = reporter;
|
|
62
|
+
}
|
|
63
|
+
|
|
48
64
|
export type SqliteRuntime = "Bun" | "Node.js";
|
|
49
65
|
|
|
50
66
|
type SqliteModule = {
|
|
@@ -158,6 +174,88 @@ const DatabaseImpl: typeof BetterSqlite3 = isBun
|
|
|
158
174
|
? (sqliteModule.Database as typeof BetterSqlite3)
|
|
159
175
|
: buildNodeSqliteDatabaseClass(sqliteModule.DatabaseSync);
|
|
160
176
|
|
|
177
|
+
interface TrackedSqliteConnection {
|
|
178
|
+
sequence: number;
|
|
179
|
+
filename: string;
|
|
180
|
+
readonly: boolean;
|
|
181
|
+
reference: WeakRef<BetterSqlite3.Database>;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export interface SqliteConnectionMemoryStats {
|
|
185
|
+
sequence: number;
|
|
186
|
+
filename: string;
|
|
187
|
+
readonly: boolean;
|
|
188
|
+
pageSize: number | null;
|
|
189
|
+
pageCount: number | null;
|
|
190
|
+
freelistCount: number | null;
|
|
191
|
+
cacheSize: number | null;
|
|
192
|
+
cacheSizeUnit: "pages" | "kib" | null;
|
|
193
|
+
cacheUpperBoundBytes: number | null;
|
|
194
|
+
mmapSizeBytes: number | null;
|
|
195
|
+
walFileBytes: number | null;
|
|
196
|
+
shmFileBytes: number | null;
|
|
197
|
+
fts5TableCount: number | null;
|
|
198
|
+
journalMode: string | null;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export interface SqliteMemoryStats {
|
|
202
|
+
connectionCount: number;
|
|
203
|
+
cacheUpperBoundBytes: number;
|
|
204
|
+
mmapUpperBoundBytes: number;
|
|
205
|
+
walFileBytes: number;
|
|
206
|
+
shmFileBytes: number;
|
|
207
|
+
sqliteStatusApi: "unavailable";
|
|
208
|
+
connections: SqliteConnectionMemoryStats[];
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const trackedSqliteConnections = new Map<number, TrackedSqliteConnection>();
|
|
212
|
+
let nextSqliteConnectionSequence = 1;
|
|
213
|
+
|
|
214
|
+
function trackSqliteConnection(
|
|
215
|
+
db: BetterSqlite3.Database,
|
|
216
|
+
filename: unknown,
|
|
217
|
+
options: unknown,
|
|
218
|
+
): BetterSqlite3.Database {
|
|
219
|
+
const originalClose = db.close.bind(db) as (...args: unknown[]) => unknown;
|
|
220
|
+
const sequence = nextSqliteConnectionSequence++;
|
|
221
|
+
const metadata = {
|
|
222
|
+
sequence,
|
|
223
|
+
filename:
|
|
224
|
+
typeof filename === "string"
|
|
225
|
+
? filename
|
|
226
|
+
: Buffer.isBuffer(filename)
|
|
227
|
+
? "<buffer>"
|
|
228
|
+
: ":memory:",
|
|
229
|
+
readonly:
|
|
230
|
+
Boolean(options) &&
|
|
231
|
+
typeof options === "object" &&
|
|
232
|
+
((options as { readonly?: unknown }).readonly === true ||
|
|
233
|
+
(options as { readOnly?: unknown }).readOnly === true),
|
|
234
|
+
};
|
|
235
|
+
Object.defineProperty(db, "close", {
|
|
236
|
+
configurable: true,
|
|
237
|
+
value: (...args: unknown[]) => {
|
|
238
|
+
try {
|
|
239
|
+
return originalClose(...args);
|
|
240
|
+
} finally {
|
|
241
|
+
trackedSqliteConnections.delete(sequence);
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
});
|
|
245
|
+
trackedSqliteConnections.set(sequence, {
|
|
246
|
+
...metadata,
|
|
247
|
+
reference: new WeakRef(db),
|
|
248
|
+
});
|
|
249
|
+
return db;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const TrackedDatabase = new Proxy(DatabaseImpl, {
|
|
253
|
+
construct(target, args) {
|
|
254
|
+
const db = Reflect.construct(target, args, target) as BetterSqlite3.Database;
|
|
255
|
+
return trackSqliteConnection(db, args[0], args[1]);
|
|
256
|
+
},
|
|
257
|
+
}) as typeof BetterSqlite3;
|
|
258
|
+
|
|
161
259
|
/**
|
|
162
260
|
* Wrap node:sqlite's `DatabaseSync` so it presents the better-sqlite3/bun
|
|
163
261
|
* surface the rest of the codebase calls:
|
|
@@ -259,7 +357,108 @@ function buildNodeSqliteDatabaseClass(DatabaseSync: any): typeof BetterSqlite3 {
|
|
|
259
357
|
return NodeSqliteDatabase as unknown as typeof BetterSqlite3;
|
|
260
358
|
}
|
|
261
359
|
|
|
262
|
-
export const Database: typeof BetterSqlite3 =
|
|
360
|
+
export const Database: typeof BetterSqlite3 = TrackedDatabase;
|
|
361
|
+
|
|
362
|
+
function pragmaValue(db: BetterSqlite3.Database, name: string): unknown {
|
|
363
|
+
const row = db.prepare(`PRAGMA ${name}`).get() as Record<string, unknown> | undefined;
|
|
364
|
+
if (!row) return undefined;
|
|
365
|
+
return row[name] ?? Object.values(row)[0];
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
function pragmaNumber(db: BetterSqlite3.Database, name: string): number | null {
|
|
369
|
+
try {
|
|
370
|
+
const value = pragmaValue(db, name);
|
|
371
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
372
|
+
} catch {
|
|
373
|
+
return null;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
function pragmaString(db: BetterSqlite3.Database, name: string): string | null {
|
|
378
|
+
try {
|
|
379
|
+
const value = pragmaValue(db, name);
|
|
380
|
+
return typeof value === "string" ? value : null;
|
|
381
|
+
} catch {
|
|
382
|
+
return null;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function sqliteSidecarBytes(filename: string, suffix: "-wal" | "-shm"): number | null {
|
|
387
|
+
if (filename === ":memory:" || filename === "<buffer>") return 0;
|
|
388
|
+
try {
|
|
389
|
+
return statSync(`${filename}${suffix}`).size;
|
|
390
|
+
} catch (error) {
|
|
391
|
+
return (error as NodeJS.ErrnoException).code === "ENOENT" ? 0 : null;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
function fts5TableCount(db: BetterSqlite3.Database): number | null {
|
|
396
|
+
try {
|
|
397
|
+
const row = db
|
|
398
|
+
.prepare(
|
|
399
|
+
"SELECT COUNT(*) AS count FROM sqlite_master WHERE type = 'table' AND sql LIKE '%USING fts5%'",
|
|
400
|
+
)
|
|
401
|
+
.get() as { count?: unknown } | undefined;
|
|
402
|
+
return typeof row?.count === "number" ? row.count : null;
|
|
403
|
+
} catch {
|
|
404
|
+
return null;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Read the SQLite memory bounds that Bun/node:sqlite expose without native FFI.
|
|
410
|
+
* SQLite's sqlite3_status()/sqlite3_db_status() counters are not surfaced by
|
|
411
|
+
* either runtime, so cache and mmap values are configured upper bounds rather
|
|
412
|
+
* than resident-byte measurements.
|
|
413
|
+
*/
|
|
414
|
+
export function getSqliteMemoryStats(): SqliteMemoryStats {
|
|
415
|
+
const connections: SqliteConnectionMemoryStats[] = [];
|
|
416
|
+
for (const [sequence, tracked] of trackedSqliteConnections) {
|
|
417
|
+
const db = tracked.reference.deref();
|
|
418
|
+
if (!db) {
|
|
419
|
+
trackedSqliteConnections.delete(sequence);
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
const pageSize = pragmaNumber(db, "page_size");
|
|
423
|
+
const cacheSize = pragmaNumber(db, "cache_size");
|
|
424
|
+
const cacheSizeUnit = cacheSize === null ? null : cacheSize < 0 ? "kib" : "pages";
|
|
425
|
+
const cacheUpperBoundBytes =
|
|
426
|
+
cacheSize === null
|
|
427
|
+
? null
|
|
428
|
+
: cacheSize < 0
|
|
429
|
+
? Math.abs(cacheSize) * 1024
|
|
430
|
+
: pageSize === null
|
|
431
|
+
? null
|
|
432
|
+
: cacheSize * pageSize;
|
|
433
|
+
connections.push({
|
|
434
|
+
sequence: tracked.sequence,
|
|
435
|
+
filename: tracked.filename,
|
|
436
|
+
readonly: tracked.readonly,
|
|
437
|
+
pageSize,
|
|
438
|
+
pageCount: pragmaNumber(db, "page_count"),
|
|
439
|
+
freelistCount: pragmaNumber(db, "freelist_count"),
|
|
440
|
+
cacheSize,
|
|
441
|
+
cacheSizeUnit,
|
|
442
|
+
cacheUpperBoundBytes,
|
|
443
|
+
mmapSizeBytes: pragmaNumber(db, "mmap_size"),
|
|
444
|
+
walFileBytes: sqliteSidecarBytes(tracked.filename, "-wal"),
|
|
445
|
+
shmFileBytes: sqliteSidecarBytes(tracked.filename, "-shm"),
|
|
446
|
+
fts5TableCount: fts5TableCount(db),
|
|
447
|
+
journalMode: pragmaString(db, "journal_mode"),
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
const sumKnown = (select: (connection: SqliteConnectionMemoryStats) => number | null): number =>
|
|
451
|
+
connections.reduce((sum, connection) => sum + (select(connection) ?? 0), 0);
|
|
452
|
+
return {
|
|
453
|
+
connectionCount: connections.length,
|
|
454
|
+
cacheUpperBoundBytes: sumKnown((connection) => connection.cacheUpperBoundBytes),
|
|
455
|
+
mmapUpperBoundBytes: sumKnown((connection) => connection.mmapSizeBytes),
|
|
456
|
+
walFileBytes: sumKnown((connection) => connection.walFileBytes),
|
|
457
|
+
shmFileBytes: sumKnown((connection) => connection.shmFileBytes),
|
|
458
|
+
sqliteStatusApi: "unavailable",
|
|
459
|
+
connections,
|
|
460
|
+
};
|
|
461
|
+
}
|
|
263
462
|
|
|
264
463
|
/** Instance type alias used by helpers and storage modules. */
|
|
265
464
|
export type Database = BetterSqlite3.Database;
|
|
@@ -298,6 +497,7 @@ export function withPrivilegedWriter<T>(db: Database, operation: () => T): T {
|
|
|
298
497
|
const previousDepth = privilegeDepth.get(db) ?? 0;
|
|
299
498
|
const nested = isInTransaction(db);
|
|
300
499
|
const savepoint = "mc_privilege_scope";
|
|
500
|
+
const transactionStartedAt = nested ? undefined : performance.now();
|
|
301
501
|
if (nested) {
|
|
302
502
|
db.exec(`SAVEPOINT ${savepoint}`);
|
|
303
503
|
} else {
|
|
@@ -316,6 +516,9 @@ export function withPrivilegedWriter<T>(db: Database, operation: () => T): T {
|
|
|
316
516
|
db.exec(`RELEASE ${savepoint}`);
|
|
317
517
|
} else {
|
|
318
518
|
db.exec("COMMIT");
|
|
519
|
+
if (transactionStartedAt !== undefined) {
|
|
520
|
+
reportSlowPrivilegedWrite?.("privileged_writer", transactionStartedAt);
|
|
521
|
+
}
|
|
319
522
|
}
|
|
320
523
|
if (previousDepth > 0) privilegeDepth.set(db, previousDepth);
|
|
321
524
|
else privilegeDepth.delete(db);
|