@cortexkit/opencode-magic-context 0.44.3 → 0.45.0
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/hidden-agent-registrations.d.ts +3 -2
- package/dist/agents/hidden-agent-registrations.d.ts.map +1 -1
- package/dist/agents/magic-context-prompt.d.ts +1 -0
- package/dist/agents/magic-context-prompt.d.ts.map +1 -1
- package/dist/agents/permissions.d.ts +8 -28
- package/dist/agents/permissions.d.ts.map +1 -1
- package/dist/{announcement-n8hs7kjw.js → announcement-f75t58v9.js} +4 -2
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/project-security.d.ts +48 -0
- package/dist/config/project-security.d.ts.map +1 -1
- package/dist/config/raw-loader.d.ts.map +1 -1
- package/dist/config/schema/magic-context.d.ts +10 -7
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/{conflict-warning-hook-hmpzxep6.js → conflict-warning-hook-5yrz2r24.js} +10 -6
- package/dist/{derive-budgets-vjmvh6pz.js → derive-budgets-a63zsm5c.js} +4 -4
- package/dist/embedding-worker.js +49 -0
- package/dist/emscripten-module-0g8f45e6.js +602 -0
- package/dist/emscripten-module-0pekdjxz.js +1532 -0
- package/dist/emscripten-module-e67xwsp3.js +503 -0
- package/dist/emscripten-module-pj1vyb44.js +4559 -0
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts +23 -3
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-embedding.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-storage.d.ts +14 -3
- package/dist/features/magic-context/compartment-storage.d.ts.map +1 -1
- package/dist/features/magic-context/context-store-uuid.d.ts +7 -0
- package/dist/features/magic-context/context-store-uuid.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/classify.d.ts +1 -3
- package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/cron.d.ts +5 -4
- package/dist/features/magic-context/dreamer/cron.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/docs-proposals.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/expire-memories.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/idle-schedule-prune.d.ts +24 -0
- package/dist/features/magic-context/dreamer/idle-schedule-prune.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/manual-summary.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/map-memories.d.ts +5 -5
- package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/module-apply.d.ts +4 -25
- package/dist/features/magic-context/dreamer/module-apply.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/retrospective-learnings.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts +5 -1
- package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/storage-task-schedule.d.ts +12 -5
- package/dist/features/magic-context/dreamer/storage-task-schedule.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-executor.d.ts +6 -0
- package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-gates.d.ts +34 -0
- package/dist/features/magic-context/dreamer/task-gates.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-prompts.d.ts +1 -1
- package/dist/features/magic-context/dreamer/task-prompts.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-registry.d.ts +7 -5
- package/dist/features/magic-context/dreamer/task-registry.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts +10 -3
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/token-budget.d.ts +3 -0
- package/dist/features/magic-context/dreamer/token-budget.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify.d.ts +2 -2
- package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/git-log-reader.d.ts +11 -2
- package/dist/features/magic-context/git-commits/git-log-reader.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/indexer.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/search-git-commits.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/storage-git-commits.d.ts +2 -0
- package/dist/features/magic-context/git-commits/storage-git-commits.d.ts.map +1 -1
- package/dist/features/magic-context/legacy-authority-fixture.test-support.d.ts +6 -0
- package/dist/features/magic-context/legacy-authority-fixture.test-support.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/embedding-backfill.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-local.d.ts +8 -0
- package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-openai.d.ts +1 -0
- package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-worker-client.d.ts +27 -0
- package/dist/features/magic-context/memory/embedding-worker-client.d.ts.map +1 -0
- package/dist/features/magic-context/memory/embedding-worker.d.ts +2 -0
- package/dist/features/magic-context/memory/embedding-worker.d.ts.map +1 -0
- package/dist/features/magic-context/memory/embedding-worker.fixture.d.ts +2 -0
- package/dist/features/magic-context/memory/embedding-worker.fixture.d.ts.map +1 -0
- package/dist/features/magic-context/memory/memory-selection.d.ts.map +1 -1
- package/dist/features/magic-context/memory/project-identity-cache.d.ts +4 -3
- package/dist/features/magic-context/memory/project-identity-cache.d.ts.map +1 -1
- package/dist/features/magic-context/memory/project-identity.d.ts +5 -4
- package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
- package/dist/features/magic-context/memory/storage-memory-fts.d.ts.map +1 -1
- package/dist/features/magic-context/memory/visibility.d.ts +1 -1
- package/dist/features/magic-context/memory/visibility.d.ts.map +1 -1
- package/dist/features/magic-context/message-fts-rowid-map.d.ts +14 -1
- package/dist/features/magic-context/message-fts-rowid-map.d.ts.map +1 -1
- 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.d.ts +1 -7
- package/dist/features/magic-context/message-index.d.ts.map +1 -1
- package/dist/features/magic-context/message-time-backfill.d.ts.map +1 -1
- package/dist/features/magic-context/migration-v94-write-split.d.ts +62 -0
- package/dist/features/magic-context/migration-v94-write-split.d.ts.map +1 -0
- package/dist/features/magic-context/migration-worker-client.d.ts +23 -0
- package/dist/features/magic-context/migration-worker-client.d.ts.map +1 -0
- package/dist/features/magic-context/migration-worker-protocol.d.ts +30 -0
- package/dist/features/magic-context/migration-worker-protocol.d.ts.map +1 -0
- package/dist/features/magic-context/migration-worker.d.ts +2 -0
- package/dist/features/magic-context/migration-worker.d.ts.map +1 -0
- package/dist/features/magic-context/migrations.d.ts +7 -0
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/mural/render-mural.d.ts +24 -2
- package/dist/features/magic-context/mural/render-mural.d.ts.map +1 -1
- package/dist/features/magic-context/mural/render-trigger.d.ts +1 -1
- package/dist/features/magic-context/mural/render-trigger.d.ts.map +1 -1
- package/dist/features/magic-context/overflow-detection.d.ts +18 -7
- package/dist/features/magic-context/overflow-detection.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts +2 -0
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/range-parser.d.ts +2 -3
- package/dist/features/magic-context/range-parser.d.ts.map +1 -1
- package/dist/features/magic-context/resolve-subagent-fallback.d.ts +2 -0
- package/dist/features/magic-context/resolve-subagent-fallback.d.ts.map +1 -1
- package/dist/features/magic-context/scheduler.d.ts +2 -0
- package/dist/features/magic-context/scheduler.d.ts.map +1 -1
- package/dist/features/magic-context/search.d.ts +7 -0
- package/dist/features/magic-context/search.d.ts.map +1 -1
- package/dist/features/magic-context/session-project-backfill.d.ts.map +1 -1
- package/dist/features/magic-context/session-project-storage.d.ts +10 -1
- package/dist/features/magic-context/session-project-storage.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/compiler-prompt.d.ts +1 -1
- package/dist/features/magic-context/smart-notes/compiler-prompt.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/compiler.d.ts +4 -0
- package/dist/features/magic-context/smart-notes/compiler.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/runner.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts +2 -0
- package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/ssrf-guard.d.ts +10 -8
- package/dist/features/magic-context/smart-notes/ssrf-guard.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/storage.d.ts +2 -2
- package/dist/features/magic-context/smart-notes/storage.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/types.d.ts +7 -2
- package/dist/features/magic-context/smart-notes/types.d.ts.map +1 -1
- 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.map +1 -1
- package/dist/features/magic-context/storage-compartment-history-version.d.ts +4 -0
- package/dist/features/magic-context/storage-compartment-history-version.d.ts.map +1 -0
- package/dist/features/magic-context/storage-db.d.ts +68 -3
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-identity-merge.d.ts +6 -0
- package/dist/features/magic-context/storage-identity-merge.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +15 -0
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-session.d.ts +1 -1
- package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-shared.d.ts +1 -1
- package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
- package/dist/features/magic-context/storage-notes.d.ts +2 -2
- package/dist/features/magic-context/storage-notes.d.ts.map +1 -1
- 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 +42 -5
- package/dist/features/magic-context/storage-replay-document.d.ts.map +1 -1
- package/dist/features/magic-context/storage-session-tables.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tags.d.ts +7 -1
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +1 -1
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/features/magic-context/store-generation-rebase.d.ts.map +1 -1
- 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/transform-decision-log.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/storage-user-memory.d.ts.map +1 -1
- package/dist/features/magic-context/v22-deferred-backfill.d.ts.map +1 -1
- package/dist/ffi-3cx1cxpk.js +78 -0
- package/dist/ffi-7bqqe4cd.js +91 -0
- package/dist/ffi-7e6gryj5.js +91 -0
- package/dist/ffi-bpvkebwr.js +78 -0
- package/dist/hooks/magic-context/apply-operations.d.ts +9 -1
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
- 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 +3 -0
- package/dist/hooks/magic-context/auto-search-hint.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-runner.d.ts +3 -0
- package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/caveman-cleanup.d.ts +8 -1
- package/dist/hooks/magic-context/caveman-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/caveman.d.ts +56 -1
- package/dist/hooks/magic-context/caveman.d.ts.map +1 -1
- package/dist/hooks/magic-context/child-session-spawn.d.ts +2 -0
- package/dist/hooks/magic-context/child-session-spawn.d.ts.map +1 -1
- package/dist/hooks/magic-context/command-handler.d.ts +1 -1
- package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts +1 -1
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-parser.d.ts +3 -3
- package/dist/hooks/magic-context/compartment-parser.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-render-epoch.d.ts +12 -1
- package/dist/hooks/magic-context/compartment-render-epoch.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts +0 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-types.d.ts +3 -0
- package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts +6 -0
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
- 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.map +1 -1
- package/dist/hooks/magic-context/drop-stale-reduce-calls.d.ts.map +1 -1
- package/dist/hooks/magic-context/dropped-input-guard.d.ts.map +1 -1
- package/dist/hooks/magic-context/embed-history-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/emergency-drop.d.ts +15 -0
- package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-resolvers.d.ts +7 -0
- package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
- package/dist/hooks/magic-context/execute-status.d.ts +1 -0
- package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts +17 -0
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -1
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts +2 -0
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/historian-host-runner.d.ts +5 -0
- package/dist/hooks/magic-context/historian-host-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/historian-prompt-fit.d.ts +116 -0
- package/dist/hooks/magic-context/historian-prompt-fit.d.ts.map +1 -0
- package/dist/hooks/magic-context/historian-prompt.generated.d.ts +1 -1
- package/dist/hooks/magic-context/historian-prompt.generated.d.ts.map +1 -1
- 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.d.ts +4 -0
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts +13 -0
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-persist.d.ts +12 -0
- package/dist/hooks/magic-context/lkg-persist.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-replay-fit.d.ts +104 -0
- package/dist/hooks/magic-context/lkg-replay-fit.d.ts.map +1 -0
- package/dist/hooks/magic-context/lkg-replay.d.ts +64 -0
- package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-client.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-state-sync-timing.d.ts +1 -1
- package/dist/hooks/magic-context/module-state-sync-timing.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-state-sync.d.ts +6 -68
- package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-tool-backends.d.ts +1 -34
- package/dist/hooks/magic-context/module-tool-backends.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-transport.d.ts +1 -55
- package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-wire.d.ts.map +1 -1
- package/dist/hooks/magic-context/note-nudger.d.ts +2 -0
- package/dist/hooks/magic-context/note-nudger.d.ts.map +1 -1
- package/dist/hooks/magic-context/pass-outcome.d.ts +59 -2
- package/dist/hooks/magic-context/pass-outcome.d.ts.map +1 -1
- package/dist/hooks/magic-context/producer-window-guard.d.ts +6 -0
- package/dist/hooks/magic-context/producer-window-guard.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts +17 -4
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-formatting.d.ts +11 -0
- package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts +2 -2
- package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
- 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 +1 -0
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
- package/dist/hooks/magic-context/reference-retrieval.d.ts +1 -1
- package/dist/hooks/magic-context/reference-retrieval.d.ts.map +1 -1
- package/dist/hooks/magic-context/reply-pages.d.ts +3 -0
- package/dist/hooks/magic-context/reply-pages.d.ts.map +1 -0
- package/dist/hooks/magic-context/rust-lkg-freeze-registry.d.ts +62 -0
- package/dist/hooks/magic-context/rust-lkg-freeze-registry.d.ts.map +1 -0
- package/dist/hooks/magic-context/rust-mode-transform.d.ts +17 -85
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/send-session-notification.d.ts.map +1 -1
- package/dist/hooks/magic-context/sentinel.d.ts +35 -0
- package/dist/hooks/magic-context/sentinel.d.ts.map +1 -1
- package/dist/hooks/magic-context/shared-compartment-boundaries.d.ts +28 -0
- package/dist/hooks/magic-context/shared-compartment-boundaries.d.ts.map +1 -0
- package/dist/hooks/magic-context/single-store-refusal.d.ts +14 -0
- package/dist/hooks/magic-context/single-store-refusal.d.ts.map +1 -0
- package/dist/hooks/magic-context/storage-busy-refusal.d.ts +7 -0
- package/dist/hooks/magic-context/storage-busy-refusal.d.ts.map +1 -1
- package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
- package/dist/hooks/magic-context/stripped-command.d.ts +1 -1
- package/dist/hooks/magic-context/stripped-command.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-injection-stripper.d.ts +7 -0
- package/dist/hooks/magic-context/system-injection-stripper.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-content-primitives.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-id-fallback.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-messages.d.ts +18 -1
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
- package/dist/hooks/magic-context/tokenizer-calibration.d.ts +1 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts +1 -0
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +38 -4
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +12 -39
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- 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/user-profile-render.d.ts +3 -0
- package/dist/hooks/magic-context/user-profile-render.d.ts.map +1 -0
- package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
- package/dist/{index-yhm60r53.js → index-16ny736w.js} +13622 -28584
- package/dist/{index-q5p1aqvv.js → index-2aq21j41.js} +1208 -429
- package/dist/{index-32b096cc.js → index-2ntg5sd4.js} +6 -2
- package/dist/index-4krbw8z9.js +6034 -0
- package/dist/{index-33q7s9y2.js → index-75zjgwga.js} +61 -85
- package/dist/{index-nf9sk8sh.js → index-8fgkmxmy.js} +28 -10
- package/dist/index-a4m2b1yv.js +530 -0
- package/dist/index-anq4nn6f.js +131 -0
- package/dist/index-avwt563y.js +62 -0
- package/dist/index-bmzf7zxv.js +445 -0
- package/dist/index-e44zzy84.js +10 -0
- package/dist/index-en1k8h8m.js +244 -0
- package/dist/{index-638hf49n.js → index-f85teqck.js} +15 -6
- package/dist/index-fr2z4qy8.js +7810 -0
- package/dist/{index-kwe03yde.js → index-fzbvakh0.js} +1 -1
- package/dist/{module-asyncify-2EFITU5U-rkqjhjxd.js → index-g20jdh0p.js} +114 -105
- package/dist/index-gd5qx1j9.js +398 -0
- package/dist/{index-3bygzk2d.js → index-hybnrwq0.js} +169 -4
- package/dist/{index-jqcbs2k1.js → index-mc22ayvf.js} +24 -5
- package/dist/{index-y5145x8k.js → index-n96ag4rk.js} +15 -1
- package/dist/index-q7yesyk9.js +9118 -0
- package/dist/index-remp7e2g.js +214 -0
- package/dist/{index-7k55qm8a.js → index-sfpzqvdz.js} +8 -8
- package/dist/{index-9y5p0d50.js → index-vvtfyw1z.js} +13 -76
- package/dist/index-w9jwmntv.js +202 -0
- package/dist/{index-kr5qehbd.js → index-x23gah8c.js} +1 -1
- package/dist/{index-jdxxq8cz.js → index-x8a7jmkh.js} +6 -1
- package/dist/{index-rdsaxnf2.js → index-xgt9k6c6.js} +23 -12
- package/dist/index-y8v6yerm.js +77 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7560 -8084
- package/dist/message-time-backfill-an311pmk.js +124 -0
- package/dist/migration-worker.js +53 -0
- package/dist/{model-resolution-dxatzjde.js → model-resolution-xhfmyyvy.js} +5 -1
- package/dist/module-ES6BEMUI-3cet1pyp.js +12 -0
- package/dist/module-asyncify-2EFITU5U-c2razzd9.js +6 -0
- package/dist/plugin/boot-deadline.d.ts.map +1 -1
- package/dist/plugin/conflict-warning-hook.d.ts.map +1 -1
- package/dist/plugin/dream-timer-module-client.d.ts +1 -11
- package/dist/plugin/dream-timer-module-client.d.ts.map +1 -1
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +8 -0
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/messages-transform.d.ts +20 -13
- package/dist/plugin/messages-transform.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/plugin/stale-build-notice.d.ts +16 -0
- package/dist/plugin/stale-build-notice.d.ts.map +1 -0
- package/dist/read-session-chunk-8rxs0tc9.js +84 -0
- package/dist/recomp-orchestrator-nzamtw29.js +39 -0
- package/dist/{rpc-notifications-4amf6mf4.js → rpc-notifications-3hed126v.js} +3 -1
- package/dist/{safe-notification-target-50gm9c58.js → safe-notification-target-43r8jsxw.js} +3 -3
- package/dist/send-session-notification-nqpv7cne.js +28 -0
- package/dist/shared/assistant-message-extractor.d.ts +4 -0
- package/dist/shared/assistant-message-extractor.d.ts.map +1 -1
- package/dist/shared/background-batch-drain.d.ts +8 -0
- package/dist/shared/background-batch-drain.d.ts.map +1 -0
- package/dist/{features/builtin-commands/commands.d.ts → shared/builtin-commands.d.ts} +1 -1
- package/dist/shared/builtin-commands.d.ts.map +1 -0
- package/dist/shared/embedding-activity.d.ts +13 -0
- package/dist/shared/embedding-activity.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/jsonc-edit.d.ts.map +1 -1
- package/dist/shared/logger.d.ts +7 -0
- package/dist/shared/logger.d.ts.map +1 -1
- package/dist/shared/model-suggestion-retry.d.ts +2 -1
- package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
- package/dist/shared/models-dev-cache.d.ts.map +1 -1
- package/dist/shared/off-thread-migration-clock.d.ts +38 -0
- package/dist/shared/off-thread-migration-clock.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-async-transport.d.ts +4 -0
- package/dist/shared/prompt-async-transport.d.ts.map +1 -1
- package/dist/shared/prompt-surface-runtime.d.ts +3 -3
- package/dist/shared/provider-response-completion.d.ts +12 -0
- package/dist/shared/provider-response-completion.d.ts.map +1 -0
- package/dist/shared/redaction.d.ts.map +1 -1
- package/dist/shared/rpc-client.d.ts +23 -2
- package/dist/shared/rpc-client.d.ts.map +1 -1
- package/dist/shared/rpc-types.d.ts +19 -0
- package/dist/shared/rpc-types.d.ts.map +1 -1
- package/dist/shared/rpc-utils.d.ts +41 -0
- package/dist/shared/rpc-utils.d.ts.map +1 -1
- package/dist/shared/sqlite.d.ts +13 -2
- package/dist/shared/sqlite.d.ts.map +1 -1
- package/dist/shared/stale-plugin-build.d.ts +21 -0
- package/dist/shared/stale-plugin-build.d.ts.map +1 -0
- package/dist/shared/status-summary.d.ts +29 -0
- package/dist/shared/status-summary.d.ts.map +1 -1
- package/dist/shared/status-view-check.d.ts +124 -0
- package/dist/shared/status-view-check.d.ts.map +1 -0
- package/dist/shared/status-view.d.ts +38 -2
- package/dist/shared/status-view.d.ts.map +1 -1
- 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 +2 -1
- package/dist/shared/tag-transcript.d.ts.map +1 -1
- package/dist/shared/test-temp-dir.d.ts +8 -2
- package/dist/shared/test-temp-dir.d.ts.map +1 -1
- package/dist/shared/transcript.d.ts +2 -0
- package/dist/shared/transcript.d.ts.map +1 -1
- 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 +41 -6
- package/dist/shared/user-facing-codes.d.ts.map +1 -1
- package/dist/shared/xml-unescape.d.ts +9 -0
- package/dist/shared/xml-unescape.d.ts.map +1 -0
- package/dist/task-config-v81k8jvk.js +17 -0
- package/dist/tools/ctx-expand/constants.d.ts +1 -1
- package/dist/tools/ctx-expand/constants.d.ts.map +1 -1
- package/dist/tools/ctx-expand/mode.d.ts +4 -0
- package/dist/tools/ctx-expand/mode.d.ts.map +1 -1
- package/dist/tools/ctx-expand/render.d.ts +5 -1
- package/dist/tools/ctx-expand/render.d.ts.map +1 -1
- package/dist/tools/ctx-expand/tools.d.ts +2 -0
- package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
- package/dist/tools/ctx-expand/types.d.ts +1 -0
- package/dist/tools/ctx-expand/types.d.ts.map +1 -1
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
- package/dist/tools/ctx-note/render.d.ts +2 -0
- package/dist/tools/ctx-note/render.d.ts.map +1 -1
- package/dist/tools/ctx-note/tools.d.ts.map +1 -1
- package/dist/tools/ctx-reduce/constants.d.ts +1 -1
- package/dist/tools/ctx-reduce/constants.d.ts.map +1 -1
- package/dist/tools/ctx-search/constants.d.ts +1 -1
- package/dist/tools/ctx-search/constants.d.ts.map +1 -1
- package/dist/tools/light-descriptions.d.ts +3 -3
- package/dist/tools/light-descriptions.d.ts.map +1 -1
- package/dist/tools/parameter-descriptions.d.ts +14 -14
- package/dist/transform-postprocess-phase-414phndq.js +61 -0
- package/dist/tui/data/context-db.d.ts +34 -10
- package/dist/tui/data/context-db.d.ts.map +1 -1
- package/dist/tui/data/notification-socket.d.ts +6 -0
- package/dist/tui/data/notification-socket.d.ts.map +1 -1
- package/dist/tui/data/session-directory.d.ts +16 -0
- package/dist/tui/data/session-directory.d.ts.map +1 -0
- package/dist/tui-compiled/data/context-db.d.ts +34 -10
- package/dist/tui-compiled/data/context-db.d.ts.map +1 -1
- package/dist/tui-compiled/data/notification-socket.d.ts +6 -0
- package/dist/tui-compiled/data/notification-socket.d.ts.map +1 -1
- package/dist/tui-compiled/data/session-directory.d.ts +16 -0
- package/dist/tui-compiled/data/session-directory.d.ts.map +1 -0
- package/dist/v2/derive-budgets-v0krf3t7.js +18 -0
- package/dist/v2/embedding-worker.js +47 -0
- package/dist/v2/emscripten-module-0g8f45e6.js +602 -0
- package/dist/v2/emscripten-module-0pekdjxz.js +1532 -0
- package/dist/v2/emscripten-module-e67xwsp3.js +503 -0
- package/dist/v2/emscripten-module-pj1vyb44.js +4559 -0
- package/dist/v2/ffi-3cx1cxpk.js +78 -0
- package/dist/v2/ffi-7bqqe4cd.js +91 -0
- package/dist/v2/ffi-7e6gryj5.js +91 -0
- package/dist/v2/ffi-bpvkebwr.js +78 -0
- package/dist/v2/fold/boundary.d.ts.map +1 -1
- 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 +135 -0
- package/dist/v2/hidden-child-record.d.ts.map +1 -0
- package/dist/v2/hidden-completion.d.ts +12 -97
- package/dist/v2/hidden-completion.d.ts.map +1 -1
- package/dist/v2/hooks/context.d.ts +20 -8
- package/dist/v2/hooks/context.d.ts.map +1 -1
- package/dist/v2/hooks/dream-manual.d.ts.map +1 -1
- package/dist/v2/hooks/dream-trigger.d.ts +5 -0
- package/dist/v2/hooks/dream-trigger.d.ts.map +1 -1
- 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 +33 -2
- package/dist/v2/hooks/hidden-child.d.ts.map +1 -1
- package/dist/v2/hooks/payload.d.ts +3 -0
- package/dist/v2/hooks/payload.d.ts.map +1 -1
- 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/storage-gate.d.ts +3 -1
- package/dist/v2/hooks/storage-gate.d.ts.map +1 -1
- package/dist/v2/hooks/store.d.ts +1 -1
- package/dist/v2/hooks/store.d.ts.map +1 -1
- package/dist/v2/hooks/tools.d.ts.map +1 -1
- package/dist/v2/hooks/types.d.ts +10 -0
- package/dist/v2/hooks/types.d.ts.map +1 -1
- package/dist/v2/hooks/update-check.d.ts.map +1 -1
- package/dist/v2/hooks/usage-persist.d.ts.map +1 -1
- package/dist/v2/hooks/usage-reading.d.ts +4 -0
- package/dist/v2/hooks/usage-reading.d.ts.map +1 -1
- package/dist/v2/index-6e4mwffh.js +5662 -0
- package/dist/v2/index-en1k8h8m.js +244 -0
- package/dist/{message-time-backfill-q374fxc5.js → v2/message-time-backfill-0n93vrd7.js} +19 -5
- package/dist/v2/migration-worker.js +52 -0
- package/dist/v2/model-resolution-xhfmyyvy.js +16 -0
- package/dist/v2/module-ES6BEMUI-3cet1pyp.js +12 -0
- package/dist/v2/module-asyncify-2EFITU5U-c2razzd9.js +6 -0
- package/dist/v2/prompt-context-5y5ms8f9.js +6 -0
- package/dist/{read-session-chunk-n072mcq4.js → v2/read-session-chunk-hjza38hr.js} +24 -7
- package/dist/v2/recomp-orchestrator-1aq7h44c.js +36 -0
- package/dist/v2/retrospective-raw-provider.d.ts +21 -0
- package/dist/v2/retrospective-raw-provider.d.ts.map +1 -0
- package/dist/v2/rpc-notifications-3hed126v.js +16 -0
- package/dist/v2/safe-notification-target-wtj0bbc2.js +9 -0
- package/dist/{send-session-notification-04hvd54c.js → v2/send-session-notification-mq9frrtm.js} +10 -5
- package/dist/v2/server-0jqw05sa.js +803 -0
- package/dist/v2/server-5317ykaf.js +40 -0
- package/dist/v2/server-a4m2b1yv.js +530 -0
- package/dist/v2/server-avwt563y.js +62 -0
- package/dist/v2/server-c4g2y1z8.js +28824 -0
- package/dist/v2/server-ckpc8pxy.js +662 -0
- package/dist/v2/server-e36nf2p1.js +7702 -0
- package/dist/v2/server-e44zzy84.js +10 -0
- package/dist/v2/server-fgmxwrgy.js +16 -0
- package/dist/v2/server-fmsr7v69.js +75 -0
- package/dist/v2/server-g20jdh0p.js +1273 -0
- package/dist/{index-dgg5y7er.js → v2/server-hfjfbg59.js} +849 -747
- package/dist/v2/server-n96ag4rk.js +633 -0
- package/dist/v2/server-qdjnb2z1.js +181 -0
- package/dist/v2/server-qpg6wf72.js +187 -0
- package/dist/v2/server-r7cmye3k.js +131 -0
- package/dist/v2/server-remp7e2g.js +214 -0
- package/dist/v2/server-rhdgxp1t.js +398 -0
- package/dist/v2/server-sfpzqvdz.js +137 -0
- package/dist/v2/server-syahy8j8.js +50 -0
- package/dist/v2/server-v5xgft5v.js +9116 -0
- package/dist/v2/server-w99cyt6a.js +361 -0
- package/dist/v2/server-x8a7jmkh.js +104 -0
- package/dist/v2/server-y8v6yerm.js +77 -0
- package/dist/v2/server-z19x7eqz.js +423 -0
- package/dist/v2/server.d.ts.map +1 -1
- package/dist/v2/server.js +8868 -107184
- package/dist/v2/store-reader.d.ts +52 -1
- package/dist/v2/store-reader.d.ts.map +1 -1
- package/dist/v2/task-config-tbndqyny.js +17 -0
- package/dist/v2/transformers-node-wasm.js +26768 -0
- package/dist/v2/transformers-web.js +25670 -0
- package/dist/v2/transformers.node-hj754h7s.js +29997 -0
- package/dist/v2/tui/index.d.ts +10 -1
- package/dist/v2/tui/index.d.ts.map +1 -1
- package/dist/v2/tui/sidebar-mount.d.ts +6 -0
- package/dist/v2/tui/sidebar-mount.d.ts.map +1 -1
- package/dist/v2/tui/status-dialog-mount.d.ts +7 -4
- package/dist/v2/tui/status-dialog-mount.d.ts.map +1 -1
- package/dist/v2/tui/types.d.ts +12 -0
- package/dist/v2/tui/types.d.ts.map +1 -1
- package/dist/v2/wrapup-orchestrator-tbyx78dz.js +425 -0
- package/dist/wrapup-orchestrator-h28bqsy6.js +26 -0
- package/package.json +8 -8
- package/src/agents/hidden-agent-registrations.ts +24 -16
- package/src/agents/magic-context-prompt.test.ts +41 -0
- package/src/agents/magic-context-prompt.ts +8 -5
- package/src/agents/permissions.test.ts +31 -49
- package/src/agents/permissions.ts +8 -28
- package/src/config/index.test.ts +60 -20
- package/src/config/index.ts +53 -1
- package/src/config/live-run-config.test.ts +5 -5
- package/src/config/live-snapshot.test.ts +4 -4
- package/src/config/migrate-config-location.test.ts +3 -10
- package/src/config/project-config-trust-boundary.test.ts +207 -0
- package/src/config/project-security.hostile-matrix.test.ts +4 -4
- package/src/config/project-security.ts +218 -1
- package/src/config/protected-tokens.test.ts +14 -9
- package/src/config/raw-loader.test.ts +31 -3
- package/src/config/raw-loader.ts +8 -3
- package/src/config/schema/magic-context.ts +20 -3
- package/src/config/variable.test.ts +3 -2
- package/src/features/magic-context/dreamer/cron.ts +30 -9
- package/src/features/magic-context/dreamer/task-registry.ts +7 -5
- package/src/shared/announcement.test.ts +2 -1
- package/src/shared/assistant-message-extractor.test.ts +27 -1
- package/src/shared/assistant-message-extractor.ts +27 -0
- package/src/shared/background-batch-drain.test.ts +38 -0
- package/src/shared/background-batch-drain.ts +29 -0
- package/src/shared/builtin-commands.ts +50 -0
- package/src/shared/console-diagnostics-fence.test.ts +145 -0
- package/src/shared/data-path.test.ts +6 -5
- package/src/shared/embedding-activity.test.ts +21 -0
- package/src/shared/embedding-activity.ts +36 -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/jsonc-edit.ts +20 -1
- package/src/shared/logger.test.ts +3 -2
- package/src/shared/logger.ts +40 -1
- package/src/shared/model-suggestion-retry.test.ts +46 -0
- package/src/shared/model-suggestion-retry.ts +16 -1
- package/src/shared/models-dev-cache.test.ts +74 -2
- package/src/shared/models-dev-cache.ts +5 -1
- package/src/shared/off-thread-migration-clock.test.ts +55 -0
- package/src/shared/off-thread-migration-clock.ts +124 -0
- package/src/shared/opencode-db-path.test.ts +3 -2
- 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-async-transport.test.ts +249 -72
- package/src/shared/prompt-async-transport.ts +131 -24
- package/src/shared/prompt-surface-a1-golden.md +41 -25
- package/src/shared/prompt-surface-runtime.test.ts +3 -3
- package/src/shared/provider-response-completion.ts +23 -0
- package/src/shared/redaction.test.ts +51 -1
- package/src/shared/redaction.ts +33 -0
- package/src/shared/rpc-async-probes.test.ts +32 -2
- package/src/shared/rpc-client.test.ts +3 -2
- package/src/shared/rpc-client.ts +76 -18
- package/src/shared/rpc-types.ts +15 -0
- package/src/shared/rpc-utils.test.ts +191 -12
- package/src/shared/rpc-utils.ts +184 -26
- package/src/shared/sqlite-acquisition-routing.test.ts +46 -3
- package/src/shared/sqlite-pass-scope.test.ts +3 -2
- package/src/shared/sqlite-transaction-mode-guard.test.ts +4 -0
- package/src/shared/sqlite-writer-diagnostics.test.ts +134 -0
- package/src/shared/sqlite.ts +225 -41
- package/src/shared/stale-plugin-build.test.ts +129 -0
- package/src/shared/stale-plugin-build.ts +151 -0
- package/src/shared/status-summary.ts +40 -13
- package/src/shared/status-view-check.test.ts +253 -0
- package/src/shared/status-view-check.ts +536 -0
- package/src/shared/status-view.test.ts +6 -1
- package/src/shared/status-view.ts +176 -4
- package/src/shared/storage-busy.test.ts +3 -2
- package/src/shared/tag-owner-id.test.ts +33 -0
- package/src/shared/tag-owner-id.ts +29 -0
- package/src/shared/tag-transcript.ts +17 -3
- package/src/shared/test-temp-dir-policy.test.ts +33 -0
- package/src/shared/test-temp-dir.test.ts +27 -0
- package/src/shared/test-temp-dir.ts +36 -12
- package/src/shared/transcript.ts +3 -0
- package/src/shared/tui-config.test.ts +6 -5
- package/src/shared/tui-preferences.test.ts +3 -2
- package/src/shared/user-answer.test.ts +40 -0
- package/src/shared/user-answer.ts +17 -0
- package/src/shared/user-facing-codes.ts +52 -6
- package/src/shared/window-geometry.test.ts +3 -2
- package/src/shared/write-transaction-attribution.test.ts +11 -7
- package/src/shared/write-transaction-hold-clock.test.ts +160 -0
- package/src/shared/xml-unescape.ts +19 -0
- package/src/tui/data/context-db.test.ts +92 -4
- package/src/tui/data/context-db.ts +184 -18
- package/src/tui/data/notification-socket.test.ts +49 -2
- package/src/tui/data/notification-socket.ts +47 -9
- package/src/tui/data/session-directory.ts +19 -0
- package/src/tui/dialogs/status-dialog-render.test.ts +284 -0
- package/src/tui/dialogs/status-dialog.tsx +41 -38
- package/src/tui/index.tsx +30 -18
- package/src/tui/slots/sidebar-content.tsx +9 -2
- package/src/tui-compiled/data/context-db.ts +184 -18
- package/src/tui-compiled/data/notification-socket.ts +47 -9
- package/src/tui-compiled/data/session-directory.ts +19 -0
- package/src/tui-compiled/dialogs/status-dialog.tsx +38 -29
- package/src/tui-compiled/index.tsx +29 -16
- package/src/tui-compiled/slots/sidebar-content.tsx +3 -2
- package/src/v2/tui/host-contract.test.ts +9 -10
- package/src/v2/tui/index.ts +78 -23
- package/src/v2/tui/load-compiled-sidebar.d.mts +5 -1
- package/src/v2/tui/load-compiled-status-dialog.d.mts +3 -2
- package/src/v2/tui/session-directory.test.ts +53 -0
- package/src/v2/tui/sidebar-mount.ts +19 -1
- package/src/v2/tui/status-dialog-mount.ts +10 -7
- package/src/v2/tui/types.ts +10 -0
- package/dist/features/builtin-commands/commands.d.ts.map +0 -1
- package/dist/features/builtin-commands/types.d.ts +0 -3
- package/dist/features/builtin-commands/types.d.ts.map +0 -1
- package/dist/features/magic-context/context-authority.d.ts +0 -272
- package/dist/features/magic-context/context-authority.d.ts.map +0 -1
- package/dist/features/magic-context/memory/mirror-reembed.d.ts +0 -22
- package/dist/features/magic-context/memory/mirror-reembed.d.ts.map +0 -1
- package/dist/hooks/magic-context/historian-state-file.d.ts +0 -43
- package/dist/hooks/magic-context/historian-state-file.d.ts.map +0 -1
- package/dist/index-4an2p8qa.js +0 -1056
- package/dist/index-rn7gafjr.js +0 -8
- package/dist/index-v6t0tg85.js +0 -13
- package/dist/plugin/memory-id-translation.d.ts +0 -109
- package/dist/plugin/memory-id-translation.d.ts.map +0 -1
- package/dist/plugin/rust-note-backend.d.ts +0 -84
- package/dist/plugin/rust-note-backend.d.ts.map +0 -1
- package/dist/recomp-orchestrator-19tr6zya.js +0 -22
- package/dist/task-config-2bm68628.js +0 -9
- package/dist/transform-postprocess-phase-z2mfc5w1.js +0 -36
- package/dist/v2/host-service.d.ts +0 -66
- package/dist/v2/host-service.d.ts.map +0 -1
- package/dist/wrapup-orchestrator-sy4m56a7.js +0 -19
- /package/dist/{index-s70wtd8k.js → index-q6hef7fh.js} +0 -0
|
@@ -23,6 +23,10 @@ const READ_ONLY_DEFERRED_TRANSACTIONS: Record<string, string> = {
|
|
|
23
23
|
"reads the latest compaction and the rows after it as one consistent snapshot of the OpenCode 2 store; never writes",
|
|
24
24
|
"packages/pi-plugin/src/inject-compartments-pi.ts#readFrozenM0InputsPi":
|
|
25
25
|
"reads the m[0] render sources and their watermarks as one consistent snapshot; never writes",
|
|
26
|
+
"packages/plugin/src/features/magic-context/message-fts-session-filter.ts#withMessageFtsSessionFilter":
|
|
27
|
+
"pins one read snapshot so the session's rowid coverage proof and the filtered message search see the same rows; never writes (read-only connections use it too)",
|
|
28
|
+
"packages/plugin/src/hooks/magic-context/lkg-persist.ts#loadPersistedLkgSlot":
|
|
29
|
+
"reads an LKG slot row and its prefix slices as one consistent snapshot; never writes (a failed verification clears the slot afterwards, outside this transaction)",
|
|
26
30
|
};
|
|
27
31
|
|
|
28
32
|
const REPOSITORY_ROOT = resolve(import.meta.dir, "../../../..");
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, rmSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { createTestTempDirFromPath } from "./test-temp-dir";
|
|
6
|
+
|
|
7
|
+
// The scenario runs in a child process with NODE_ENV=production because the
|
|
8
|
+
// shared logger is silent under test. It imports storage-db for its side effect
|
|
9
|
+
// of registering the real log sink, then drives three privileged writes and one
|
|
10
|
+
// background writer through two connections on a throwaway database:
|
|
11
|
+
// wait - another connection holds the lock for 300 ms, the hold is short
|
|
12
|
+
// hold - the lock comes at once, the operation keeps it for 300 ms
|
|
13
|
+
// fast - neither crosses the threshold, so nothing is logged
|
|
14
|
+
// async - beginSqliteWriterAsync acquires at once and holds for 300 ms
|
|
15
|
+
const scenario = `
|
|
16
|
+
await import(${JSON.stringify(new URL("../features/magic-context/storage-db.ts", import.meta.url).href)});
|
|
17
|
+
const sqlite = await import(${JSON.stringify(new URL("./sqlite.ts", import.meta.url).href)});
|
|
18
|
+
const logger = await import(${JSON.stringify(new URL("./logger.ts", import.meta.url).href)});
|
|
19
|
+
const dbPath = process.env.SCENARIO_DB_PATH;
|
|
20
|
+
const holder = new sqlite.Database(dbPath);
|
|
21
|
+
holder.exec("PRAGMA journal_mode=WAL; CREATE TABLE context_privilege_state(id INTEGER PRIMARY KEY, enabled INTEGER)");
|
|
22
|
+
const writer = new sqlite.Database(dbPath);
|
|
23
|
+
const spin = (ms) => { const end = performance.now() + ms; while (performance.now() < end) {} };
|
|
24
|
+
|
|
25
|
+
holder.exec("BEGIN IMMEDIATE");
|
|
26
|
+
setTimeout(() => holder.exec("COMMIT"), 300);
|
|
27
|
+
await sqlite.withAsyncPrivilegedWriter(writer, () => undefined);
|
|
28
|
+
|
|
29
|
+
await sqlite.withAsyncPrivilegedWriter(writer, () => spin(300));
|
|
30
|
+
|
|
31
|
+
await sqlite.withAsyncPrivilegedWriter(writer, () => undefined);
|
|
32
|
+
|
|
33
|
+
await sqlite.beginSqliteWriterAsync(writer, "historian-publish");
|
|
34
|
+
spin(300);
|
|
35
|
+
writer.exec("COMMIT");
|
|
36
|
+
|
|
37
|
+
logger.flushLogger();
|
|
38
|
+
writer.close();
|
|
39
|
+
holder.close();
|
|
40
|
+
`;
|
|
41
|
+
|
|
42
|
+
let root: string | null = null;
|
|
43
|
+
let logLines: string[] = [];
|
|
44
|
+
let consoleOutput = "";
|
|
45
|
+
|
|
46
|
+
function field(line: string, name: string): number {
|
|
47
|
+
const value = new RegExp(`\\b${name}=(\\d+)`).exec(line)?.[1];
|
|
48
|
+
if (value === undefined) throw new Error(`${name} missing from: ${line}`);
|
|
49
|
+
return Number(value);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
describe("sqlite writer diagnostics", () => {
|
|
53
|
+
beforeAll(async () => {
|
|
54
|
+
root = createTestTempDirFromPath(join(tmpdir(), "mc-sqlite-writer-diagnostics-"));
|
|
55
|
+
const logPath = join(root, "magic-context.log");
|
|
56
|
+
const env: Record<string, string> = {
|
|
57
|
+
...(process.env as Record<string, string>),
|
|
58
|
+
NODE_ENV: "production",
|
|
59
|
+
MAGIC_CONTEXT_LOG_PATH: logPath,
|
|
60
|
+
MAGIC_CONTEXT_STORAGE_DIR: join(root, "storage"),
|
|
61
|
+
SCENARIO_DB_PATH: join(root, "writer.db"),
|
|
62
|
+
};
|
|
63
|
+
for (const key of [
|
|
64
|
+
"XDG_DATA_HOME",
|
|
65
|
+
"XDG_CONFIG_HOME",
|
|
66
|
+
"XDG_STATE_HOME",
|
|
67
|
+
"XDG_CACHE_HOME",
|
|
68
|
+
]) {
|
|
69
|
+
env[key] = join(root, key);
|
|
70
|
+
mkdirSync(env[key]);
|
|
71
|
+
}
|
|
72
|
+
const child = Bun.spawn({
|
|
73
|
+
windowsHide: true,
|
|
74
|
+
cmd: ["bun", "--eval", scenario],
|
|
75
|
+
cwd: import.meta.dir,
|
|
76
|
+
env,
|
|
77
|
+
stdout: "pipe",
|
|
78
|
+
stderr: "pipe",
|
|
79
|
+
});
|
|
80
|
+
const [exitCode, stdout, stderr] = await Promise.all([
|
|
81
|
+
child.exited,
|
|
82
|
+
new Response(child.stdout).text(),
|
|
83
|
+
new Response(child.stderr).text(),
|
|
84
|
+
]);
|
|
85
|
+
expect(exitCode, stderr).toBe(0);
|
|
86
|
+
consoleOutput = stdout + stderr;
|
|
87
|
+
logLines = existsSync(logPath)
|
|
88
|
+
? readFileSync(logPath, "utf8")
|
|
89
|
+
.split("\n")
|
|
90
|
+
.filter((line) => line.includes("sqlite writer"))
|
|
91
|
+
: [];
|
|
92
|
+
}, 30_000);
|
|
93
|
+
|
|
94
|
+
afterAll(() => {
|
|
95
|
+
if (root) rmSync(root, { recursive: true, force: true });
|
|
96
|
+
root = null;
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test("nothing reaches the host console", () => {
|
|
100
|
+
expect(consoleOutput).not.toContain("[magic-context]");
|
|
101
|
+
expect(consoleOutput).not.toContain("sqlite writer");
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test("a writer that waited for the lock reports the wait, not its short hold", () => {
|
|
105
|
+
const waited = logLines.find((line) => line.includes("attempts=2"));
|
|
106
|
+
if (!waited) throw new Error(`no retried acquisition logged:\n${logLines.join("\n")}`);
|
|
107
|
+
expect(waited).toContain("[magic-context] sqlite writer site=privileged_writer");
|
|
108
|
+
expect(waited).toContain("lane=foreground");
|
|
109
|
+
expect(waited).toContain("outcome=committed");
|
|
110
|
+
expect(field(waited, "acquire_ms")).toBeGreaterThanOrEqual(250);
|
|
111
|
+
expect(field(waited, "hold_ms")).toBeLessThan(250);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test("a writer that held the lock reports the hold, not its quick acquisition", () => {
|
|
115
|
+
const held = logLines.filter(
|
|
116
|
+
(line) => line.includes("site=privileged_writer") && line.includes("attempts=1"),
|
|
117
|
+
);
|
|
118
|
+
expect(held).toHaveLength(1);
|
|
119
|
+
expect(field(held[0], "acquire_ms")).toBeLessThan(250);
|
|
120
|
+
expect(field(held[0], "hold_ms")).toBeGreaterThanOrEqual(300);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test("an async background writer reports its hold under its own site", () => {
|
|
124
|
+
const held = logLines.filter((line) => line.includes("site=historian-publish"));
|
|
125
|
+
expect(held).toHaveLength(1);
|
|
126
|
+
expect(held[0]).toContain("lane=background");
|
|
127
|
+
expect(field(held[0], "acquire_ms")).toBeLessThan(250);
|
|
128
|
+
expect(field(held[0], "hold_ms")).toBeGreaterThanOrEqual(300);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test("a fast writer stays out of the log", () => {
|
|
132
|
+
expect(logLines.filter((line) => line.includes("site=privileged_writer"))).toHaveLength(2);
|
|
133
|
+
});
|
|
134
|
+
});
|
package/src/shared/sqlite.ts
CHANGED
|
@@ -62,6 +62,28 @@ export function registerSlowWriteReporter(reporter: SlowWriteReporter): void {
|
|
|
62
62
|
reportSlowPrivilegedWrite = reporter;
|
|
63
63
|
}
|
|
64
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
|
+
|
|
65
87
|
export type SqliteRuntime = "Bun" | "Node.js";
|
|
66
88
|
|
|
67
89
|
type SqliteModule = {
|
|
@@ -224,14 +246,43 @@ function installTransactionRouting(db: BetterSqlite3.Database, readonly: boolean
|
|
|
224
246
|
writable: true,
|
|
225
247
|
value: (sql: string) => {
|
|
226
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);
|
|
227
252
|
if (transformPassScope.getStore()?.active || backgroundWriterScope.getStore())
|
|
228
253
|
acquireShort(db, () => nativeExec(sql), sql.trim());
|
|
229
254
|
else nativeExec(sql);
|
|
230
255
|
return db;
|
|
231
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));
|
|
232
261
|
return nativeExec(sql);
|
|
233
262
|
},
|
|
234
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
|
+
});
|
|
235
286
|
Object.defineProperty(db, "transaction", {
|
|
236
287
|
configurable: true,
|
|
237
288
|
writable: true,
|
|
@@ -490,7 +541,9 @@ export type Database = BetterSqlite3.Database;
|
|
|
490
541
|
export type Statement = BetterSqlite3.Statement<unknown[], unknown>;
|
|
491
542
|
|
|
492
543
|
const privilegeDepth = new WeakMap<Database, number>();
|
|
493
|
-
const transformPassScope = new AsyncLocalStorage<
|
|
544
|
+
const transformPassScope = new AsyncLocalStorage<
|
|
545
|
+
{ active: boolean; remainingWaitMs: number } | undefined
|
|
546
|
+
>();
|
|
494
547
|
const admissionScope = new AsyncLocalStorage<boolean>();
|
|
495
548
|
const backgroundWriterScope = new AsyncLocalStorage<boolean>();
|
|
496
549
|
|
|
@@ -502,7 +555,9 @@ export function withSqliteBackgroundWriter<T>(operation: () => T): T {
|
|
|
502
555
|
/** Only an awaited foreground transform may spend the extra acquisition budget.
|
|
503
556
|
* The mutable lease also expires for detached descendants when that pass ends. */
|
|
504
557
|
export function withSqliteTransformPass<T>(operation: () => T): T {
|
|
505
|
-
const
|
|
558
|
+
const existing = transformPassScope.getStore();
|
|
559
|
+
if (existing?.active) return operation();
|
|
560
|
+
const lease = { active: true, remainingWaitMs: FOREGROUND_IN_PASS_BUSY_TIMEOUT_MS };
|
|
506
561
|
return transformPassScope.run(lease, () => {
|
|
507
562
|
try {
|
|
508
563
|
const result = operation();
|
|
@@ -548,60 +603,182 @@ export class SqliteAcquisitionBusyError extends Error {
|
|
|
548
603
|
const SHORT_BUSY_TIMEOUT_MS = 25;
|
|
549
604
|
const FOREGROUND_IN_PASS_BUSY_TIMEOUT_MS = 250;
|
|
550
605
|
const FOREGROUND_ACQUISITION_BUDGET_MS = 16_500;
|
|
606
|
+
/** Waiting this long for the writer lock, or holding it this long, is logged. */
|
|
607
|
+
const SLOW_WRITER_LOG_MS = 250;
|
|
608
|
+
const WRITER_TRANSACTION_END = /^\s*(?:COMMIT|END|ROLLBACK)(?:\s+TRANSACTION)?\s*;?\s*$/i;
|
|
609
|
+
|
|
610
|
+
type WriterLane = "foreground" | "background";
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
* One attempt of an outer acquisition loop (`beginSqliteWriterAsync`,
|
|
614
|
+
* `withAsyncPrivilegedWriter`). It names the writer and remembers when the loop
|
|
615
|
+
* started, so the time spent in earlier busy attempts and the sleeps between
|
|
616
|
+
* them counts as waiting for the lock. Only the first BEGIN issued inside the
|
|
617
|
+
* attempt may claim it; a later BEGIN from detached work started inside the
|
|
618
|
+
* same async scope is timed on its own.
|
|
619
|
+
*/
|
|
620
|
+
interface WriterAcquisition {
|
|
621
|
+
site: string;
|
|
622
|
+
lane: WriterLane;
|
|
623
|
+
startedAt: number;
|
|
624
|
+
attempts: number;
|
|
625
|
+
claimed: boolean;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
/** A write transaction whose BEGIN went through `acquireShort` and has not ended yet. */
|
|
629
|
+
interface OpenWriterTransaction {
|
|
630
|
+
site: string;
|
|
631
|
+
lane: WriterLane;
|
|
632
|
+
acquireMs: number;
|
|
633
|
+
attempts: number;
|
|
634
|
+
acquiredAt: number;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
const writerAcquisitionScope = new AsyncLocalStorage<WriterAcquisition | undefined>();
|
|
638
|
+
const openWriterTransactions = new WeakMap<Database, OpenWriterTransaction>();
|
|
639
|
+
|
|
640
|
+
function foregroundWaitLease() {
|
|
641
|
+
const lease = transformPassScope.getStore();
|
|
642
|
+
return lease?.active && !admissionScope.getStore() && !backgroundWriterScope.getStore()
|
|
643
|
+
? lease
|
|
644
|
+
: undefined;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/** Bound implicit writer admission too, including prepared INSERT OR IGNORE and
|
|
648
|
+
* writes with RETURNING. Charge successful execution time conservatively: the
|
|
649
|
+
* native API cannot separate lock waiting from statement execution. Exhaustion
|
|
650
|
+
* switches to zero-wait acquisition, not a refusal when the writer is free. */
|
|
651
|
+
function withAutocommitTimeout<T>(db: Database, operation: () => T): T {
|
|
652
|
+
const lease = foregroundWaitLease();
|
|
653
|
+
if (isInTransaction(db) || (!lease && !backgroundWriterScope.getStore())) return operation();
|
|
654
|
+
const previous = pragmaNumber(db, "busy_timeout");
|
|
655
|
+
db.exec(
|
|
656
|
+
`PRAGMA busy_timeout=${lease ? Math.floor(lease.remainingWaitMs) : SHORT_BUSY_TIMEOUT_MS}`,
|
|
657
|
+
);
|
|
658
|
+
const started = performance.now();
|
|
659
|
+
try {
|
|
660
|
+
return operation();
|
|
661
|
+
} catch (error) {
|
|
662
|
+
if (lease && isTransientSqliteError(error))
|
|
663
|
+
throw new SqliteAcquisitionBusyError(error, "autocommit");
|
|
664
|
+
throw error;
|
|
665
|
+
} finally {
|
|
666
|
+
if (lease)
|
|
667
|
+
lease.remainingWaitMs = Math.max(
|
|
668
|
+
0,
|
|
669
|
+
lease.remainingWaitMs - (performance.now() - started),
|
|
670
|
+
);
|
|
671
|
+
if (previous !== null) db.exec(`PRAGMA busy_timeout=${previous}`);
|
|
672
|
+
}
|
|
673
|
+
}
|
|
551
674
|
|
|
552
675
|
/** The connection is never handed back to another caller with a shortened timeout. */
|
|
553
676
|
function acquireShort(db: Database, acquire: () => unknown, site: string): void {
|
|
554
677
|
const started = performance.now();
|
|
555
678
|
const previous = pragmaNumber(db, "busy_timeout");
|
|
556
|
-
|
|
679
|
+
const outer = writerAcquisitionScope.getStore();
|
|
680
|
+
const owner = outer && !outer.claimed ? outer : undefined;
|
|
681
|
+
if (owner) owner.claimed = true;
|
|
682
|
+
const writerSite = owner?.site ?? site;
|
|
683
|
+
const lane: WriterLane =
|
|
684
|
+
owner?.lane ?? (transformPassScope.getStore()?.active ? "foreground" : "background");
|
|
685
|
+
let acquiredAt: number | undefined;
|
|
557
686
|
try {
|
|
558
687
|
// Async admission retries after yielding, so each of its BEGIN attempts
|
|
559
688
|
// stays short. An ordinary BEGIN inside a transform pass cannot yield;
|
|
560
689
|
// give that single attempt enough time for a brief writer to finish.
|
|
561
|
-
const
|
|
562
|
-
|
|
563
|
-
!admissionScope.getStore() &&
|
|
564
|
-
!backgroundWriterScope.getStore()
|
|
565
|
-
? FOREGROUND_IN_PASS_BUSY_TIMEOUT_MS
|
|
566
|
-
: SHORT_BUSY_TIMEOUT_MS;
|
|
690
|
+
const lease = foregroundWaitLease();
|
|
691
|
+
const timeout = lease ? Math.floor(lease.remainingWaitMs) : SHORT_BUSY_TIMEOUT_MS;
|
|
567
692
|
db.exec(`PRAGMA busy_timeout=${timeout}`);
|
|
568
693
|
acquire();
|
|
569
|
-
|
|
694
|
+
acquiredAt = performance.now();
|
|
570
695
|
} catch (error) {
|
|
571
696
|
if (transformPassScope.getStore()?.active && isTransientSqliteError(error))
|
|
572
697
|
throw new SqliteAcquisitionBusyError(error, site);
|
|
573
698
|
throw error;
|
|
574
699
|
} finally {
|
|
700
|
+
const attemptMs = (acquiredAt ?? performance.now()) - started;
|
|
701
|
+
const lease = foregroundWaitLease();
|
|
702
|
+
if (lease) lease.remainingWaitMs = Math.max(0, lease.remainingWaitMs - attemptMs);
|
|
575
703
|
if (previous !== null) db.exec(`PRAGMA busy_timeout=${previous}`);
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
704
|
+
if (acquiredAt !== undefined) {
|
|
705
|
+
// Reported when the transaction ends, together with how long it held
|
|
706
|
+
// the lock (see endWriterTransaction).
|
|
707
|
+
openWriterTransactions.set(db, {
|
|
708
|
+
site: writerSite,
|
|
709
|
+
lane,
|
|
710
|
+
acquireMs: acquiredAt - (owner?.startedAt ?? started),
|
|
711
|
+
attempts: owner?.attempts ?? 1,
|
|
712
|
+
acquiredAt,
|
|
713
|
+
});
|
|
714
|
+
} else if (attemptMs >= SLOW_WRITER_LOG_MS) {
|
|
715
|
+
reportSqliteDiagnostic(
|
|
716
|
+
`sqlite writer site=${writerSite} lane=${lane} acquire_ms=${Math.round(attemptMs)} attempts=${owner?.attempts ?? 1} outcome=busy`,
|
|
580
717
|
);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
/**
|
|
723
|
+
* Run the COMMIT, END or ROLLBACK that closes a transaction opened through
|
|
724
|
+
* `acquireShort`, then report how long the writer waited for the lock
|
|
725
|
+
* (`acquire_ms`) and how long it then held it (`hold_ms`) when either crosses
|
|
726
|
+
* the threshold. A long hold blocks every other process's writer, so it is
|
|
727
|
+
* worth seeing even when the lock itself came quickly.
|
|
728
|
+
*/
|
|
729
|
+
function endWriterTransaction(db: Database, end: () => unknown, sql: string): unknown {
|
|
730
|
+
let ended = false;
|
|
731
|
+
try {
|
|
732
|
+
const result = end();
|
|
733
|
+
ended = true;
|
|
734
|
+
return result;
|
|
735
|
+
} finally {
|
|
736
|
+
const open = openWriterTransactions.get(db);
|
|
737
|
+
// A COMMIT that failed with the transaction still open has not ended it.
|
|
738
|
+
if (open && !isInTransaction(db)) {
|
|
739
|
+
openWriterTransactions.delete(db);
|
|
740
|
+
const holdMs = performance.now() - open.acquiredAt;
|
|
741
|
+
if (open.acquireMs >= SLOW_WRITER_LOG_MS || holdMs >= SLOW_WRITER_LOG_MS) {
|
|
742
|
+
const outcome = /^\s*ROLLBACK/i.test(sql)
|
|
743
|
+
? "rolled_back"
|
|
744
|
+
: ended
|
|
745
|
+
? "committed"
|
|
746
|
+
: "failed";
|
|
747
|
+
reportSqliteDiagnostic(
|
|
748
|
+
`sqlite writer site=${open.site} lane=${open.lane} acquire_ms=${Math.round(open.acquireMs)} hold_ms=${Math.round(holdMs)} attempts=${open.attempts} outcome=${outcome}`,
|
|
749
|
+
);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
581
752
|
}
|
|
582
753
|
}
|
|
583
754
|
|
|
584
755
|
/** Begin an immediate transaction with bounded asynchronous retries on writer contention.
|
|
585
|
-
* Callers must recheck any lease or source snapshot after this function returns.
|
|
586
|
-
|
|
756
|
+
* Callers must recheck any lease or source snapshot after this function returns.
|
|
757
|
+
* Resolves with the `performance.now()` time at which BEGIN IMMEDIATE succeeded,
|
|
758
|
+
* so a caller timing its transaction measures the hold, not the wait for the lock. */
|
|
759
|
+
export async function beginSqliteWriterAsync(db: Database, site: string): Promise<number> {
|
|
587
760
|
const started = performance.now();
|
|
588
761
|
let attempts = 0;
|
|
589
762
|
for (;;) {
|
|
590
763
|
attempts++;
|
|
591
764
|
try {
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
765
|
+
const acquisition: WriterAcquisition = {
|
|
766
|
+
site,
|
|
767
|
+
lane: "background",
|
|
768
|
+
startedAt: started,
|
|
769
|
+
attempts,
|
|
770
|
+
claimed: false,
|
|
771
|
+
};
|
|
772
|
+
writerAcquisitionScope.run(acquisition, () =>
|
|
773
|
+
withSqliteBackgroundWriter(() => db.exec("BEGIN IMMEDIATE")),
|
|
774
|
+
);
|
|
775
|
+
return performance.now();
|
|
599
776
|
} catch (error) {
|
|
600
777
|
if (!isTransientSqliteError(error)) throw error;
|
|
601
778
|
const elapsed = performance.now() - started;
|
|
602
779
|
if (elapsed >= FOREGROUND_ACQUISITION_BUDGET_MS) {
|
|
603
|
-
|
|
604
|
-
`
|
|
780
|
+
reportSqliteDiagnostic(
|
|
781
|
+
`sqlite writer site=${site} lane=background acquire_ms=${Math.round(elapsed)} attempts=${attempts} outcome=busy`,
|
|
605
782
|
);
|
|
606
783
|
throw error;
|
|
607
784
|
}
|
|
@@ -625,27 +802,31 @@ export async function withAsyncPrivilegedWriter<T>(db: Database, operation: () =
|
|
|
625
802
|
for (;;) {
|
|
626
803
|
attempts++;
|
|
627
804
|
try {
|
|
628
|
-
const
|
|
629
|
-
|
|
805
|
+
const acquisition: WriterAcquisition = {
|
|
806
|
+
site: "privileged_writer",
|
|
807
|
+
lane: "foreground",
|
|
808
|
+
startedAt: started,
|
|
809
|
+
attempts,
|
|
810
|
+
claimed: false,
|
|
811
|
+
};
|
|
812
|
+
// The acquisition and hold of this transaction are reported when it
|
|
813
|
+
// commits or rolls back (see endWriterTransaction).
|
|
814
|
+
return admissionScope.run(true, () =>
|
|
815
|
+
withSqliteTransformPass(() =>
|
|
816
|
+
writerAcquisitionScope.run(acquisition, () =>
|
|
817
|
+
withPrivilegedWriter(db, operation),
|
|
818
|
+
),
|
|
819
|
+
),
|
|
630
820
|
);
|
|
631
|
-
const elapsed = performance.now() - started;
|
|
632
|
-
if (elapsed >= 250)
|
|
633
|
-
console.warn(
|
|
634
|
-
`[${new Date().toISOString()}] [magic-context] sqlite acquisition site=privileged_writer lane=foreground elapsed=${Math.round(elapsed)}ms attempts=${attempts} outcome=acquired`,
|
|
635
|
-
);
|
|
636
|
-
return result;
|
|
637
821
|
} catch (error) {
|
|
638
822
|
// A callback failure can occur after writes; only retry a failed BEGIN.
|
|
639
823
|
if (!(error instanceof SqliteAcquisitionBusyError)) throw error;
|
|
640
824
|
const elapsed = performance.now() - started;
|
|
641
825
|
if (elapsed >= FOREGROUND_ACQUISITION_BUDGET_MS) {
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
throw error instanceof SqliteAcquisitionBusyError
|
|
647
|
-
? error
|
|
648
|
-
: new SqliteAcquisitionBusyError(error);
|
|
826
|
+
reportSqliteDiagnostic(
|
|
827
|
+
`sqlite writer site=privileged_writer lane=foreground acquire_ms=${Math.round(elapsed)} attempts=${attempts} outcome=busy`,
|
|
828
|
+
);
|
|
829
|
+
throw error;
|
|
649
830
|
}
|
|
650
831
|
await new Promise<void>((resolve) =>
|
|
651
832
|
setTimeout(
|
|
@@ -680,7 +861,9 @@ export function withPrivilegedWriter<T>(db: Database, operation: () => T): T {
|
|
|
680
861
|
const previousDepth = privilegeDepth.get(db) ?? 0;
|
|
681
862
|
const nested = isInTransaction(db);
|
|
682
863
|
const savepoint = "mc_privilege_scope";
|
|
683
|
-
|
|
864
|
+
// Timed from the moment the lock is held, so a slow-write report measures
|
|
865
|
+
// the hold and not the wait for BEGIN IMMEDIATE.
|
|
866
|
+
let transactionStartedAt: number | undefined;
|
|
684
867
|
if (nested) {
|
|
685
868
|
db.exec(`SAVEPOINT ${savepoint}`);
|
|
686
869
|
} else {
|
|
@@ -691,6 +874,7 @@ export function withPrivilegedWriter<T>(db: Database, operation: () => T): T {
|
|
|
691
874
|
throw new SqliteAcquisitionBusyError(error);
|
|
692
875
|
throw error;
|
|
693
876
|
}
|
|
877
|
+
transactionStartedAt = performance.now();
|
|
694
878
|
}
|
|
695
879
|
privilegeDepth.set(db, previousDepth + 1);
|
|
696
880
|
try {
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it } from "bun:test";
|
|
2
|
+
import { bindStaleBuildNotice } from "../plugin/stale-build-notice";
|
|
3
|
+
import { __resetNotificationStateForTests, drainNotifications } from "./rpc-notifications";
|
|
4
|
+
import {
|
|
5
|
+
classifyStalePluginBuild,
|
|
6
|
+
importPluginModule,
|
|
7
|
+
registerStalePluginBuildHost,
|
|
8
|
+
StalePluginBuildError,
|
|
9
|
+
stalePluginBuildDiagnostic,
|
|
10
|
+
} from "./stale-plugin-build";
|
|
11
|
+
|
|
12
|
+
function reset(): void {
|
|
13
|
+
delete (globalThis as Record<symbol, unknown>)[Symbol.for("magic-context.stale-plugin-build")];
|
|
14
|
+
__resetNotificationStateForTests();
|
|
15
|
+
}
|
|
16
|
+
beforeEach(reset);
|
|
17
|
+
afterEach(reset);
|
|
18
|
+
|
|
19
|
+
const dist = "/tmp/magic-context/fixture/packages/pi-plugin/dist";
|
|
20
|
+
const missing = (path: string) =>
|
|
21
|
+
new Error(`Cannot find module '${path}' imported from ${dist}/index.js`);
|
|
22
|
+
|
|
23
|
+
describe("stale plugin build classification", () => {
|
|
24
|
+
it("recognizes Node, Bun, file URLs and relative imports only inside the loaded package dist", () => {
|
|
25
|
+
registerStalePluginBuildHost({ moduleUrl: `file://${dist}/index.js`, harness: "pi" });
|
|
26
|
+
for (const error of [
|
|
27
|
+
missing(`${dist}/index-old.js`),
|
|
28
|
+
missing(`file://${dist}/index-old.js`),
|
|
29
|
+
new Error(`Cannot find module './index-old.js' from '${dist}/index.js'`),
|
|
30
|
+
`BuildMessage: ENOENT reading "${dist}/index-old.js"`,
|
|
31
|
+
]) {
|
|
32
|
+
expect(classifyStalePluginBuild(error)?.chunk).toBe(`${dist}/index-old.js`);
|
|
33
|
+
}
|
|
34
|
+
for (const error of [
|
|
35
|
+
missing("quickjs-emscripten"),
|
|
36
|
+
missing(`${dist}-other/index-old.js`),
|
|
37
|
+
missing(`${dist}/../src/index-old.js`),
|
|
38
|
+
missing("/another/package/dist/index-old.js"),
|
|
39
|
+
new Error(`ENOENT: no such file or directory, open '${dist}/note.txt'`),
|
|
40
|
+
new Error(`network error mentioning ${dist}/index-old.js`),
|
|
41
|
+
new Error(`Cannot find module '../src/missing.js' from '${dist}/index.js'`),
|
|
42
|
+
])
|
|
43
|
+
expect(classifyStalePluginBuild(error)).toBeNull();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("recognizes Windows paths without confusing an external package for our dist", () => {
|
|
47
|
+
registerStalePluginBuildHost({
|
|
48
|
+
moduleUrl: "file:///C:/dev/pi-plugin/dist/index.js",
|
|
49
|
+
harness: "pi",
|
|
50
|
+
});
|
|
51
|
+
expect(
|
|
52
|
+
classifyStalePluginBuild(missing("C:\\dev\\pi-plugin\\dist\\index-old.js"))?.chunk,
|
|
53
|
+
).toBe("c:/dev/pi-plugin/dist/index-old.js");
|
|
54
|
+
expect(classifyStalePluginBuild(missing("C:\\other\\dist\\index-old.js"))).toBeNull();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("does not classify source-mode missing modules using the error's dist path", () => {
|
|
58
|
+
registerStalePluginBuildHost({
|
|
59
|
+
moduleUrl: "file:///tmp/plugin/src/index.ts",
|
|
60
|
+
harness: "pi",
|
|
61
|
+
});
|
|
62
|
+
expect(classifyStalePluginBuild(missing(`${dist}/index-old.js`))).toBeNull();
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("warns once per process and logs once per missing chunk across registrations and wakes", () => {
|
|
66
|
+
const notices: string[] = [];
|
|
67
|
+
const host = {
|
|
68
|
+
moduleUrl: `file://${dist}/index.js`,
|
|
69
|
+
harness: "pi" as const,
|
|
70
|
+
notify: (message: string) => notices.push(message),
|
|
71
|
+
};
|
|
72
|
+
registerStalePluginBuildHost(host);
|
|
73
|
+
const error = missing(`${dist}/index-first.js`);
|
|
74
|
+
expect(stalePluginBuildDiagnostic(error)).toContain("stale plugin build");
|
|
75
|
+
registerStalePluginBuildHost(host); // Another instance or a reload.
|
|
76
|
+
expect(stalePluginBuildDiagnostic(error)).toBeNull();
|
|
77
|
+
expect(stalePluginBuildDiagnostic(`dry-run failed: ${error.message}`)).toBeNull();
|
|
78
|
+
expect(stalePluginBuildDiagnostic(missing(`${dist}/index-second.js`))).toContain(
|
|
79
|
+
"index-second.js",
|
|
80
|
+
);
|
|
81
|
+
expect(notices).toEqual([
|
|
82
|
+
"Magic Context was rebuilt while this Pi was running; type /reload to load the new build",
|
|
83
|
+
]);
|
|
84
|
+
expect(stalePluginBuildDiagnostic(new Error(notices[0]))).toBeNull();
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("delivers an early failure when the Pi UI becomes available, without logging it again", () => {
|
|
88
|
+
const notices: string[] = [];
|
|
89
|
+
registerStalePluginBuildHost({ moduleUrl: `file://${dist}/index.js`, harness: "pi" });
|
|
90
|
+
expect(stalePluginBuildDiagnostic(missing(`${dist}/index-first.js`))).toContain(
|
|
91
|
+
"stale plugin build",
|
|
92
|
+
);
|
|
93
|
+
registerStalePluginBuildHost({
|
|
94
|
+
moduleUrl: `file://${dist}/index.js`,
|
|
95
|
+
harness: "pi",
|
|
96
|
+
notify: (message) => notices.push(message),
|
|
97
|
+
});
|
|
98
|
+
expect(stalePluginBuildDiagnostic(missing(`${dist}/index-first.js`))).toBeNull();
|
|
99
|
+
expect(notices).toHaveLength(1);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("queues useful OpenCode 2 guidance even without the legacy SDK toast API", () => {
|
|
103
|
+
bindStaleBuildNotice({}, "file:///tmp/plugin/dist/v2/server.js", "opencode2");
|
|
104
|
+
stalePluginBuildDiagnostic(missing("/tmp/plugin/dist/v2/index-old.js"));
|
|
105
|
+
stalePluginBuildDiagnostic(missing("/tmp/plugin/dist/v2/index-old.js"));
|
|
106
|
+
const notifications = drainNotifications();
|
|
107
|
+
expect(notifications).toHaveLength(1);
|
|
108
|
+
expect(notifications[0].payload.message).toBe(
|
|
109
|
+
"Magic Context was rebuilt while this OpenCode host was running; restart the host to load the new build",
|
|
110
|
+
);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("guards arbitrary lazy imports while preserving unrelated errors", async () => {
|
|
114
|
+
registerStalePluginBuildHost({ moduleUrl: `file://${dist}/index.js`, harness: "pi" });
|
|
115
|
+
const error = missing(`${dist}/index-old.js`);
|
|
116
|
+
await expect(
|
|
117
|
+
importPluginModule(async () => {
|
|
118
|
+
throw error;
|
|
119
|
+
}),
|
|
120
|
+
).rejects.toBeInstanceOf(StalePluginBuildError);
|
|
121
|
+
const unrelated = missing("an-external-dependency");
|
|
122
|
+
await expect(
|
|
123
|
+
importPluginModule(async () => {
|
|
124
|
+
throw unrelated;
|
|
125
|
+
}),
|
|
126
|
+
).rejects.toBe(unrelated);
|
|
127
|
+
expect(await importPluginModule(async () => 4)).toBe(4);
|
|
128
|
+
});
|
|
129
|
+
});
|