@cortexkit/opencode-magic-context 0.41.3 → 0.42.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/README.md +21 -3
- package/dist/agents/hidden-agent-registrations.d.ts +1 -3
- package/dist/agents/hidden-agent-registrations.d.ts.map +1 -1
- package/dist/agents/magic-context-prompt.d.ts +1 -1
- package/dist/agents/magic-context-prompt.d.ts.map +1 -1
- package/dist/agents/permissions.d.ts +1 -22
- package/dist/agents/permissions.d.ts.map +1 -1
- package/dist/config/agent-disable.d.ts +0 -5
- package/dist/config/agent-disable.d.ts.map +1 -1
- package/dist/config/index.d.ts +14 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/migrate-config-location.d.ts.map +1 -1
- package/dist/config/project-security.d.ts +17 -0
- package/dist/config/project-security.d.ts.map +1 -1
- package/dist/config/removed-agent-config.d.ts +8 -0
- package/dist/config/removed-agent-config.d.ts.map +1 -0
- package/dist/config/schema/magic-context.d.ts +23 -201
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/{conflict-warning-hook-z5sd697e.js → conflict-warning-hook-6p3xqeac.js} +4 -4
- package/dist/{derive-budgets-901a0pk0.js → derive-budgets-s2pgnnm4.js} +4 -2
- package/dist/features/builtin-commands/commands.d.ts +0 -4
- package/dist/features/builtin-commands/commands.d.ts.map +1 -1
- package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts +7 -0
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-storage.d.ts.map +1 -1
- package/dist/features/magic-context/context-authority.d.ts +31 -4
- package/dist/features/magic-context/context-authority.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/open-opencode-db.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/refresh-primers.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/retrospective-orphan-sweep.d.ts +19 -9
- package/dist/features/magic-context/dreamer/retrospective-orphan-sweep.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts +13 -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.map +1 -1
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts +7 -0
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
- package/dist/features/magic-context/fail-closed-block.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/sweep-coordinator.d.ts.map +1 -1
- package/dist/features/magic-context/index.d.ts +0 -1
- package/dist/features/magic-context/index.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-local.d.ts +13 -0
- package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-synapse.d.ts +43 -10
- package/dist/features/magic-context/memory/embedding-synapse.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding.d.ts +1 -1
- package/dist/features/magic-context/memory/embedding.d.ts.map +1 -1
- package/dist/features/magic-context/memory/memory-migration.d.ts.map +1 -1
- package/dist/features/magic-context/memory/project-identity.d.ts +1 -0
- package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
- package/dist/features/magic-context/memory/promotion.d.ts +7 -1
- package/dist/features/magic-context/memory/promotion.d.ts.map +1 -1
- package/dist/features/magic-context/merged-reasoning-decisions.d.ts +6 -0
- package/dist/features/magic-context/merged-reasoning-decisions.d.ts.map +1 -0
- package/dist/features/magic-context/message-fts-rowid-map.d.ts.map +1 -1
- package/dist/features/magic-context/message-index-async.d.ts +12 -0
- package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
- package/dist/features/magic-context/message-index.d.ts.map +1 -1
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
- package/dist/features/magic-context/mural/render-trigger.d.ts +6 -0
- package/dist/features/magic-context/mural/render-trigger.d.ts.map +1 -1
- package/dist/features/magic-context/no-content-compartment.d.ts +12 -0
- package/dist/features/magic-context/no-content-compartment.d.ts.map +1 -0
- package/dist/features/magic-context/pi-content-decisions.d.ts +9 -0
- package/dist/features/magic-context/pi-content-decisions.d.ts.map +1 -0
- package/dist/features/magic-context/project-docs-hash.d.ts +4 -0
- package/dist/features/magic-context/project-docs-hash.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts +13 -4
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/protection-window.d.ts +79 -0
- package/dist/features/magic-context/protection-window.d.ts.map +1 -0
- package/dist/features/magic-context/search.d.ts.map +1 -1
- package/dist/features/magic-context/session-project-backfill.d.ts.map +1 -1
- package/dist/features/magic-context/shadow-backfill-state.d.ts +26 -0
- package/dist/features/magic-context/shadow-backfill-state.d.ts.map +1 -0
- package/dist/features/magic-context/smart-notes/compiler.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts +4 -0
- package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/storage.d.ts.map +1 -1
- package/dist/features/magic-context/storage-clone.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts +1 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-embedding-measurements.d.ts +2 -2
- package/dist/features/magic-context/storage-embedding-measurements.d.ts.map +1 -1
- package/dist/features/magic-context/storage-historian-runs.d.ts +4 -0
- package/dist/features/magic-context/storage-historian-runs.d.ts.map +1 -1
- package/dist/features/magic-context/storage-memory-mutation-log.d.ts +1 -0
- package/dist/features/magic-context/storage-memory-mutation-log.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +81 -15
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta.d.ts +1 -1
- package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
- package/dist/features/magic-context/storage-native-replay.d.ts +29 -0
- package/dist/features/magic-context/storage-native-replay.d.ts.map +1 -0
- package/dist/features/magic-context/storage-notes.d.ts +6 -0
- package/dist/features/magic-context/storage-notes.d.ts.map +1 -1
- package/dist/features/magic-context/storage-replay-document.d.ts +33 -0
- package/dist/features/magic-context/storage-replay-document.d.ts.map +1 -0
- package/dist/features/magic-context/storage-subagent-invocations.d.ts +1 -1
- package/dist/features/magic-context/storage-subagent-invocations.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tags.d.ts +19 -11
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +3 -3
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/features/magic-context/subagent-token-capture.d.ts.map +1 -1
- package/dist/features/magic-context/tagger.d.ts +13 -0
- package/dist/features/magic-context/tagger.d.ts.map +1 -1
- package/dist/features/magic-context/tool-owner-backfill.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/storage-user-memory.d.ts.map +1 -1
- package/dist/features/magic-context/workspaces.d.ts.map +1 -1
- package/dist/hooks/magic-context/apply-operations.d.ts +11 -5
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/cache-busting-signals.d.ts +9 -1
- package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -1
- package/dist/hooks/magic-context/caveman-cleanup.d.ts +1 -1
- package/dist/hooks/magic-context/caveman-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
- package/dist/hooks/magic-context/child-session-spawn.d.ts +3 -3
- package/dist/hooks/magic-context/child-session-spawn.d.ts.map +1 -1
- package/dist/hooks/magic-context/command-handler.d.ts +5 -10
- package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts +10 -21
- package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-types.d.ts +4 -0
- package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts +26 -2
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts.map +1 -1
- package/dist/hooks/magic-context/decay-render.d.ts.map +1 -1
- package/dist/hooks/magic-context/derive-budgets.d.ts +1 -0
- package/dist/hooks/magic-context/derive-budgets.d.ts.map +1 -1
- package/dist/hooks/magic-context/dropped-input-guard.d.ts +9 -0
- package/dist/hooks/magic-context/dropped-input-guard.d.ts.map +1 -0
- package/dist/hooks/magic-context/emergency-drop.d.ts +9 -2
- package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-handler.d.ts +0 -1
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-payloads.d.ts +7 -6
- package/dist/hooks/magic-context/event-payloads.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-resolvers.d.ts +1 -1
- package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
- package/dist/hooks/magic-context/execute-status.d.ts +8 -2
- package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
- package/dist/hooks/magic-context/format-embed-status.d.ts.map +1 -1
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts +11 -4
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook-handlers.d.ts +5 -1
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts +17 -5
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts +14 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/issue-423-fixture.d.ts +37 -0
- package/dist/hooks/magic-context/issue-423-fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/issue-424-fixture.d.ts +11 -0
- package/dist/hooks/magic-context/issue-424-fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/live-session-state.d.ts +1 -1
- package/dist/hooks/magic-context/lkg-slot.d.ts +34 -0
- package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-state-sync-timing.d.ts +21 -0
- package/dist/hooks/magic-context/module-state-sync-timing.d.ts.map +1 -0
- package/dist/hooks/magic-context/module-state-sync.d.ts +21 -7
- package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-transport.d.ts +12 -0
- package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-wire.d.ts +8 -0
- package/dist/hooks/magic-context/module-wire.d.ts.map +1 -1
- package/dist/hooks/magic-context/note-nudger.d.ts.map +1 -1
- package/dist/hooks/magic-context/persist-filtered-noise.d.ts +5 -0
- package/dist/hooks/magic-context/persist-filtered-noise.d.ts.map +1 -0
- package/dist/hooks/magic-context/producer-window-guard.d.ts +8 -0
- package/dist/hooks/magic-context/producer-window-guard.d.ts.map +1 -0
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts +65 -0
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts +20 -18
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-db.d.ts +22 -12
- package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-formatting.d.ts +8 -0
- package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts +10 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts +4 -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.map +1 -1
- package/dist/hooks/magic-context/rust-mode-transform.d.ts +79 -11
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/send-session-notification.d.ts +11 -10
- package/dist/hooks/magic-context/send-session-notification.d.ts.map +1 -1
- package/dist/hooks/magic-context/sentinel.d.ts +3 -3
- package/dist/hooks/magic-context/sentinel.d.ts.map +1 -1
- package/dist/hooks/magic-context/strip-content.d.ts +7 -0
- package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
- package/dist/hooks/magic-context/supersession-reclaim.d.ts +13 -0
- package/dist/hooks/magic-context/supersession-reclaim.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts +2 -3
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-messages.d.ts +2 -0
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts +16 -6
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts +1 -0
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts +2 -0
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-context-state.d.ts +7 -1
- package/dist/hooks/magic-context/transform-context-state.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +11 -4
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +11 -2
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/upgrade-reminder.d.ts +7 -9
- package/dist/hooks/magic-context/upgrade-reminder.d.ts.map +1 -1
- package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
- package/dist/index-1974jvn3.js +783 -0
- package/dist/{index-npx8vhmy.js → index-36wd1d6k.js} +7 -30
- package/dist/{index-kby1sng5.js → index-avwt563y.js} +8 -1
- package/dist/{index-vmmjdpc0.js → index-c9hamh36.js} +18357 -16010
- package/dist/{index-0bycg0np.js → index-jmtjh2d3.js} +4 -4
- package/dist/{index-q264erdp.js → index-nqgjwfzn.js} +70 -38
- package/dist/index-sd3egckz.js +1583 -0
- package/dist/{index-dn1rwpd8.js → index-xdtge3y2.js} +58 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6826 -6660
- package/dist/plugin/conflict-warning-hook.d.ts +5 -6
- package/dist/plugin/conflict-warning-hook.d.ts.map +1 -1
- package/dist/plugin/dream-timer.d.ts +1 -0
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/embedding-routing.d.ts +4 -1
- package/dist/plugin/embedding-routing.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +19 -2
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts +31 -1
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/plugin/rust-tool-backends.d.ts +1 -0
- package/dist/plugin/rust-tool-backends.d.ts.map +1 -1
- package/dist/plugin/tool-registry.d.ts.map +1 -1
- package/dist/{recomp-orchestrator-f5m2wk74.js → recomp-orchestrator-3atsasjy.js} +6 -6
- package/dist/{send-session-notification-hdh02wy9.js → send-session-notification-1qeqkswb.js} +6 -4
- package/dist/shared/cache-ttl-display.d.ts +23 -0
- package/dist/shared/cache-ttl-display.d.ts.map +1 -0
- package/dist/shared/cache-ttl-seed.d.ts +10 -0
- package/dist/shared/cache-ttl-seed.d.ts.map +1 -0
- package/dist/shared/child-session-teardown.d.ts +34 -0
- package/dist/shared/child-session-teardown.d.ts.map +1 -0
- package/dist/shared/config-diagnostics.d.ts +30 -0
- package/dist/shared/config-diagnostics.d.ts.map +1 -0
- package/dist/shared/config-warning-surface.d.ts +3 -0
- package/dist/shared/config-warning-surface.d.ts.map +1 -0
- package/dist/shared/data-path.d.ts +10 -9
- package/dist/shared/data-path.d.ts.map +1 -1
- package/dist/shared/harness-provider-map.d.ts +7 -0
- package/dist/shared/harness-provider-map.d.ts.map +1 -1
- package/dist/shared/jsonc-parser.d.ts +12 -0
- package/dist/shared/jsonc-parser.d.ts.map +1 -1
- package/dist/shared/keep-subagents.d.ts +1 -1
- package/dist/shared/keep-subagents.d.ts.map +1 -1
- package/dist/shared/model-suggestion-retry.d.ts +15 -11
- package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
- package/dist/shared/opencode-db-path.d.ts +24 -0
- package/dist/shared/opencode-db-path.d.ts.map +1 -0
- package/dist/shared/pi-executable.d.ts +6 -0
- package/dist/shared/pi-executable.d.ts.map +1 -0
- package/dist/shared/prompt-surface-runtime.d.ts +10 -5
- package/dist/shared/prompt-surface-runtime.d.ts.map +1 -1
- package/dist/shared/resolve-fallbacks.d.ts +1 -1
- package/dist/shared/rpc-types.d.ts +117 -0
- package/dist/shared/rpc-types.d.ts.map +1 -1
- package/dist/shared/rpc-utils.d.ts.map +1 -1
- package/dist/shared/sqlite.d.ts +42 -0
- package/dist/shared/sqlite.d.ts.map +1 -1
- package/dist/shared/status-detail-text.d.ts.map +1 -1
- package/dist/shared/subagent-runner.d.ts +17 -10
- package/dist/shared/subagent-runner.d.ts.map +1 -1
- package/dist/shared/tag-transcript.d.ts.map +1 -1
- package/dist/shared/transcript.d.ts +6 -0
- package/dist/shared/transcript.d.ts.map +1 -1
- package/dist/shared/window-geometry.d.ts +23 -0
- package/dist/shared/window-geometry.d.ts.map +1 -1
- package/dist/shared/write-transaction-timing.d.ts +1 -1
- package/dist/shared/write-transaction-timing.d.ts.map +1 -1
- package/dist/{storage-meta-session-3rxx9ekm.js → storage-meta-session-e6g0mmec.js} +2 -2
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
- package/dist/tools/ctx-memory/verification-recording.d.ts.map +1 -1
- package/dist/tools/ctx-note/constants.d.ts +1 -1
- package/dist/tools/ctx-note/constants.d.ts.map +1 -1
- package/dist/tools/ctx-note/tools.d.ts.map +1 -1
- package/dist/tools/ctx-note/types.d.ts +1 -0
- package/dist/tools/ctx-note/types.d.ts.map +1 -1
- package/dist/tools/ctx-reduce/tools.d.ts +10 -1
- package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
- package/dist/tools/ctx-search/constants.d.ts +1 -1
- package/dist/tools/ctx-search/constants.d.ts.map +1 -1
- package/dist/tools/light-descriptions.d.ts +2 -2
- package/dist/tools/light-descriptions.d.ts.map +1 -1
- package/package.json +2 -3
- package/src/agents/hidden-agent-registrations.ts +3 -15
- package/src/agents/magic-context-prompt.test.ts +7 -5
- package/src/agents/magic-context-prompt.ts +22 -30
- package/src/agents/permissions.test.ts +1 -42
- package/src/agents/permissions.ts +1 -24
- package/src/config/agent-disable.ts +5 -22
- package/src/config/index.test.ts +169 -14
- package/src/config/index.ts +137 -21
- package/src/config/latch-permanence-guard.test.ts +4 -0
- package/src/config/migrate-config-location.test.ts +39 -6
- package/src/config/migrate-config-location.ts +18 -31
- package/src/config/profiles.ts +1 -1
- package/src/config/project-security.hostile-matrix.test.ts +0 -8
- package/src/config/project-security.test.ts +11 -22
- package/src/config/project-security.ts +103 -9
- package/src/config/protected-tokens.test.ts +235 -0
- package/src/config/removed-agent-config.ts +45 -0
- package/src/config/removed-agent-source-fence.test.ts +56 -0
- package/src/config/schema/magic-context.test.ts +21 -42
- package/src/config/schema/magic-context.ts +46 -37
- package/src/shared/cache-ttl-display.test.ts +84 -0
- package/src/shared/cache-ttl-display.ts +64 -0
- package/src/shared/cache-ttl-seed.ts +23 -0
- package/src/shared/child-session-teardown.test.ts +218 -0
- package/src/shared/child-session-teardown.ts +66 -0
- package/src/shared/config-diagnostics.test.ts +29 -0
- package/src/shared/config-diagnostics.ts +64 -0
- package/src/shared/config-warning-surface.ts +28 -0
- package/src/shared/data-path.ts +10 -9
- package/src/shared/harness-provider-map.test.ts +16 -0
- package/src/shared/harness-provider-map.ts +15 -0
- package/src/shared/jsonc-parser.test.ts +14 -1
- package/src/shared/jsonc-parser.ts +93 -0
- package/src/shared/keep-subagents.ts +9 -14
- package/src/shared/model-suggestion-retry.ts +144 -29
- package/src/shared/opencode-db-path.test.ts +196 -0
- package/src/shared/opencode-db-path.ts +215 -0
- package/src/shared/pi-executable.ts +20 -0
- package/src/shared/prompt-surface-a1-golden.md +50 -35
- package/src/shared/prompt-surface-runtime.test.ts +28 -0
- package/src/shared/prompt-surface-runtime.ts +22 -5
- package/src/shared/resolve-fallbacks.ts +1 -1
- package/src/shared/rpc-types.ts +124 -0
- package/src/shared/rpc-utils.ts +2 -3
- package/src/shared/session-messages-bounded.test.ts +1 -1
- package/src/shared/sqlite-import-fence.test.ts +19 -0
- package/src/shared/sqlite.test.ts +27 -1
- package/src/shared/sqlite.ts +204 -1
- package/src/shared/status-detail-text.test.ts +8 -4
- package/src/shared/status-detail-text.ts +20 -1
- package/src/shared/subagent-runner.ts +17 -10
- package/src/shared/tag-transcript.ts +53 -22
- package/src/shared/transcript.ts +7 -0
- package/src/shared/window-geometry.test.ts +44 -0
- package/src/shared/window-geometry.ts +89 -11
- package/src/shared/write-transaction-attribution.test.ts +241 -0
- package/src/shared/write-transaction-timing.ts +2 -1
- package/src/tui/index.tsx +18 -4
- package/src/tui/slots/sidebar-content.tsx +12 -7
- package/src/tui-compiled/index.tsx +237 -225
- package/src/tui-compiled/slots/sidebar-content.tsx +301 -305
- package/dist/agents/sidekick.d.ts +0 -2
- package/dist/agents/sidekick.d.ts.map +0 -1
- package/dist/features/magic-context/defaults.d.ts +0 -2
- package/dist/features/magic-context/defaults.d.ts.map +0 -1
- package/dist/features/magic-context/sidekick/agent.d.ts +0 -14
- package/dist/features/magic-context/sidekick/agent.d.ts.map +0 -1
- package/dist/features/magic-context/sidekick/core.d.ts +0 -38
- package/dist/features/magic-context/sidekick/core.d.ts.map +0 -1
- package/dist/features/magic-context/sidekick/index.d.ts +0 -3
- package/dist/features/magic-context/sidekick/index.d.ts.map +0 -1
- package/dist/hooks/magic-context/boundary-execution.d.ts +0 -27
- package/dist/hooks/magic-context/boundary-execution.d.ts.map +0 -1
- package/dist/index-jfpk81yt.js +0 -146
- package/dist/index-raatkvw5.js +0 -360
- package/src/agents/sidekick.ts +0 -1
- package/src/features/magic-context/defaults.ts +0 -1
package/src/config/index.test.ts
CHANGED
|
@@ -3,7 +3,10 @@ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
|
|
6
|
+
import { resolveEpochFloorForPass } from "../features/magic-context/storage-meta-persisted";
|
|
7
|
+
import { buildOpenCodeConfigWarningBanner } from "../shared/config-warning-surface";
|
|
6
8
|
import { resolveHistorianModel } from "../shared/model-resolution";
|
|
9
|
+
import { Database } from "../shared/sqlite";
|
|
7
10
|
import { createTestTempDir } from "../shared/test-temp-dir";
|
|
8
11
|
import {
|
|
9
12
|
getWindowOverlay,
|
|
@@ -12,6 +15,8 @@ import {
|
|
|
12
15
|
} from "../shared/window-geometry";
|
|
13
16
|
import { loadPluginConfig, loadPluginConfigDetailed } from "./index";
|
|
14
17
|
import { resolveConfigProfile } from "./profiles";
|
|
18
|
+
import { getProtectedTokensTierOverrides } from "./project-security";
|
|
19
|
+
import { REMOVED_AGENT_CONFIG_WARNING } from "./removed-agent-config";
|
|
15
20
|
import { DEFAULT_LOCAL_EMBEDDING_MODEL } from "./schema/magic-context";
|
|
16
21
|
import { RUST_COMPACTION_OFF_WARNING } from "./transform-mode";
|
|
17
22
|
|
|
@@ -192,6 +197,49 @@ describe("loadPluginConfig — preload user-config isolation", () => {
|
|
|
192
197
|
});
|
|
193
198
|
});
|
|
194
199
|
|
|
200
|
+
describe("loadPluginConfig — parse failure diagnostics", () => {
|
|
201
|
+
it("recovers the reporter's stray leading character and keeps a loud location warning", () => {
|
|
202
|
+
const result = loadWithUserConfig('\\{\n "cache_ttl": "1h"\n}');
|
|
203
|
+
|
|
204
|
+
expect(result.cache_ttl).toBe("1h");
|
|
205
|
+
expect(result.configParseFailures).toHaveLength(1);
|
|
206
|
+
expect(result.configParseFailures?.[0]).toMatchObject({
|
|
207
|
+
warningClass: "file-parse",
|
|
208
|
+
line: 1,
|
|
209
|
+
column: 1,
|
|
210
|
+
recovered: true,
|
|
211
|
+
message: "invalid symbol",
|
|
212
|
+
});
|
|
213
|
+
expect(result.configWarnings?.[0]).toContain(":1:1: invalid symbol");
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
it("keeps file parse and invalid-leaf warning classes distinct", () => {
|
|
217
|
+
const parseResult = loadWithUserConfig('\\{\n "cache_ttl": "1h"\n}');
|
|
218
|
+
const leafResult = loadWithUserConfig('{"protected_tokens":"bogus"}');
|
|
219
|
+
|
|
220
|
+
expect(parseResult.configWarningDetails?.[0]?.warningClass).toBe("file-parse");
|
|
221
|
+
expect(
|
|
222
|
+
leafResult.configWarningDetails?.some(
|
|
223
|
+
(detail) => detail.warningClass === "invalid-leaf",
|
|
224
|
+
),
|
|
225
|
+
).toBe(true);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
it("puts a recovered parse failure first in the OpenCode warning banner", () => {
|
|
229
|
+
const result = loadWithUserConfig('\\{\n "cache_ttl": "1h"\n}');
|
|
230
|
+
const failures = result.configParseFailures ?? [];
|
|
231
|
+
const banner = buildOpenCodeConfigWarningBanner(
|
|
232
|
+
result.configWarnings ?? [],
|
|
233
|
+
failures,
|
|
234
|
+
failures,
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
expect(banner).toStartWith("## ⚠️ Magic Context Config Warning");
|
|
238
|
+
expect(banner.indexOf("PARSE FAILED")).toBeLessThan(banner.indexOf("Fix the reported"));
|
|
239
|
+
expect(banner).toContain(":1:1");
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
|
|
195
243
|
describe("loadPluginConfig — graduated mural config", () => {
|
|
196
244
|
it("adopts legacy experimental.mural at the top-level and warns once", () => {
|
|
197
245
|
const result = loadWithUserConfig(
|
|
@@ -703,18 +751,26 @@ describe("loadPluginConfig — legacy agent enabled migration", () => {
|
|
|
703
751
|
expect(warnings).not.toContain("dreamer.enabled");
|
|
704
752
|
});
|
|
705
753
|
|
|
706
|
-
it("
|
|
707
|
-
const
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
754
|
+
it("ignores the removed agent block with one warning", () => {
|
|
755
|
+
const removedKey = ["side", "kick"].join("");
|
|
756
|
+
const result = loadWithUserConfig(
|
|
757
|
+
JSON.stringify({
|
|
758
|
+
profile: "work",
|
|
759
|
+
[removedKey]: { enabled: false, model: "example/model" },
|
|
760
|
+
profiles: {
|
|
761
|
+
work: {
|
|
762
|
+
[removedKey]: { model: "example/profile-model" },
|
|
763
|
+
historian: { opencode: { model: "example/historian" } },
|
|
764
|
+
},
|
|
765
|
+
},
|
|
766
|
+
}),
|
|
711
767
|
);
|
|
712
768
|
|
|
713
|
-
|
|
714
|
-
expect(
|
|
715
|
-
expect(
|
|
716
|
-
|
|
717
|
-
|
|
769
|
+
expect(removedKey in result).toBe(false);
|
|
770
|
+
expect(result.historian?.opencode?.model).toBe("example/historian");
|
|
771
|
+
expect(result.configWarnings?.filter((warning) => warning.includes(removedKey))).toEqual([
|
|
772
|
+
`[config] ${REMOVED_AGENT_CONFIG_WARNING}`,
|
|
773
|
+
]);
|
|
718
774
|
});
|
|
719
775
|
|
|
720
776
|
it("removes invalid historian.enabled and applies conflict rules", () => {
|
|
@@ -722,13 +778,11 @@ describe("loadPluginConfig — legacy agent enabled migration", () => {
|
|
|
722
778
|
JSON.stringify({
|
|
723
779
|
historian: { enabled: false },
|
|
724
780
|
dreamer: { enabled: false, disable: false },
|
|
725
|
-
sidekick: { enabled: true, disable: true },
|
|
726
781
|
}),
|
|
727
782
|
);
|
|
728
783
|
|
|
729
784
|
expect(result.historian).toEqual({ two_pass: false, disallowed_tools: [] });
|
|
730
785
|
expect(result.dreamer?.disable).toBe(true);
|
|
731
|
-
expect(result.sidekick?.disable).toBe(true);
|
|
732
786
|
expect(result.configWarnings?.join("\n")).toContain(
|
|
733
787
|
'Removed invalid "historian.enabled" in-memory (run doctor to persist).',
|
|
734
788
|
);
|
|
@@ -900,6 +954,109 @@ describe("loadPluginConfig — user-only settings", () => {
|
|
|
900
954
|
});
|
|
901
955
|
|
|
902
956
|
describe("loadPluginConfig — project compaction trust boundary", () => {
|
|
957
|
+
it("keeps protected_tokens scalar-only at both tiers and preserves the user scalar on an invalid project leaf", () => {
|
|
958
|
+
const vectors = [
|
|
959
|
+
{
|
|
960
|
+
name: "user scalar",
|
|
961
|
+
user: { protected_tokens: 20_000 },
|
|
962
|
+
project: {},
|
|
963
|
+
expected: 20_000,
|
|
964
|
+
warns: false,
|
|
965
|
+
},
|
|
966
|
+
{
|
|
967
|
+
name: "user object",
|
|
968
|
+
user: { protected_tokens: { default: 20_000 } },
|
|
969
|
+
project: {},
|
|
970
|
+
expected: undefined,
|
|
971
|
+
warns: true,
|
|
972
|
+
},
|
|
973
|
+
{
|
|
974
|
+
name: "project scalar",
|
|
975
|
+
user: {},
|
|
976
|
+
project: { protected_tokens: 20_000 },
|
|
977
|
+
expected: 20_000,
|
|
978
|
+
warns: false,
|
|
979
|
+
},
|
|
980
|
+
{
|
|
981
|
+
name: "project object",
|
|
982
|
+
user: {},
|
|
983
|
+
project: { protected_tokens: { default: 20_000 } },
|
|
984
|
+
expected: undefined,
|
|
985
|
+
warns: true,
|
|
986
|
+
},
|
|
987
|
+
{
|
|
988
|
+
name: "invalid project object over user scalar",
|
|
989
|
+
user: { protected_tokens: 25_000 },
|
|
990
|
+
project: { protected_tokens: { default: 30_000 } },
|
|
991
|
+
expected: 25_000,
|
|
992
|
+
warns: true,
|
|
993
|
+
},
|
|
994
|
+
] as const;
|
|
995
|
+
|
|
996
|
+
for (const vector of vectors) {
|
|
997
|
+
const result = loadWithUserAndProjectConfig(
|
|
998
|
+
JSON.stringify(vector.user),
|
|
999
|
+
JSON.stringify(vector.project),
|
|
1000
|
+
);
|
|
1001
|
+
expect(result.protected_tokens, vector.name).toBe(vector.expected);
|
|
1002
|
+
const warned = (result.configWarnings ?? []).some((warning) =>
|
|
1003
|
+
warning.includes("protected_tokens"),
|
|
1004
|
+
);
|
|
1005
|
+
expect(warned, vector.name).toBe(vector.warns);
|
|
1006
|
+
}
|
|
1007
|
+
});
|
|
1008
|
+
|
|
1009
|
+
it("rejects a project protected_tokens floor below the derived floor once geometry is known", () => {
|
|
1010
|
+
const result = loadWithUserAndProjectConfig(
|
|
1011
|
+
JSON.stringify({}),
|
|
1012
|
+
JSON.stringify({ protected_tokens: 4_000 }),
|
|
1013
|
+
);
|
|
1014
|
+
const db = new Database(":memory:");
|
|
1015
|
+
db.exec(`
|
|
1016
|
+
CREATE TABLE session_meta (
|
|
1017
|
+
session_id TEXT PRIMARY KEY,
|
|
1018
|
+
harness TEXT NOT NULL DEFAULT 'opencode',
|
|
1019
|
+
last_response_time INTEGER NOT NULL DEFAULT 0,
|
|
1020
|
+
cache_ttl TEXT NOT NULL DEFAULT '5m',
|
|
1021
|
+
counter INTEGER NOT NULL DEFAULT 0,
|
|
1022
|
+
last_nudge_tokens INTEGER NOT NULL DEFAULT 0,
|
|
1023
|
+
last_nudge_band TEXT NOT NULL DEFAULT '',
|
|
1024
|
+
last_transform_error TEXT NOT NULL DEFAULT '',
|
|
1025
|
+
is_subagent INTEGER NOT NULL DEFAULT 0,
|
|
1026
|
+
last_context_percentage REAL NOT NULL DEFAULT 0,
|
|
1027
|
+
last_input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
1028
|
+
observed_safe_input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
1029
|
+
cache_alert_sent INTEGER NOT NULL DEFAULT 0,
|
|
1030
|
+
times_execute_threshold_reached INTEGER NOT NULL DEFAULT 0,
|
|
1031
|
+
compartment_in_progress INTEGER NOT NULL DEFAULT 0,
|
|
1032
|
+
system_prompt_hash TEXT NOT NULL DEFAULT '',
|
|
1033
|
+
cleared_reasoning_through_tag INTEGER NOT NULL DEFAULT 0,
|
|
1034
|
+
protected_tokens_effective INTEGER,
|
|
1035
|
+
protected_tokens_pre_snapshot TEXT
|
|
1036
|
+
)
|
|
1037
|
+
`);
|
|
1038
|
+
const warnings: string[] = [];
|
|
1039
|
+
const tierOverrides = getProtectedTokensTierOverrides(result);
|
|
1040
|
+
|
|
1041
|
+
const resolved = resolveEpochFloorForPass(db, "loader-derived-floor", {
|
|
1042
|
+
tierOverrides,
|
|
1043
|
+
usableSoft: 200_000,
|
|
1044
|
+
isCacheBustingPass: true,
|
|
1045
|
+
onRejectedProjectOverride: (warning) => warnings.push(warning),
|
|
1046
|
+
});
|
|
1047
|
+
resolveEpochFloorForPass(db, "loader-derived-floor-next", {
|
|
1048
|
+
tierOverrides,
|
|
1049
|
+
usableSoft: 200_000,
|
|
1050
|
+
isCacheBustingPass: true,
|
|
1051
|
+
onRejectedProjectOverride: (warning) => warnings.push(warning),
|
|
1052
|
+
});
|
|
1053
|
+
|
|
1054
|
+
expect(resolved.floor).toBe(16_000);
|
|
1055
|
+
expect(warnings).toHaveLength(1);
|
|
1056
|
+
expect(warnings[0]).toContain("protected_tokens=4000");
|
|
1057
|
+
db.close();
|
|
1058
|
+
});
|
|
1059
|
+
|
|
903
1060
|
it("ignores a lower project execute_threshold_percentage with a warning", () => {
|
|
904
1061
|
const result = loadWithUserAndProjectConfig(
|
|
905
1062
|
JSON.stringify({ execute_threshold_percentage: 60 }),
|
|
@@ -1132,7 +1289,6 @@ describe("loadPluginConfig — user-owned model profiles", () => {
|
|
|
1132
1289
|
],
|
|
1133
1290
|
},
|
|
1134
1291
|
},
|
|
1135
|
-
sidekick: { model: "anthropic/work-sidekick" },
|
|
1136
1292
|
},
|
|
1137
1293
|
personal: {
|
|
1138
1294
|
historian: { opencode: { model: "anthropic/personal-historian" } },
|
|
@@ -1156,7 +1312,6 @@ describe("loadPluginConfig — user-owned model profiles", () => {
|
|
|
1156
1312
|
expect(result.dreamer?.opencode?.fallback_models).toEqual([
|
|
1157
1313
|
{ model: "openai/work-dreamer-fallback", variant: "medium" },
|
|
1158
1314
|
]);
|
|
1159
|
-
expect(result.sidekick?.model).toBe("anthropic/work-sidekick");
|
|
1160
1315
|
});
|
|
1161
1316
|
|
|
1162
1317
|
it("uses project selection over user selection and falls back to the base on an unknown name", () => {
|
package/src/config/index.ts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
CONFIG_WARNING_CLASS,
|
|
5
|
+
type ConfigParseFailure,
|
|
6
|
+
type ConfigWarningDetail,
|
|
7
|
+
} from "../shared/config-diagnostics";
|
|
8
|
+
import {
|
|
9
|
+
detectConfigFile,
|
|
10
|
+
isPrototypePollutionKey,
|
|
11
|
+
parseJsoncRecovering,
|
|
12
|
+
} from "../shared/jsonc-parser";
|
|
4
13
|
import { setOutputReserveConfig } from "../shared/models-dev-cache";
|
|
5
14
|
import type { PromptSurfaceConfig } from "../shared/prompt-surface";
|
|
6
15
|
import { setWindowOverlayPath } from "../shared/window-geometry";
|
|
@@ -16,18 +25,25 @@ import { migrateDreamerV2 } from "./migrate-dreamer-v2";
|
|
|
16
25
|
import { migrateLegacyExperimental } from "./migrate-experimental";
|
|
17
26
|
import { resolveConfigProfile } from "./profiles";
|
|
18
27
|
import {
|
|
28
|
+
attachProtectedTokensTierOverrides,
|
|
19
29
|
constrainProjectThresholdOverrides,
|
|
20
30
|
dropInheritedEmbeddingKeyOnRedirect,
|
|
21
31
|
stripUnsafeProjectConfigFields,
|
|
22
32
|
} from "./project-security";
|
|
23
33
|
import { pruneNestedConfigLeaf } from "./prune-config-leaf";
|
|
24
34
|
import { loadRawConfigFile } from "./raw-loader";
|
|
35
|
+
import { stripRemovedAgentConfig } from "./removed-agent-config";
|
|
25
36
|
import { type MagicContextConfig, MagicContextConfigSchema } from "./schema/magic-context";
|
|
26
37
|
import { resolveTransformMode } from "./transform-mode";
|
|
27
38
|
import { substituteConfigVariables } from "./variable";
|
|
28
39
|
|
|
29
40
|
export interface MagicContextPluginConfig extends MagicContextConfig {
|
|
30
41
|
disabled_hooks?: string[];
|
|
42
|
+
/** Runtime-only diagnostics; never read from user config. */
|
|
43
|
+
configParseFailures?: ConfigParseFailure[];
|
|
44
|
+
configWarningDetails?: ConfigWarningDetail[];
|
|
45
|
+
/** Whether cache_ttl existed in resolved raw config rather than coming from Zod defaults. */
|
|
46
|
+
cacheTtlConfigured?: boolean;
|
|
31
47
|
command?: Record<
|
|
32
48
|
string,
|
|
33
49
|
{
|
|
@@ -74,6 +90,8 @@ interface LoadedConfigFile {
|
|
|
74
90
|
config: Record<string, unknown>;
|
|
75
91
|
/** Warnings from {env:} / {file:} substitution, with config-path prefix applied. */
|
|
76
92
|
warnings: string[];
|
|
93
|
+
parseFailures: ConfigParseFailure[];
|
|
94
|
+
warningDetails: ConfigWarningDetail[];
|
|
77
95
|
}
|
|
78
96
|
|
|
79
97
|
export type LoadOutcome =
|
|
@@ -95,6 +113,9 @@ export interface LoadResultDetailed {
|
|
|
95
113
|
};
|
|
96
114
|
substitutionFailures: Array<{ keyPath: string; source: "user" | "project"; message: string }>;
|
|
97
115
|
recoveredTopLevelKeys: string[];
|
|
116
|
+
configParseFailures: ConfigParseFailure[];
|
|
117
|
+
warningDetails: ConfigWarningDetail[];
|
|
118
|
+
cacheTtlConfigured: boolean;
|
|
98
119
|
}
|
|
99
120
|
|
|
100
121
|
interface LoadedConfigFileDetailed extends LoadedConfigFile {
|
|
@@ -118,10 +139,13 @@ function loadConfigFileDetailed(
|
|
|
118
139
|
rawText = raw.text;
|
|
119
140
|
rawWarnings = raw.warnings;
|
|
120
141
|
} catch (error) {
|
|
142
|
+
const message = `failed to read config: ${error instanceof Error ? error.message : String(error)}`;
|
|
121
143
|
return {
|
|
122
144
|
config: {},
|
|
123
|
-
warnings: [
|
|
124
|
-
|
|
145
|
+
warnings: [`${configPath}: ${message}`],
|
|
146
|
+
parseFailures: [],
|
|
147
|
+
warningDetails: [
|
|
148
|
+
{ warningClass: CONFIG_WARNING_CLASS.FILE_IO, source, path: configPath, message },
|
|
125
149
|
],
|
|
126
150
|
outcome: "project-file-io-error",
|
|
127
151
|
source,
|
|
@@ -135,32 +159,71 @@ function loadConfigFileDetailed(
|
|
|
135
159
|
isProjectConfig: source === "project",
|
|
136
160
|
});
|
|
137
161
|
const rejectedKeyPaths: string[] = [];
|
|
138
|
-
const
|
|
162
|
+
const parsed = parseJsoncRecovering<Record<string, unknown>>(substituted.text, {
|
|
139
163
|
onRejectedKey: (path) => rejectedKeyPaths.push(path.join(".")),
|
|
140
164
|
});
|
|
165
|
+
const config =
|
|
166
|
+
parsed.value && typeof parsed.value === "object" && !Array.isArray(parsed.value)
|
|
167
|
+
? parsed.value
|
|
168
|
+
: {};
|
|
141
169
|
const unsafeKeyWarnings = rejectedKeyPaths.map(
|
|
142
170
|
(path) =>
|
|
143
171
|
`Ignored unsafe config key "${path}" (security: prototype-pollution keys are not allowed).`,
|
|
144
172
|
);
|
|
173
|
+
const firstIssue = parsed.issues[0];
|
|
174
|
+
const recovered = firstIssue !== undefined && Object.keys(config).length > 0;
|
|
175
|
+
const parseFailures: ConfigParseFailure[] = firstIssue
|
|
176
|
+
? [
|
|
177
|
+
{
|
|
178
|
+
warningClass: CONFIG_WARNING_CLASS.FILE_PARSE,
|
|
179
|
+
source,
|
|
180
|
+
path: configPath,
|
|
181
|
+
line: firstIssue.line,
|
|
182
|
+
column: firstIssue.column,
|
|
183
|
+
message: firstIssue.message,
|
|
184
|
+
recovered,
|
|
185
|
+
warning: `${configPath}:${firstIssue.line}:${firstIssue.column}: ${firstIssue.message}; ${recovered ? "recovered values were applied, but the file must be fixed." : "using defaults for this file."}`,
|
|
186
|
+
},
|
|
187
|
+
]
|
|
188
|
+
: [];
|
|
145
189
|
return {
|
|
146
190
|
config,
|
|
147
|
-
warnings: [
|
|
148
|
-
(
|
|
149
|
-
|
|
191
|
+
warnings: [
|
|
192
|
+
...parseFailures.map((failure) => failure.warning),
|
|
193
|
+
...rawWarnings.map((warning) => `${configPath}: ${warning}`),
|
|
194
|
+
...substituted.warnings.map((warning) => `${configPath}: ${warning}`),
|
|
195
|
+
...unsafeKeyWarnings.map((warning) => `${configPath}: ${warning}`),
|
|
196
|
+
],
|
|
197
|
+
parseFailures,
|
|
198
|
+
warningDetails: parseFailures,
|
|
150
199
|
outcome:
|
|
151
|
-
|
|
152
|
-
? "
|
|
153
|
-
:
|
|
154
|
-
? "
|
|
155
|
-
:
|
|
200
|
+
parseFailures.length > 0
|
|
201
|
+
? "project-file-parse-error"
|
|
202
|
+
: rejectedKeyPaths.length > 0
|
|
203
|
+
? "schema-recovery"
|
|
204
|
+
: substituted.warnings.length > 0
|
|
205
|
+
? "substitution-failure"
|
|
206
|
+
: "ok",
|
|
156
207
|
source,
|
|
157
208
|
};
|
|
158
209
|
} catch (error) {
|
|
210
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
211
|
+
const warning = `${configPath}:1:1: ${message}; using defaults for this file.`;
|
|
212
|
+
const failure: ConfigParseFailure = {
|
|
213
|
+
warningClass: CONFIG_WARNING_CLASS.FILE_PARSE,
|
|
214
|
+
source,
|
|
215
|
+
path: configPath,
|
|
216
|
+
line: 1,
|
|
217
|
+
column: 1,
|
|
218
|
+
message,
|
|
219
|
+
recovered: false,
|
|
220
|
+
warning,
|
|
221
|
+
};
|
|
159
222
|
return {
|
|
160
223
|
config: {},
|
|
161
|
-
warnings: [
|
|
162
|
-
|
|
163
|
-
],
|
|
224
|
+
warnings: [warning],
|
|
225
|
+
parseFailures: [failure],
|
|
226
|
+
warningDetails: [failure],
|
|
164
227
|
outcome: "project-file-parse-error",
|
|
165
228
|
source,
|
|
166
229
|
};
|
|
@@ -258,14 +321,39 @@ function redactConfigValue(value: unknown): string {
|
|
|
258
321
|
return typeof value;
|
|
259
322
|
}
|
|
260
323
|
|
|
261
|
-
|
|
324
|
+
let warnedProtectedTagsDeprecation = false;
|
|
325
|
+
|
|
326
|
+
export function resetProtectedTagsDeprecationWarningForTest(): void {
|
|
327
|
+
warnedProtectedTagsDeprecation = false;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
export function warnProtectedTagsDeprecationOnce(): void {
|
|
331
|
+
if (!warnedProtectedTagsDeprecation) {
|
|
332
|
+
warnedProtectedTagsDeprecation = true;
|
|
333
|
+
console.warn(
|
|
334
|
+
"[magic-context] protected_tags is deprecated and ignored; use protected_tokens instead.",
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
export function parsePluginConfig(
|
|
262
340
|
rawConfig: Record<string, unknown>,
|
|
263
341
|
recoveredTopLevelKeys: string[] = [],
|
|
264
342
|
): MagicContextPluginConfig & { configWarnings?: string[] } {
|
|
265
343
|
// Pre-Zod shim: reshape legacy experimental.* graduated keys so the user's
|
|
266
344
|
// opt-in/out state survives upgrades even when they never run `doctor`.
|
|
267
345
|
const preMigrationWarnings: string[] = [];
|
|
268
|
-
const
|
|
346
|
+
const configWithoutRemovedAgent = stripRemovedAgentConfig(rawConfig, preMigrationWarnings);
|
|
347
|
+
if (Object.hasOwn(rawConfig, "protected_tags")) {
|
|
348
|
+
warnProtectedTagsDeprecationOnce();
|
|
349
|
+
preMigrationWarnings.push(
|
|
350
|
+
"protected_tags is deprecated and ignored; use protected_tokens instead.",
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
const migratedExperimental = migrateLegacyExperimental(
|
|
354
|
+
configWithoutRemovedAgent,
|
|
355
|
+
preMigrationWarnings,
|
|
356
|
+
);
|
|
269
357
|
// Dreamer v2: convert the legacy v1 dreamer shape (window schedule, tasks
|
|
270
358
|
// array, user_memories/pin_key_files blocks) into the per-task `tasks` record.
|
|
271
359
|
// Runs AFTER migrate-experimental so experimental.user_memories (already
|
|
@@ -336,7 +424,7 @@ function parsePluginConfig(
|
|
|
336
424
|
const patched: Record<string, unknown> = { ...rawConfig };
|
|
337
425
|
for (const key of errorPaths) {
|
|
338
426
|
recoveredTopLevelKeys.push(key);
|
|
339
|
-
const isAgentConfig = key === "historian" || key === "dreamer"
|
|
427
|
+
const isAgentConfig = key === "historian" || key === "dreamer";
|
|
340
428
|
|
|
341
429
|
// For object-valued keys (including agent harness blocks), prune only invalid
|
|
342
430
|
// nested leaves and keep valid siblings, so one bad field does not remove
|
|
@@ -549,6 +637,8 @@ export function loadPluginConfigDetailed(directory: string): LoadResultDetailed
|
|
|
549
637
|
: null;
|
|
550
638
|
|
|
551
639
|
const allWarnings: string[] = [];
|
|
640
|
+
const removedConfigWarnings: string[] = [];
|
|
641
|
+
const userRaw = stripRemovedAgentConfig(userLoaded?.config ?? {}, removedConfigWarnings);
|
|
552
642
|
|
|
553
643
|
if (userLegacyFallback.source) {
|
|
554
644
|
allWarnings.push(
|
|
@@ -577,18 +667,20 @@ export function loadPluginConfigDetailed(directory: string): LoadResultDetailed
|
|
|
577
667
|
let projectRaw: Record<string, unknown> = {};
|
|
578
668
|
if (projectLoaded) {
|
|
579
669
|
allWarnings.push(...projectLoaded.warnings.map((w) => `[project config] ${w}`));
|
|
580
|
-
projectRaw =
|
|
670
|
+
projectRaw = stripRemovedAgentConfig(projectLoaded.config, removedConfigWarnings);
|
|
581
671
|
for (const warning of stripUnsafeProjectConfigFields(projectRaw)) {
|
|
582
672
|
allWarnings.push(`[project config] ${warning}`);
|
|
583
673
|
}
|
|
584
674
|
}
|
|
585
675
|
|
|
676
|
+
allWarnings.push(...removedConfigWarnings.map((warning) => `[config] ${warning}`));
|
|
677
|
+
|
|
586
678
|
// Resolve profiles at the single user→project merge choke point. The profile
|
|
587
679
|
// definition is parsed from the trusted user tier, then its validated model
|
|
588
680
|
// overlay is merged before the untrusted project config. The raw selector is
|
|
589
681
|
// consumed here; only the resolved name remains as status metadata.
|
|
590
682
|
const profileResolution = resolveConfigProfile({
|
|
591
|
-
userRaw
|
|
683
|
+
userRaw,
|
|
592
684
|
projectRaw,
|
|
593
685
|
});
|
|
594
686
|
allWarnings.push(...profileResolution.warnings.map((warning) => `[config] ${warning}`));
|
|
@@ -621,10 +713,16 @@ export function loadPluginConfigDetailed(directory: string): LoadResultDetailed
|
|
|
621
713
|
}
|
|
622
714
|
|
|
623
715
|
const recoveredTopLevelKeys: string[] = [];
|
|
716
|
+
const cacheTtlConfigured = Object.hasOwn(mergedRaw, "cache_ttl");
|
|
624
717
|
const config = parsePluginConfig(mergedRaw, recoveredTopLevelKeys);
|
|
718
|
+
attachProtectedTokensTierOverrides(config, {
|
|
719
|
+
trustedUser: trustedBaseConfig.protected_tokens,
|
|
720
|
+
project: projectLoaded ? profileResolution.projectBase.protected_tokens : undefined,
|
|
721
|
+
});
|
|
625
722
|
if (profileResolution.activeProfile) config.profile = profileResolution.activeProfile;
|
|
626
723
|
setOutputReserveConfig(config.output_reserve);
|
|
627
724
|
setWindowOverlayPath(config.models?.window_overlay_path);
|
|
725
|
+
const leafValidationWarnings = [...(config.configWarnings ?? [])];
|
|
628
726
|
if (config.configWarnings?.length) {
|
|
629
727
|
allWarnings.push(
|
|
630
728
|
...config.configWarnings.map((w) => {
|
|
@@ -637,7 +735,7 @@ export function loadPluginConfigDetailed(directory: string): LoadResultDetailed
|
|
|
637
735
|
|
|
638
736
|
const resolvedTransformMode = resolveTransformMode({
|
|
639
737
|
configured: config.transform_mode,
|
|
640
|
-
userTierHasSubc: hasUserTierSubcConfig(
|
|
738
|
+
userTierHasSubc: hasUserTierSubcConfig(userRaw),
|
|
641
739
|
compactionEnabled: isCompactionEnabled(config),
|
|
642
740
|
});
|
|
643
741
|
config.transform_mode = resolvedTransformMode.mode;
|
|
@@ -653,6 +751,21 @@ export function loadPluginConfigDetailed(directory: string): LoadResultDetailed
|
|
|
653
751
|
...bindSubstitutionFailures(userLoaded),
|
|
654
752
|
...bindSubstitutionFailures(projectLoaded),
|
|
655
753
|
];
|
|
754
|
+
const configParseFailures = [
|
|
755
|
+
...(userLoaded?.parseFailures ?? []),
|
|
756
|
+
...(projectLoaded?.parseFailures ?? []),
|
|
757
|
+
];
|
|
758
|
+
const warningDetails: ConfigWarningDetail[] = [
|
|
759
|
+
...(userLoaded?.warningDetails ?? []),
|
|
760
|
+
...(projectLoaded?.warningDetails ?? []),
|
|
761
|
+
...leafValidationWarnings.map((message) => ({
|
|
762
|
+
warningClass: CONFIG_WARNING_CLASS.INVALID_LEAF,
|
|
763
|
+
message,
|
|
764
|
+
})),
|
|
765
|
+
];
|
|
766
|
+
config.configParseFailures = configParseFailures;
|
|
767
|
+
config.configWarningDetails = warningDetails;
|
|
768
|
+
config.cacheTtlConfigured = cacheTtlConfigured;
|
|
656
769
|
const sources = {
|
|
657
770
|
userConfig:
|
|
658
771
|
userLoaded?.outcome ??
|
|
@@ -669,5 +782,8 @@ export function loadPluginConfigDetailed(directory: string): LoadResultDetailed
|
|
|
669
782
|
sources,
|
|
670
783
|
substitutionFailures,
|
|
671
784
|
recoveredTopLevelKeys,
|
|
785
|
+
configParseFailures,
|
|
786
|
+
warningDetails,
|
|
787
|
+
cacheTtlConfigured,
|
|
672
788
|
};
|
|
673
789
|
}
|
|
@@ -126,6 +126,10 @@ const KNOWN_SLOTS: Record<string, KnownSlot> = {
|
|
|
126
126
|
classification: "VERDICT",
|
|
127
127
|
reason: "Saved: the promise has a 60-second TTL, including rejections, and discovery is retried after expiry.",
|
|
128
128
|
},
|
|
129
|
+
"packages/plugin/src/shared/opencode-db-path.ts:lastReadFailure": {
|
|
130
|
+
classification: "DIAGNOSTIC",
|
|
131
|
+
reason: "Most-recent OpenCode DB read diagnostic: a successful open clears it, and path discovery re-probes after disappearance.",
|
|
132
|
+
},
|
|
129
133
|
"packages/plugin/src/shared/models-dev-cache.ts:authRewarmDone": {
|
|
130
134
|
classification: "VERDICT",
|
|
131
135
|
reason: "Saved: refreshModelLimitsAfterAuthOnce resets the latch when its warm fails.",
|
|
@@ -186,10 +186,10 @@ describe("migrateConfigFile (location migration)", () => {
|
|
|
186
186
|
try {
|
|
187
187
|
const target = join(dir, ".cortexkit", "magic-context.jsonc");
|
|
188
188
|
mkdirSync(join(dir, ".cortexkit"), { recursive: true });
|
|
189
|
-
writeFileSync(target, '{ "
|
|
189
|
+
writeFileSync(target, '{ "cache_ttl": "5m" }');
|
|
190
190
|
const legacy = join(dir, ".opencode", "magic-context.jsonc");
|
|
191
191
|
mkdirSync(join(dir, ".opencode"), { recursive: true });
|
|
192
|
-
writeFileSync(legacy, '{ "
|
|
192
|
+
writeFileSync(legacy, '{ "cache_ttl": "9m" }');
|
|
193
193
|
|
|
194
194
|
const r = migrateConfigFile({
|
|
195
195
|
scope: "project",
|
|
@@ -201,8 +201,8 @@ describe("migrateConfigFile (location migration)", () => {
|
|
|
201
201
|
expect(r.migrated).toBe(false);
|
|
202
202
|
expect(r.warnings.join("\n")).toContain("already exists with different settings");
|
|
203
203
|
// BOTH left as-is for manual reconciliation — never auto-clobbered.
|
|
204
|
-
expect(readFileSync(target, "utf8")).toContain('"
|
|
205
|
-
expect(readFileSync(legacy, "utf8")).toContain('"
|
|
204
|
+
expect(readFileSync(target, "utf8")).toContain('"cache_ttl": "5m"');
|
|
205
|
+
expect(readFileSync(legacy, "utf8")).toContain('"cache_ttl": "9m"');
|
|
206
206
|
expect(existsSync(`${legacy}.MOVED_READPLEASE`)).toBe(false);
|
|
207
207
|
} finally {
|
|
208
208
|
rmSync(dir, { recursive: true, force: true });
|
|
@@ -216,8 +216,8 @@ describe("migrateConfigFile (location migration)", () => {
|
|
|
216
216
|
const b = join(dir, ".pi", "magic-context.jsonc");
|
|
217
217
|
mkdirSync(join(dir, ".opencode"), { recursive: true });
|
|
218
218
|
mkdirSync(join(dir, ".pi"), { recursive: true });
|
|
219
|
-
writeFileSync(a, '{ "
|
|
220
|
-
writeFileSync(b, '{ "
|
|
219
|
+
writeFileSync(a, '{ "cache_ttl": "5m" }');
|
|
220
|
+
writeFileSync(b, '{ "cache_ttl": "9m" }');
|
|
221
221
|
const target = join(dir, ".cortexkit", "magic-context.jsonc");
|
|
222
222
|
|
|
223
223
|
const r = migrateConfigFile({
|
|
@@ -256,12 +256,45 @@ describe("migrateConfigFile (location migration)", () => {
|
|
|
256
256
|
|
|
257
257
|
expect(r.migrated).toBe(true);
|
|
258
258
|
expect(existsSync(target)).toBe(true);
|
|
259
|
+
expect(readFileSync(target, "utf8")).not.toContain("protected_tags");
|
|
259
260
|
expect(existsSync(`${a}.MOVED_READPLEASE`)).toBe(true);
|
|
260
261
|
expect(existsSync(`${b}.MOVED_READPLEASE`)).toBe(true);
|
|
261
262
|
} finally {
|
|
262
263
|
rmSync(dir, { recursive: true, force: true });
|
|
263
264
|
}
|
|
264
265
|
});
|
|
266
|
+
|
|
267
|
+
it("strips deprecated protected_tags key during migration to target with notice", () => {
|
|
268
|
+
const dir = tmp();
|
|
269
|
+
try {
|
|
270
|
+
const legacy = join(dir, "magic-context.jsonc");
|
|
271
|
+
writeFileSync(legacy, '{\n "protected_tags": 20,\n "cache_ttl": "15m"\n}\n');
|
|
272
|
+
const target = join(dir, ".cortexkit", "magic-context.jsonc");
|
|
273
|
+
const infos: string[] = [];
|
|
274
|
+
const r = migrateConfigFile({
|
|
275
|
+
scope: "project",
|
|
276
|
+
targetPath: target,
|
|
277
|
+
legacySources: [src(legacy)],
|
|
278
|
+
logger: {
|
|
279
|
+
info: (msg) => infos.push(msg),
|
|
280
|
+
warn: () => {},
|
|
281
|
+
},
|
|
282
|
+
});
|
|
283
|
+
expect(r.migrated).toBe(true);
|
|
284
|
+
const targetContent = readFileSync(target, "utf8");
|
|
285
|
+
expect(targetContent).not.toContain("protected_tags");
|
|
286
|
+
expect(targetContent).toContain('"cache_ttl": "15m"');
|
|
287
|
+
expect(
|
|
288
|
+
infos.some((msg) =>
|
|
289
|
+
msg.includes(
|
|
290
|
+
'Stripped deprecated "protected_tags" key during config location migration',
|
|
291
|
+
),
|
|
292
|
+
),
|
|
293
|
+
).toBe(true);
|
|
294
|
+
} finally {
|
|
295
|
+
rmSync(dir, { recursive: true, force: true });
|
|
296
|
+
}
|
|
297
|
+
});
|
|
265
298
|
});
|
|
266
299
|
|
|
267
300
|
describe("resolveLegacyConfigSources", () => {
|