@retaw106/mmc-oc 0.0.0-stage → 1.2.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/dist/agents/historian.d.ts +4 -0
- package/dist/agents/historian.d.ts.map +1 -0
- package/dist/agents/language-directive.d.ts +26 -0
- package/dist/agents/language-directive.d.ts.map +1 -0
- package/dist/agents/magic-context-prompt.d.ts +5 -0
- package/dist/agents/magic-context-prompt.d.ts.map +1 -0
- package/dist/agents/memory-maintainer.d.ts +96 -0
- package/dist/agents/memory-maintainer.d.ts.map +1 -0
- package/dist/config/agent-disable.d.ts +29 -0
- package/dist/config/agent-disable.d.ts.map +1 -0
- package/dist/config/config-paths.d.ts +7 -0
- package/dist/config/config-paths.d.ts.map +1 -0
- package/dist/config/index.d.ts +69 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/live-run-config.d.ts +11 -0
- package/dist/config/live-run-config.d.ts.map +1 -0
- package/dist/config/live-snapshot.d.ts +32 -0
- package/dist/config/live-snapshot.d.ts.map +1 -0
- package/dist/config/migrate-experimental.d.ts +26 -0
- package/dist/config/migrate-experimental.d.ts.map +1 -0
- package/dist/config/profiles.d.ts +22 -0
- package/dist/config/profiles.d.ts.map +1 -0
- package/dist/config/project-security.d.ts +124 -0
- package/dist/config/project-security.d.ts.map +1 -0
- package/dist/config/prune-config-leaf.d.ts +26 -0
- package/dist/config/prune-config-leaf.d.ts.map +1 -0
- package/dist/config/raw-loader.d.ts +42 -0
- package/dist/config/raw-loader.d.ts.map +1 -0
- 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/agent-overrides.d.ts +52 -0
- package/dist/config/schema/agent-overrides.d.ts.map +1 -0
- package/dist/config/schema/magic-context.d.ts +805 -0
- package/dist/config/schema/magic-context.d.ts.map +1 -0
- package/dist/config/variable.d.ts +48 -0
- package/dist/config/variable.d.ts.map +1 -0
- package/dist/context-a6px04s0.js +23932 -0
- package/dist/context-d7jrfd5d.js +23932 -0
- package/dist/context-m94zd2xr.js +23932 -0
- package/dist/derive-budgets-fhk00zv8.js +18 -0
- package/dist/features/magic-context/compaction-marker.d.ts +211 -0
- package/dist/features/magic-context/compaction-marker.d.ts.map +1 -0
- package/dist/features/magic-context/compaction.d.ts +7 -0
- package/dist/features/magic-context/compaction.d.ts.map +1 -0
- package/dist/features/magic-context/compartment-events.d.ts +50 -0
- package/dist/features/magic-context/compartment-events.d.ts.map +1 -0
- package/dist/features/magic-context/compartment-lease.d.ts +28 -0
- package/dist/features/magic-context/compartment-lease.d.ts.map +1 -0
- package/dist/features/magic-context/compartment-storage.d.ts +178 -0
- package/dist/features/magic-context/compartment-storage.d.ts.map +1 -0
- package/dist/features/magic-context/compression-depth-storage.d.ts +14 -0
- package/dist/features/magic-context/compression-depth-storage.d.ts.map +1 -0
- package/dist/features/magic-context/context-authority.d.ts +15 -0
- package/dist/features/magic-context/context-authority.d.ts.map +1 -0
- package/dist/features/magic-context/fail-closed-block.d.ts +117 -0
- package/dist/features/magic-context/fail-closed-block.d.ts.map +1 -0
- package/dist/features/magic-context/index.d.ts +10 -0
- package/dist/features/magic-context/index.d.ts.map +1 -0
- package/dist/features/magic-context/literal-probes.d.ts +24 -0
- package/dist/features/magic-context/literal-probes.d.ts.map +1 -0
- package/dist/features/magic-context/lkg-prefix-chunks.d.ts +53 -0
- package/dist/features/magic-context/lkg-prefix-chunks.d.ts.map +1 -0
- package/dist/features/magic-context/memory/constants.d.ts +16 -0
- package/dist/features/magic-context/memory/constants.d.ts.map +1 -0
- package/dist/features/magic-context/memory/index.d.ts +11 -0
- package/dist/features/magic-context/memory/index.d.ts.map +1 -0
- package/dist/features/magic-context/memory/memory-diagnostics.d.ts +6 -0
- package/dist/features/magic-context/memory/memory-diagnostics.d.ts.map +1 -0
- package/dist/features/magic-context/memory/memory-selection.d.ts +12 -0
- package/dist/features/magic-context/memory/memory-selection.d.ts.map +1 -0
- package/dist/features/magic-context/memory/memory-visibility.d.ts +46 -0
- package/dist/features/magic-context/memory/memory-visibility.d.ts.map +1 -0
- package/dist/features/magic-context/memory/normalize-hash.d.ts +3 -0
- package/dist/features/magic-context/memory/normalize-hash.d.ts.map +1 -0
- package/dist/features/magic-context/memory/project-identity-cache.d.ts +7 -0
- package/dist/features/magic-context/memory/project-identity-cache.d.ts.map +1 -0
- package/dist/features/magic-context/memory/project-identity.d.ts +97 -0
- package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -0
- package/dist/features/magic-context/memory/promotion.d.ts +26 -0
- package/dist/features/magic-context/memory/promotion.d.ts.map +1 -0
- package/dist/features/magic-context/memory/relocate-memory.d.ts +58 -0
- package/dist/features/magic-context/memory/relocate-memory.d.ts.map +1 -0
- package/dist/features/magic-context/memory/storage-memory-fts.d.ts +11 -0
- package/dist/features/magic-context/memory/storage-memory-fts.d.ts.map +1 -0
- package/dist/features/magic-context/memory/storage-memory-verifications.d.ts +35 -0
- package/dist/features/magic-context/memory/storage-memory-verifications.d.ts.map +1 -0
- package/dist/features/magic-context/memory/storage-memory.d.ts +89 -0
- package/dist/features/magic-context/memory/storage-memory.d.ts.map +1 -0
- package/dist/features/magic-context/memory/types.d.ts +59 -0
- package/dist/features/magic-context/memory/types.d.ts.map +1 -0
- package/dist/features/magic-context/memory/verification-paths.d.ts +48 -0
- package/dist/features/magic-context/memory/verification-paths.d.ts.map +1 -0
- package/dist/features/magic-context/memory/visibility.d.ts +6 -0
- package/dist/features/magic-context/memory/visibility.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/apply.d.ts +65 -0
- package/dist/features/magic-context/memory-maintainer/apply.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/budget.d.ts +75 -0
- package/dist/features/magic-context/memory-maintainer/budget.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/coverage.d.ts +91 -0
- package/dist/features/magic-context/memory-maintainer/coverage.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/dream-state.d.ts +18 -0
- package/dist/features/magic-context/memory-maintainer/dream-state.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/launcher.d.ts +119 -0
- package/dist/features/magic-context/memory-maintainer/launcher.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/lease.d.ts +56 -0
- package/dist/features/magic-context/memory-maintainer/lease.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/manifest.d.ts +127 -0
- package/dist/features/magic-context/memory-maintainer/manifest.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/manual-commands.d.ts +46 -0
- package/dist/features/magic-context/memory-maintainer/manual-commands.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/oc2-adapter.d.ts +79 -0
- package/dist/features/magic-context/memory-maintainer/oc2-adapter.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/pause-report.d.ts +37 -0
- package/dist/features/magic-context/memory-maintainer/pause-report.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/pipeline.d.ts +199 -0
- package/dist/features/magic-context/memory-maintainer/pipeline.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/provider-output-failure.d.ts +15 -0
- package/dist/features/magic-context/memory-maintainer/provider-output-failure.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/schedule-storage.d.ts +76 -0
- package/dist/features/magic-context/memory-maintainer/schedule-storage.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/schedule.d.ts +90 -0
- package/dist/features/magic-context/memory-maintainer/schedule.d.ts.map +1 -0
- 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 +50 -0
- package/dist/features/magic-context/message-fts-rowid-map.d.ts.map +1 -0
- package/dist/features/magic-context/message-fts-session-filter.d.ts +14 -0
- package/dist/features/magic-context/message-fts-session-filter.d.ts.map +1 -0
- package/dist/features/magic-context/message-index-async.d.ts +33 -0
- package/dist/features/magic-context/message-index-async.d.ts.map +1 -0
- package/dist/features/magic-context/message-index-sweep.d.ts +11 -0
- package/dist/features/magic-context/message-index-sweep.d.ts.map +1 -0
- package/dist/features/magic-context/message-index.d.ts +88 -0
- package/dist/features/magic-context/message-index.d.ts.map +1 -0
- package/dist/features/magic-context/message-time-backfill.d.ts +19 -0
- package/dist/features/magic-context/message-time-backfill.d.ts.map +1 -0
- package/dist/features/magic-context/migration-v2-write-split.d.ts +62 -0
- package/dist/features/magic-context/migration-v2-write-split.d.ts.map +1 -0
- package/dist/features/magic-context/migrations.d.ts +73 -0
- package/dist/features/magic-context/migrations.d.ts.map +1 -0
- package/dist/features/magic-context/mock-database.d.ts +3 -0
- package/dist/features/magic-context/mock-database.d.ts.map +1 -0
- package/dist/features/magic-context/mural/storage-mural-cues.d.ts +65 -0
- package/dist/features/magic-context/mural/storage-mural-cues.d.ts.map +1 -0
- 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/opencode2-relabel.d.ts +132 -0
- package/dist/features/magic-context/opencode2-relabel.d.ts.map +1 -0
- package/dist/features/magic-context/overflow-detection.d.ts +108 -0
- package/dist/features/magic-context/overflow-detection.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-identity.d.ts +2 -0
- package/dist/features/magic-context/project-identity.d.ts.map +1 -0
- 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/range-parser.d.ts +18 -0
- package/dist/features/magic-context/range-parser.d.ts.map +1 -0
- package/dist/features/magic-context/reclaim-protection.d.ts +13 -0
- package/dist/features/magic-context/reclaim-protection.d.ts.map +1 -0
- package/dist/features/magic-context/resolve-subagent-fallback.d.ts +42 -0
- package/dist/features/magic-context/resolve-subagent-fallback.d.ts.map +1 -0
- package/dist/features/magic-context/scheduler.d.ts +20 -0
- package/dist/features/magic-context/scheduler.d.ts.map +1 -0
- package/dist/features/magic-context/schema-fence-probe.d.ts +29 -0
- package/dist/features/magic-context/schema-fence-probe.d.ts.map +1 -0
- package/dist/features/magic-context/search.d.ts +118 -0
- package/dist/features/magic-context/search.d.ts.map +1 -0
- package/dist/features/magic-context/session-cache-ttl.d.ts +10 -0
- package/dist/features/magic-context/session-cache-ttl.d.ts.map +1 -0
- package/dist/features/magic-context/session-decision-calibration.d.ts +31 -0
- package/dist/features/magic-context/session-decision-calibration.d.ts.map +1 -0
- package/dist/features/magic-context/session-project-backfill.d.ts +37 -0
- package/dist/features/magic-context/session-project-backfill.d.ts.map +1 -0
- package/dist/features/magic-context/session-project-storage.d.ts +23 -0
- package/dist/features/magic-context/session-project-storage.d.ts.map +1 -0
- package/dist/features/magic-context/storage-caveman-rules.d.ts +21 -0
- package/dist/features/magic-context/storage-caveman-rules.d.ts.map +1 -0
- package/dist/features/magic-context/storage-clone.d.ts +44 -0
- package/dist/features/magic-context/storage-clone.d.ts.map +1 -0
- package/dist/features/magic-context/storage-db.d.ts +183 -0
- package/dist/features/magic-context/storage-db.d.ts.map +1 -0
- package/dist/features/magic-context/storage-historian-runs.d.ts +79 -0
- package/dist/features/magic-context/storage-historian-runs.d.ts.map +1 -0
- package/dist/features/magic-context/storage-identity-merge.d.ts +26 -0
- package/dist/features/magic-context/storage-identity-merge.d.ts.map +1 -0
- package/dist/features/magic-context/storage-identity-rekey-map.d.ts +11 -0
- package/dist/features/magic-context/storage-identity-rekey-map.d.ts.map +1 -0
- package/dist/features/magic-context/storage-m0-mutation-log.d.ts +22 -0
- package/dist/features/magic-context/storage-m0-mutation-log.d.ts.map +1 -0
- package/dist/features/magic-context/storage-memory-mutation-log.d.ts +29 -0
- package/dist/features/magic-context/storage-memory-mutation-log.d.ts.map +1 -0
- package/dist/features/magic-context/storage-meta-persisted.d.ts +623 -0
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -0
- package/dist/features/magic-context/storage-meta-session.d.ts +14 -0
- package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -0
- package/dist/features/magic-context/storage-meta-shared.d.ts +102 -0
- package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -0
- package/dist/features/magic-context/storage-meta.d.ts +4 -0
- package/dist/features/magic-context/storage-meta.d.ts.map +1 -0
- 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 +80 -0
- package/dist/features/magic-context/storage-notes.d.ts.map +1 -0
- package/dist/features/magic-context/storage-ops.d.ts +14 -0
- package/dist/features/magic-context/storage-ops.d.ts.map +1 -0
- package/dist/features/magic-context/storage-primers.d.ts +96 -0
- package/dist/features/magic-context/storage-primers.d.ts.map +1 -0
- package/dist/features/magic-context/storage-project-state.d.ts +19 -0
- package/dist/features/magic-context/storage-project-state.d.ts.map +1 -0
- package/dist/features/magic-context/storage-reasoning-removal.d.ts +30 -0
- package/dist/features/magic-context/storage-reasoning-removal.d.ts.map +1 -0
- package/dist/features/magic-context/storage-replay-document.d.ts +72 -0
- package/dist/features/magic-context/storage-replay-document.d.ts.map +1 -0
- package/dist/features/magic-context/storage-schema-helpers.d.ts +31 -0
- package/dist/features/magic-context/storage-schema-helpers.d.ts.map +1 -0
- package/dist/features/magic-context/storage-session-tables.d.ts +18 -0
- package/dist/features/magic-context/storage-session-tables.d.ts.map +1 -0
- package/dist/features/magic-context/storage-source.d.ts +5 -0
- package/dist/features/magic-context/storage-source.d.ts.map +1 -0
- package/dist/features/magic-context/storage-subagent-invocations.d.ts +62 -0
- package/dist/features/magic-context/storage-subagent-invocations.d.ts.map +1 -0
- package/dist/features/magic-context/storage-tags.d.ts +542 -0
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -0
- package/dist/features/magic-context/storage-unavailable-reason.d.ts +17 -0
- package/dist/features/magic-context/storage-unavailable-reason.d.ts.map +1 -0
- package/dist/features/magic-context/storage-v22-backfill-failures.d.ts +26 -0
- package/dist/features/magic-context/storage-v22-backfill-failures.d.ts.map +1 -0
- package/dist/features/magic-context/storage.d.ts +23 -0
- package/dist/features/magic-context/storage.d.ts.map +1 -0
- package/dist/features/magic-context/store-generation-rebase.d.ts +188 -0
- package/dist/features/magic-context/store-generation-rebase.d.ts.map +1 -0
- package/dist/features/magic-context/subagent-token-capture.d.ts +35 -0
- package/dist/features/magic-context/subagent-token-capture.d.ts.map +1 -0
- package/dist/features/magic-context/tag-input.d.ts +4 -0
- package/dist/features/magic-context/tag-input.d.ts.map +1 -0
- package/dist/features/magic-context/tagger.d.ts +119 -0
- package/dist/features/magic-context/tagger.d.ts.map +1 -0
- package/dist/features/magic-context/tool-definition-tokens.d.ts +90 -0
- package/dist/features/magic-context/tool-definition-tokens.d.ts.map +1 -0
- package/dist/features/magic-context/tool-owner-backfill.d.ts +93 -0
- package/dist/features/magic-context/tool-owner-backfill.d.ts.map +1 -0
- package/dist/features/magic-context/transform-decision-log.d.ts +110 -0
- package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -0
- package/dist/features/magic-context/types.d.ts +133 -0
- package/dist/features/magic-context/types.d.ts.map +1 -0
- package/dist/features/magic-context/window-report-ledger.d.ts +70 -0
- package/dist/features/magic-context/window-report-ledger.d.ts.map +1 -0
- package/dist/features/magic-context/work-metrics.d.ts +79 -0
- package/dist/features/magic-context/work-metrics.d.ts.map +1 -0
- package/dist/features/magic-context/workspaces.d.ts +28 -0
- package/dist/features/magic-context/workspaces.d.ts.map +1 -0
- package/dist/hooks/auto-update-checker/semver.d.ts +26 -0
- package/dist/hooks/auto-update-checker/semver.d.ts.map +1 -0
- package/dist/hooks/magic-context/apply-operations.d.ts +158 -0
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -0
- package/dist/hooks/magic-context/auto-search-deadline.d.ts +10 -0
- package/dist/hooks/magic-context/auto-search-deadline.d.ts.map +1 -0
- package/dist/hooks/magic-context/auto-search-hint.d.ts +36 -0
- package/dist/hooks/magic-context/auto-search-hint.d.ts.map +1 -0
- package/dist/hooks/magic-context/auto-search-runner.d.ts +60 -0
- package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -0
- package/dist/hooks/magic-context/cache-busting-signals.d.ts +42 -0
- package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -0
- package/dist/hooks/magic-context/caveman-cleanup.d.ts +98 -0
- package/dist/hooks/magic-context/caveman-cleanup.d.ts.map +1 -0
- package/dist/hooks/magic-context/caveman.d.ts +90 -0
- package/dist/hooks/magic-context/caveman.d.ts.map +1 -0
- package/dist/hooks/magic-context/channel2-cycle.d.ts +16 -0
- package/dist/hooks/magic-context/channel2-cycle.d.ts.map +1 -0
- package/dist/hooks/magic-context/channel2-delivery.d.ts +32 -0
- package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -0
- package/dist/hooks/magic-context/child-session-spawn.d.ts +27 -0
- package/dist/hooks/magic-context/child-session-spawn.d.ts.map +1 -0
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts +154 -0
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -0
- package/dist/hooks/magic-context/compaction-off-transition.d.ts +97 -0
- package/dist/hooks/magic-context/compaction-off-transition.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-parser.d.ts +66 -0
- package/dist/hooks/magic-context/compartment-parser.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-prompt.d.ts +33 -0
- package/dist/hooks/magic-context/compartment-prompt.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-render-epoch.d.ts +27 -0
- package/dist/hooks/magic-context/compartment-render-epoch.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts +29 -0
- package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts +43 -0
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts +31 -0
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-mapping.d.ts +25 -0
- package/dist/hooks/magic-context/compartment-runner-mapping.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts +29 -0
- package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts +11 -0
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-types.d.ts +295 -0
- package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts +83 -0
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner.d.ts +59 -0
- package/dist/hooks/magic-context/compartment-runner.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-trigger.d.ts +77 -0
- package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -0
- package/dist/hooks/magic-context/ctx-reduce-availability.d.ts +170 -0
- package/dist/hooks/magic-context/ctx-reduce-availability.d.ts.map +1 -0
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts +104 -0
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts.map +1 -0
- package/dist/hooks/magic-context/decay-curve.d.ts +84 -0
- package/dist/hooks/magic-context/decay-curve.d.ts.map +1 -0
- package/dist/hooks/magic-context/decay-render.d.ts +80 -0
- package/dist/hooks/magic-context/decay-render.d.ts.map +1 -0
- package/dist/hooks/magic-context/decision-calibration.d.ts +24 -0
- package/dist/hooks/magic-context/decision-calibration.d.ts.map +1 -0
- package/dist/hooks/magic-context/degraded-pass-refusal.d.ts +35 -0
- package/dist/hooks/magic-context/degraded-pass-refusal.d.ts.map +1 -0
- package/dist/hooks/magic-context/derive-budgets.d.ts +60 -0
- package/dist/hooks/magic-context/derive-budgets.d.ts.map +1 -0
- package/dist/hooks/magic-context/drop-stale-reduce-calls.d.ts +39 -0
- package/dist/hooks/magic-context/drop-stale-reduce-calls.d.ts.map +1 -0
- package/dist/hooks/magic-context/dropped-input-guard.d.ts +55 -0
- package/dist/hooks/magic-context/dropped-input-guard.d.ts.map +1 -0
- package/dist/hooks/magic-context/dropped-token-estimate.d.ts +20 -0
- package/dist/hooks/magic-context/dropped-token-estimate.d.ts.map +1 -0
- package/dist/hooks/magic-context/edit-marker.d.ts +11 -0
- package/dist/hooks/magic-context/edit-marker.d.ts.map +1 -0
- package/dist/hooks/magic-context/emergency-drop.d.ts +112 -0
- package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -0
- package/dist/hooks/magic-context/emergency-fail-closed.d.ts +14 -0
- package/dist/hooks/magic-context/emergency-fail-closed.d.ts.map +1 -0
- package/dist/hooks/magic-context/empty-task-output.d.ts +16 -0
- package/dist/hooks/magic-context/empty-task-output.d.ts.map +1 -0
- package/dist/hooks/magic-context/event-payloads.d.ts +73 -0
- package/dist/hooks/magic-context/event-payloads.d.ts.map +1 -0
- package/dist/hooks/magic-context/event-resolvers.d.ts +114 -0
- package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -0
- package/dist/hooks/magic-context/execute-flush.d.ts +3 -0
- package/dist/hooks/magic-context/execute-flush.d.ts.map +1 -0
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts +56 -0
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -0
- package/dist/hooks/magic-context/fold-execution-gate.d.ts +2 -0
- package/dist/hooks/magic-context/fold-execution-gate.d.ts.map +1 -0
- package/dist/hooks/magic-context/format-bytes.d.ts +2 -0
- package/dist/hooks/magic-context/format-bytes.d.ts.map +1 -0
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts +48 -0
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -0
- package/dist/hooks/magic-context/historian-no-fire-cause.d.ts +5 -0
- package/dist/hooks/magic-context/historian-no-fire-cause.d.ts.map +1 -0
- package/dist/hooks/magic-context/historian-prompt-fit.d.ts +112 -0
- package/dist/hooks/magic-context/historian-prompt-fit.d.ts.map +1 -0
- package/dist/hooks/magic-context/historian-prompt.generated.d.ts +2 -0
- package/dist/hooks/magic-context/historian-prompt.generated.d.ts.map +1 -0
- package/dist/hooks/magic-context/historian-publish-stage-logger.d.ts +3 -0
- package/dist/hooks/magic-context/historian-publish-stage-logger.d.ts.map +1 -0
- package/dist/hooks/magic-context/historian-state-file.d.ts +43 -0
- package/dist/hooks/magic-context/historian-state-file.d.ts.map +1 -0
- package/dist/hooks/magic-context/history-boundary-repair.d.ts +44 -0
- package/dist/hooks/magic-context/history-boundary-repair.d.ts.map +1 -0
- package/dist/hooks/magic-context/hook-handlers.d.ts +177 -0
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -0
- package/dist/hooks/magic-context/host-served-rows.d.ts +58 -0
- package/dist/hooks/magic-context/host-served-rows.d.ts.map +1 -0
- package/dist/hooks/magic-context/image-token-estimate.d.ts +15 -0
- package/dist/hooks/magic-context/image-token-estimate.d.ts.map +1 -0
- package/dist/hooks/magic-context/inject-compartments.d.ts +389 -0
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -0
- package/dist/hooks/magic-context/issue-135-wire-fixtures.d.ts +8 -0
- package/dist/hooks/magic-context/issue-135-wire-fixtures.d.ts.map +1 -0
- package/dist/hooks/magic-context/issue-423-fixture.d.ts +37 -0
- package/dist/hooks/magic-context/issue-423-fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/issue-424-fixture.d.ts +11 -0
- package/dist/hooks/magic-context/issue-424-fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/legacy-compartments.d.ts +20 -0
- package/dist/hooks/magic-context/legacy-compartments.d.ts.map +1 -0
- package/dist/hooks/magic-context/live-session-state.d.ts +68 -0
- package/dist/hooks/magic-context/live-session-state.d.ts.map +1 -0
- package/dist/hooks/magic-context/lkg-persist.d.ts +22 -0
- package/dist/hooks/magic-context/lkg-persist.d.ts.map +1 -0
- package/dist/hooks/magic-context/lkg-replay.d.ts +71 -0
- package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -0
- package/dist/hooks/magic-context/lkg-slot.d.ts +119 -0
- package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -0
- package/dist/hooks/magic-context/m0-token-breakdown.d.ts +44 -0
- package/dist/hooks/magic-context/m0-token-breakdown.d.ts.map +1 -0
- package/dist/hooks/magic-context/maintenance-authority.d.ts +2 -0
- package/dist/hooks/magic-context/maintenance-authority.d.ts.map +1 -0
- package/dist/hooks/magic-context/openai-compat-adjacency.d.ts +38 -0
- package/dist/hooks/magic-context/openai-compat-adjacency.d.ts.map +1 -0
- package/dist/hooks/magic-context/opencode-v1-store-fixture.d.ts +12 -0
- package/dist/hooks/magic-context/opencode-v1-store-fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/pass-outcome.d.ts +70 -0
- package/dist/hooks/magic-context/pass-outcome.d.ts.map +1 -0
- 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/postprocess-read-cache.d.ts +8 -0
- package/dist/hooks/magic-context/postprocess-read-cache.d.ts.map +1 -0
- package/dist/hooks/magic-context/producer-window-guard.d.ts +63 -0
- package/dist/hooks/magic-context/producer-window-guard.d.ts.map +1 -0
- package/dist/hooks/magic-context/producer-window-test-support.d.ts +14 -0
- package/dist/hooks/magic-context/producer-window-test-support.d.ts.map +1 -0
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts +234 -0
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -0
- package/dist/hooks/magic-context/raw-fallback-context-limit.d.ts +10 -0
- package/dist/hooks/magic-context/raw-fallback-context-limit.d.ts.map +1 -0
- package/dist/hooks/magic-context/read-session-chunk.d.ts +271 -0
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -0
- package/dist/hooks/magic-context/read-session-db.d.ts +66 -0
- package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -0
- package/dist/hooks/magic-context/read-session-formatting.d.ts +65 -0
- package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -0
- package/dist/hooks/magic-context/read-session-raw.d.ts +164 -0
- package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -0
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts +82 -0
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -0
- package/dist/hooks/magic-context/reasoning-removal.d.ts +60 -0
- package/dist/hooks/magic-context/reasoning-removal.d.ts.map +1 -0
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts +93 -0
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -0
- package/dist/hooks/magic-context/reference-retrieval.d.ts +72 -0
- package/dist/hooks/magic-context/reference-retrieval.d.ts.map +1 -0
- package/dist/hooks/magic-context/reference-seeds.generated.d.ts +8 -0
- package/dist/hooks/magic-context/reference-seeds.generated.d.ts.map +1 -0
- package/dist/hooks/magic-context/send-session-notification.d.ts +43 -0
- package/dist/hooks/magic-context/send-session-notification.d.ts.map +1 -0
- package/dist/hooks/magic-context/sentinel.d.ts +146 -0
- package/dist/hooks/magic-context/sentinel.d.ts.map +1 -0
- package/dist/hooks/magic-context/storage-busy-refusal.d.ts +20 -0
- package/dist/hooks/magic-context/storage-busy-refusal.d.ts.map +1 -0
- package/dist/hooks/magic-context/strip-content.d.ts +216 -0
- package/dist/hooks/magic-context/strip-content.d.ts.map +1 -0
- package/dist/hooks/magic-context/strip-structural-noise.d.ts +15 -0
- package/dist/hooks/magic-context/strip-structural-noise.d.ts.map +1 -0
- package/dist/hooks/magic-context/stripped-command.d.ts +56 -0
- package/dist/hooks/magic-context/stripped-command.d.ts.map +1 -0
- package/dist/hooks/magic-context/supersession-reclaim.d.ts +58 -0
- package/dist/hooks/magic-context/supersession-reclaim.d.ts.map +1 -0
- package/dist/hooks/magic-context/system-injection-stripper.d.ts +2 -0
- package/dist/hooks/magic-context/system-injection-stripper.d.ts.map +1 -0
- package/dist/hooks/magic-context/system-prompt-hash.d.ts +129 -0
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -0
- package/dist/hooks/magic-context/tag-content-primitives.d.ts +31 -0
- package/dist/hooks/magic-context/tag-content-primitives.d.ts.map +1 -0
- package/dist/hooks/magic-context/tag-id-fallback.d.ts +11 -0
- package/dist/hooks/magic-context/tag-id-fallback.d.ts.map +1 -0
- package/dist/hooks/magic-context/tag-messages.d.ts +145 -0
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -0
- package/dist/hooks/magic-context/tag-part-guards.d.ts +23 -0
- package/dist/hooks/magic-context/tag-part-guards.d.ts.map +1 -0
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts +178 -0
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -0
- package/dist/hooks/magic-context/temporal-awareness.d.ts +73 -0
- package/dist/hooks/magic-context/temporal-awareness.d.ts.map +1 -0
- package/dist/hooks/magic-context/text-complete.d.ts +31 -0
- package/dist/hooks/magic-context/text-complete.d.ts.map +1 -0
- package/dist/hooks/magic-context/todo-view.d.ts +127 -0
- package/dist/hooks/magic-context/todo-view.d.ts.map +1 -0
- package/dist/hooks/magic-context/tokenizer-calibration.d.ts +92 -0
- package/dist/hooks/magic-context/tokenizer-calibration.d.ts.map +1 -0
- package/dist/hooks/magic-context/tool-drop-target.d.ts +144 -0
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -0
- package/dist/hooks/magic-context/tool-input-size.d.ts +21 -0
- package/dist/hooks/magic-context/tool-input-size.d.ts.map +1 -0
- package/dist/hooks/magic-context/tool-reclaim.d.ts +12 -0
- package/dist/hooks/magic-context/tool-reclaim.d.ts.map +1 -0
- package/dist/hooks/magic-context/tool-sweep-policy.d.ts +50 -0
- package/dist/hooks/magic-context/tool-sweep-policy.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts +133 -0
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-context-state.d.ts +28 -0
- package/dist/hooks/magic-context/transform-context-state.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-message-helpers.d.ts +32 -0
- package/dist/hooks/magic-context/transform-message-helpers.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-operations.d.ts +5 -0
- package/dist/hooks/magic-context/transform-operations.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +350 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-stage-logger.d.ts +2 -0
- package/dist/hooks/magic-context/transform-stage-logger.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform.d.ts +334 -0
- package/dist/hooks/magic-context/transform.d.ts.map +1 -0
- package/dist/hooks/magic-context/unmanaged-over-window.d.ts +36 -0
- package/dist/hooks/magic-context/unmanaged-over-window.d.ts.map +1 -0
- package/dist/hooks/magic-context/unresolved-history-boundary.d.ts +15 -0
- package/dist/hooks/magic-context/unresolved-history-boundary.d.ts.map +1 -0
- package/dist/hooks/magic-context/wrapup-orchestrator.d.ts +14 -0
- package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -0
- package/dist/index-1vs6anwz.js +126 -0
- package/dist/index-2axapwjs.js +6388 -0
- package/dist/index-3wagyrnj.js +670 -0
- package/dist/index-46j0tj1s.js +27883 -0
- package/dist/index-53g38ggt.js +40 -0
- package/dist/index-5pg0acf7.js +410 -0
- package/dist/index-5s9w99sf.js +126 -0
- package/dist/index-7dgv6pzg.js +126 -0
- package/dist/index-977gxfz0.js +514 -0
- package/dist/index-by6h2pav.js +27883 -0
- package/dist/index-e1q8002h.js +16 -0
- package/dist/index-fg34g6a5.js +584 -0
- package/dist/index-jdxxq8cz.js +99 -0
- package/dist/index-me3zcj5t.js +69 -0
- package/dist/index-qbkzdkk0.js +496 -0
- package/dist/index-qkdksr6f.js +6388 -0
- package/dist/index-wgt4gamw.js +6388 -0
- package/dist/index-xyjcjq10.js +27883 -0
- package/dist/index-zx63j2e2.js +907 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/message-time-backfill-5ewk0axe.js +116 -0
- package/dist/model-resolution-5haaxnpt.js +6 -0
- package/dist/plugin/boot-deadline.d.ts +47 -0
- package/dist/plugin/boot-deadline.d.ts.map +1 -0
- package/dist/plugin/boot-quiet.d.ts +12 -0
- package/dist/plugin/boot-quiet.d.ts.map +1 -0
- package/dist/plugin/normalize-tool-arg-schemas.d.ts +7 -0
- package/dist/plugin/normalize-tool-arg-schemas.d.ts.map +1 -0
- package/dist/plugin/rpc-handlers.d.ts +52 -0
- package/dist/plugin/rpc-handlers.d.ts.map +1 -0
- package/dist/plugin/sidebar-snapshot-cache.d.ts +19 -0
- package/dist/plugin/sidebar-snapshot-cache.d.ts.map +1 -0
- package/dist/plugin/subagent-tool-policy.d.ts +9 -0
- package/dist/plugin/subagent-tool-policy.d.ts.map +1 -0
- package/dist/plugin/types.d.ts +3 -0
- package/dist/plugin/types.d.ts.map +1 -0
- package/dist/prompt-context-ffa5xcfx.js +76 -0
- package/dist/read-session-chunk-apjwrttc.js +56 -0
- package/dist/read-session-chunk-s79jhs7t.js +56 -0
- package/dist/read-session-chunk-tt4vhgq3.js +56 -0
- package/dist/recomp-orchestrator-g66dssga.js +21 -0
- package/dist/recomp-orchestrator-gyeevxaw.js +21 -0
- package/dist/recomp-orchestrator-r4zzvjxc.js +21 -0
- package/dist/rpc-notifications-4amf6mf4.js +14 -0
- package/dist/safe-notification-target-ph3xd1ve.js +9 -0
- package/dist/send-session-notification-y29y9fsr.js +18 -0
- package/dist/shared/announcement.d.ts +69 -0
- package/dist/shared/announcement.d.ts.map +1 -0
- package/dist/shared/assistant-message-extractor.d.ts +13 -0
- package/dist/shared/assistant-message-extractor.d.ts.map +1 -0
- package/dist/shared/auto-update-provenance.d.ts +9 -0
- package/dist/shared/auto-update-provenance.d.ts.map +1 -0
- package/dist/shared/bounded-session-map.d.ts +45 -0
- package/dist/shared/bounded-session-map.d.ts.map +1 -0
- package/dist/shared/builtin-commands.d.ts +24 -0
- package/dist/shared/builtin-commands.d.ts.map +1 -0
- package/dist/shared/cache-ttl-display.d.ts +25 -0
- package/dist/shared/cache-ttl-display.d.ts.map +1 -0
- package/dist/shared/cache-ttl-seed.d.ts +10 -0
- package/dist/shared/cache-ttl-seed.d.ts.map +1 -0
- package/dist/shared/child-session-teardown.d.ts +34 -0
- package/dist/shared/child-session-teardown.d.ts.map +1 -0
- package/dist/shared/commit-detection.d.ts +29 -0
- package/dist/shared/commit-detection.d.ts.map +1 -0
- package/dist/shared/config-diagnostics.d.ts +30 -0
- package/dist/shared/config-diagnostics.d.ts.map +1 -0
- package/dist/shared/conflict-detector.d.ts +139 -0
- package/dist/shared/conflict-detector.d.ts.map +1 -0
- package/dist/shared/conflict-fixer.d.ts +20 -0
- package/dist/shared/conflict-fixer.d.ts.map +1 -0
- package/dist/shared/context-limit-provenance.d.ts +3 -0
- package/dist/shared/context-limit-provenance.d.ts.map +1 -0
- package/dist/shared/data-path.d.ts +176 -0
- package/dist/shared/data-path.d.ts.map +1 -0
- package/dist/shared/error-message.d.ts +32 -0
- package/dist/shared/error-message.d.ts.map +1 -0
- package/dist/shared/escalation-bands.d.ts +9 -0
- package/dist/shared/escalation-bands.d.ts.map +1 -0
- package/dist/shared/format-bytes.d.ts +2 -0
- package/dist/shared/format-bytes.d.ts.map +1 -0
- package/dist/shared/format-threshold.d.ts +43 -0
- package/dist/shared/format-threshold.d.ts.map +1 -0
- package/dist/shared/harness-provider-map.d.ts +64 -0
- package/dist/shared/harness-provider-map.d.ts.map +1 -0
- package/dist/shared/harness.d.ts +55 -0
- package/dist/shared/harness.d.ts.map +1 -0
- package/dist/shared/hidden-variant-warnings.d.ts +5 -0
- package/dist/shared/hidden-variant-warnings.d.ts.map +1 -0
- package/dist/shared/historian-tool-expansions.d.ts +5 -0
- package/dist/shared/historian-tool-expansions.d.ts.map +1 -0
- package/dist/shared/historian-tool-template.d.ts +5 -0
- package/dist/shared/historian-tool-template.d.ts.map +1 -0
- package/dist/shared/historian-transient-error.d.ts +2 -0
- package/dist/shared/historian-transient-error.d.ts.map +1 -0
- package/dist/shared/host-limitations.d.ts +14 -0
- package/dist/shared/host-limitations.d.ts.map +1 -0
- package/dist/shared/index.d.ts +8 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/internal-initiator-marker.d.ts +2 -0
- package/dist/shared/internal-initiator-marker.d.ts.map +1 -0
- package/dist/shared/jsonc-edit.d.ts +23 -0
- package/dist/shared/jsonc-edit.d.ts.map +1 -0
- package/dist/shared/jsonc-parser.d.ts +30 -0
- package/dist/shared/jsonc-parser.d.ts.map +1 -0
- package/dist/shared/keep-subagents.d.ts +7 -0
- package/dist/shared/keep-subagents.d.ts.map +1 -0
- package/dist/shared/logger.d.ts +18 -0
- package/dist/shared/logger.d.ts.map +1 -0
- package/dist/shared/model-cache-ttl.d.ts +9 -0
- package/dist/shared/model-cache-ttl.d.ts.map +1 -0
- package/dist/shared/model-resolution.d.ts +35 -0
- package/dist/shared/model-resolution.d.ts.map +1 -0
- package/dist/shared/model-suggestion-retry.d.ts +138 -0
- package/dist/shared/model-suggestion-retry.d.ts.map +1 -0
- package/dist/shared/models-dev-cache.d.ts +156 -0
- package/dist/shared/models-dev-cache.d.ts.map +1 -0
- package/dist/shared/normalize-sdk-response.d.ts +5 -0
- package/dist/shared/normalize-sdk-response.d.ts.map +1 -0
- package/dist/shared/opencode-config-dir-types.d.ts +14 -0
- package/dist/shared/opencode-config-dir-types.d.ts.map +1 -0
- package/dist/shared/opencode-config-dir.d.ts +57 -0
- package/dist/shared/opencode-config-dir.d.ts.map +1 -0
- package/dist/shared/opencode-db-path.d.ts +68 -0
- package/dist/shared/opencode-db-path.d.ts.map +1 -0
- package/dist/shared/pi-executable.d.ts +6 -0
- package/dist/shared/pi-executable.d.ts.map +1 -0
- package/dist/shared/plugin-package-version.d.ts +14 -0
- package/dist/shared/plugin-package-version.d.ts.map +1 -0
- package/dist/shared/project-directory-key.d.ts +26 -0
- package/dist/shared/project-directory-key.d.ts.map +1 -0
- package/dist/shared/prompt-context.d.ts +31 -0
- package/dist/shared/prompt-context.d.ts.map +1 -0
- package/dist/shared/prompt-surface-a1-golden.d.ts +28 -0
- package/dist/shared/prompt-surface-a1-golden.d.ts.map +1 -0
- package/dist/shared/prompt-surface-runtime.d.ts +62 -0
- package/dist/shared/prompt-surface-runtime.d.ts.map +1 -0
- package/dist/shared/prompt-surface.d.ts +53 -0
- package/dist/shared/prompt-surface.d.ts.map +1 -0
- package/dist/shared/provider-response-completion.d.ts +12 -0
- package/dist/shared/provider-response-completion.d.ts.map +1 -0
- package/dist/shared/record-type-guard.d.ts +2 -0
- package/dist/shared/record-type-guard.d.ts.map +1 -0
- package/dist/shared/redaction.d.ts +7 -0
- package/dist/shared/redaction.d.ts.map +1 -0
- package/dist/shared/resolve-fallbacks.d.ts +48 -0
- package/dist/shared/resolve-fallbacks.d.ts.map +1 -0
- package/dist/shared/rpc-client.d.ts +28 -0
- package/dist/shared/rpc-client.d.ts.map +1 -0
- package/dist/shared/rpc-notifications.d.ts +74 -0
- package/dist/shared/rpc-notifications.d.ts.map +1 -0
- package/dist/shared/rpc-server.d.ts +52 -0
- package/dist/shared/rpc-server.d.ts.map +1 -0
- package/dist/shared/rpc-types.d.ts +385 -0
- package/dist/shared/rpc-types.d.ts.map +1 -0
- package/dist/shared/rpc-utils.d.ts +162 -0
- package/dist/shared/rpc-utils.d.ts.map +1 -0
- package/dist/shared/run-token-log.d.ts +13 -0
- package/dist/shared/run-token-log.d.ts.map +1 -0
- package/dist/shared/safe-notification-target.d.ts +23 -0
- package/dist/shared/safe-notification-target.d.ts.map +1 -0
- package/dist/shared/sqlite-context-pragmas.d.ts +12 -0
- package/dist/shared/sqlite-context-pragmas.d.ts.map +1 -0
- package/dist/shared/sqlite-helpers.d.ts +25 -0
- package/dist/shared/sqlite-helpers.d.ts.map +1 -0
- package/dist/shared/sqlite-write-locker-test-support.d.ts +7 -0
- package/dist/shared/sqlite-write-locker-test-support.d.ts.map +1 -0
- package/dist/shared/sqlite.d.ts +163 -0
- package/dist/shared/sqlite.d.ts.map +1 -0
- package/dist/shared/stable-json.d.ts +21 -0
- package/dist/shared/stable-json.d.ts.map +1 -0
- package/dist/shared/status-detail-text.d.ts +4 -0
- package/dist/shared/status-detail-text.d.ts.map +1 -0
- package/dist/shared/status-summary.d.ts +54 -0
- package/dist/shared/status-summary.d.ts.map +1 -0
- package/dist/shared/status-view-check.d.ts +130 -0
- package/dist/shared/status-view-check.d.ts.map +1 -0
- package/dist/shared/status-view.d.ts +230 -0
- package/dist/shared/status-view.d.ts.map +1 -0
- package/dist/shared/storage-permissions.d.ts +29 -0
- package/dist/shared/storage-permissions.d.ts.map +1 -0
- package/dist/shared/subagent-runner.d.ts +231 -0
- package/dist/shared/subagent-runner.d.ts.map +1 -0
- package/dist/shared/summarize-child-stderr.d.ts +2 -0
- package/dist/shared/summarize-child-stderr.d.ts.map +1 -0
- package/dist/shared/system-directive.d.ts +3 -0
- package/dist/shared/system-directive.d.ts.map +1 -0
- package/dist/shared/tag-owner-id.d.ts +19 -0
- package/dist/shared/tag-owner-id.d.ts.map +1 -0
- package/dist/shared/tag-transcript.d.ts +103 -0
- package/dist/shared/tag-transcript.d.ts.map +1 -0
- package/dist/shared/tail-hygiene-status.d.ts +24 -0
- package/dist/shared/tail-hygiene-status.d.ts.map +1 -0
- package/dist/shared/test-temp-dir.d.ts +46 -0
- package/dist/shared/test-temp-dir.d.ts.map +1 -0
- package/dist/shared/transcript.d.ts +251 -0
- package/dist/shared/transcript.d.ts.map +1 -0
- package/dist/shared/user-answer.d.ts +4 -0
- package/dist/shared/user-answer.d.ts.map +1 -0
- package/dist/shared/user-facing-codes.d.ts +135 -0
- package/dist/shared/user-facing-codes.d.ts.map +1 -0
- package/dist/shared/window-geometry.d.ts +121 -0
- package/dist/shared/window-geometry.d.ts.map +1 -0
- package/dist/shared/write-transaction-timing.d.ts +11 -0
- package/dist/shared/write-transaction-timing.d.ts.map +1 -0
- package/dist/shared/xml-unescape.d.ts +9 -0
- package/dist/shared/xml-unescape.d.ts.map +1 -0
- package/dist/tools/ctx-expand/constants.d.ts +3 -0
- package/dist/tools/ctx-expand/constants.d.ts.map +1 -0
- package/dist/tools/ctx-expand/index.d.ts +2 -0
- package/dist/tools/ctx-expand/index.d.ts.map +1 -0
- package/dist/tools/ctx-expand/mode.d.ts +35 -0
- package/dist/tools/ctx-expand/mode.d.ts.map +1 -0
- package/dist/tools/ctx-expand/render.d.ts +47 -0
- package/dist/tools/ctx-expand/render.d.ts.map +1 -0
- package/dist/tools/ctx-expand/tools.d.ts +10 -0
- package/dist/tools/ctx-expand/tools.d.ts.map +1 -0
- package/dist/tools/ctx-expand/types.d.ts +11 -0
- package/dist/tools/ctx-expand/types.d.ts.map +1 -0
- package/dist/tools/ctx-memory/constants.d.ts +3 -0
- package/dist/tools/ctx-memory/constants.d.ts.map +1 -0
- package/dist/tools/ctx-memory/index.d.ts +4 -0
- package/dist/tools/ctx-memory/index.d.ts.map +1 -0
- package/dist/tools/ctx-memory/tools.d.ts +5 -0
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -0
- package/dist/tools/ctx-memory/types.d.ts +38 -0
- package/dist/tools/ctx-memory/types.d.ts.map +1 -0
- package/dist/tools/ctx-memory/verification-recording.d.ts +8 -0
- package/dist/tools/ctx-memory/verification-recording.d.ts.map +1 -0
- package/dist/tools/ctx-note/constants.d.ts +2 -0
- package/dist/tools/ctx-note/constants.d.ts.map +1 -0
- package/dist/tools/ctx-note/index.d.ts +4 -0
- package/dist/tools/ctx-note/index.d.ts.map +1 -0
- package/dist/tools/ctx-note/render.d.ts +67 -0
- package/dist/tools/ctx-note/render.d.ts.map +1 -0
- package/dist/tools/ctx-note/tools.d.ts +13 -0
- package/dist/tools/ctx-note/tools.d.ts.map +1 -0
- package/dist/tools/ctx-note/types.d.ts +14 -0
- package/dist/tools/ctx-note/types.d.ts.map +1 -0
- package/dist/tools/ctx-reduce/constants.d.ts +4 -0
- package/dist/tools/ctx-reduce/constants.d.ts.map +1 -0
- package/dist/tools/ctx-reduce/index.d.ts +4 -0
- package/dist/tools/ctx-reduce/index.d.ts.map +1 -0
- package/dist/tools/ctx-reduce/tools.d.ts +19 -0
- package/dist/tools/ctx-reduce/tools.d.ts.map +1 -0
- package/dist/tools/ctx-reduce/types.d.ts +5 -0
- package/dist/tools/ctx-reduce/types.d.ts.map +1 -0
- package/dist/tools/ctx-search/constants.d.ts +4 -0
- package/dist/tools/ctx-search/constants.d.ts.map +1 -0
- package/dist/tools/ctx-search/date-range.d.ts +9 -0
- package/dist/tools/ctx-search/date-range.d.ts.map +1 -0
- package/dist/tools/ctx-search/index.d.ts +4 -0
- package/dist/tools/ctx-search/index.d.ts.map +1 -0
- package/dist/tools/ctx-search/tools.d.ts +5 -0
- package/dist/tools/ctx-search/tools.d.ts.map +1 -0
- package/dist/tools/ctx-search/types.d.ts +34 -0
- package/dist/tools/ctx-search/types.d.ts.map +1 -0
- package/dist/tools/light-descriptions.d.ts +6 -0
- package/dist/tools/light-descriptions.d.ts.map +1 -0
- package/dist/tools/parameter-descriptions.d.ts +75 -0
- package/dist/tools/parameter-descriptions.d.ts.map +1 -0
- package/dist/tools/unwrap-imitated-reduced-args.d.ts +21 -0
- package/dist/tools/unwrap-imitated-reduced-args.d.ts.map +1 -0
- package/dist/v2/fold/boundary.d.ts +61 -0
- package/dist/v2/fold/boundary.d.ts.map +1 -0
- package/dist/v2/fold/host-media.d.ts +36 -0
- package/dist/v2/fold/host-media.d.ts.map +1 -0
- package/dist/v2/fold/markers.d.ts +7 -0
- package/dist/v2/fold/markers.d.ts.map +1 -0
- package/dist/v2/fold/owner.d.ts +40 -0
- package/dist/v2/fold/owner.d.ts.map +1 -0
- package/dist/v2/fold/restore.d.ts +31 -0
- package/dist/v2/fold/restore.d.ts.map +1 -0
- package/dist/v2/fork-inheritance.d.ts +101 -0
- package/dist/v2/fork-inheritance.d.ts.map +1 -0
- package/dist/v2/hidden-child-cleanup.d.ts +11 -0
- package/dist/v2/hidden-child-cleanup.d.ts.map +1 -0
- package/dist/v2/hidden-child-native.d.ts +29 -0
- package/dist/v2/hidden-child-native.d.ts.map +1 -0
- package/dist/v2/hidden-child-record.d.ts +137 -0
- package/dist/v2/hidden-child-record.d.ts.map +1 -0
- package/dist/v2/hidden-completion.d.ts +57 -0
- package/dist/v2/hidden-completion.d.ts.map +1 -0
- package/dist/v2/hooks/channel2.d.ts +10 -0
- package/dist/v2/hooks/channel2.d.ts.map +1 -0
- package/dist/v2/hooks/commands.d.ts +29 -0
- package/dist/v2/hooks/commands.d.ts.map +1 -0
- package/dist/v2/hooks/context.d.ts +112 -0
- package/dist/v2/hooks/context.d.ts.map +1 -0
- package/dist/v2/hooks/deleted-session-tombstones.d.ts +10 -0
- package/dist/v2/hooks/deleted-session-tombstones.d.ts.map +1 -0
- package/dist/v2/hooks/generate.d.ts +10 -0
- package/dist/v2/hooks/generate.d.ts.map +1 -0
- package/dist/v2/hooks/hidden-child.d.ts +76 -0
- package/dist/v2/hooks/hidden-child.d.ts.map +1 -0
- package/dist/v2/hooks/hidden-terminal-error.d.ts +8 -0
- package/dist/v2/hooks/hidden-terminal-error.d.ts.map +1 -0
- package/dist/v2/hooks/lkg-system.d.ts +11 -0
- package/dist/v2/hooks/lkg-system.d.ts.map +1 -0
- package/dist/v2/hooks/model-limit-cache.d.ts +19 -0
- package/dist/v2/hooks/model-limit-cache.d.ts.map +1 -0
- package/dist/v2/hooks/payload.d.ts +15 -0
- package/dist/v2/hooks/payload.d.ts.map +1 -0
- package/dist/v2/hooks/refusal.d.ts +15 -0
- package/dist/v2/hooks/refusal.d.ts.map +1 -0
- package/dist/v2/hooks/restore-rows.d.ts +29 -0
- package/dist/v2/hooks/restore-rows.d.ts.map +1 -0
- package/dist/v2/hooks/rpc-live-state.d.ts +9 -0
- package/dist/v2/hooks/rpc-live-state.d.ts.map +1 -0
- package/dist/v2/hooks/session-api-gate.d.ts +4 -0
- package/dist/v2/hooks/session-api-gate.d.ts.map +1 -0
- package/dist/v2/hooks/session-project-backfill.d.ts +15 -0
- package/dist/v2/hooks/session-project-backfill.d.ts.map +1 -0
- package/dist/v2/hooks/storage-gate.d.ts +48 -0
- package/dist/v2/hooks/storage-gate.d.ts.map +1 -0
- package/dist/v2/hooks/storage-notice.d.ts +29 -0
- package/dist/v2/hooks/storage-notice.d.ts.map +1 -0
- package/dist/v2/hooks/store.d.ts +58 -0
- package/dist/v2/hooks/store.d.ts.map +1 -0
- package/dist/v2/hooks/tools.d.ts +8 -0
- package/dist/v2/hooks/tools.d.ts.map +1 -0
- package/dist/v2/hooks/types.d.ts +250 -0
- package/dist/v2/hooks/types.d.ts.map +1 -0
- package/dist/v2/hooks/usage-persist.d.ts +31 -0
- package/dist/v2/hooks/usage-persist.d.ts.map +1 -0
- package/dist/v2/hooks/usage-reading.d.ts +46 -0
- package/dist/v2/hooks/usage-reading.d.ts.map +1 -0
- package/dist/v2/server.d.ts +27 -0
- package/dist/v2/server.d.ts.map +1 -0
- package/dist/v2/server.js +76235 -0
- package/dist/v2/store-reader.d.ts +218 -0
- package/dist/v2/store-reader.d.ts.map +1 -0
- package/dist/web/api.d.ts +40 -0
- package/dist/web/api.d.ts.map +1 -0
- package/dist/web/context-store.d.ts +74 -0
- package/dist/web/context-store.d.ts.map +1 -0
- package/dist/web/fixtures.d.ts +53 -0
- package/dist/web/fixtures.d.ts.map +1 -0
- package/dist/web/host-opencode.d.ts +56 -0
- package/dist/web/host-opencode.d.ts.map +1 -0
- package/dist/web/host-pi.d.ts +116 -0
- package/dist/web/host-pi.d.ts.map +1 -0
- package/dist/web/main.d.ts +24 -0
- package/dist/web/main.d.ts.map +1 -0
- package/dist/web/main.js +6071 -0
- package/dist/web/memories.d.ts +67 -0
- package/dist/web/memories.d.ts.map +1 -0
- package/dist/web/server.d.ts +42 -0
- package/dist/web/server.d.ts.map +1 -0
- package/dist/web/types.d.ts +52 -0
- package/dist/web/types.d.ts.map +1 -0
- package/dist/web/ui/favicon.svg +4 -0
- package/dist/web/ui/index.html +36 -0
- package/dist/web/ui/panel.css +8 -0
- package/dist/web/ui/panel.js +373 -0
- package/dist/web/views.d.ts +155 -0
- package/dist/web/views.d.ts.map +1 -0
- package/dist/web/writes.d.ts +86 -0
- package/dist/web/writes.d.ts.map +1 -0
- package/dist/wrapup-orchestrator-az866scb.js +420 -0
- package/dist/wrapup-orchestrator-fztjahrk.js +420 -0
- package/dist/wrapup-orchestrator-z9sqpqjf.js +420 -0
- package/index.js +1 -0
- package/package.json +76 -4
- package/src/agents/historian.ts +3 -0
- package/src/agents/language-directive.test.ts +129 -0
- package/src/agents/language-directive.ts +113 -0
- package/src/agents/magic-context-prompt.language.test.ts +37 -0
- package/src/agents/magic-context-prompt.test.ts +520 -0
- package/src/agents/magic-context-prompt.ts +196 -0
- package/src/agents/memory-maintainer.test.ts +249 -0
- package/src/agents/memory-maintainer.ts +374 -0
- package/src/config/agent-disable.ts +58 -0
- package/src/config/compaction-accessor-guard.test.ts +81 -0
- package/src/config/compaction-backcompat.test.ts +52 -0
- package/src/config/config-paths.ts +42 -0
- package/src/config/index.test.ts +1252 -0
- package/src/config/index.ts +762 -0
- package/src/config/latch-permanence-guard.test.ts +218 -0
- package/src/config/live-run-config.test.ts +139 -0
- package/src/config/live-run-config.ts +79 -0
- package/src/config/live-schema-drift.test.ts +67 -0
- package/src/config/live-snapshot.test.ts +86 -0
- package/src/config/live-snapshot.ts +187 -0
- package/src/config/migrate-experimental.ts +92 -0
- package/src/config/misplaced-agent-model.test.ts +55 -0
- package/src/config/profiles.ts +106 -0
- package/src/config/project-config-trust-boundary.test.ts +185 -0
- package/src/config/project-security.hostile-matrix.test.ts +281 -0
- package/src/config/project-security.test.ts +329 -0
- package/src/config/project-security.ts +940 -0
- package/src/config/protected-tokens.test.ts +229 -0
- package/src/config/prune-config-leaf.test.ts +78 -0
- package/src/config/prune-config-leaf.ts +67 -0
- package/src/config/raw-loader.test.ts +389 -0
- package/src/config/raw-loader.ts +435 -0
- package/src/config/removed-agent-config.ts +45 -0
- package/src/config/removed-agent-source-fence.test.ts +53 -0
- package/src/config/removed-config-keys.test.ts +106 -0
- package/src/config/schema/agent-overrides.ts +45 -0
- package/src/config/schema/magic-context.test.ts +434 -0
- package/src/config/schema/magic-context.ts +1019 -0
- package/src/config/variable.test.ts +324 -0
- package/src/config/variable.ts +192 -0
- package/src/shared/__fixtures__/window-overlay.v1.json +337 -0
- package/src/shared/announcement.test.ts +198 -0
- package/src/shared/announcement.ts +145 -0
- package/src/shared/assistant-message-extractor.test.ts +47 -0
- package/src/shared/assistant-message-extractor.ts +156 -0
- package/src/shared/auto-update-provenance.ts +42 -0
- package/src/shared/bounded-session-map.test.ts +97 -0
- package/src/shared/bounded-session-map.ts +84 -0
- package/src/shared/builtin-commands.ts +46 -0
- package/src/shared/cache-ttl-display.test.ts +84 -0
- package/src/shared/cache-ttl-display.ts +58 -0
- package/src/shared/cache-ttl-seed.ts +23 -0
- package/src/shared/child-session-teardown.test.ts +241 -0
- package/src/shared/child-session-teardown.ts +66 -0
- package/src/shared/commit-detection.test.ts +63 -0
- package/src/shared/commit-detection.ts +53 -0
- package/src/shared/config-diagnostics.test.ts +29 -0
- package/src/shared/config-diagnostics.ts +64 -0
- package/src/shared/conflict-detector.test.ts +780 -0
- package/src/shared/conflict-detector.ts +596 -0
- package/src/shared/conflict-fixer.test.ts +608 -0
- package/src/shared/conflict-fixer.ts +295 -0
- package/src/shared/context-limit-provenance.ts +6 -0
- package/src/shared/data-path.test.ts +352 -0
- package/src/shared/data-path.ts +310 -0
- package/src/shared/error-message.test.ts +94 -0
- package/src/shared/error-message.ts +115 -0
- package/src/shared/escalation-bands.test.ts +23 -0
- package/src/shared/escalation-bands.ts +18 -0
- package/src/shared/format-bytes.ts +5 -0
- package/src/shared/format-threshold.ts +54 -0
- package/src/shared/harness-provider-map.test.ts +176 -0
- package/src/shared/harness-provider-map.ts +130 -0
- package/src/shared/harness.ts +76 -0
- package/src/shared/hidden-variant-warnings.ts +21 -0
- package/src/shared/historian-tool-defaults.json +13 -0
- package/src/shared/historian-tool-expansions.ts +18 -0
- package/src/shared/historian-tool-template.ts +248 -0
- package/src/shared/historian-transient-error.test.ts +36 -0
- package/src/shared/historian-transient-error.ts +22 -0
- package/src/shared/host-limitations.ts +43 -0
- package/src/shared/index.ts +7 -0
- package/src/shared/internal-initiator-marker.ts +1 -0
- package/src/shared/jsonc-edit.ts +387 -0
- package/src/shared/jsonc-parser.test.ts +46 -0
- package/src/shared/jsonc-parser.ts +283 -0
- package/src/shared/keep-subagents.test.ts +39 -0
- package/src/shared/keep-subagents.ts +28 -0
- package/src/shared/logger.test.ts +292 -0
- package/src/shared/logger.ts +248 -0
- package/src/shared/model-cache-ttl.test.ts +40 -0
- package/src/shared/model-cache-ttl.ts +58 -0
- package/src/shared/model-resolution.test.ts +132 -0
- package/src/shared/model-resolution.ts +158 -0
- package/src/shared/model-suggestion-retry.test.ts +698 -0
- package/src/shared/model-suggestion-retry.ts +838 -0
- package/src/shared/models-dev-cache.test.ts +720 -0
- package/src/shared/models-dev-cache.ts +661 -0
- package/src/shared/normalize-sdk-response.ts +40 -0
- package/src/shared/opencode-config-dir-types.ts +15 -0
- package/src/shared/opencode-config-dir.ts +111 -0
- package/src/shared/opencode-db-path.test.ts +389 -0
- package/src/shared/opencode-db-path.ts +396 -0
- package/src/shared/opencode-host-generation.test.ts +29 -0
- package/src/shared/pi-executable.ts +20 -0
- package/src/shared/plugin-package-version.ts +52 -0
- package/src/shared/project-directory-key.test.ts +111 -0
- package/src/shared/project-directory-key.ts +54 -0
- package/src/shared/prompt-context.ts +135 -0
- package/src/shared/prompt-surface-a1-golden.md +407 -0
- package/src/shared/prompt-surface-a1-golden.ts +41 -0
- package/src/shared/prompt-surface-runtime.test.ts +190 -0
- package/src/shared/prompt-surface-runtime.ts +263 -0
- package/src/shared/prompt-surface.test.ts +195 -0
- package/src/shared/prompt-surface.ts +162 -0
- package/src/shared/provider-response-completion.ts +23 -0
- package/src/shared/record-type-guard.ts +3 -0
- package/src/shared/redaction.test.ts +134 -0
- package/src/shared/redaction.ts +298 -0
- package/src/shared/resolve-fallbacks.test.ts +114 -0
- package/src/shared/resolve-fallbacks.ts +95 -0
- package/src/shared/rpc-async-probes.test.ts +320 -0
- package/src/shared/rpc-client.test.ts +576 -0
- package/src/shared/rpc-client.ts +218 -0
- package/src/shared/rpc-notifications.test.ts +151 -0
- package/src/shared/rpc-notifications.ts +222 -0
- package/src/shared/rpc-server.ts +431 -0
- package/src/shared/rpc-types.ts +386 -0
- package/src/shared/rpc-utils.test.ts +822 -0
- package/src/shared/rpc-utils.ts +1146 -0
- package/src/shared/run-token-log.test.ts +65 -0
- package/src/shared/run-token-log.ts +39 -0
- package/src/shared/safe-notification-target.test.ts +97 -0
- package/src/shared/safe-notification-target.ts +102 -0
- package/src/shared/session-messages-bounded.test.ts +112 -0
- package/src/shared/sqlite-acquisition-fence.test.ts +133 -0
- package/src/shared/sqlite-acquisition-routing.test.ts +145 -0
- package/src/shared/sqlite-bind-style.test.ts +80 -0
- package/src/shared/sqlite-context-pragmas.ts +24 -0
- package/src/shared/sqlite-helpers.ts +44 -0
- package/src/shared/sqlite-import-fence.test.ts +19 -0
- package/src/shared/sqlite-pass-scope.test.ts +154 -0
- package/src/shared/sqlite-transaction-mode-guard.test.ts +234 -0
- package/src/shared/sqlite-write-locker-test-support.ts +63 -0
- package/src/shared/sqlite.test.ts +58 -0
- package/src/shared/sqlite.ts +988 -0
- package/src/shared/stable-json.test.ts +87 -0
- package/src/shared/stable-json.ts +37 -0
- package/src/shared/status-detail-text.test.ts +194 -0
- package/src/shared/status-detail-text.ts +7 -0
- package/src/shared/status-summary.ts +189 -0
- package/src/shared/status-view-check.test.ts +252 -0
- package/src/shared/status-view-check.ts +519 -0
- package/src/shared/status-view.test.ts +395 -0
- package/src/shared/status-view.ts +794 -0
- package/src/shared/storage-busy.test.ts +73 -0
- package/src/shared/storage-permissions.test.ts +190 -0
- package/src/shared/storage-permissions.ts +212 -0
- package/src/shared/subagent-runner.ts +240 -0
- package/src/shared/summarize-child-stderr.test.ts +55 -0
- package/src/shared/summarize-child-stderr.ts +33 -0
- package/src/shared/system-directive.ts +9 -0
- package/src/shared/tag-owner-id.test.ts +33 -0
- package/src/shared/tag-owner-id.ts +29 -0
- package/src/shared/tag-transcript.test.ts +554 -0
- package/src/shared/tag-transcript.ts +1400 -0
- package/src/shared/tail-hygiene-status.ts +73 -0
- package/src/shared/test-temp-dir.test.ts +84 -0
- package/src/shared/test-temp-dir.ts +192 -0
- package/src/shared/transcript.ts +274 -0
- package/src/shared/user-answer.test.ts +12 -0
- package/src/shared/user-answer.ts +17 -0
- package/src/shared/user-facing-codes.test.ts +82 -0
- package/src/shared/user-facing-codes.ts +180 -0
- package/src/shared/window-geometry.test.ts +405 -0
- package/src/shared/window-geometry.ts +726 -0
- package/src/shared/windows-hidden-spawns.test.ts +133 -0
- package/src/shared/write-transaction-attribution.test.ts +214 -0
- package/src/shared/write-transaction-timing.ts +26 -0
- package/src/shared/xml-unescape.ts +19 -0
- package/README.md +0 -3
|
@@ -0,0 +1,988 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite chokepoint — runtime-detected backend selection.
|
|
3
|
+
*
|
|
4
|
+
* The same shipped plugin artifact must run under two different runtimes:
|
|
5
|
+
* - Bun (current OpenCode releases) → uses `bun:sqlite` (built-in, fast)
|
|
6
|
+
* - Node / Electron (Pi plugin, OpenCode Desktop) → uses `node:sqlite`
|
|
7
|
+
* (`DatabaseSync`, built into Node 22.5+ / Electron 41+, stable-enough and
|
|
8
|
+
* flag-free since Node 22.13/23.4).
|
|
9
|
+
*
|
|
10
|
+
* Bun has no `node:sqlite`, and Node/Electron have no `bun:sqlite`. Static
|
|
11
|
+
* imports of either would crash at parse time in the wrong runtime, so we use
|
|
12
|
+
* dynamic imports gated by runtime detection.
|
|
13
|
+
*
|
|
14
|
+
* Why `node:sqlite` instead of `better-sqlite3`: better-sqlite3 is a native
|
|
15
|
+
* module requiring per-ABI prebuilds, and Electron's ABI never matches the npm
|
|
16
|
+
* Node prebuild — which forced a runtime download of an Electron-matched
|
|
17
|
+
* `.node` binary (a supply-chain + maintenance liability). `node:sqlite` is
|
|
18
|
+
* built into the runtime, so there is NOTHING to download or rebuild. Both Pi
|
|
19
|
+
* (plain Node 24) and OpenCode Desktop (Electron 41 → Node 24.14.1) ship it.
|
|
20
|
+
*
|
|
21
|
+
* API surface we use (common across both backends, modulo the shims below):
|
|
22
|
+
* - new Database(path, { readonly?: boolean }) ← we map readonly→readOnly
|
|
23
|
+
* - db.prepare(sql).run/get/all
|
|
24
|
+
* - db.exec(multistatement)
|
|
25
|
+
* - db.transaction(fn) → wrapped function ← shimmed for node:sqlite
|
|
26
|
+
* - db.close()
|
|
27
|
+
*
|
|
28
|
+
* The three backend differences we bridge for node:sqlite:
|
|
29
|
+
* 1. node:sqlite has no `db.transaction(fn)` helper — we add a savepoint-aware
|
|
30
|
+
* shim (below) that matches better-sqlite3/bun semantics.
|
|
31
|
+
* 2. node:sqlite's constructor option is `readOnly` (camel-case), not
|
|
32
|
+
* better-sqlite3/bun's `readonly` — we translate it so call sites are
|
|
33
|
+
* unchanged.
|
|
34
|
+
* 3. node:sqlite reads a lone array bind arg (`.run([a,b])`) as NAMED params
|
|
35
|
+
* and throws `Unknown named parameter '0'`; bun binds it positionally. We
|
|
36
|
+
* normalize it in the `prepare()` override (below) so the bind surface is
|
|
37
|
+
* identical (issue #151 / Pi /ctx-dream).
|
|
38
|
+
* Everything else (named params with bare keys, ATTACH under defensive mode,
|
|
39
|
+
* `run()` → {changes,lastInsertRowid}) is identical and was verified directly.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
43
|
+
import { statSync } from "node:fs";
|
|
44
|
+
// Type import only — runtime is loaded dynamically below. @types/better-sqlite3
|
|
45
|
+
// has the richest definitions and is a structural superset of the API surface
|
|
46
|
+
// we use, so calls typed against BetterSqlite3 work under bun:sqlite and
|
|
47
|
+
// node:sqlite at runtime (both expose prepare/run/get/all/exec/close).
|
|
48
|
+
import type BetterSqlite3 from "better-sqlite3";
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Slow-write reporting is injected rather than imported: this module is also
|
|
52
|
+
* executed directly by Node (the `node:sqlite` smoke in CI, Pi, Desktop), and
|
|
53
|
+
* Node's type-stripping loader does not resolve extensionless imports, so any
|
|
54
|
+
* static import of the plugin's logging chain here breaks that path. The
|
|
55
|
+
* storage bootstrap registers the real reporter; until then slow privileged
|
|
56
|
+
* writes are simply not logged.
|
|
57
|
+
*/
|
|
58
|
+
type SlowWriteReporter = (site: string, transactionStartedAt: number) => void;
|
|
59
|
+
let reportSlowPrivilegedWrite: SlowWriteReporter | undefined;
|
|
60
|
+
|
|
61
|
+
export function registerSlowWriteReporter(reporter: SlowWriteReporter): void {
|
|
62
|
+
reportSlowPrivilegedWrite = reporter;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Writer acquisition and hold diagnostics are injected the same way. They must
|
|
67
|
+
* reach the Magic Context log file and never the console: OpenCode and Pi pass
|
|
68
|
+
* plugin stderr straight through to the operator's terminal. The storage
|
|
69
|
+
* bootstrap registers the shared logger here; until then these lines are
|
|
70
|
+
* dropped.
|
|
71
|
+
*/
|
|
72
|
+
type SqliteDiagnosticSink = (message: string) => void;
|
|
73
|
+
let sqliteDiagnosticSink: SqliteDiagnosticSink | undefined;
|
|
74
|
+
|
|
75
|
+
export function registerSqliteDiagnosticSink(sink: SqliteDiagnosticSink): void {
|
|
76
|
+
sqliteDiagnosticSink = sink;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function reportSqliteDiagnostic(message: string): void {
|
|
80
|
+
try {
|
|
81
|
+
sqliteDiagnosticSink?.(`[magic-context] ${message}`);
|
|
82
|
+
} catch {
|
|
83
|
+
// Diagnostics must never change the outcome of the write they describe.
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export type SqliteRuntime = "Bun" | "Node.js";
|
|
88
|
+
|
|
89
|
+
type SqliteModule = {
|
|
90
|
+
Database?: unknown;
|
|
91
|
+
DatabaseSync?: unknown;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export function detectSqliteRuntime(): SqliteRuntime {
|
|
95
|
+
// process.versions.bun is the least ambiguous marker, but some launchers
|
|
96
|
+
// proxy or partially sandbox process. Keep globalThis.Bun as a fallback so
|
|
97
|
+
// a Bun process does not accidentally select node:sqlite just because its
|
|
98
|
+
// process compatibility surface was trimmed.
|
|
99
|
+
const hasBunVersion =
|
|
100
|
+
typeof process !== "undefined" && typeof process.versions?.bun === "string";
|
|
101
|
+
const hasBunGlobal =
|
|
102
|
+
typeof globalThis !== "undefined" &&
|
|
103
|
+
typeof (globalThis as { Bun?: unknown }).Bun !== "undefined";
|
|
104
|
+
return hasBunVersion || hasBunGlobal ? "Bun" : "Node.js";
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// IMPORTANT: bundler-evading dynamic imports.
|
|
108
|
+
//
|
|
109
|
+
// We can't write `await import("node:sqlite")` directly because esbuild/bun
|
|
110
|
+
// would try to resolve both modules at build time, and one of them won't exist
|
|
111
|
+
// in the build runtime (bun:sqlite is missing in Node, node:sqlite is missing
|
|
112
|
+
// in Bun). Earlier versions used `new Function("p", "return import(p)")(...)`
|
|
113
|
+
// to defeat static analysis, but that breaks Pi's vm-based extension loader: a
|
|
114
|
+
// Function constructed at runtime has no module record, so `import()` inside it
|
|
115
|
+
// has no referrer module and Node throws "A dynamic import callback was not
|
|
116
|
+
// specified".
|
|
117
|
+
//
|
|
118
|
+
// The /* @vite-ignore */ + variable indirection pattern hides the specifier
|
|
119
|
+
// from static analyzers while keeping a real referrer module for the
|
|
120
|
+
// dynamic import — Pi's loader, esbuild, and bun build all accept it.
|
|
121
|
+
const bunSpec = "bun:" + "sqlite";
|
|
122
|
+
const nodeSpec = "node:" + "sqlite";
|
|
123
|
+
|
|
124
|
+
async function importSqliteModule(specifier: string): Promise<SqliteModule> {
|
|
125
|
+
// The runtime chooses this specifier; Vite must not resolve it as a
|
|
126
|
+
// build-time dependency because the other runtime's backend is absent.
|
|
127
|
+
return (await import(
|
|
128
|
+
/* @vite-ignore -- keep the runtime-selected backend unresolved */ specifier
|
|
129
|
+
)) as SqliteModule;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function isModuleNotFoundError(error: unknown, specifier: string): boolean {
|
|
133
|
+
const candidate = error as { code?: unknown; name?: unknown } | null;
|
|
134
|
+
const code = typeof candidate?.code === "string" ? candidate.code : "";
|
|
135
|
+
const name = typeof candidate?.name === "string" ? candidate.name : "";
|
|
136
|
+
const message = error instanceof Error ? error.message : String(error ?? "");
|
|
137
|
+
const details = `${code} ${name} ${message}`.toLowerCase();
|
|
138
|
+
const mentionsSpecifier = details.includes(specifier.toLowerCase());
|
|
139
|
+
if (!mentionsSpecifier) return false;
|
|
140
|
+
|
|
141
|
+
return (
|
|
142
|
+
code === "ERR_MODULE_NOT_FOUND" ||
|
|
143
|
+
code === "ERR_UNKNOWN_BUILTIN_MODULE" ||
|
|
144
|
+
code === "MODULE_NOT_FOUND" ||
|
|
145
|
+
name === "ResolveMessage" ||
|
|
146
|
+
details.includes("module not found") ||
|
|
147
|
+
details.includes("cannot find module") ||
|
|
148
|
+
details.includes("cannot find package") ||
|
|
149
|
+
details.includes("no such built-in module")
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export class SqliteRuntimeUnavailableError extends Error {
|
|
154
|
+
readonly runtime: SqliteRuntime;
|
|
155
|
+
readonly specifier: string;
|
|
156
|
+
|
|
157
|
+
constructor(runtime: SqliteRuntime, specifier: string, cause: unknown) {
|
|
158
|
+
const requirement =
|
|
159
|
+
specifier === nodeSpec
|
|
160
|
+
? "Requires Node.js >= 24, or Bun with bun:sqlite — this Bun build lacks node:sqlite."
|
|
161
|
+
: "Requires Bun with bun:sqlite, or Node.js >= 24 — this Bun build lacks bun:sqlite.";
|
|
162
|
+
super(
|
|
163
|
+
`Magic Context detected ${runtime}, but could not load ${specifier}. ${requirement}`,
|
|
164
|
+
{ cause },
|
|
165
|
+
);
|
|
166
|
+
this.name = "SqliteRuntimeUnavailableError";
|
|
167
|
+
this.runtime = runtime;
|
|
168
|
+
this.specifier = specifier;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export async function loadSqliteModule(
|
|
173
|
+
runtime: SqliteRuntime = detectSqliteRuntime(),
|
|
174
|
+
importer: (specifier: string) => Promise<SqliteModule> = importSqliteModule,
|
|
175
|
+
): Promise<SqliteModule> {
|
|
176
|
+
const specifier = runtime === "Bun" ? bunSpec : nodeSpec;
|
|
177
|
+
try {
|
|
178
|
+
return await importer(specifier);
|
|
179
|
+
} catch (error) {
|
|
180
|
+
if (isModuleNotFoundError(error, specifier)) {
|
|
181
|
+
throw new SqliteRuntimeUnavailableError(runtime, specifier, error);
|
|
182
|
+
}
|
|
183
|
+
throw error;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const detectedRuntime = detectSqliteRuntime();
|
|
188
|
+
const isBun = detectedRuntime === "Bun";
|
|
189
|
+
const sqliteModule = await loadSqliteModule(detectedRuntime);
|
|
190
|
+
|
|
191
|
+
// Different export shapes between the two backends:
|
|
192
|
+
// - bun:sqlite → named export `Database` (has its own .transaction, accepts
|
|
193
|
+
// `{ readonly }`) — usable as-is.
|
|
194
|
+
// - node:sqlite → named export `DatabaseSync` (no .transaction, option is
|
|
195
|
+
// `readOnly`) — wrapped below.
|
|
196
|
+
const DatabaseImpl: typeof BetterSqlite3 = isBun
|
|
197
|
+
? (sqliteModule.Database as typeof BetterSqlite3)
|
|
198
|
+
: buildNodeSqliteDatabaseClass(sqliteModule.DatabaseSync);
|
|
199
|
+
|
|
200
|
+
interface TrackedSqliteConnection {
|
|
201
|
+
sequence: number;
|
|
202
|
+
filename: string;
|
|
203
|
+
readonly: boolean;
|
|
204
|
+
reference: WeakRef<BetterSqlite3.Database>;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export interface SqliteConnectionMemoryStats {
|
|
208
|
+
sequence: number;
|
|
209
|
+
filename: string;
|
|
210
|
+
readonly: boolean;
|
|
211
|
+
pageSize: number | null;
|
|
212
|
+
pageCount: number | null;
|
|
213
|
+
freelistCount: number | null;
|
|
214
|
+
cacheSize: number | null;
|
|
215
|
+
cacheSizeUnit: "pages" | "kib" | null;
|
|
216
|
+
cacheUpperBoundBytes: number | null;
|
|
217
|
+
mmapSizeBytes: number | null;
|
|
218
|
+
walFileBytes: number | null;
|
|
219
|
+
shmFileBytes: number | null;
|
|
220
|
+
fts5TableCount: number | null;
|
|
221
|
+
journalMode: string | null;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export interface SqliteMemoryStats {
|
|
225
|
+
connectionCount: number;
|
|
226
|
+
cacheUpperBoundBytes: number;
|
|
227
|
+
mmapUpperBoundBytes: number;
|
|
228
|
+
walFileBytes: number;
|
|
229
|
+
shmFileBytes: number;
|
|
230
|
+
sqliteStatusApi: "unavailable";
|
|
231
|
+
connections: SqliteConnectionMemoryStats[];
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const trackedSqliteConnections = new Map<number, TrackedSqliteConnection>();
|
|
235
|
+
let nextSqliteConnectionSequence = 1;
|
|
236
|
+
|
|
237
|
+
/** Route native Bun and Node transaction entry through the same acquisition retry.
|
|
238
|
+
* Native Bun transaction wrappers execute BEGIN internally, bypassing an exec override,
|
|
239
|
+
* so both runtimes use this small synchronous wrapper instead. Writable handles
|
|
240
|
+
* default to IMMEDIATE; explicit deferred calls and readonly handles keep read
|
|
241
|
+
* snapshots without acquiring the writer lock. */
|
|
242
|
+
function installTransactionRouting(db: BetterSqlite3.Database, readonly: boolean): void {
|
|
243
|
+
const nativeExec = db.exec.bind(db);
|
|
244
|
+
Object.defineProperty(db, "exec", {
|
|
245
|
+
configurable: true,
|
|
246
|
+
writable: true,
|
|
247
|
+
value: (sql: string) => {
|
|
248
|
+
if (/^\s*BEGIN\s+(?:IMMEDIATE|EXCLUSIVE)(?:\s+TRANSACTION)?\s*;?\s*$/i.test(sql)) {
|
|
249
|
+
// A transaction that ended without passing through exec (for
|
|
250
|
+
// example an automatic rollback) must not be timed as this one.
|
|
251
|
+
openWriterTransactions.delete(db);
|
|
252
|
+
if (transformPassScope.getStore()?.active || backgroundWriterScope.getStore())
|
|
253
|
+
acquireShort(db, () => nativeExec(sql), sql.trim());
|
|
254
|
+
else nativeExec(sql);
|
|
255
|
+
return db;
|
|
256
|
+
}
|
|
257
|
+
if (WRITER_TRANSACTION_END.test(sql) && openWriterTransactions.has(db))
|
|
258
|
+
return endWriterTransaction(db, () => nativeExec(sql), sql);
|
|
259
|
+
if (!/^\s*(?:SELECT|EXPLAIN|PRAGMA|COMMIT|END|ROLLBACK|SAVEPOINT|RELEASE)\b/i.test(sql))
|
|
260
|
+
return withAutocommitTimeout(db, () => nativeExec(sql));
|
|
261
|
+
return nativeExec(sql);
|
|
262
|
+
},
|
|
263
|
+
});
|
|
264
|
+
const nativePrepare = db.prepare.bind(db);
|
|
265
|
+
Object.defineProperty(db, "prepare", {
|
|
266
|
+
configurable: true,
|
|
267
|
+
writable: true,
|
|
268
|
+
value: (sql: string) => {
|
|
269
|
+
const statement = nativePrepare(sql);
|
|
270
|
+
// SELECT/EXPLAIN cannot acquire a writer. Treat CTEs conservatively:
|
|
271
|
+
// WITH can introduce INSERT/UPDATE/DELETE as well as a read query.
|
|
272
|
+
if (!readonly && !/^\s*(?:SELECT|EXPLAIN|PRAGMA)\b/i.test(sql)) {
|
|
273
|
+
for (const method of ["run", "get", "all"] as const) {
|
|
274
|
+
const execute = statement[method].bind(statement);
|
|
275
|
+
Object.defineProperty(statement, method, {
|
|
276
|
+
configurable: true,
|
|
277
|
+
// biome-ignore lint/suspicious/noExplicitAny: retain SQLite's native binding overloads.
|
|
278
|
+
value: (...args: any[]) =>
|
|
279
|
+
withAutocommitTimeout(db, () => execute(...args)),
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return statement;
|
|
284
|
+
},
|
|
285
|
+
});
|
|
286
|
+
Object.defineProperty(db, "transaction", {
|
|
287
|
+
configurable: true,
|
|
288
|
+
writable: true,
|
|
289
|
+
// biome-ignore lint/suspicious/noExplicitAny: preserve the native callback's receiver and argument types.
|
|
290
|
+
value: (fn: (...args: any[]) => any) => {
|
|
291
|
+
const make = (mode: "IMMEDIATE" | "EXCLUSIVE" | "DEFERRED") =>
|
|
292
|
+
function (this: unknown, ...args: unknown[]): unknown {
|
|
293
|
+
const nested = isInTransaction(db);
|
|
294
|
+
// Equal savepoint names stack LIFO, matching both native backends.
|
|
295
|
+
const savepoint = "mc_tx_sp";
|
|
296
|
+
db.exec(nested ? `SAVEPOINT ${savepoint}` : `BEGIN ${mode}`);
|
|
297
|
+
try {
|
|
298
|
+
const result = fn.apply(this, args);
|
|
299
|
+
db.exec(nested ? `RELEASE ${savepoint}` : "COMMIT");
|
|
300
|
+
return result;
|
|
301
|
+
} catch (error) {
|
|
302
|
+
if (isInTransaction(db)) {
|
|
303
|
+
if (nested) {
|
|
304
|
+
db.exec(`ROLLBACK TO ${savepoint}`);
|
|
305
|
+
db.exec(`RELEASE ${savepoint}`);
|
|
306
|
+
} else db.exec("ROLLBACK");
|
|
307
|
+
}
|
|
308
|
+
throw error;
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
const defaultTransaction = make(readonly ? "DEFERRED" : "IMMEDIATE");
|
|
312
|
+
const variants = {
|
|
313
|
+
default: defaultTransaction,
|
|
314
|
+
deferred: make("DEFERRED"),
|
|
315
|
+
immediate: make("IMMEDIATE"),
|
|
316
|
+
exclusive: make("EXCLUSIVE"),
|
|
317
|
+
database: db,
|
|
318
|
+
};
|
|
319
|
+
for (const transaction of [
|
|
320
|
+
variants.default,
|
|
321
|
+
variants.deferred,
|
|
322
|
+
variants.immediate,
|
|
323
|
+
variants.exclusive,
|
|
324
|
+
]) {
|
|
325
|
+
Object.assign(transaction, variants);
|
|
326
|
+
}
|
|
327
|
+
return defaultTransaction;
|
|
328
|
+
},
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
function trackSqliteConnection(
|
|
333
|
+
db: BetterSqlite3.Database,
|
|
334
|
+
filename: unknown,
|
|
335
|
+
options: unknown,
|
|
336
|
+
): BetterSqlite3.Database {
|
|
337
|
+
const originalClose = db.close.bind(db) as (...args: unknown[]) => unknown;
|
|
338
|
+
const sequence = nextSqliteConnectionSequence++;
|
|
339
|
+
const metadata = {
|
|
340
|
+
sequence,
|
|
341
|
+
filename:
|
|
342
|
+
typeof filename === "string"
|
|
343
|
+
? filename
|
|
344
|
+
: Buffer.isBuffer(filename)
|
|
345
|
+
? "<buffer>"
|
|
346
|
+
: ":memory:",
|
|
347
|
+
readonly:
|
|
348
|
+
Boolean(options) &&
|
|
349
|
+
typeof options === "object" &&
|
|
350
|
+
((options as { readonly?: unknown }).readonly === true ||
|
|
351
|
+
(options as { readOnly?: unknown }).readOnly === true),
|
|
352
|
+
};
|
|
353
|
+
installTransactionRouting(db, metadata.readonly);
|
|
354
|
+
Object.defineProperty(db, "close", {
|
|
355
|
+
configurable: true,
|
|
356
|
+
value: (...args: unknown[]) => {
|
|
357
|
+
try {
|
|
358
|
+
return originalClose(...args);
|
|
359
|
+
} finally {
|
|
360
|
+
trackedSqliteConnections.delete(sequence);
|
|
361
|
+
}
|
|
362
|
+
},
|
|
363
|
+
});
|
|
364
|
+
trackedSqliteConnections.set(sequence, {
|
|
365
|
+
...metadata,
|
|
366
|
+
reference: new WeakRef(db),
|
|
367
|
+
});
|
|
368
|
+
const prepare = db.prepare.bind(db);
|
|
369
|
+
Object.defineProperty(db, "prepare", {
|
|
370
|
+
configurable: true,
|
|
371
|
+
writable: true,
|
|
372
|
+
value: (sql: string) => ownPreparedStatement(db, prepare(sql)),
|
|
373
|
+
});
|
|
374
|
+
return db;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
const TrackedDatabase = new Proxy(DatabaseImpl, {
|
|
378
|
+
construct(target, args) {
|
|
379
|
+
const db = Reflect.construct(target, args, target) as BetterSqlite3.Database;
|
|
380
|
+
return trackSqliteConnection(db, args[0], args[1]);
|
|
381
|
+
},
|
|
382
|
+
}) as typeof BetterSqlite3;
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Wrap node:sqlite's `DatabaseSync` so it presents the better-sqlite3/bun
|
|
386
|
+
* surface the rest of the codebase calls:
|
|
387
|
+
* - translate the `{ readonly }` constructor option → node:sqlite's `readOnly`
|
|
388
|
+
* Transaction routing is installed for both runtimes by trackSqliteConnection.
|
|
389
|
+
*/
|
|
390
|
+
// biome-ignore lint/suspicious/noExplicitAny: node:sqlite has no shipped types here; the public export is cast to the better-sqlite3 shape.
|
|
391
|
+
function buildNodeSqliteDatabaseClass(DatabaseSync: any): typeof BetterSqlite3 {
|
|
392
|
+
class NodeSqliteDatabase extends DatabaseSync {
|
|
393
|
+
constructor(filename?: string | Buffer, options?: BetterSqlite3.Options) {
|
|
394
|
+
const translated: Record<string, unknown> = { ...options };
|
|
395
|
+
if (options && "readonly" in options) {
|
|
396
|
+
translated.readOnly = (options as { readonly?: boolean }).readonly;
|
|
397
|
+
delete translated.readonly;
|
|
398
|
+
}
|
|
399
|
+
super(typeof filename === "string" ? filename : ":memory:", translated);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Normalize a single ARRAY bind arg to spread positional, matching
|
|
403
|
+
// bun:sqlite. bun's `.run([a,b])` binds positionally; node:sqlite instead
|
|
404
|
+
// reads a lone array as NAMED params with keys "0","1" and throws
|
|
405
|
+
// `Unknown named parameter '0'`. That divergence let an array-form bind
|
|
406
|
+
// (e.g. `.run([x, y])`) silently work on OpenCode/Bun yet break Pi and
|
|
407
|
+
// OpenCode Desktop (both node:sqlite) — issue #151 (/ctx-dream). Wrapping
|
|
408
|
+
// every prepared statement here keeps the two backends' bind surface
|
|
409
|
+
// truly identical so this whole class is impossible regardless of how a
|
|
410
|
+
// call site writes its bind. Named-object binds (`.run({k:v})`), no-arg
|
|
411
|
+
// calls, and already-spread positional args are passed through unchanged;
|
|
412
|
+
// the normalization only triggers on the exact 1-array shape. Overhead
|
|
413
|
+
// measured at ~12ns/call against real node:sqlite (negligible).
|
|
414
|
+
// biome-ignore lint/suspicious/noExplicitAny: node:sqlite StatementSync has no shipped types here.
|
|
415
|
+
prepare(sql: string): any {
|
|
416
|
+
const stmt = super.prepare(sql);
|
|
417
|
+
for (const method of ["run", "get", "all"] as const) {
|
|
418
|
+
const original = stmt[method].bind(stmt);
|
|
419
|
+
stmt[method] = (...args: unknown[]): unknown =>
|
|
420
|
+
args.length === 1 && Array.isArray(args[0])
|
|
421
|
+
? original(...args[0])
|
|
422
|
+
: original(...args);
|
|
423
|
+
}
|
|
424
|
+
return stmt;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
return NodeSqliteDatabase as unknown as typeof BetterSqlite3;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
export const Database: typeof BetterSqlite3 = TrackedDatabase;
|
|
432
|
+
|
|
433
|
+
function pragmaValue(db: BetterSqlite3.Database, name: string): unknown {
|
|
434
|
+
const row = db.prepare(`PRAGMA ${name}`).get() as Record<string, unknown> | undefined;
|
|
435
|
+
if (!row) return undefined;
|
|
436
|
+
return row[name] ?? Object.values(row)[0];
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
function pragmaNumber(db: BetterSqlite3.Database, name: string): number | null {
|
|
440
|
+
try {
|
|
441
|
+
const value = pragmaValue(db, name);
|
|
442
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
443
|
+
} catch {
|
|
444
|
+
return null;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
function pragmaString(db: BetterSqlite3.Database, name: string): string | null {
|
|
449
|
+
try {
|
|
450
|
+
const value = pragmaValue(db, name);
|
|
451
|
+
return typeof value === "string" ? value : null;
|
|
452
|
+
} catch {
|
|
453
|
+
return null;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
function sqliteSidecarBytes(filename: string, suffix: "-wal" | "-shm"): number | null {
|
|
458
|
+
if (filename === ":memory:" || filename === "<buffer>") return 0;
|
|
459
|
+
try {
|
|
460
|
+
return statSync(`${filename}${suffix}`).size;
|
|
461
|
+
} catch (error) {
|
|
462
|
+
return (error as NodeJS.ErrnoException).code === "ENOENT" ? 0 : null;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
function fts5TableCount(db: BetterSqlite3.Database): number | null {
|
|
467
|
+
try {
|
|
468
|
+
const row = db
|
|
469
|
+
.prepare(
|
|
470
|
+
"SELECT COUNT(*) AS count FROM sqlite_master WHERE type = 'table' AND sql LIKE '%USING fts5%'",
|
|
471
|
+
)
|
|
472
|
+
.get() as { count?: unknown } | undefined;
|
|
473
|
+
return typeof row?.count === "number" ? row.count : null;
|
|
474
|
+
} catch {
|
|
475
|
+
return null;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* Read the SQLite memory bounds that Bun/node:sqlite expose without native FFI.
|
|
481
|
+
* SQLite's sqlite3_status()/sqlite3_db_status() counters are not surfaced by
|
|
482
|
+
* either runtime, so cache and mmap values are configured upper bounds rather
|
|
483
|
+
* than resident-byte measurements.
|
|
484
|
+
*/
|
|
485
|
+
export function getSqliteMemoryStats(): SqliteMemoryStats {
|
|
486
|
+
const connections: SqliteConnectionMemoryStats[] = [];
|
|
487
|
+
for (const [sequence, tracked] of trackedSqliteConnections) {
|
|
488
|
+
const db = tracked.reference.deref();
|
|
489
|
+
if (!db) {
|
|
490
|
+
trackedSqliteConnections.delete(sequence);
|
|
491
|
+
continue;
|
|
492
|
+
}
|
|
493
|
+
const pageSize = pragmaNumber(db, "page_size");
|
|
494
|
+
const cacheSize = pragmaNumber(db, "cache_size");
|
|
495
|
+
const cacheSizeUnit = cacheSize === null ? null : cacheSize < 0 ? "kib" : "pages";
|
|
496
|
+
const cacheUpperBoundBytes =
|
|
497
|
+
cacheSize === null
|
|
498
|
+
? null
|
|
499
|
+
: cacheSize < 0
|
|
500
|
+
? Math.abs(cacheSize) * 1024
|
|
501
|
+
: pageSize === null
|
|
502
|
+
? null
|
|
503
|
+
: cacheSize * pageSize;
|
|
504
|
+
connections.push({
|
|
505
|
+
sequence: tracked.sequence,
|
|
506
|
+
filename: tracked.filename,
|
|
507
|
+
readonly: tracked.readonly,
|
|
508
|
+
pageSize,
|
|
509
|
+
pageCount: pragmaNumber(db, "page_count"),
|
|
510
|
+
freelistCount: pragmaNumber(db, "freelist_count"),
|
|
511
|
+
cacheSize,
|
|
512
|
+
cacheSizeUnit,
|
|
513
|
+
cacheUpperBoundBytes,
|
|
514
|
+
mmapSizeBytes: pragmaNumber(db, "mmap_size"),
|
|
515
|
+
walFileBytes: sqliteSidecarBytes(tracked.filename, "-wal"),
|
|
516
|
+
shmFileBytes: sqliteSidecarBytes(tracked.filename, "-shm"),
|
|
517
|
+
fts5TableCount: fts5TableCount(db),
|
|
518
|
+
journalMode: pragmaString(db, "journal_mode"),
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
const sumKnown = (select: (connection: SqliteConnectionMemoryStats) => number | null): number =>
|
|
522
|
+
connections.reduce((sum, connection) => sum + (select(connection) ?? 0), 0);
|
|
523
|
+
return {
|
|
524
|
+
connectionCount: connections.length,
|
|
525
|
+
cacheUpperBoundBytes: sumKnown((connection) => connection.cacheUpperBoundBytes),
|
|
526
|
+
mmapUpperBoundBytes: sumKnown((connection) => connection.mmapSizeBytes),
|
|
527
|
+
walFileBytes: sumKnown((connection) => connection.walFileBytes),
|
|
528
|
+
shmFileBytes: sumKnown((connection) => connection.shmFileBytes),
|
|
529
|
+
sqliteStatusApi: "unavailable",
|
|
530
|
+
connections,
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/** Instance type alias used by helpers and storage modules. */
|
|
535
|
+
export type Database = BetterSqlite3.Database;
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* Statement instance type used for WeakMap caches throughout the codebase.
|
|
539
|
+
*
|
|
540
|
+
* We deliberately use the variadic Statement<unknown[], unknown> shape rather
|
|
541
|
+
* than `ReturnType<Database["prepare"]>` because the latter resolves through
|
|
542
|
+
* a conditional return type in @types/better-sqlite3 that confuses TypeScript
|
|
543
|
+
* about how many arguments .run/.get/.all accept. With this explicit type,
|
|
544
|
+
* cached statements accept any number of bind args (matching bun:sqlite's
|
|
545
|
+
* historical behavior in this codebase).
|
|
546
|
+
*/
|
|
547
|
+
export type Statement = BetterSqlite3.Statement<unknown[], unknown>;
|
|
548
|
+
|
|
549
|
+
type FinalizableStatement = Statement & { finalize(): void };
|
|
550
|
+
interface StatementOwner {
|
|
551
|
+
references: Set<WeakRef<FinalizableStatement>>;
|
|
552
|
+
registered: WeakSet<FinalizableStatement>;
|
|
553
|
+
/** Set size at which collected references are next swept out. */
|
|
554
|
+
pruneAt: number;
|
|
555
|
+
}
|
|
556
|
+
const statementOwners = new WeakMap<Database, StatementOwner>();
|
|
557
|
+
const FIRST_PRUNE_AT = 256;
|
|
558
|
+
|
|
559
|
+
function ownPreparedStatement(db: Database, statement: Statement): Statement {
|
|
560
|
+
const finalizable = statement as FinalizableStatement;
|
|
561
|
+
// Node finalizes its statements on close and exposes no finalize() method.
|
|
562
|
+
if (typeof finalizable.finalize !== "function") return statement;
|
|
563
|
+
let owner = statementOwners.get(db);
|
|
564
|
+
if (!owner) {
|
|
565
|
+
const references = new Set<WeakRef<FinalizableStatement>>();
|
|
566
|
+
owner = { references, registered: new WeakSet(), pruneAt: FIRST_PRUNE_AT };
|
|
567
|
+
statementOwners.set(db, owner);
|
|
568
|
+
const close = db.close.bind(db) as (...args: unknown[]) => unknown;
|
|
569
|
+
Object.defineProperty(db, "close", {
|
|
570
|
+
configurable: true,
|
|
571
|
+
writable: true,
|
|
572
|
+
value: (...args: unknown[]) => {
|
|
573
|
+
let failure: unknown;
|
|
574
|
+
for (const reference of references) {
|
|
575
|
+
try {
|
|
576
|
+
reference.deref()?.finalize();
|
|
577
|
+
} catch (error) {
|
|
578
|
+
failure ??= error;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
references.clear();
|
|
582
|
+
const result = close(...args);
|
|
583
|
+
if (failure) throw failure;
|
|
584
|
+
return result;
|
|
585
|
+
},
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
if (!owner.registered.has(finalizable)) {
|
|
589
|
+
// No FinalizationRegistry: its callbacks run at GC time, where a throw
|
|
590
|
+
// is uncaught (seen in Bun's parallel test runner). Sweep references to
|
|
591
|
+
// collected statements whenever the set doubles instead, so one-shot
|
|
592
|
+
// statements in a long-running host stay bounded.
|
|
593
|
+
if (owner.references.size >= owner.pruneAt) {
|
|
594
|
+
for (const reference of owner.references) {
|
|
595
|
+
if (reference.deref() === undefined) owner.references.delete(reference);
|
|
596
|
+
}
|
|
597
|
+
owner.pruneAt = Math.max(FIRST_PRUNE_AT, owner.references.size * 2);
|
|
598
|
+
}
|
|
599
|
+
owner.references.add(new WeakRef(finalizable));
|
|
600
|
+
owner.registered.add(finalizable);
|
|
601
|
+
}
|
|
602
|
+
return statement;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* Cached statements must be finalized before closing their connection. Bun's
|
|
607
|
+
* prepare() leaves SQLite's native close deferred until all statements finish,
|
|
608
|
+
* even after the JS Database reports closed. Delayed WAL checkpoints can then
|
|
609
|
+
* overwrite a restored database if a caller reuses the file in the meantime.
|
|
610
|
+
* The shared Database owns every preparation; use this for caches that also
|
|
611
|
+
* accept direct bun:sqlite handles. Weak references avoid retaining one-shot
|
|
612
|
+
* statements for the lifetime of a long-running host.
|
|
613
|
+
*/
|
|
614
|
+
export function prepareCachedStatement(db: Database, sql: string): Statement {
|
|
615
|
+
return ownPreparedStatement(db, db.prepare(sql));
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
const privilegeDepth = new WeakMap<Database, number>();
|
|
619
|
+
const transformPassScope = new AsyncLocalStorage<
|
|
620
|
+
{ active: boolean; remainingWaitMs: number } | undefined
|
|
621
|
+
>();
|
|
622
|
+
const admissionScope = new AsyncLocalStorage<boolean>();
|
|
623
|
+
const backgroundWriterScope = new AsyncLocalStorage<boolean>();
|
|
624
|
+
|
|
625
|
+
/** Opt in only a writer that can safely defer its work after a busy acquisition. */
|
|
626
|
+
export function withSqliteBackgroundWriter<T>(operation: () => T): T {
|
|
627
|
+
return backgroundWriterScope.run(true, operation);
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/** Only an awaited foreground transform may spend the extra acquisition budget.
|
|
631
|
+
* The mutable lease also expires for detached descendants when that pass ends. */
|
|
632
|
+
export function withSqliteTransformPass<T>(operation: () => T): T {
|
|
633
|
+
const existing = transformPassScope.getStore();
|
|
634
|
+
if (existing?.active) return operation();
|
|
635
|
+
const lease = { active: true, remainingWaitMs: FOREGROUND_IN_PASS_BUSY_TIMEOUT_MS };
|
|
636
|
+
return transformPassScope.run(lease, () => {
|
|
637
|
+
try {
|
|
638
|
+
const result = operation();
|
|
639
|
+
if (result && typeof (result as { then?: unknown }).then === "function") {
|
|
640
|
+
return Promise.resolve(result).finally(() => {
|
|
641
|
+
lease.active = false;
|
|
642
|
+
}) as T;
|
|
643
|
+
}
|
|
644
|
+
lease.active = false;
|
|
645
|
+
return result;
|
|
646
|
+
} catch (error) {
|
|
647
|
+
lease.active = false;
|
|
648
|
+
throw error;
|
|
649
|
+
}
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/** Start detached maintenance work without borrowing a foreground pass's budget. */
|
|
654
|
+
export function withoutSqliteTransformPass<T>(operation: () => T): T {
|
|
655
|
+
return transformPassScope.run(undefined, operation);
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
/** Bun names SQLite codes; node:sqlite exposes the numeric (possibly extended) errcode. */
|
|
659
|
+
export function isTransientSqliteError(error: unknown): boolean {
|
|
660
|
+
if (!error || typeof error !== "object") return false;
|
|
661
|
+
const value = error as { code?: unknown; errcode?: unknown };
|
|
662
|
+
return (
|
|
663
|
+
(typeof value.code === "string" && /^(SQLITE_BUSY|SQLITE_LOCKED)(_|$)/.test(value.code)) ||
|
|
664
|
+
(typeof value.errcode === "number" && [5, 6].includes(value.errcode & 0xff))
|
|
665
|
+
);
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
export class SqliteAcquisitionBusyError extends Error {
|
|
669
|
+
readonly code = "SQLITE_BUSY";
|
|
670
|
+
readonly stage: string;
|
|
671
|
+
constructor(cause: unknown, stage = "BEGIN IMMEDIATE") {
|
|
672
|
+
super("SQLite writer acquisition remained busy", { cause });
|
|
673
|
+
this.name = "SqliteAcquisitionBusyError";
|
|
674
|
+
this.stage = stage;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
const SHORT_BUSY_TIMEOUT_MS = 25;
|
|
679
|
+
const FOREGROUND_IN_PASS_BUSY_TIMEOUT_MS = 250;
|
|
680
|
+
const FOREGROUND_ACQUISITION_BUDGET_MS = 16_500;
|
|
681
|
+
/** Waiting this long for the writer lock, or holding it this long, is logged. */
|
|
682
|
+
const SLOW_WRITER_LOG_MS = 250;
|
|
683
|
+
const WRITER_TRANSACTION_END = /^\s*(?:COMMIT|END|ROLLBACK)(?:\s+TRANSACTION)?\s*;?\s*$/i;
|
|
684
|
+
|
|
685
|
+
type WriterLane = "foreground" | "background";
|
|
686
|
+
|
|
687
|
+
/**
|
|
688
|
+
* One attempt of an outer acquisition loop (`beginSqliteWriterAsync`,
|
|
689
|
+
* `withAsyncPrivilegedWriter`). It names the writer and remembers when the loop
|
|
690
|
+
* started, so the time spent in earlier busy attempts and the sleeps between
|
|
691
|
+
* them counts as waiting for the lock. Only the first BEGIN issued inside the
|
|
692
|
+
* attempt may claim it; a later BEGIN from detached work started inside the
|
|
693
|
+
* same async scope is timed on its own.
|
|
694
|
+
*/
|
|
695
|
+
interface WriterAcquisition {
|
|
696
|
+
site: string;
|
|
697
|
+
lane: WriterLane;
|
|
698
|
+
startedAt: number;
|
|
699
|
+
attempts: number;
|
|
700
|
+
claimed: boolean;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
/** A write transaction whose BEGIN went through `acquireShort` and has not ended yet. */
|
|
704
|
+
interface OpenWriterTransaction {
|
|
705
|
+
site: string;
|
|
706
|
+
lane: WriterLane;
|
|
707
|
+
acquireMs: number;
|
|
708
|
+
attempts: number;
|
|
709
|
+
acquiredAt: number;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
const writerAcquisitionScope = new AsyncLocalStorage<WriterAcquisition | undefined>();
|
|
713
|
+
const openWriterTransactions = new WeakMap<Database, OpenWriterTransaction>();
|
|
714
|
+
|
|
715
|
+
function foregroundWaitLease() {
|
|
716
|
+
const lease = transformPassScope.getStore();
|
|
717
|
+
return lease?.active && !admissionScope.getStore() && !backgroundWriterScope.getStore()
|
|
718
|
+
? lease
|
|
719
|
+
: undefined;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
/** Bound implicit writer admission too, including prepared INSERT OR IGNORE and
|
|
723
|
+
* writes with RETURNING. Charge successful execution time conservatively: the
|
|
724
|
+
* native API cannot separate lock waiting from statement execution. Exhaustion
|
|
725
|
+
* switches to zero-wait acquisition, not a refusal when the writer is free. */
|
|
726
|
+
function withAutocommitTimeout<T>(db: Database, operation: () => T): T {
|
|
727
|
+
const lease = foregroundWaitLease();
|
|
728
|
+
if (isInTransaction(db) || (!lease && !backgroundWriterScope.getStore())) return operation();
|
|
729
|
+
const previous = pragmaNumber(db, "busy_timeout");
|
|
730
|
+
db.exec(
|
|
731
|
+
`PRAGMA busy_timeout=${lease ? Math.floor(lease.remainingWaitMs) : SHORT_BUSY_TIMEOUT_MS}`,
|
|
732
|
+
);
|
|
733
|
+
const started = performance.now();
|
|
734
|
+
try {
|
|
735
|
+
return operation();
|
|
736
|
+
} catch (error) {
|
|
737
|
+
if (lease && isTransientSqliteError(error))
|
|
738
|
+
throw new SqliteAcquisitionBusyError(error, "autocommit");
|
|
739
|
+
throw error;
|
|
740
|
+
} finally {
|
|
741
|
+
if (lease)
|
|
742
|
+
lease.remainingWaitMs = Math.max(
|
|
743
|
+
0,
|
|
744
|
+
lease.remainingWaitMs - (performance.now() - started),
|
|
745
|
+
);
|
|
746
|
+
if (previous !== null) db.exec(`PRAGMA busy_timeout=${previous}`);
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
/** The connection is never handed back to another caller with a shortened timeout. */
|
|
751
|
+
function acquireShort(db: Database, acquire: () => unknown, site: string): void {
|
|
752
|
+
const started = performance.now();
|
|
753
|
+
const previous = pragmaNumber(db, "busy_timeout");
|
|
754
|
+
const outer = writerAcquisitionScope.getStore();
|
|
755
|
+
const owner = outer && !outer.claimed ? outer : undefined;
|
|
756
|
+
if (owner) owner.claimed = true;
|
|
757
|
+
const writerSite = owner?.site ?? site;
|
|
758
|
+
const lane: WriterLane =
|
|
759
|
+
owner?.lane ?? (transformPassScope.getStore()?.active ? "foreground" : "background");
|
|
760
|
+
let acquiredAt: number | undefined;
|
|
761
|
+
try {
|
|
762
|
+
// Async admission retries after yielding, so each of its BEGIN attempts
|
|
763
|
+
// stays short. An ordinary BEGIN inside a transform pass cannot yield;
|
|
764
|
+
// give that single attempt enough time for a brief writer to finish.
|
|
765
|
+
const lease = foregroundWaitLease();
|
|
766
|
+
const timeout = lease ? Math.floor(lease.remainingWaitMs) : SHORT_BUSY_TIMEOUT_MS;
|
|
767
|
+
db.exec(`PRAGMA busy_timeout=${timeout}`);
|
|
768
|
+
acquire();
|
|
769
|
+
acquiredAt = performance.now();
|
|
770
|
+
} catch (error) {
|
|
771
|
+
if (transformPassScope.getStore()?.active && isTransientSqliteError(error))
|
|
772
|
+
throw new SqliteAcquisitionBusyError(error, site);
|
|
773
|
+
throw error;
|
|
774
|
+
} finally {
|
|
775
|
+
const attemptMs = (acquiredAt ?? performance.now()) - started;
|
|
776
|
+
const lease = foregroundWaitLease();
|
|
777
|
+
if (lease) lease.remainingWaitMs = Math.max(0, lease.remainingWaitMs - attemptMs);
|
|
778
|
+
if (previous !== null) db.exec(`PRAGMA busy_timeout=${previous}`);
|
|
779
|
+
if (acquiredAt !== undefined) {
|
|
780
|
+
// Reported when the transaction ends, together with how long it held
|
|
781
|
+
// the lock (see endWriterTransaction).
|
|
782
|
+
openWriterTransactions.set(db, {
|
|
783
|
+
site: writerSite,
|
|
784
|
+
lane,
|
|
785
|
+
acquireMs: acquiredAt - (owner?.startedAt ?? started),
|
|
786
|
+
attempts: owner?.attempts ?? 1,
|
|
787
|
+
acquiredAt,
|
|
788
|
+
});
|
|
789
|
+
} else if (attemptMs >= SLOW_WRITER_LOG_MS) {
|
|
790
|
+
reportSqliteDiagnostic(
|
|
791
|
+
`sqlite writer site=${writerSite} lane=${lane} acquire_ms=${Math.round(attemptMs)} attempts=${owner?.attempts ?? 1} outcome=busy`,
|
|
792
|
+
);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
/**
|
|
798
|
+
* Run the COMMIT, END or ROLLBACK that closes a transaction opened through
|
|
799
|
+
* `acquireShort`, then report how long the writer waited for the lock
|
|
800
|
+
* (`acquire_ms`) and how long it then held it (`hold_ms`) when either crosses
|
|
801
|
+
* the threshold. A long hold blocks every other process's writer, so it is
|
|
802
|
+
* worth seeing even when the lock itself came quickly.
|
|
803
|
+
*/
|
|
804
|
+
function endWriterTransaction(db: Database, end: () => unknown, sql: string): unknown {
|
|
805
|
+
let ended = false;
|
|
806
|
+
try {
|
|
807
|
+
const result = end();
|
|
808
|
+
ended = true;
|
|
809
|
+
return result;
|
|
810
|
+
} finally {
|
|
811
|
+
const open = openWriterTransactions.get(db);
|
|
812
|
+
// A COMMIT that failed with the transaction still open has not ended it.
|
|
813
|
+
if (open && !isInTransaction(db)) {
|
|
814
|
+
openWriterTransactions.delete(db);
|
|
815
|
+
const holdMs = performance.now() - open.acquiredAt;
|
|
816
|
+
if (open.acquireMs >= SLOW_WRITER_LOG_MS || holdMs >= SLOW_WRITER_LOG_MS) {
|
|
817
|
+
const outcome = /^\s*ROLLBACK/i.test(sql)
|
|
818
|
+
? "rolled_back"
|
|
819
|
+
: ended
|
|
820
|
+
? "committed"
|
|
821
|
+
: "failed";
|
|
822
|
+
reportSqliteDiagnostic(
|
|
823
|
+
`sqlite writer site=${open.site} lane=${open.lane} acquire_ms=${Math.round(open.acquireMs)} hold_ms=${Math.round(holdMs)} attempts=${open.attempts} outcome=${outcome}`,
|
|
824
|
+
);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
/** Begin an immediate transaction with bounded asynchronous retries on writer contention.
|
|
831
|
+
* Callers must recheck any lease or source snapshot after this function returns.
|
|
832
|
+
* Resolves with the `performance.now()` time at which BEGIN IMMEDIATE succeeded,
|
|
833
|
+
* so a caller timing its transaction measures the hold, not the wait for the lock. */
|
|
834
|
+
export async function beginSqliteWriterAsync(db: Database, site: string): Promise<number> {
|
|
835
|
+
const started = performance.now();
|
|
836
|
+
let attempts = 0;
|
|
837
|
+
for (;;) {
|
|
838
|
+
attempts++;
|
|
839
|
+
try {
|
|
840
|
+
const acquisition: WriterAcquisition = {
|
|
841
|
+
site,
|
|
842
|
+
lane: "background",
|
|
843
|
+
startedAt: started,
|
|
844
|
+
attempts,
|
|
845
|
+
claimed: false,
|
|
846
|
+
};
|
|
847
|
+
writerAcquisitionScope.run(acquisition, () =>
|
|
848
|
+
withSqliteBackgroundWriter(() => db.exec("BEGIN IMMEDIATE")),
|
|
849
|
+
);
|
|
850
|
+
return performance.now();
|
|
851
|
+
} catch (error) {
|
|
852
|
+
if (!isTransientSqliteError(error)) throw error;
|
|
853
|
+
const elapsed = performance.now() - started;
|
|
854
|
+
if (elapsed >= FOREGROUND_ACQUISITION_BUDGET_MS) {
|
|
855
|
+
reportSqliteDiagnostic(
|
|
856
|
+
`sqlite writer site=${site} lane=background acquire_ms=${Math.round(elapsed)} attempts=${attempts} outcome=busy`,
|
|
857
|
+
);
|
|
858
|
+
throw error;
|
|
859
|
+
}
|
|
860
|
+
await new Promise<void>((resolve) =>
|
|
861
|
+
setTimeout(
|
|
862
|
+
resolve,
|
|
863
|
+
Math.min(
|
|
864
|
+
attempts === 1 ? 500 : 1000,
|
|
865
|
+
FOREGROUND_ACQUISITION_BUDGET_MS - elapsed,
|
|
866
|
+
),
|
|
867
|
+
),
|
|
868
|
+
);
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
/** Retry admission before any turn work, yielding between short lock attempts. */
|
|
874
|
+
export async function withAsyncPrivilegedWriter<T>(db: Database, operation: () => T): Promise<T> {
|
|
875
|
+
const started = performance.now();
|
|
876
|
+
let attempts = 0;
|
|
877
|
+
for (;;) {
|
|
878
|
+
attempts++;
|
|
879
|
+
try {
|
|
880
|
+
const acquisition: WriterAcquisition = {
|
|
881
|
+
site: "privileged_writer",
|
|
882
|
+
lane: "foreground",
|
|
883
|
+
startedAt: started,
|
|
884
|
+
attempts,
|
|
885
|
+
claimed: false,
|
|
886
|
+
};
|
|
887
|
+
// The acquisition and hold of this transaction are reported when it
|
|
888
|
+
// commits or rolls back (see endWriterTransaction).
|
|
889
|
+
return admissionScope.run(true, () =>
|
|
890
|
+
withSqliteTransformPass(() =>
|
|
891
|
+
writerAcquisitionScope.run(acquisition, () =>
|
|
892
|
+
withPrivilegedWriter(db, operation),
|
|
893
|
+
),
|
|
894
|
+
),
|
|
895
|
+
);
|
|
896
|
+
} catch (error) {
|
|
897
|
+
// A callback failure can occur after writes; only retry a failed BEGIN.
|
|
898
|
+
if (!(error instanceof SqliteAcquisitionBusyError)) throw error;
|
|
899
|
+
const elapsed = performance.now() - started;
|
|
900
|
+
if (elapsed >= FOREGROUND_ACQUISITION_BUDGET_MS) {
|
|
901
|
+
reportSqliteDiagnostic(
|
|
902
|
+
`sqlite writer site=privileged_writer lane=foreground acquire_ms=${Math.round(elapsed)} attempts=${attempts} outcome=busy`,
|
|
903
|
+
);
|
|
904
|
+
throw error;
|
|
905
|
+
}
|
|
906
|
+
await new Promise<void>((resolve) =>
|
|
907
|
+
setTimeout(
|
|
908
|
+
resolve,
|
|
909
|
+
Math.min(
|
|
910
|
+
attempts === 1 ? 500 : 1000,
|
|
911
|
+
FOREGROUND_ACQUISITION_BUDGET_MS - elapsed,
|
|
912
|
+
),
|
|
913
|
+
),
|
|
914
|
+
);
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
function isInTransaction(db: Database): boolean {
|
|
920
|
+
const candidate = db as unknown as { inTransaction?: unknown; isTransaction?: unknown };
|
|
921
|
+
return candidate.inTransaction === true || candidate.isTransaction === true;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
/**
|
|
925
|
+
* Run a storage operation with the managed-write privilege enabled.
|
|
926
|
+
*
|
|
927
|
+
* The privilege is recorded in the durable `context_privilege_state` table (row
|
|
928
|
+
* id=1, enabled=1) so the guard triggers — which reference that table, never a
|
|
929
|
+
* connection-local UDF — stand down for this connection's writes. The write happens
|
|
930
|
+
* inside a BEGIN IMMEDIATE transaction (single writer), and enabled is cleared back
|
|
931
|
+
* to 0 before commit, so no second connection can ever observe enabled=1. Nesting is
|
|
932
|
+
* tracked by privilegeDepth (outside SQLite): only the outermost scope clears the
|
|
933
|
+
* flag, so an inner scope releasing does not drop permission out from under its caller.
|
|
934
|
+
*/
|
|
935
|
+
export function withPrivilegedWriter<T>(db: Database, operation: () => T): T {
|
|
936
|
+
const previousDepth = privilegeDepth.get(db) ?? 0;
|
|
937
|
+
const nested = isInTransaction(db);
|
|
938
|
+
const savepoint = "mc_privilege_scope";
|
|
939
|
+
// Timed from the moment the lock is held, so a slow-write report measures
|
|
940
|
+
// the hold and not the wait for BEGIN IMMEDIATE.
|
|
941
|
+
let transactionStartedAt: number | undefined;
|
|
942
|
+
if (nested) {
|
|
943
|
+
db.exec(`SAVEPOINT ${savepoint}`);
|
|
944
|
+
} else {
|
|
945
|
+
try {
|
|
946
|
+
db.exec("BEGIN IMMEDIATE");
|
|
947
|
+
} catch (error) {
|
|
948
|
+
if (transformPassScope.getStore()?.active && isTransientSqliteError(error))
|
|
949
|
+
throw new SqliteAcquisitionBusyError(error);
|
|
950
|
+
throw error;
|
|
951
|
+
}
|
|
952
|
+
transactionStartedAt = performance.now();
|
|
953
|
+
}
|
|
954
|
+
privilegeDepth.set(db, previousDepth + 1);
|
|
955
|
+
try {
|
|
956
|
+
db.prepare(
|
|
957
|
+
"INSERT INTO context_privilege_state(id, enabled) VALUES (1, 1) ON CONFLICT(id) DO UPDATE SET enabled = 1",
|
|
958
|
+
).run();
|
|
959
|
+
const result = operation();
|
|
960
|
+
if (previousDepth === 0) {
|
|
961
|
+
db.prepare("UPDATE context_privilege_state SET enabled = 0 WHERE id = 1").run();
|
|
962
|
+
}
|
|
963
|
+
if (nested) {
|
|
964
|
+
db.exec(`RELEASE ${savepoint}`);
|
|
965
|
+
} else {
|
|
966
|
+
db.exec("COMMIT");
|
|
967
|
+
if (transactionStartedAt !== undefined) {
|
|
968
|
+
reportSlowPrivilegedWrite?.("privileged_writer", transactionStartedAt);
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
if (previousDepth > 0) privilegeDepth.set(db, previousDepth);
|
|
972
|
+
else privilegeDepth.delete(db);
|
|
973
|
+
return result;
|
|
974
|
+
} catch (error) {
|
|
975
|
+
try {
|
|
976
|
+
if (nested) {
|
|
977
|
+
db.exec(`ROLLBACK TO ${savepoint}`);
|
|
978
|
+
db.exec(`RELEASE ${savepoint}`);
|
|
979
|
+
} else {
|
|
980
|
+
db.exec("ROLLBACK");
|
|
981
|
+
}
|
|
982
|
+
} finally {
|
|
983
|
+
if (previousDepth > 0) privilegeDepth.set(db, previousDepth);
|
|
984
|
+
else privilegeDepth.delete(db);
|
|
985
|
+
}
|
|
986
|
+
throw error;
|
|
987
|
+
}
|
|
988
|
+
}
|