@cortexkit/opencode-magic-context 0.45.0 → 0.46.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -0
- package/dist/{announcement-f75t58v9.js → announcement-y35wzg2r.js} +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/live-run-config.d.ts.map +1 -1
- package/dist/config/migrate-config-location.d.ts.map +1 -1
- package/dist/config/schema/magic-context.d.ts +13 -7
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/{conflict-warning-hook-5yrz2r24.js → conflict-warning-hook-7fj2b9jw.js} +6 -5
- package/dist/context-sh2m2vde.js +4525 -0
- package/dist/{derive-budgets-a63zsm5c.js → derive-budgets-7nj7r1rv.js} +2 -2
- package/dist/embedding-worker.js +4 -4
- package/dist/features/magic-context/checkout-claim-fake-subc.test-support.d.ts +45 -0
- package/dist/features/magic-context/checkout-claim-fake-subc.test-support.d.ts.map +1 -0
- package/dist/features/magic-context/checkout-claim.d.ts +155 -0
- package/dist/features/magic-context/checkout-claim.d.ts.map +1 -0
- package/dist/features/magic-context/compaction-marker.d.ts +20 -3
- package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-storage.d.ts +23 -2
- package/dist/features/magic-context/compartment-storage.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/provider-output-failure.d.ts +6 -2
- package/dist/features/magic-context/dreamer/provider-output-failure.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/provider-output-failure.test-support.d.ts +30 -0
- package/dist/features/magic-context/dreamer/provider-output-failure.test-support.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-executor.d.ts +9 -0
- package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-gates.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify-diff.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify-gate.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify.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/memory/embedding-local.d.ts.map +1 -1
- package/dist/features/magic-context/memory/project-identity-cache.d.ts.map +1 -1
- package/dist/features/magic-context/memory/storage-memory-verifications.d.ts.map +1 -1
- package/dist/features/magic-context/memory/storage-memory.d.ts +3 -0
- package/dist/features/magic-context/memory/storage-memory.d.ts.map +1 -1
- package/dist/features/magic-context/memory/verification-paths.d.ts +2 -2
- package/dist/features/magic-context/memory/verification-paths.d.ts.map +1 -1
- package/dist/features/magic-context/merged-reasoning-decisions.d.ts.map +1 -1
- package/dist/features/magic-context/message-index-async.d.ts +3 -3
- package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
- package/dist/features/magic-context/message-index.d.ts +2 -0
- package/dist/features/magic-context/message-index.d.ts.map +1 -1
- package/dist/features/magic-context/migration-v95-perf-indexes.d.ts +12 -0
- package/dist/features/magic-context/migration-v95-perf-indexes.d.ts.map +1 -0
- package/dist/features/magic-context/migration-worker-client.d.ts +4 -4
- package/dist/features/magic-context/migration-worker-client.d.ts.map +1 -1
- package/dist/features/magic-context/migrations.d.ts +1 -0
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/mural/render-trigger.d.ts.map +1 -1
- package/dist/features/magic-context/mural/resolve-mural.d.ts +15 -4
- package/dist/features/magic-context/mural/resolve-mural.d.ts.map +1 -1
- package/dist/features/magic-context/mural/source-revision.d.ts +7 -0
- package/dist/features/magic-context/mural/source-revision.d.ts.map +1 -0
- package/dist/features/magic-context/mural/storage-mural-cues.d.ts.map +1 -1
- package/dist/features/magic-context/reclaim-protection.d.ts +15 -10
- package/dist/features/magic-context/reclaim-protection.d.ts.map +1 -1
- package/dist/features/magic-context/session-cache-ttl.d.ts +4 -2
- package/dist/features/magic-context/session-cache-ttl.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/capabilities.d.ts +3 -0
- package/dist/features/magic-context/smart-notes/capabilities.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/compiler.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/github-token.d.ts +5 -0
- package/dist/features/magic-context/smart-notes/github-token.d.ts.map +1 -0
- package/dist/features/magic-context/smart-notes/runner.d.ts +1 -0
- package/dist/features/magic-context/smart-notes/runner.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts +12 -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 +6 -0
- package/dist/features/magic-context/smart-notes/ssrf-guard.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/storage.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/types.d.ts +2 -0
- package/dist/features/magic-context/smart-notes/types.d.ts.map +1 -1
- package/dist/features/magic-context/storage-clone.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts +6 -9
- package/dist/features/magic-context/storage-db.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-ops.d.ts +8 -1
- package/dist/features/magic-context/storage-ops.d.ts.map +1 -1
- package/dist/features/magic-context/storage-replay-document.d.ts +7 -0
- package/dist/features/magic-context/storage-replay-document.d.ts.map +1 -1
- package/dist/features/magic-context/storage-schema-helpers.d.ts +2 -0
- package/dist/features/magic-context/storage-schema-helpers.d.ts.map +1 -1
- package/dist/features/magic-context/storage-session-tables.d.ts.map +1 -1
- package/dist/features/magic-context/storage-source.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tags.d.ts +11 -3
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +2 -2
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/features/magic-context/temporal-decisions.d.ts +10 -0
- package/dist/features/magic-context/temporal-decisions.d.ts.map +1 -0
- package/dist/features/magic-context/tool-definition-tokens.d.ts +2 -0
- package/dist/features/magic-context/tool-definition-tokens.d.ts.map +1 -1
- package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -1
- package/dist/features/magic-context/types.d.ts +7 -6
- package/dist/features/magic-context/types.d.ts.map +1 -1
- package/dist/features/magic-context/window-report-ledger.d.ts.map +1 -1
- package/dist/hooks/auto-update-checker/index.d.ts.map +1 -1
- package/dist/hooks/magic-context/apply-operations.d.ts +8 -0
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
- package/dist/hooks/magic-context/cache-busting-signals.d.ts +6 -3
- package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -1
- package/dist/hooks/magic-context/channel2-cycle.d.ts +2 -0
- package/dist/hooks/magic-context/channel2-cycle.d.ts.map +1 -1
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts +7 -0
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-prompt.d.ts +2 -2
- package/dist/hooks/magic-context/compartment-prompt.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-render-epoch.d.ts +8 -0
- package/dist/hooks/magic-context/compartment-render-epoch.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts +18 -4
- package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/ctx-reduce-availability.d.ts +12 -0
- package/dist/hooks/magic-context/ctx-reduce-availability.d.ts.map +1 -1
- package/dist/hooks/magic-context/decision-calibration.d.ts +3 -0
- package/dist/hooks/magic-context/decision-calibration.d.ts.map +1 -1
- package/dist/hooks/magic-context/default-protection-pressure.test-support.d.ts +37 -0
- package/dist/hooks/magic-context/default-protection-pressure.test-support.d.ts.map +1 -0
- package/dist/hooks/magic-context/drop-stale-reduce-calls.d.ts +4 -0
- package/dist/hooks/magic-context/drop-stale-reduce-calls.d.ts.map +1 -1
- package/dist/hooks/magic-context/edit-marker.d.ts.map +1 -1
- package/dist/hooks/magic-context/emergency-drop.d.ts +2 -0
- package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -1
- package/dist/hooks/magic-context/emergency-fail-closed.d.ts +21 -1
- package/dist/hooks/magic-context/emergency-fail-closed.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-handler.d.ts +5 -0
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts +30 -1
- 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-prompt-fit.d.ts +4 -2
- package/dist/hooks/magic-context/historian-prompt-fit.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts +2 -1
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts +9 -10
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-measured-request.d.ts +69 -0
- package/dist/hooks/magic-context/lkg-measured-request.d.ts.map +1 -0
- package/dist/hooks/magic-context/lkg-persist.d.ts +2 -0
- package/dist/hooks/magic-context/lkg-persist.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-replay-fit.d.ts +14 -0
- package/dist/hooks/magic-context/lkg-replay-fit.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-replay.d.ts +10 -1
- package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-slot.d.ts +4 -0
- package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-state-sync.d.ts +2 -0
- package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
- 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 +17 -5
- package/dist/hooks/magic-context/note-nudger.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-db.d.ts +1 -0
- package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-formatting.d.ts +7 -0
- package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts +4 -0
- package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts +2 -0
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
- package/dist/hooks/magic-context/reference-retrieval.d.ts +27 -17
- package/dist/hooks/magic-context/reference-retrieval.d.ts.map +1 -1
- package/dist/hooks/magic-context/request-hook-order.d.ts +56 -0
- package/dist/hooks/magic-context/request-hook-order.d.ts.map +1 -0
- package/dist/hooks/magic-context/rust-mode-transform.d.ts +22 -3
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/strip-content.d.ts +4 -2
- package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
- package/dist/hooks/magic-context/supersession-reclaim.d.ts +4 -0
- package/dist/hooks/magic-context/supersession-reclaim.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts +7 -0
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts +12 -3
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
- package/dist/hooks/magic-context/temporal-awareness.d.ts +6 -3
- package/dist/hooks/magic-context/temporal-awareness.d.ts.map +1 -1
- package/dist/hooks/magic-context/temporal-served-projection.d.ts +4 -0
- package/dist/hooks/magic-context/temporal-served-projection.d.ts.map +1 -0
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/tool-reclaim.d.ts +2 -0
- package/dist/hooks/magic-context/tool-reclaim.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-message-helpers.d.ts +5 -0
- package/dist/hooks/magic-context/transform-message-helpers.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +41 -17
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +12 -0
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
- package/dist/{index-vvtfyw1z.js → index-0d3g3461.js} +5 -13
- package/dist/index-1bc61ans.js +154 -0
- package/dist/{index-n96ag4rk.js → index-1zx87sdm.js} +5 -1
- package/dist/{index-4krbw8z9.js → index-3h0ybwah.js} +608 -102
- package/dist/{index-gd5qx1j9.js → index-5eqk6z3s.js} +62 -1
- package/dist/index-5gq3b2ya.js +494 -0
- package/dist/{index-8fgkmxmy.js → index-5p8jdswx.js} +4 -3
- package/dist/{index-75zjgwga.js → index-7qw742ev.js} +1 -1
- package/dist/{index-f85teqck.js → index-8da2zjhz.js} +3 -256
- package/dist/{index-q7yesyk9.js → index-8x2v7gg9.js} +25 -24
- package/dist/{index-w9jwmntv.js → index-b35pxds2.js} +9 -1
- package/dist/{v2/server-a4m2b1yv.js → index-fg34g6a5.js} +55 -1
- package/dist/index-hpecdzec.js +28506 -0
- package/dist/{index-2ntg5sd4.js → index-k5bdx1bx.js} +9 -5
- package/dist/{index-bmzf7zxv.js → index-majxda46.js} +23 -5
- package/dist/{index-2aq21j41.js → index-pkbcrdqs.js} +418 -127
- package/dist/{index-remp7e2g.js → index-q4yp4b52.js} +16 -1
- package/dist/{index-fr2z4qy8.js → index-r5hmbx3t.js} +132 -169
- package/dist/index-sfnj6h8h.js +259 -0
- package/dist/{index-xgt9k6c6.js → index-sgthv3f7.js} +2 -1
- package/dist/index-sj29b3z2.js +30 -0
- package/dist/{index-16ny736w.js → index-sjthx78w.js} +20526 -19817
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1983 -33118
- package/dist/{message-time-backfill-an311pmk.js → message-time-backfill-68gj6t3e.js} +2 -2
- package/dist/migration-worker.js +12 -7
- package/dist/plugin/dream-timer.d.ts +25 -1
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +2 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/messages-transform.d.ts +13 -0
- package/dist/plugin/messages-transform.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts +4 -0
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/plugin/subagent-tool-policy.d.ts +14 -0
- package/dist/plugin/subagent-tool-policy.d.ts.map +1 -0
- package/dist/plugin/tool-registry.d.ts +1 -0
- package/dist/plugin/tool-registry.d.ts.map +1 -1
- package/dist/{read-session-chunk-8rxs0tc9.js → read-session-chunk-egz7r68d.js} +8 -8
- package/dist/{recomp-orchestrator-nzamtw29.js → recomp-orchestrator-y15j0rb9.js} +15 -15
- package/dist/{send-session-notification-nqpv7cne.js → send-session-notification-dyw42dtr.js} +4 -4
- package/dist/shared/announcement.d.ts.map +1 -1
- package/dist/shared/cache-ttl-display.d.ts +6 -4
- package/dist/shared/cache-ttl-display.d.ts.map +1 -1
- package/dist/shared/model-cache-ttl.d.ts +1 -1
- package/dist/shared/model-cache-ttl.d.ts.map +1 -1
- package/dist/shared/model-suggestion-retry.d.ts +2 -0
- 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/protected-tools-policy.d.ts +6 -0
- package/dist/shared/protected-tools-policy.d.ts.map +1 -0
- package/dist/shared/quota-diagnostic.d.ts +4 -0
- package/dist/shared/quota-diagnostic.d.ts.map +1 -0
- package/dist/shared/rpc-server.d.ts.map +1 -1
- 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 +9 -0
- package/dist/shared/sqlite-helpers.d.ts.map +1 -1
- package/dist/shared/sqlite.d.ts +10 -0
- package/dist/shared/sqlite.d.ts.map +1 -1
- package/dist/shared/status-summary.d.ts +1 -0
- package/dist/shared/status-summary.d.ts.map +1 -1
- package/dist/shared/status-view-check.d.ts.map +1 -1
- package/dist/shared/status-view.d.ts +4 -0
- package/dist/shared/status-view.d.ts.map +1 -1
- package/dist/shared/storage-permissions.d.ts +24 -0
- package/dist/shared/storage-permissions.d.ts.map +1 -1
- package/dist/shared/temporal-upgrade-fixture.d.ts +19 -0
- package/dist/shared/temporal-upgrade-fixture.d.ts.map +1 -0
- package/dist/shared/user-facing-codes.d.ts +5 -0
- package/dist/shared/user-facing-codes.d.ts.map +1 -1
- package/dist/shared/write-transaction-timing.d.ts +8 -1
- package/dist/shared/write-transaction-timing.d.ts.map +1 -1
- package/dist/tools/ctx-expand/render.d.ts.map +1 -1
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
- package/dist/tools/ctx-reduce/constants.d.ts +2 -0
- package/dist/tools/ctx-reduce/constants.d.ts.map +1 -1
- package/dist/tools/ctx-reduce/tools.d.ts +4 -4
- package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
- package/dist/{transform-postprocess-phase-414phndq.js → transform-postprocess-phase-bqhz6vdr.js} +15 -15
- package/dist/v2/context-zecmzk5s.js +52209 -0
- package/dist/v2/{derive-budgets-v0krf3t7.js → derive-budgets-kdgp4s3r.js} +4 -3
- package/dist/v2/embedding-worker.js +6 -5
- package/dist/v2/fold/boundary.d.ts +2 -0
- package/dist/v2/fold/boundary.d.ts.map +1 -1
- package/dist/v2/fold/owner.d.ts.map +1 -1
- package/dist/v2/hidden-child-native.d.ts +7 -0
- package/dist/v2/hidden-child-native.d.ts.map +1 -1
- package/dist/v2/hidden-child-record.d.ts +8 -0
- package/dist/v2/hidden-child-record.d.ts.map +1 -1
- package/dist/v2/hidden-completion.d.ts.map +1 -1
- package/dist/v2/hooks/channel2.d.ts +2 -0
- package/dist/v2/hooks/channel2.d.ts.map +1 -1
- package/dist/v2/hooks/context.d.ts +2 -2
- package/dist/v2/hooks/context.d.ts.map +1 -1
- package/dist/v2/hooks/dream-timer.d.ts +39 -0
- package/dist/v2/hooks/dream-timer.d.ts.map +1 -0
- package/dist/v2/hooks/dream-trigger.d.ts +15 -1
- package/dist/v2/hooks/dream-trigger.d.ts.map +1 -1
- package/dist/v2/hooks/hidden-child.d.ts +54 -3
- package/dist/v2/hooks/hidden-child.d.ts.map +1 -1
- package/dist/v2/hooks/payload.d.ts.map +1 -1
- package/dist/v2/hooks/store.d.ts.map +1 -1
- package/dist/v2/hooks/tools.d.ts +1 -1
- package/dist/v2/hooks/tools.d.ts.map +1 -1
- package/dist/v2/hooks/types.d.ts +12 -1
- package/dist/v2/hooks/types.d.ts.map +1 -1
- package/dist/v2/hooks/update-check.d.ts.map +1 -1
- package/dist/v2/{message-time-backfill-0n93vrd7.js → message-time-backfill-r6qkem1x.js} +3 -3
- package/dist/v2/migration-worker.js +13 -8
- package/dist/v2/{read-session-chunk-hjza38hr.js → read-session-chunk-8vjp6581.js} +9 -9
- package/dist/v2/recomp-orchestrator-8ejxvrzz.js +39 -0
- package/dist/v2/{safe-notification-target-wtj0bbc2.js → safe-notification-target-eb1n1vfb.js} +2 -2
- package/dist/v2/{send-session-notification-mq9frrtm.js → send-session-notification-qs0j78v6.js} +6 -6
- package/dist/v2/server-14vq4kpm.js +30 -0
- package/dist/v2/server-1bc61ans.js +154 -0
- package/dist/v2/{server-n96ag4rk.js → server-1zx87sdm.js} +5 -1
- package/dist/v2/server-3n4q9xme.js +79 -0
- package/dist/v2/{server-rhdgxp1t.js → server-51dv1pr5.js} +63 -2
- package/dist/v2/{server-5317ykaf.js → server-6r257mf5.js} +1 -1
- package/dist/v2/server-84w6rvvf.js +14 -0
- package/dist/v2/{server-qpg6wf72.js → server-ajzeteqw.js} +9 -1
- package/dist/v2/server-c5gz8wph.js +3892 -0
- package/dist/v2/{server-v5xgft5v.js → server-e29d7p7c.js} +188 -3533
- package/dist/{index-a4m2b1yv.js → v2/server-fg34g6a5.js} +55 -1
- package/dist/v2/{server-e36nf2p1.js → server-frbm99q5.js} +1595 -1599
- package/dist/v2/{server-remp7e2g.js → server-g0fjrkta.js} +16 -1
- package/dist/v2/{server-c4g2y1z8.js → server-jc7y02q0.js} +2816 -5392
- package/dist/v2/{server-z19x7eqz.js → server-mcfawjgc.js} +4 -4
- package/dist/v2/{server-hfjfbg59.js → server-qp5hx1ad.js} +608 -105
- package/dist/v2/server-vs5gpnd4.js +493 -0
- package/dist/v2/{server-w99cyt6a.js → server-wvjvfhck.js} +14 -6
- package/dist/v2/server-xa4xe3rv.js +3351 -0
- package/dist/v2/{server-0jqw05sa.js → server-y8maxeft.js} +6 -84
- package/dist/v2/server.d.ts.map +1 -1
- package/dist/v2/server.js +104 -49288
- package/dist/v2/store-reader.d.ts +39 -1
- package/dist/v2/store-reader.d.ts.map +1 -1
- package/dist/v2/tool-result.d.ts +8 -0
- package/dist/v2/tool-result.d.ts.map +1 -0
- package/dist/v2/tui/index.d.ts.map +1 -1
- package/dist/v2/{wrapup-orchestrator-tbyx78dz.js → wrapup-orchestrator-0snhvwcv.js} +20 -16
- package/dist/wrapup-orchestrator-39amhv9s.js +26 -0
- package/package.json +26 -10
- package/src/config/index.ts +21 -4
- package/src/config/latch-permanence-guard.test.ts +6 -1
- package/src/config/live-run-config.ts +1 -0
- package/src/config/migrate-config-location.test.ts +31 -1
- package/src/config/migrate-config-location.ts +8 -41
- package/src/config/protected-tools.test.ts +70 -0
- package/src/config/raw-loader.test.ts +15 -0
- package/src/config/raw-loader.ts +1 -1
- package/src/config/removed-agent-source-fence.test.ts +10 -1
- package/src/config/schema/magic-context.test.ts +20 -1
- package/src/config/schema/magic-context.ts +26 -7
- package/src/shared/announcement.ts +6 -5
- package/src/shared/cache-ttl-display.test.ts +1 -1
- package/src/shared/cache-ttl-display.ts +17 -16
- package/src/shared/fold-render-lock-fence.test.ts +84 -0
- package/src/shared/fold-render-lock-fixtures.test.ts +276 -0
- package/src/shared/model-cache-ttl.test.ts +2 -2
- package/src/shared/model-cache-ttl.ts +8 -4
- package/src/shared/model-suggestion-retry.test.ts +104 -1
- package/src/shared/model-suggestion-retry.ts +63 -6
- package/src/shared/models-dev-cache.ts +3 -11
- package/src/shared/protected-tools-policy.ts +23 -0
- package/src/shared/quota-diagnostic.ts +9 -0
- package/src/shared/rpc-server.ts +6 -54
- package/src/shared/sqlite-context-pragmas.test.ts +105 -0
- package/src/shared/sqlite-context-pragmas.ts +24 -0
- package/src/shared/sqlite-helpers.ts +17 -0
- package/src/shared/sqlite.ts +75 -0
- package/src/shared/status-detail-text.test.ts +18 -1
- package/src/shared/status-summary.ts +11 -0
- package/src/shared/status-view-check.ts +5 -0
- package/src/shared/status-view.test.ts +11 -2
- package/src/shared/status-view.ts +12 -1
- package/src/shared/storage-permissions.test.ts +204 -0
- package/src/shared/storage-permissions.ts +192 -0
- package/src/shared/temporal-upgrade-fixture.ts +50 -0
- package/src/shared/user-facing-codes.ts +6 -0
- package/src/shared/write-transaction-timing.test.ts +39 -0
- package/src/shared/write-transaction-timing.ts +25 -1
- package/src/tui/dialogs/status-dialog-render.test.ts +1 -1
- package/src/tui/index.tsx +3 -1
- package/src/tui/startup-order.test.ts +16 -0
- package/src/tui-compiled/index.tsx +3 -1
- package/src/v2/tui/index.ts +9 -2
- package/dist/index-anq4nn6f.js +0 -131
- package/dist/index-e44zzy84.js +0 -10
- package/dist/index-x23gah8c.js +0 -16
- package/dist/v2/recomp-orchestrator-1aq7h44c.js +0 -36
- package/dist/v2/server-e44zzy84.js +0 -10
- package/dist/v2/server-fgmxwrgy.js +0 -16
- package/dist/v2/server-r7cmye3k.js +0 -131
- package/dist/wrapup-orchestrator-h28bqsy6.js +0 -26
- package/dist/v2/{server-ckpc8pxy.js → server-1qbnzc80.js} +8 -8
|
@@ -9,6 +9,25 @@ import {
|
|
|
9
9
|
} from "./magic-context";
|
|
10
10
|
|
|
11
11
|
describe("MagicContextConfigSchema", () => {
|
|
12
|
+
it("documents that Rust transform mode always keeps the shared data directory private", () => {
|
|
13
|
+
const inputSchema = MagicContextConfigSchema._def.in as unknown as {
|
|
14
|
+
shape: {
|
|
15
|
+
storage: {
|
|
16
|
+
unwrap: () => {
|
|
17
|
+
shape: {
|
|
18
|
+
enforce_private_permissions: { description?: string };
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
const description =
|
|
25
|
+
inputSchema.shape.storage.unwrap().shape.enforce_private_permissions.description ?? "";
|
|
26
|
+
expect(description).toContain("Rust transform mode");
|
|
27
|
+
expect(description).toContain("always keeps the shared data directory owner-only 0700");
|
|
28
|
+
expect(description).toContain("regardless of this setting");
|
|
29
|
+
});
|
|
30
|
+
|
|
12
31
|
describe("defaults", () => {
|
|
13
32
|
it("applies defaults for an empty config", () => {
|
|
14
33
|
const result = MagicContextConfigSchema.parse({});
|
|
@@ -166,7 +185,7 @@ describe("MagicContextConfigSchema", () => {
|
|
|
166
185
|
|
|
167
186
|
const result = MagicContextConfigSchema.parse(input);
|
|
168
187
|
|
|
169
|
-
expect(result).toEqual(input);
|
|
188
|
+
expect(result).toEqual({ ...input, protected_tools: { todowrite: 1, ctx_reduce: 3 } });
|
|
170
189
|
});
|
|
171
190
|
|
|
172
191
|
it("accepts a boolean storage permission policy and rejects non-booleans", () => {
|
|
@@ -8,6 +8,7 @@ import type {
|
|
|
8
8
|
} from "../../features/magic-context/dreamer/task-registry";
|
|
9
9
|
import { toolTemplateError } from "../../shared/historian-tool-template";
|
|
10
10
|
import { isValidPromptSurfaceModelKey } from "../../shared/prompt-surface";
|
|
11
|
+
import { DEFAULT_PROTECTED_TOOLS, mergeProtectedTools } from "../../shared/protected-tools-policy";
|
|
11
12
|
import { AgentOverrideConfigSchema } from "./agent-overrides";
|
|
12
13
|
|
|
13
14
|
export const DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE = 65;
|
|
@@ -640,6 +641,10 @@ const AgentMetadataSchema = AgentOverrideConfigSchema.pick({
|
|
|
640
641
|
|
|
641
642
|
/** Combined dreamer metadata plus independent strict execution blocks. */
|
|
642
643
|
export const DreamerConfigSchema = AgentMetadataSchema.extend({
|
|
644
|
+
// Its own node rather than the one shared with the historian through
|
|
645
|
+
// AgentMetadataSchema: `dreamer.disable` is a live-reload key and the
|
|
646
|
+
// historian's is not, and the live marker is set on the schema node.
|
|
647
|
+
disable: z.boolean().optional().describe("Disable this agent"),
|
|
643
648
|
runner: z
|
|
644
649
|
.enum(["broca", "host"])
|
|
645
650
|
.optional()
|
|
@@ -918,6 +923,8 @@ export interface MuralConfig {
|
|
|
918
923
|
}
|
|
919
924
|
|
|
920
925
|
export interface MagicContextConfig {
|
|
926
|
+
/** The loader sets this to distinguish an explicit `5m` from the built-in default; users do not configure it. */
|
|
927
|
+
cacheTtlConfigured?: boolean;
|
|
921
928
|
enabled: boolean;
|
|
922
929
|
/** User-level setting that lets a session in the canonical home directory use project memory. */
|
|
923
930
|
allow_home_project: boolean;
|
|
@@ -955,6 +962,7 @@ export interface MagicContextConfig {
|
|
|
955
962
|
execute_threshold_tokens?: { default?: number; [modelKey: string]: number | undefined };
|
|
956
963
|
protected_tokens?: number;
|
|
957
964
|
protected_tags?: number;
|
|
965
|
+
protected_tools: Record<string, number>;
|
|
958
966
|
clear_reasoning_age: number;
|
|
959
967
|
history_budget_percentage: number;
|
|
960
968
|
historian_timeout_ms: number;
|
|
@@ -1038,7 +1046,8 @@ export interface MagicContextConfig {
|
|
|
1038
1046
|
* on its own; when off, the messages sent to the model are byte-identical to
|
|
1039
1047
|
* the age-based-only behavior. Experimental, opt-in, default off until cache
|
|
1040
1048
|
* stability is proven. */
|
|
1041
|
-
|
|
1049
|
+
/** Deprecated and ignored: supersession reclaim is always on. */
|
|
1050
|
+
smart_drops?: unknown;
|
|
1042
1051
|
/**
|
|
1043
1052
|
* Age-tier caveman compression for long user/assistant text parts.
|
|
1044
1053
|
* Graduated from `experimental.caveman_text_compression`; opt-in, default off.
|
|
@@ -1187,7 +1196,7 @@ export const MagicContextConfigSchema = z
|
|
|
1187
1196
|
.union([z.string(), z.object({ default: z.string() }).catchall(z.string())])
|
|
1188
1197
|
.default("5m")
|
|
1189
1198
|
.describe(
|
|
1190
|
-
'How long Magic Context assumes the provider\'s cached prefix stays valid. This is MC\'s own deferral gate — it does not change the provider\'s actual cache lifetime. String (e.g. "5m", "1h", "30s") or per-model object ({ default: "5m", "provider/model": "1h", "provider/*": "never" }); keys resolve most-specific first (exact provider/model, bare model ID, shorter dash-prefixes, then the provider/* wildcard).
|
|
1199
|
+
'How long Magic Context assumes the provider\'s cached prefix stays valid. This is MC\'s own deferral gate — it does not change the provider\'s actual cache lifetime. String (e.g. "5m", "1h", "30s") or per-model object ({ default: "5m", "provider/model": "1h", "provider/*": "never" }); keys resolve most-specific first (exact provider/model, bare model ID, shorter dash-prefixes, then the provider/* wildcard, then default). User and project settings, including an explicit "5m" or object default, apply on the next pass. Only built-in defaults are frozen per session, including across restarts: when unset, GPT-5.6 and later (including gpt-6*, through any provider prefix) use 30m, other models use 5m. /ctx-status shows the effective TTL and whether it comes from your config or a frozen built-in default. Editing the TTL does not itself rewrite prompt bytes; a lowered TTL rebuilds only after normal idle expiry. OpenAI documents at least 30 minutes since the latest write or reuse: https://developers.openai.com/api/docs/guides/prompt-caching (Cache lifetime and Summary of model differences). Set to "never" to mean MC never assumes expiry (for lanes kept warm externally by a cache-keep tool) — disables the idle-TTL heuristic so MC never initiates a rebuild based on elapsed time. Provider-side extended TTL is a separate request-level concern (cache_control: { ttl } in the request body).',
|
|
1191
1200
|
),
|
|
1192
1201
|
prompt_surface: PromptSurfaceConfigSchema.default({ default: "full" }).describe(
|
|
1193
1202
|
"Prompt-surface presets: default is full; models use bare model IDs, provider/model, or provider/* routing keys. Guidance and tool-description overrides are user-level only. OpenCode 1.x, Pi, and OMP register tool descriptions once per process (they follow the default preset). OpenCode 2 rewrites the five ctx_* descriptions per request from the draft model.",
|
|
@@ -1346,12 +1355,12 @@ export const MagicContextConfigSchema = z
|
|
|
1346
1355
|
.boolean()
|
|
1347
1356
|
.default(true)
|
|
1348
1357
|
.describe(
|
|
1349
|
-
"When true (default), Magic Context creates and re-tightens its storage directories to owner-only 0700 and storage files to owner-only 0600. Set false only for a deliberate trusted-group deployment whose operator manages
|
|
1358
|
+
"When true (default), Magic Context creates and re-tightens its TypeScript-mode storage directories to owner-only 0700 and storage files to owner-only 0600. Set false only for a deliberate trusted-group deployment whose operator manages those files externally; in TypeScript mode Magic Context then skips its own creation modes and recursive tightening. In Rust transform mode, ck-mc's store library always keeps the shared data directory owner-only 0700, regardless of this setting. USER-LEVEL ONLY — ignored in project config for security. On Windows, POSIX chmod modes are already meaningless, so this setting is a no-op.",
|
|
1350
1359
|
),
|
|
1351
1360
|
})
|
|
1352
1361
|
.default({ enforce_private_permissions: true })
|
|
1353
1362
|
.describe(
|
|
1354
|
-
"Storage permission policy. The default keeps session content and memories owner-private. Disabling enforcement is for trusted shared-group storage managed externally;
|
|
1363
|
+
"Storage permission policy. The default keeps session content and memories owner-private. Disabling enforcement is for trusted shared-group storage managed externally; TypeScript mode follows that policy, but Rust transform mode always keeps its shared data directory owner-only because ck-mc's store library enforces it.",
|
|
1355
1364
|
),
|
|
1356
1365
|
embedding: EmbeddingConfigSchema.default({
|
|
1357
1366
|
provider: "local",
|
|
@@ -1438,10 +1447,18 @@ export const MagicContextConfigSchema = z
|
|
|
1438
1447
|
"Pi-only child-process extension controls. This setting is user-level only; project configuration cannot choose which extensions a user's subagent children load.",
|
|
1439
1448
|
),
|
|
1440
1449
|
smart_drops: z
|
|
1441
|
-
.
|
|
1442
|
-
.
|
|
1450
|
+
.unknown()
|
|
1451
|
+
.optional()
|
|
1452
|
+
.describe(
|
|
1453
|
+
"Deprecated: ignored. Content-aware supersession reclaim is always on, only on passes already rebuilding the cache. Remove this key; it no longer does anything.",
|
|
1454
|
+
)
|
|
1455
|
+
.meta({ deprecated: true }),
|
|
1456
|
+
protected_tools: z
|
|
1457
|
+
.record(z.string(), z.number().int().nonnegative())
|
|
1458
|
+
.default({ ...DEFAULT_PROTECTED_TOOLS })
|
|
1459
|
+
.transform((map) => mergeProtectedTools(map))
|
|
1443
1460
|
.describe(
|
|
1444
|
-
"
|
|
1461
|
+
"Keep each tool's newest N still-active results in every automatic drop lane (issue 621). User and project maps merge over defaults {todowrite: 1, ctx_reduce: 3}; 0 turns protection off. Names are case-insensitive and ignore leading mcp_. Holds even at 95% pressure, with no byte cap: large protected outputs can reach refusal sooner. Queued drops, from the agent or historian publication, are held until newer calls displace the result and a later cache-rebuilding pass applies them. The historian's summary is unaffected; the raw result leaves at the next fold. Frozen strips are unaffected. Changes and rotation never originate a bust; dropped results are never restored.",
|
|
1445
1462
|
),
|
|
1446
1463
|
caveman_text_compression: z
|
|
1447
1464
|
.object({
|
|
@@ -1571,6 +1588,7 @@ export const MagicContextConfigSchema = z
|
|
|
1571
1588
|
|
|
1572
1589
|
/** Settings whose fresh values can be used by later agent runs without changing rendered prompt bytes. */
|
|
1573
1590
|
export const LIVE_RELOAD_CONFIG_PATHS = [
|
|
1591
|
+
"cache_ttl",
|
|
1574
1592
|
"mural.model",
|
|
1575
1593
|
"toast_duration_ms",
|
|
1576
1594
|
"historian.opencode.model",
|
|
@@ -1589,6 +1607,7 @@ export const LIVE_RELOAD_CONFIG_PATHS = [
|
|
|
1589
1607
|
"commit_cluster_trigger.enabled",
|
|
1590
1608
|
"commit_cluster_trigger.min_clusters",
|
|
1591
1609
|
"memory.auto_promote",
|
|
1610
|
+
"dreamer.disable",
|
|
1592
1611
|
"dreamer.maxTokens",
|
|
1593
1612
|
"dreamer.opencode.model",
|
|
1594
1613
|
"dreamer.opencode.fallback_models",
|
|
@@ -15,10 +15,11 @@
|
|
|
15
15
|
* Leave both empty (`""` and `[]`) to skip the dialog entirely.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
import
|
|
18
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
19
19
|
import * as path from "node:path";
|
|
20
20
|
import { compareSemverCore } from "../hooks/auto-update-checker/semver";
|
|
21
21
|
import { getMagicContextStorageDir } from "./data-path";
|
|
22
|
+
import { ensureStorageDirectorySync, writeStorageFileAtomicSync } from "./storage-permissions";
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* Bump only when there are user-visible changes worth a startup dialog.
|
|
@@ -60,8 +61,8 @@ type AnnouncementStateRead =
|
|
|
60
61
|
function readAnnouncementState(): AnnouncementStateRead {
|
|
61
62
|
try {
|
|
62
63
|
const file = getStateFilePath();
|
|
63
|
-
if (!
|
|
64
|
-
const version =
|
|
64
|
+
if (!existsSync(file)) return { status: "missing" };
|
|
65
|
+
const version = readFileSync(file, "utf-8").trim();
|
|
65
66
|
if (!version) return { status: "error" };
|
|
66
67
|
return { status: "valid", version };
|
|
67
68
|
} catch {
|
|
@@ -88,8 +89,8 @@ export function markAnnouncementSeen(version: string): void {
|
|
|
88
89
|
if (!version) return;
|
|
89
90
|
try {
|
|
90
91
|
const dir = getMagicContextStorageDir();
|
|
91
|
-
|
|
92
|
-
|
|
92
|
+
ensureStorageDirectorySync(dir);
|
|
93
|
+
writeStorageFileAtomicSync(getStateFilePath(), version);
|
|
93
94
|
} catch {
|
|
94
95
|
// best-effort
|
|
95
96
|
}
|
|
@@ -45,7 +45,7 @@ describe("resolveCacheTtlDisplay", () => {
|
|
|
45
45
|
});
|
|
46
46
|
|
|
47
47
|
expect(configured.source).toBe("config");
|
|
48
|
-
expect(session).toEqual({ value: "
|
|
48
|
+
expect(session).toEqual({ value: "1h", source: "config", modelKey });
|
|
49
49
|
expect(fallback).toEqual({ value: "5m", source: "default", modelKey });
|
|
50
50
|
});
|
|
51
51
|
|
|
@@ -10,7 +10,7 @@ export interface CacheTtlDisplay {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export interface ResolveCacheTtlDisplayArgs {
|
|
13
|
-
frozen?: ResolvedCacheTtl;
|
|
13
|
+
frozen?: ResolvedCacheTtl & { builtInDefault?: ResolvedCacheTtl };
|
|
14
14
|
configured: MagicContextConfig["cache_ttl"];
|
|
15
15
|
configuredExplicitly: boolean;
|
|
16
16
|
modelKey: string | undefined;
|
|
@@ -20,12 +20,22 @@ export interface ResolveCacheTtlDisplayArgs {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
* Resolve
|
|
24
|
-
*
|
|
25
|
-
*
|
|
23
|
+
* Resolve the lifetime shown in status without changing the value saved for the scheduler.
|
|
24
|
+
* The next pass uses current settings; a saved built-in lifetime applies only to the same
|
|
25
|
+
* model, even after an override is removed.
|
|
26
26
|
*/
|
|
27
27
|
export function resolveCacheTtlDisplay(args: ResolveCacheTtlDisplayArgs): CacheTtlDisplay {
|
|
28
|
-
|
|
28
|
+
const resolved = resolveModelCacheTtl(
|
|
29
|
+
args.configured,
|
|
30
|
+
args.modelKey,
|
|
31
|
+
args.configuredExplicitly,
|
|
32
|
+
);
|
|
33
|
+
if (resolved.source === "config") return resolved;
|
|
34
|
+
if (args.frozen && (!args.modelKey || args.frozen.modelKey === args.modelKey)) {
|
|
35
|
+
return args.frozen.source === "config"
|
|
36
|
+
? (args.frozen.builtInDefault ?? resolved)
|
|
37
|
+
: args.frozen;
|
|
38
|
+
}
|
|
29
39
|
if (
|
|
30
40
|
(args.sessionModelKey && (!args.modelKey || args.sessionModelKey === args.modelKey)) ||
|
|
31
41
|
(!args.modelKey && !args.sessionModelKey && args.sessionValue !== "5m")
|
|
@@ -37,22 +47,13 @@ export function resolveCacheTtlDisplay(args: ResolveCacheTtlDisplayArgs): CacheT
|
|
|
37
47
|
};
|
|
38
48
|
}
|
|
39
49
|
|
|
40
|
-
const resolved = resolveModelCacheTtl(args.configured, args.modelKey);
|
|
41
|
-
if (
|
|
42
|
-
resolved.source === "default" &&
|
|
43
|
-
typeof args.configured === "string" &&
|
|
44
|
-
args.configuredExplicitly
|
|
45
|
-
)
|
|
46
|
-
return { ...resolved, source: "config" };
|
|
47
50
|
return resolved;
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
export function formatCacheTtlDisplay(display: CacheTtlDisplay): string {
|
|
51
|
-
if (display.source === "OpenAI GPT-5.6+ default")
|
|
52
|
-
return `Cache TTL: ${display.value} (${display.source})`;
|
|
53
54
|
if (display.source === "session") return `Cache TTL: ${display.value} (session)`;
|
|
54
55
|
if (display.source === "config") {
|
|
55
|
-
return `Cache TTL: ${display.value} (config
|
|
56
|
+
return `Cache TTL: ${display.value} (your config)`;
|
|
56
57
|
}
|
|
57
|
-
return `Cache TTL: ${display.value} (default
|
|
58
|
+
return `Cache TTL: ${display.value} (built-in default, frozen for this session)`;
|
|
58
59
|
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { expect, test } from "bun:test";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import ts from "typescript";
|
|
5
|
+
|
|
6
|
+
const root = resolve(import.meta.dir, "../../../../");
|
|
7
|
+
|
|
8
|
+
for (const [host, path, functions] of [
|
|
9
|
+
[
|
|
10
|
+
"OpenCode",
|
|
11
|
+
"packages/plugin/src/hooks/magic-context/inject-compartments.ts",
|
|
12
|
+
["materializeM0", "softRefreshCachedM1"],
|
|
13
|
+
],
|
|
14
|
+
[
|
|
15
|
+
"Pi",
|
|
16
|
+
"packages/pi-plugin/src/inject-compartments-pi.ts",
|
|
17
|
+
["materializeM0Pi", "softRefreshCachedM1Pi"],
|
|
18
|
+
],
|
|
19
|
+
] as const) {
|
|
20
|
+
test(`${host} fold and refresh render m[1] inside their writer section`, () => {
|
|
21
|
+
const source = ts.createSourceFile(
|
|
22
|
+
path,
|
|
23
|
+
readFileSync(resolve(root, path), "utf8"),
|
|
24
|
+
ts.ScriptTarget.Latest,
|
|
25
|
+
true,
|
|
26
|
+
);
|
|
27
|
+
const inspected: string[] = [];
|
|
28
|
+
const violations: string[] = [];
|
|
29
|
+
function visit(node: ts.Node): void {
|
|
30
|
+
if (
|
|
31
|
+
ts.isFunctionDeclaration(node) &&
|
|
32
|
+
node.name &&
|
|
33
|
+
functions.some((name) => name === node.name?.text)
|
|
34
|
+
) {
|
|
35
|
+
inspected.push(node.name.text);
|
|
36
|
+
const calls: ts.CallExpression[] = [];
|
|
37
|
+
function collect(child: ts.Node): void {
|
|
38
|
+
if (ts.isCallExpression(child)) calls.push(child);
|
|
39
|
+
ts.forEachChild(child, collect);
|
|
40
|
+
}
|
|
41
|
+
collect(node);
|
|
42
|
+
const admission = calls.find(
|
|
43
|
+
(call) =>
|
|
44
|
+
call.expression.getText(source).endsWith(".exec") &&
|
|
45
|
+
call.arguments[0]?.getText(source) === '"BEGIN IMMEDIATE"',
|
|
46
|
+
);
|
|
47
|
+
expect(admission).toBeDefined();
|
|
48
|
+
const commit = calls.find(
|
|
49
|
+
(call) =>
|
|
50
|
+
admission &&
|
|
51
|
+
call.pos > admission.pos &&
|
|
52
|
+
call.expression.getText(source).endsWith(".exec") &&
|
|
53
|
+
call.arguments[0]?.getText(source) === '"COMMIT"',
|
|
54
|
+
);
|
|
55
|
+
expect(commit).toBeDefined();
|
|
56
|
+
const renders = calls.filter((call) =>
|
|
57
|
+
/^renderM1(?:Pi)?WithMetadata$/.test(call.expression.getText(source)),
|
|
58
|
+
);
|
|
59
|
+
expect(renders).toHaveLength(1);
|
|
60
|
+
for (const render of renders) {
|
|
61
|
+
if (
|
|
62
|
+
!admission ||
|
|
63
|
+
!commit ||
|
|
64
|
+
render.pos < admission.pos ||
|
|
65
|
+
render.pos > commit.pos
|
|
66
|
+
)
|
|
67
|
+
violations.push(`${node.name.text}: m[1] render outside writer`);
|
|
68
|
+
}
|
|
69
|
+
for (const call of calls) {
|
|
70
|
+
if (
|
|
71
|
+
call.expression.getText(source).endsWith("onFoldPrepare") &&
|
|
72
|
+
admission &&
|
|
73
|
+
call.pos > admission.pos
|
|
74
|
+
)
|
|
75
|
+
violations.push(`${node.name.text}: wire preparation inside writer`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
ts.forEachChild(node, visit);
|
|
79
|
+
}
|
|
80
|
+
visit(source);
|
|
81
|
+
expect(inspected.sort()).toEqual([...functions].sort());
|
|
82
|
+
expect(violations).toEqual([]);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { expect, test } from "bun:test";
|
|
2
|
+
import { rmSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { appendCompartments } from "../features/magic-context/compartment-storage";
|
|
6
|
+
import {
|
|
7
|
+
insertMemory,
|
|
8
|
+
setMemoryClassification,
|
|
9
|
+
updateMemorySeenCount,
|
|
10
|
+
updateMemoryVerification,
|
|
11
|
+
} from "../features/magic-context/memory/storage-memory";
|
|
12
|
+
import {
|
|
13
|
+
recordIndexedMessageTime,
|
|
14
|
+
recordMessageFtsRowid,
|
|
15
|
+
} from "../features/magic-context/message-fts-rowid-map";
|
|
16
|
+
import { runMigrations } from "../features/magic-context/migrations";
|
|
17
|
+
import { getOrCreateSessionMeta } from "../features/magic-context/storage";
|
|
18
|
+
import { initializeDatabase } from "../features/magic-context/storage-db";
|
|
19
|
+
import { recoverUnresolvedCompartments } from "../features/magic-context/store-generation-rebase";
|
|
20
|
+
import { renderMemoryBlockV2 } from "../hooks/magic-context/inject-compartments";
|
|
21
|
+
import { estimateTokens } from "../hooks/magic-context/read-session-formatting";
|
|
22
|
+
import { Database } from "./sqlite";
|
|
23
|
+
import { createTestTempDirFromPath } from "./test-temp-dir";
|
|
24
|
+
|
|
25
|
+
export interface LockedDeltaFixture {
|
|
26
|
+
db: Database;
|
|
27
|
+
sibling: Database;
|
|
28
|
+
directory: string;
|
|
29
|
+
sessionId: string;
|
|
30
|
+
projectPath: string;
|
|
31
|
+
close: () => void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function createLockedDeltaFixture(
|
|
35
|
+
label: string,
|
|
36
|
+
open?: (path: string) => Database,
|
|
37
|
+
): LockedDeltaFixture {
|
|
38
|
+
const directory = createTestTempDirFromPath(join(tmpdir(), `mc-locked-delta-${label}-`));
|
|
39
|
+
const path = join(directory, "context.db");
|
|
40
|
+
const db = open ? open(path) : new Database(path);
|
|
41
|
+
if (!open) {
|
|
42
|
+
initializeDatabase(db);
|
|
43
|
+
runMigrations(db);
|
|
44
|
+
}
|
|
45
|
+
db.exec("PRAGMA journal_mode=WAL");
|
|
46
|
+
const sibling = new Database(path);
|
|
47
|
+
const sessionId = label;
|
|
48
|
+
const projectPath = "git:locked-delta";
|
|
49
|
+
getOrCreateSessionMeta(db, sessionId);
|
|
50
|
+
return {
|
|
51
|
+
db,
|
|
52
|
+
sibling,
|
|
53
|
+
directory,
|
|
54
|
+
sessionId,
|
|
55
|
+
projectPath,
|
|
56
|
+
close: () => {
|
|
57
|
+
sibling.close();
|
|
58
|
+
db.close();
|
|
59
|
+
rmSync(directory, { recursive: true, force: true });
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export interface LockedDeltaOptions {
|
|
64
|
+
memoryBudget?: number;
|
|
65
|
+
temporalAwareness?: boolean;
|
|
66
|
+
}
|
|
67
|
+
interface LockedDeltaDriver<Markers> {
|
|
68
|
+
host: string;
|
|
69
|
+
create: (label: string) => LockedDeltaFixture;
|
|
70
|
+
materialize: (fixture: LockedDeltaFixture, options: LockedDeltaOptions) => Markers;
|
|
71
|
+
refresh: (
|
|
72
|
+
fixture: LockedDeltaFixture,
|
|
73
|
+
options: LockedDeltaOptions,
|
|
74
|
+
beforeAdmission: () => void,
|
|
75
|
+
) => void;
|
|
76
|
+
render: (fixture: LockedDeltaFixture, options: LockedDeltaOptions, markers: Markers) => string;
|
|
77
|
+
temporalHeadings?: boolean;
|
|
78
|
+
}
|
|
79
|
+
function compartment() {
|
|
80
|
+
return {
|
|
81
|
+
sequence: 0,
|
|
82
|
+
startMessage: 1,
|
|
83
|
+
endMessage: 2,
|
|
84
|
+
startMessageId: "a",
|
|
85
|
+
endMessageId: "b",
|
|
86
|
+
title: "locked history",
|
|
87
|
+
content: "locked history",
|
|
88
|
+
p1: "locked history",
|
|
89
|
+
p2: "summary",
|
|
90
|
+
p3: "outcome",
|
|
91
|
+
p4: "anchor",
|
|
92
|
+
legacy: 0,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function persistedDelta(f: LockedDeltaFixture): string {
|
|
96
|
+
return getOrCreateSessionMeta(f.db, f.sessionId).cachedM1Bytes?.toString("utf8") ?? "";
|
|
97
|
+
}
|
|
98
|
+
function refreshAtAdmission<Markers>(
|
|
99
|
+
driver: LockedDeltaDriver<Markers>,
|
|
100
|
+
f: LockedDeltaFixture,
|
|
101
|
+
options: LockedDeltaOptions,
|
|
102
|
+
write: () => void,
|
|
103
|
+
) {
|
|
104
|
+
let admissions = 0;
|
|
105
|
+
let hooks = 0;
|
|
106
|
+
const exec = f.db.exec.bind(f.db);
|
|
107
|
+
f.db.exec = (sql) => {
|
|
108
|
+
if (sql === "BEGIN IMMEDIATE") admissions++;
|
|
109
|
+
return exec(sql);
|
|
110
|
+
};
|
|
111
|
+
try {
|
|
112
|
+
driver.refresh(f, options, () => {
|
|
113
|
+
expect(admissions).toBe(0);
|
|
114
|
+
hooks++;
|
|
115
|
+
write();
|
|
116
|
+
});
|
|
117
|
+
expect(hooks).toBe(1);
|
|
118
|
+
expect(admissions).toBe(1);
|
|
119
|
+
} finally {
|
|
120
|
+
f.db.exec = exec;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** These fixtures use real sibling writes, then compare persisted bytes to an independent live render. */
|
|
125
|
+
export function registerLockedDeltaRegressions<Markers>(driver: LockedDeltaDriver<Markers>): void {
|
|
126
|
+
for (const change of ["importance", "reinforcement", "verification"] as const) {
|
|
127
|
+
test(`${driver.host} m[1] reads memory ${change} under its writer`, () => {
|
|
128
|
+
const f = driver.create(`${driver.host}-${change}`);
|
|
129
|
+
try {
|
|
130
|
+
const sample = insertMemory(f.db, {
|
|
131
|
+
projectPath: "git:budget-only",
|
|
132
|
+
category: "ARCHITECTURE",
|
|
133
|
+
content: "candidate A ".repeat(40),
|
|
134
|
+
});
|
|
135
|
+
const options = {
|
|
136
|
+
memoryBudget:
|
|
137
|
+
4 * (estimateTokens(renderMemoryBlockV2([sample], "new-memories")) + 2),
|
|
138
|
+
};
|
|
139
|
+
const markers = driver.materialize(f, options);
|
|
140
|
+
const a = insertMemory(f.db, {
|
|
141
|
+
projectPath: f.projectPath,
|
|
142
|
+
category: "ARCHITECTURE",
|
|
143
|
+
content: "candidate A ".repeat(40),
|
|
144
|
+
});
|
|
145
|
+
const b = insertMemory(f.db, {
|
|
146
|
+
projectPath: f.projectPath,
|
|
147
|
+
category: "ARCHITECTURE",
|
|
148
|
+
content: "candidate B ".repeat(40),
|
|
149
|
+
});
|
|
150
|
+
setMemoryClassification(f.db, a.id, { importance: 50 });
|
|
151
|
+
setMemoryClassification(f.db, b.id, { importance: 50 });
|
|
152
|
+
f.db
|
|
153
|
+
.prepare(
|
|
154
|
+
"UPDATE memories SET last_seen_at = CASE WHEN id = ? THEN 1000 ELSE 0 END, verified_at = NULL WHERE id IN (?, ?)",
|
|
155
|
+
)
|
|
156
|
+
.run(a.id, a.id, b.id);
|
|
157
|
+
const before = driver.render(f, options, markers);
|
|
158
|
+
expect(before).toContain("candidate A");
|
|
159
|
+
expect(before).not.toContain("candidate B");
|
|
160
|
+
refreshAtAdmission(driver, f, options, () => {
|
|
161
|
+
if (change === "importance")
|
|
162
|
+
setMemoryClassification(f.sibling, b.id, { importance: 100 });
|
|
163
|
+
else if (change === "reinforcement") updateMemorySeenCount(f.sibling, b.id);
|
|
164
|
+
else updateMemoryVerification(f.sibling, b.id, "verified");
|
|
165
|
+
});
|
|
166
|
+
const fresh = driver.render(f, options, markers);
|
|
167
|
+
expect(fresh).toContain("candidate B");
|
|
168
|
+
expect(fresh).not.toContain("candidate A");
|
|
169
|
+
expect(persistedDelta(f)).toBe(fresh);
|
|
170
|
+
expect(persistedDelta(f)).not.toBe(before);
|
|
171
|
+
} finally {
|
|
172
|
+
f.close();
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
test(`${driver.host} m[1] reads in-place recovered compartment ranges under its writer`, () => {
|
|
178
|
+
const f = driver.create(`${driver.host}-ranges`);
|
|
179
|
+
try {
|
|
180
|
+
const options = {};
|
|
181
|
+
const markers = driver.materialize(f, options);
|
|
182
|
+
appendCompartments(f.db, f.sessionId, [compartment()]);
|
|
183
|
+
f.db
|
|
184
|
+
.prepare(
|
|
185
|
+
"UPDATE compartments SET rebase_status = 'unresolved' WHERE session_id = ?",
|
|
186
|
+
)
|
|
187
|
+
.run(f.sessionId);
|
|
188
|
+
const before = driver.render(f, options, markers);
|
|
189
|
+
expect(before).toContain("## 1-2");
|
|
190
|
+
const revision = f.db
|
|
191
|
+
.prepare("SELECT version FROM compartment_history_versions WHERE session_id = ?")
|
|
192
|
+
.get(f.sessionId) as { version: number };
|
|
193
|
+
refreshAtAdmission(driver, f, options, () => {
|
|
194
|
+
const recovered = recoverUnresolvedCompartments({
|
|
195
|
+
db: f.sibling,
|
|
196
|
+
sessionId: f.sessionId,
|
|
197
|
+
resolveOrdinal: (id) => (id === "a" ? 3 : id === "b" ? 4 : undefined),
|
|
198
|
+
reason: "Recovered fixture anchors",
|
|
199
|
+
});
|
|
200
|
+
expect(recovered.rowsRewritten).toBe(1);
|
|
201
|
+
});
|
|
202
|
+
const updated = f.db
|
|
203
|
+
.prepare("SELECT version FROM compartment_history_versions WHERE session_id = ?")
|
|
204
|
+
.get(f.sessionId) as { version: number };
|
|
205
|
+
expect(updated.version).toBeGreaterThan(revision.version);
|
|
206
|
+
const fresh = driver.render(f, options, markers);
|
|
207
|
+
expect(fresh).toContain("## 3-4");
|
|
208
|
+
expect(fresh).not.toContain("## 1-2");
|
|
209
|
+
expect(persistedDelta(f)).toBe(fresh);
|
|
210
|
+
} finally {
|
|
211
|
+
f.close();
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
test(`${driver.host} m[1] uses the baseline cutoff for a newly expired additive memory`, () => {
|
|
216
|
+
const f = driver.create(`${driver.host}-expiry`);
|
|
217
|
+
const realNow = Date.now;
|
|
218
|
+
let now = 1000;
|
|
219
|
+
Date.now = () => now;
|
|
220
|
+
try {
|
|
221
|
+
const options = {};
|
|
222
|
+
const markers = driver.materialize(f, options);
|
|
223
|
+
now = 2000;
|
|
224
|
+
const before = driver.render(f, options, markers);
|
|
225
|
+
expect(before).not.toContain("eligible at the baseline cutoff");
|
|
226
|
+
refreshAtAdmission(driver, f, options, () => {
|
|
227
|
+
insertMemory(f.sibling, {
|
|
228
|
+
projectPath: f.projectPath,
|
|
229
|
+
category: "ARCHITECTURE",
|
|
230
|
+
content: "Memory eligible at the baseline cutoff",
|
|
231
|
+
expiresAt: 2500,
|
|
232
|
+
});
|
|
233
|
+
now = 3000;
|
|
234
|
+
});
|
|
235
|
+
const fresh = driver.render(f, options, markers);
|
|
236
|
+
expect(fresh).toContain("eligible at the baseline cutoff");
|
|
237
|
+
expect(persistedDelta(f)).toBe(fresh);
|
|
238
|
+
} finally {
|
|
239
|
+
Date.now = realNow;
|
|
240
|
+
f.close();
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
if (driver.temporalHeadings) {
|
|
245
|
+
test(`${driver.host} m[1] reads indexed temporal headings under its writer`, () => {
|
|
246
|
+
const f = driver.create(`${driver.host}-dates`);
|
|
247
|
+
const originalXdgDataHome = process.env.XDG_DATA_HOME;
|
|
248
|
+
process.env.XDG_DATA_HOME = f.directory;
|
|
249
|
+
try {
|
|
250
|
+
const options = { temporalAwareness: true };
|
|
251
|
+
const markers = driver.materialize(f, options);
|
|
252
|
+
appendCompartments(f.db, f.sessionId, [compartment()]);
|
|
253
|
+
for (const ordinal of [1, 2])
|
|
254
|
+
recordMessageFtsRowid(f.db, f.sessionId, ordinal, ordinal);
|
|
255
|
+
const before = driver.render(f, options, markers);
|
|
256
|
+
expect(before).not.toContain("2025-01-01");
|
|
257
|
+
refreshAtAdmission(driver, f, options, () => {
|
|
258
|
+
for (const ordinal of [1, 2])
|
|
259
|
+
recordIndexedMessageTime(
|
|
260
|
+
f.sibling,
|
|
261
|
+
f.sessionId,
|
|
262
|
+
ordinal,
|
|
263
|
+
Date.UTC(2025, 0, 1),
|
|
264
|
+
);
|
|
265
|
+
});
|
|
266
|
+
const fresh = driver.render(f, options, markers);
|
|
267
|
+
expect(fresh).toContain("2025-01-01");
|
|
268
|
+
expect(persistedDelta(f)).toBe(fresh);
|
|
269
|
+
} finally {
|
|
270
|
+
if (originalXdgDataHome === undefined) delete process.env.XDG_DATA_HOME;
|
|
271
|
+
else process.env.XDG_DATA_HOME = originalXdgDataHome;
|
|
272
|
+
f.close();
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
}
|
|
@@ -29,8 +29,8 @@ describe("known model cache TTL", () => {
|
|
|
29
29
|
expect(resolveCacheTtl("5m", "openai/gpt-6")).toBe("30m");
|
|
30
30
|
expect(resolveCacheTtl("10m", "openai/gpt-6")).toBe("10m");
|
|
31
31
|
});
|
|
32
|
-
it("honors per-model entries
|
|
33
|
-
expect(resolveCacheTtl({ default: "10m" }, "openai/gpt-6")).toBe("
|
|
32
|
+
it("honors per-model entries and configured defaults before built-ins", () => {
|
|
33
|
+
expect(resolveCacheTtl({ default: "10m" }, "openai/gpt-6")).toBe("10m");
|
|
34
34
|
expect(resolveCacheTtl({ default: "10m", "gpt-6": "5m" }, "openai/gpt-6")).toBe("5m");
|
|
35
35
|
expect(resolveCacheTtl({ default: "10m", "openai/*": "never" }, "openai/gpt-6")).toBe(
|
|
36
36
|
"never",
|
|
@@ -28,6 +28,8 @@ const MODEL_CACHE_LIFETIMES = [
|
|
|
28
28
|
export function resolveModelCacheTtl(
|
|
29
29
|
config: CacheTtlConfig | undefined,
|
|
30
30
|
modelKey: string | undefined,
|
|
31
|
+
configuredExplicitly = typeof config === "object" ||
|
|
32
|
+
(typeof config === "string" && config !== "5m"),
|
|
31
33
|
): ResolvedCacheTtl {
|
|
32
34
|
if (config && typeof config !== "string") {
|
|
33
35
|
const match =
|
|
@@ -37,11 +39,13 @@ export function resolveModelCacheTtl(
|
|
|
37
39
|
modelKey !== "default"
|
|
38
40
|
? config[modelKey]
|
|
39
41
|
: resolveModelConfigValue(config, modelKey)?.value;
|
|
40
|
-
|
|
42
|
+
const value = match ?? config.default;
|
|
43
|
+
if (value !== undefined && configuredExplicitly)
|
|
44
|
+
return { value, source: "config", modelKey };
|
|
41
45
|
}
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
if (typeof config === "string" &&
|
|
46
|
+
// The loader supplies provenance: an explicit 5m is policy too. Older callers
|
|
47
|
+
// without that bit still distinguish non-default strings from the schema's 5m.
|
|
48
|
+
if (typeof config === "string" && configuredExplicitly)
|
|
45
49
|
return { value: config, source: "config", modelKey };
|
|
46
50
|
const model =
|
|
47
51
|
canonicalModelIdentity(modelKey ?? "")
|