@cortexkit/opencode-magic-context 0.41.4 → 0.42.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -3
- package/dist/agents/hidden-agent-registrations.d.ts +1 -3
- package/dist/agents/hidden-agent-registrations.d.ts.map +1 -1
- package/dist/agents/magic-context-prompt.d.ts +1 -1
- package/dist/agents/magic-context-prompt.d.ts.map +1 -1
- package/dist/agents/permissions.d.ts +1 -22
- package/dist/agents/permissions.d.ts.map +1 -1
- package/dist/config/agent-disable.d.ts +0 -5
- package/dist/config/agent-disable.d.ts.map +1 -1
- package/dist/config/index.d.ts +5 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/migrate-config-location.d.ts.map +1 -1
- package/dist/config/project-security.d.ts +20 -2
- package/dist/config/project-security.d.ts.map +1 -1
- package/dist/config/removed-agent-config.d.ts +8 -0
- package/dist/config/removed-agent-config.d.ts.map +1 -0
- package/dist/config/schema/magic-context.d.ts +43 -201
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/{conflict-warning-hook-ejkc9sjn.js → conflict-warning-hook-6p3xqeac.js} +3 -3
- package/dist/{derive-budgets-bc366cz8.js → derive-budgets-s2pgnnm4.js} +1 -1
- package/dist/features/builtin-commands/commands.d.ts +0 -4
- package/dist/features/builtin-commands/commands.d.ts.map +1 -1
- package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts +15 -4
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-storage.d.ts.map +1 -1
- package/dist/features/magic-context/context-authority.d.ts +31 -4
- package/dist/features/magic-context/context-authority.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/open-opencode-db.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/refresh-primers.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/retrospective-orphan-sweep.d.ts +19 -9
- package/dist/features/magic-context/dreamer/retrospective-orphan-sweep.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts +4 -0
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
- package/dist/features/magic-context/fail-closed-block.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/sweep-coordinator.d.ts.map +1 -1
- package/dist/features/magic-context/index.d.ts +0 -1
- package/dist/features/magic-context/index.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-identity.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-local.d.ts +13 -0
- package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-model-match.d.ts +41 -0
- package/dist/features/magic-context/memory/embedding-model-match.d.ts.map +1 -0
- package/dist/features/magic-context/memory/embedding-openai.d.ts +7 -20
- package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-provider.d.ts +2 -2
- package/dist/features/magic-context/memory/embedding-provider.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-synapse.d.ts +48 -14
- package/dist/features/magic-context/memory/embedding-synapse.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding.d.ts +1 -1
- package/dist/features/magic-context/memory/embedding.d.ts.map +1 -1
- package/dist/features/magic-context/memory/memory-migration.d.ts.map +1 -1
- package/dist/features/magic-context/memory/project-identity.d.ts +1 -0
- package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
- package/dist/features/magic-context/memory/promotion.d.ts +7 -1
- package/dist/features/magic-context/memory/promotion.d.ts.map +1 -1
- package/dist/features/magic-context/merged-reasoning-decisions.d.ts +6 -0
- package/dist/features/magic-context/merged-reasoning-decisions.d.ts.map +1 -0
- package/dist/features/magic-context/message-fts-rowid-map.d.ts.map +1 -1
- package/dist/features/magic-context/message-index-async.d.ts +12 -0
- package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
- package/dist/features/magic-context/message-index.d.ts.map +1 -1
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
- package/dist/features/magic-context/mural/render-trigger.d.ts +6 -0
- package/dist/features/magic-context/mural/render-trigger.d.ts.map +1 -1
- package/dist/features/magic-context/no-content-compartment.d.ts +12 -0
- package/dist/features/magic-context/no-content-compartment.d.ts.map +1 -0
- package/dist/features/magic-context/pi-content-decisions.d.ts +9 -0
- package/dist/features/magic-context/pi-content-decisions.d.ts.map +1 -0
- package/dist/features/magic-context/project-docs-hash.d.ts +4 -0
- package/dist/features/magic-context/project-docs-hash.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts +13 -4
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/protection-window.d.ts +79 -0
- package/dist/features/magic-context/protection-window.d.ts.map +1 -0
- package/dist/features/magic-context/search.d.ts.map +1 -1
- package/dist/features/magic-context/session-project-backfill.d.ts.map +1 -1
- package/dist/features/magic-context/shadow-backfill-state.d.ts +26 -0
- package/dist/features/magic-context/shadow-backfill-state.d.ts.map +1 -0
- package/dist/features/magic-context/smart-notes/compiler.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts +4 -0
- package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/storage.d.ts.map +1 -1
- package/dist/features/magic-context/storage-clone.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts +1 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-embedding-measurements.d.ts +2 -2
- package/dist/features/magic-context/storage-embedding-measurements.d.ts.map +1 -1
- package/dist/features/magic-context/storage-historian-runs.d.ts +4 -0
- package/dist/features/magic-context/storage-historian-runs.d.ts.map +1 -1
- package/dist/features/magic-context/storage-memory-mutation-log.d.ts +1 -0
- package/dist/features/magic-context/storage-memory-mutation-log.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +79 -13
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta.d.ts +1 -1
- package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
- package/dist/features/magic-context/storage-native-replay.d.ts +29 -0
- package/dist/features/magic-context/storage-native-replay.d.ts.map +1 -0
- package/dist/features/magic-context/storage-notes.d.ts +6 -0
- package/dist/features/magic-context/storage-notes.d.ts.map +1 -1
- package/dist/features/magic-context/storage-replay-document.d.ts +33 -0
- package/dist/features/magic-context/storage-replay-document.d.ts.map +1 -0
- package/dist/features/magic-context/storage-subagent-invocations.d.ts +1 -1
- package/dist/features/magic-context/storage-subagent-invocations.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tags.d.ts +19 -11
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +3 -3
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/features/magic-context/subagent-token-capture.d.ts.map +1 -1
- package/dist/features/magic-context/tagger.d.ts +13 -0
- package/dist/features/magic-context/tagger.d.ts.map +1 -1
- package/dist/features/magic-context/tool-owner-backfill.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/storage-user-memory.d.ts.map +1 -1
- package/dist/features/magic-context/workspaces.d.ts.map +1 -1
- package/dist/hooks/magic-context/apply-operations.d.ts +11 -5
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/cache-busting-signals.d.ts +9 -1
- package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -1
- package/dist/hooks/magic-context/caveman-cleanup.d.ts +1 -1
- package/dist/hooks/magic-context/caveman-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
- package/dist/hooks/magic-context/child-session-spawn.d.ts +3 -3
- package/dist/hooks/magic-context/child-session-spawn.d.ts.map +1 -1
- package/dist/hooks/magic-context/command-handler.d.ts +1 -10
- package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts +10 -21
- package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts +1 -1
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts +26 -2
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts.map +1 -1
- package/dist/hooks/magic-context/decay-render.d.ts.map +1 -1
- package/dist/hooks/magic-context/dropped-input-guard.d.ts +9 -0
- package/dist/hooks/magic-context/dropped-input-guard.d.ts.map +1 -0
- package/dist/hooks/magic-context/embed-session-state.d.ts +1 -1
- package/dist/hooks/magic-context/embed-session-state.d.ts.map +1 -1
- package/dist/hooks/magic-context/emergency-drop.d.ts +6 -1
- package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-handler.d.ts +0 -1
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-payloads.d.ts +7 -6
- package/dist/hooks/magic-context/event-payloads.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-resolvers.d.ts +1 -1
- package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
- package/dist/hooks/magic-context/execute-status.d.ts +3 -1
- package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
- package/dist/hooks/magic-context/format-embed-failure.d.ts +2 -1
- package/dist/hooks/magic-context/format-embed-failure.d.ts.map +1 -1
- package/dist/hooks/magic-context/format-embed-status.d.ts.map +1 -1
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts +7 -1
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook-handlers.d.ts +3 -1
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts +13 -4
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts +14 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/live-session-state.d.ts +1 -1
- package/dist/hooks/magic-context/lkg-slot.d.ts +34 -0
- package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
- package/dist/hooks/magic-context/maintenance-authority.d.ts +2 -2
- package/dist/hooks/magic-context/maintenance-authority.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-state-sync-timing.d.ts +21 -0
- package/dist/hooks/magic-context/module-state-sync-timing.d.ts.map +1 -0
- package/dist/hooks/magic-context/module-state-sync.d.ts +21 -7
- package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-transport.d.ts +12 -0
- package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-wire.d.ts +8 -0
- package/dist/hooks/magic-context/module-wire.d.ts.map +1 -1
- package/dist/hooks/magic-context/note-nudger.d.ts.map +1 -1
- package/dist/hooks/magic-context/persist-filtered-noise.d.ts +5 -0
- package/dist/hooks/magic-context/persist-filtered-noise.d.ts.map +1 -0
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts +6 -0
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts +18 -18
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-db.d.ts +22 -12
- package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-formatting.d.ts +8 -0
- package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts +10 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
- package/dist/hooks/magic-context/reference-retrieval.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-mode-transform.d.ts +74 -9
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/send-session-notification.d.ts +11 -10
- package/dist/hooks/magic-context/send-session-notification.d.ts.map +1 -1
- package/dist/hooks/magic-context/strip-content.d.ts +7 -0
- package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
- package/dist/hooks/magic-context/supersession-reclaim.d.ts +13 -0
- package/dist/hooks/magic-context/supersession-reclaim.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts +2 -3
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts +8 -3
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-context-state.d.ts +7 -1
- package/dist/hooks/magic-context/transform-context-state.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +11 -4
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +7 -2
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/upgrade-reminder.d.ts +7 -9
- package/dist/hooks/magic-context/upgrade-reminder.d.ts.map +1 -1
- package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
- package/dist/index-1974jvn3.js +783 -0
- package/dist/{index-0y2mcg5y.js → index-1q9kay7n.js} +18717 -16197
- package/dist/{index-4avmwfp5.js → index-36wd1d6k.js} +6 -29
- package/dist/{index-fz104x1j.js → index-jmtjh2d3.js} +3 -3
- package/dist/{index-q264erdp.js → index-nqgjwfzn.js} +70 -38
- package/dist/{index-mjv9je4e.js → index-xdtge3y2.js} +45 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6457 -5190
- package/dist/plugin/conflict-warning-hook.d.ts +5 -6
- package/dist/plugin/conflict-warning-hook.d.ts.map +1 -1
- package/dist/plugin/dream-timer.d.ts +1 -0
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/embedding-bootstrap-helpers.d.ts.map +1 -1
- package/dist/plugin/embedding-routing.d.ts +4 -1
- package/dist/plugin/embedding-routing.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +16 -2
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts +31 -1
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/plugin/rust-tool-backends.d.ts +1 -0
- package/dist/plugin/rust-tool-backends.d.ts.map +1 -1
- package/dist/plugin/tool-registry.d.ts.map +1 -1
- package/dist/{recomp-orchestrator-q98r6rga.js → recomp-orchestrator-m33b3rk9.js} +5 -5
- package/dist/{send-session-notification-hdh02wy9.js → send-session-notification-1qeqkswb.js} +6 -4
- package/dist/shared/child-session-teardown.d.ts +34 -0
- package/dist/shared/child-session-teardown.d.ts.map +1 -0
- package/dist/shared/keep-subagents.d.ts +1 -1
- package/dist/shared/keep-subagents.d.ts.map +1 -1
- package/dist/shared/model-suggestion-retry.d.ts +1 -1
- package/dist/shared/opencode-db-path.d.ts +24 -0
- package/dist/shared/opencode-db-path.d.ts.map +1 -0
- package/dist/shared/prompt-surface-runtime.d.ts +10 -5
- package/dist/shared/prompt-surface-runtime.d.ts.map +1 -1
- package/dist/shared/resolve-fallbacks.d.ts +1 -1
- package/dist/shared/rpc-types.d.ts +121 -0
- package/dist/shared/rpc-types.d.ts.map +1 -1
- package/dist/shared/sqlite.d.ts +42 -0
- package/dist/shared/sqlite.d.ts.map +1 -1
- package/dist/shared/status-detail-text.d.ts +3 -1
- package/dist/shared/status-detail-text.d.ts.map +1 -1
- package/dist/shared/status-summary.d.ts +30 -0
- package/dist/shared/status-summary.d.ts.map +1 -0
- package/dist/shared/subagent-runner.d.ts +17 -10
- package/dist/shared/subagent-runner.d.ts.map +1 -1
- package/dist/shared/tag-transcript.d.ts.map +1 -1
- package/dist/shared/tail-hygiene-status.d.ts +1 -0
- package/dist/shared/tail-hygiene-status.d.ts.map +1 -1
- package/dist/shared/transcript.d.ts +6 -0
- package/dist/shared/transcript.d.ts.map +1 -1
- package/dist/shared/user-facing-codes.d.ts +191 -0
- package/dist/shared/user-facing-codes.d.ts.map +1 -0
- package/dist/shared/window-geometry.d.ts +23 -0
- package/dist/shared/window-geometry.d.ts.map +1 -1
- package/dist/shared/write-transaction-timing.d.ts +1 -1
- package/dist/shared/write-transaction-timing.d.ts.map +1 -1
- package/dist/{storage-meta-session-dvwfw778.js → storage-meta-session-e6g0mmec.js} +2 -2
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
- package/dist/tools/ctx-memory/verification-recording.d.ts.map +1 -1
- package/dist/tools/ctx-note/constants.d.ts +1 -1
- package/dist/tools/ctx-note/constants.d.ts.map +1 -1
- package/dist/tools/ctx-note/tools.d.ts.map +1 -1
- package/dist/tools/ctx-note/types.d.ts +1 -0
- package/dist/tools/ctx-note/types.d.ts.map +1 -1
- package/dist/tools/ctx-reduce/tools.d.ts +10 -1
- package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
- package/dist/tools/ctx-search/constants.d.ts +1 -1
- package/dist/tools/ctx-search/constants.d.ts.map +1 -1
- package/dist/tools/light-descriptions.d.ts +2 -2
- package/dist/tools/light-descriptions.d.ts.map +1 -1
- package/package.json +2 -3
- package/src/agents/hidden-agent-registrations.ts +3 -15
- package/src/agents/magic-context-prompt.test.ts +7 -5
- package/src/agents/magic-context-prompt.ts +22 -30
- package/src/agents/permissions.test.ts +1 -42
- package/src/agents/permissions.ts +1 -24
- package/src/config/agent-disable.ts +5 -22
- package/src/config/index.test.ts +126 -15
- package/src/config/index.ts +41 -6
- package/src/config/latch-permanence-guard.test.ts +4 -0
- package/src/config/migrate-config-location.test.ts +39 -6
- package/src/config/migrate-config-location.ts +18 -31
- package/src/config/profiles.ts +1 -1
- package/src/config/project-security.hostile-matrix.test.ts +0 -8
- package/src/config/project-security.test.ts +21 -24
- package/src/config/project-security.ts +115 -14
- package/src/config/protected-tokens.test.ts +235 -0
- package/src/config/removed-agent-config.ts +45 -0
- package/src/config/removed-agent-source-fence.test.ts +56 -0
- package/src/config/schema/magic-context.test.ts +50 -42
- package/src/config/schema/magic-context.ts +70 -37
- package/src/shared/child-session-teardown.test.ts +218 -0
- package/src/shared/child-session-teardown.ts +66 -0
- package/src/shared/keep-subagents.ts +9 -14
- package/src/shared/model-suggestion-retry.ts +1 -1
- package/src/shared/opencode-db-path.test.ts +196 -0
- package/src/shared/opencode-db-path.ts +215 -0
- package/src/shared/prompt-surface-a1-golden.md +50 -35
- package/src/shared/prompt-surface-runtime.test.ts +28 -0
- package/src/shared/prompt-surface-runtime.ts +22 -5
- package/src/shared/resolve-fallbacks.ts +1 -1
- package/src/shared/rpc-types.ts +128 -0
- package/src/shared/session-messages-bounded.test.ts +1 -1
- package/src/shared/sqlite-import-fence.test.ts +19 -0
- package/src/shared/sqlite.test.ts +27 -1
- package/src/shared/sqlite.ts +204 -1
- package/src/shared/status-detail-text.test.ts +92 -20
- package/src/shared/status-detail-text.ts +24 -2
- package/src/shared/status-summary.ts +167 -0
- package/src/shared/subagent-runner.ts +17 -10
- package/src/shared/tag-transcript.ts +33 -21
- package/src/shared/tail-hygiene-status.ts +8 -0
- package/src/shared/transcript.ts +7 -0
- package/src/shared/user-facing-codes.test.ts +140 -0
- package/src/shared/user-facing-codes.ts +276 -0
- package/src/shared/window-geometry.test.ts +44 -0
- package/src/shared/window-geometry.ts +89 -11
- package/src/shared/write-transaction-attribution.test.ts +241 -0
- package/src/shared/write-transaction-timing.ts +2 -1
- package/src/tui/index.tsx +44 -11
- package/src/tui/slots/sidebar-content.tsx +12 -7
- package/src/tui-compiled/index.tsx +662 -649
- package/src/tui-compiled/slots/sidebar-content.tsx +301 -305
- package/dist/agents/sidekick.d.ts +0 -2
- package/dist/agents/sidekick.d.ts.map +0 -1
- package/dist/features/magic-context/defaults.d.ts +0 -2
- package/dist/features/magic-context/defaults.d.ts.map +0 -1
- package/dist/features/magic-context/sidekick/agent.d.ts +0 -14
- package/dist/features/magic-context/sidekick/agent.d.ts.map +0 -1
- package/dist/features/magic-context/sidekick/core.d.ts +0 -38
- package/dist/features/magic-context/sidekick/core.d.ts.map +0 -1
- package/dist/features/magic-context/sidekick/index.d.ts +0 -3
- package/dist/features/magic-context/sidekick/index.d.ts.map +0 -1
- package/dist/hooks/magic-context/boundary-execution.d.ts +0 -27
- package/dist/hooks/magic-context/boundary-execution.d.ts.map +0 -1
- package/dist/index-raatkvw5.js +0 -360
- package/src/agents/sidekick.ts +0 -1
- package/src/features/magic-context/defaults.ts +0 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { homedir } from "node:os";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { isValidLanguageCode } from "../../agents/language-directive";
|
|
4
|
-
import { DEFAULT_PROTECTED_TAGS } from "../../features/magic-context/defaults";
|
|
5
4
|
import { isValidCron } from "../../features/magic-context/dreamer/cron";
|
|
6
5
|
import type {
|
|
7
6
|
AGENTIC_DREAM_TASKS,
|
|
@@ -446,27 +445,15 @@ const ProfileDreamerSchema = z
|
|
|
446
445
|
omp: ProfileOmpModelBlockSchema.optional(),
|
|
447
446
|
})
|
|
448
447
|
.strict();
|
|
449
|
-
const ProfileSidekickSchema = AgentOverrideConfigSchema.pick({
|
|
450
|
-
model: true,
|
|
451
|
-
fallback_models: true,
|
|
452
|
-
variant: true,
|
|
453
|
-
})
|
|
454
|
-
.extend({
|
|
455
|
-
thinking_level: PiThinkingLevelSchema.describe(
|
|
456
|
-
"Pi thinking level for the sidekick model selection.",
|
|
457
|
-
),
|
|
458
|
-
})
|
|
459
|
-
.strict();
|
|
460
448
|
|
|
461
449
|
export const ConfigProfileSchema = z
|
|
462
450
|
.object({
|
|
463
451
|
historian: ProfileHistorianSchema.optional(),
|
|
464
452
|
dreamer: ProfileDreamerSchema.optional(),
|
|
465
|
-
sidekick: ProfileSidekickSchema.optional(),
|
|
466
453
|
})
|
|
467
454
|
.strict()
|
|
468
455
|
.describe(
|
|
469
|
-
"User-owned model-selection overlay. Only historian/dreamer harness model blocks
|
|
456
|
+
"User-owned model-selection overlay. Only historian/dreamer harness model blocks are allowed.",
|
|
470
457
|
);
|
|
471
458
|
export type ConfigProfile = z.infer<typeof ConfigProfileSchema>;
|
|
472
459
|
|
|
@@ -626,15 +613,6 @@ export const DreamerConfigSchema = AgentMetadataSchema.extend({
|
|
|
626
613
|
});
|
|
627
614
|
export type DreamerConfig = z.infer<typeof DreamerConfigSchema>;
|
|
628
615
|
|
|
629
|
-
export const SidekickConfigSchema = AgentOverrideConfigSchema.extend({
|
|
630
|
-
timeout_ms: z.number().default(30000).describe("Timeout for sidekick calls in milliseconds"),
|
|
631
|
-
system_prompt: z.string().optional().describe("Custom system prompt for sidekick"),
|
|
632
|
-
thinking_level: PiThinkingLevelSchema.describe(
|
|
633
|
-
"Pi only: explicit thinking level for sidekick subagent invocations. See historian.pi.thinking_level.",
|
|
634
|
-
),
|
|
635
|
-
}).optional();
|
|
636
|
-
export type SidekickConfig = NonNullable<z.infer<typeof SidekickConfigSchema>>;
|
|
637
|
-
|
|
638
616
|
/**
|
|
639
617
|
* Historian metadata remains harness-independent. Only model resolution moves to
|
|
640
618
|
* the strict opencode, pi, and omp blocks; two_pass and disallowed_tools stay here.
|
|
@@ -699,6 +677,18 @@ const BaseEmbeddingConfigSchema = z
|
|
|
699
677
|
.describe(
|
|
700
678
|
"Optional input_type for query (search) embeddings on asymmetric models (e.g. NVIDIA NIM 'query'). When unset, query embeddings use embedding.input_type. Passage/stored content always uses embedding.input_type.",
|
|
701
679
|
),
|
|
680
|
+
query_instruction: z
|
|
681
|
+
.union([z.string(), z.literal(false)])
|
|
682
|
+
.optional()
|
|
683
|
+
.describe(
|
|
684
|
+
"OpenAI-compatible query prefix override. A string is prepended verbatim to search queries; false disables the built-in model-family instruction. Qwen3-Embedding, gte-Qwen instruct, e5 instruct, and Nomic families have built-in recipes. Query-only changes do not re-embed stored content. User-level only; project values are ignored.",
|
|
685
|
+
),
|
|
686
|
+
document_prefix: z
|
|
687
|
+
.string()
|
|
688
|
+
.optional()
|
|
689
|
+
.describe(
|
|
690
|
+
"OpenAI-compatible stored-document prefix override, prepended verbatim. Defaults to the model-family recipe (empty for Qwen3/gte/e5 instruct; 'search_document: ' for Nomic). Changing it changes stored vectors and triggers re-embedding. User-level only; project values are ignored.",
|
|
691
|
+
),
|
|
702
692
|
truncate: z
|
|
703
693
|
.string()
|
|
704
694
|
.optional()
|
|
@@ -776,6 +766,12 @@ export const EmbeddingConfigSchema = BaseEmbeddingConfigSchema.transform((data)
|
|
|
776
766
|
...(apiKey ? { api_key: apiKey } : {}),
|
|
777
767
|
...(inputType ? { input_type: inputType } : {}),
|
|
778
768
|
...(queryInputType ? { query_input_type: queryInputType } : {}),
|
|
769
|
+
...(data.query_instruction !== undefined
|
|
770
|
+
? { query_instruction: data.query_instruction }
|
|
771
|
+
: {}),
|
|
772
|
+
...(data.document_prefix !== undefined
|
|
773
|
+
? { document_prefix: data.document_prefix }
|
|
774
|
+
: {}),
|
|
779
775
|
...(truncate ? { truncate } : {}),
|
|
780
776
|
...(data.max_input_tokens ? { max_input_tokens: data.max_input_tokens } : {}),
|
|
781
777
|
};
|
|
@@ -809,6 +805,12 @@ export const EmbeddingConfigSchema = BaseEmbeddingConfigSchema.transform((data)
|
|
|
809
805
|
...(apiKey ? { api_key: apiKey } : {}),
|
|
810
806
|
...(inputType ? { input_type: inputType } : {}),
|
|
811
807
|
...(queryInputType ? { query_input_type: queryInputType } : {}),
|
|
808
|
+
...(data.query_instruction !== undefined
|
|
809
|
+
? { query_instruction: data.query_instruction }
|
|
810
|
+
: {}),
|
|
811
|
+
...(data.document_prefix !== undefined
|
|
812
|
+
? { document_prefix: data.document_prefix }
|
|
813
|
+
: {}),
|
|
812
814
|
...(truncate ? { truncate } : {}),
|
|
813
815
|
...(data.max_input_tokens ? { max_input_tokens: data.max_input_tokens } : {}),
|
|
814
816
|
};
|
|
@@ -871,7 +873,8 @@ export interface MagicContextConfig {
|
|
|
871
873
|
* this overrides `execute_threshold_percentage` for that model. Useful for hard caps
|
|
872
874
|
* matching provider input limits. Values above 90% × context_limit are clamped with a warning. */
|
|
873
875
|
execute_threshold_tokens?: { default?: number; [modelKey: string]: number | undefined };
|
|
874
|
-
|
|
876
|
+
protected_tokens?: number;
|
|
877
|
+
protected_tags?: number;
|
|
875
878
|
clear_reasoning_age: number;
|
|
876
879
|
history_budget_percentage: number;
|
|
877
880
|
historian_timeout_ms: number;
|
|
@@ -917,10 +920,12 @@ export interface MagicContextConfig {
|
|
|
917
920
|
* Graduated from `experimental.temporal_awareness`; default: true. */
|
|
918
921
|
temporal_awareness: boolean;
|
|
919
922
|
/** Debug: when true, keep the child sessions Magic Context spawns for its
|
|
920
|
-
* own subagents (historian, dreamer,
|
|
923
|
+
* own subagents (historian, dreamer, memory-migration) instead
|
|
921
924
|
* of deleting them on success. For short-term inspection/data collection;
|
|
922
925
|
* kept sessions accumulate until manually cleared. Default false. */
|
|
923
926
|
keep_subagents: boolean;
|
|
927
|
+
/** Enable loopback-only diagnostic RPCs that expose memory usage and heap snapshots. */
|
|
928
|
+
debug_rpc?: boolean;
|
|
924
929
|
/**
|
|
925
930
|
* When true (default), deterministic inoperability (schema fence, storage
|
|
926
931
|
* open/migration failure) blocks the primary-session transform with a loud
|
|
@@ -1011,7 +1016,6 @@ export interface MagicContextConfig {
|
|
|
1011
1016
|
max_commits: number;
|
|
1012
1017
|
};
|
|
1013
1018
|
};
|
|
1014
|
-
sidekick?: SidekickConfig;
|
|
1015
1019
|
}
|
|
1016
1020
|
|
|
1017
1021
|
export const MagicContextConfigSchema = z
|
|
@@ -1063,7 +1067,7 @@ export const MagicContextConfigSchema = z
|
|
|
1063
1067
|
.describe(
|
|
1064
1068
|
"Output language for Magic Context's generated content and guidance, as a " +
|
|
1065
1069
|
'2-letter ISO 639-1 code (e.g. "tr", "es", "de", "ja", "pt"). When set, the ' +
|
|
1066
|
-
"historian, dreamer,
|
|
1070
|
+
"historian, dreamer, and the agent-guidance block instruct the model to " +
|
|
1067
1071
|
"write its PROSE in this language while keeping all structural tokens (XML tags, " +
|
|
1068
1072
|
"the five memory category names, code identifiers, file paths) in English. " +
|
|
1069
1073
|
"USER-LEVEL ONLY (ignored in project config for security). Unset = today's " +
|
|
@@ -1080,7 +1084,7 @@ export const MagicContextConfigSchema = z
|
|
|
1080
1084
|
"Select a named user-owned model profile. A valid project name overrides this user default; an empty string, null, or other non-string project value is ignored with a warning so the user selection still applies. Unknown names warn and use the base configuration.",
|
|
1081
1085
|
),
|
|
1082
1086
|
profiles: ConfigProfilesSchema.optional().describe(
|
|
1083
|
-
"User-level named model profiles. A profile may contain only historian/dreamer model, fallback_models, OpenCode variant, and Pi/OMP thinking_level fields
|
|
1087
|
+
"User-level named model profiles. A profile may contain only historian/dreamer model, fallback_models, OpenCode variant, and Pi/OMP thinking_level fields; task execution policy (including timeout_minutes) is excluded. Project configs may select a name but cannot define profiles.",
|
|
1084
1088
|
),
|
|
1085
1089
|
historian: HistorianConfigSchema.describe(
|
|
1086
1090
|
"Historian metadata plus independent strict OpenCode, Pi, and OMP execution blocks. Retained metadata stays at historian; model, fallback_models, variant, and thinking_level belong only in historian.opencode, historian.pi, or historian.omp.",
|
|
@@ -1153,14 +1157,22 @@ export const MagicContextConfigSchema = z
|
|
|
1153
1157
|
.describe(
|
|
1154
1158
|
"Absolute token thresholds per model. When matched, overrides execute_threshold_percentage for that model. Accepts `default` for all models or per-model keys. Values above 90% × context_limit are clamped with a warning log. Min 5_000, max 2_000_000.",
|
|
1155
1159
|
),
|
|
1156
|
-
|
|
1160
|
+
protected_tokens: z
|
|
1157
1161
|
.number()
|
|
1158
|
-
.
|
|
1159
|
-
.
|
|
1162
|
+
.int()
|
|
1163
|
+
.min(4000)
|
|
1164
|
+
.max(1_000_000)
|
|
1160
1165
|
.optional()
|
|
1161
1166
|
.describe(
|
|
1162
|
-
"
|
|
1167
|
+
"Positive integer token floor to protect from automatic reclaim (min: 4_000, max: 1_000_000). When omitted, the derived default is clamp(round(0.05 × usableSoft), min(16_000, round(0.08 × usableSoft)), 64_000).",
|
|
1163
1168
|
),
|
|
1169
|
+
protected_tags: z
|
|
1170
|
+
.unknown()
|
|
1171
|
+
.optional()
|
|
1172
|
+
.describe(
|
|
1173
|
+
"Deprecated: number of recent tags to protect. Ignored for behaviour; use protected_tokens instead.",
|
|
1174
|
+
)
|
|
1175
|
+
.meta({ deprecated: true }),
|
|
1164
1176
|
clear_reasoning_age: z
|
|
1165
1177
|
.number()
|
|
1166
1178
|
.min(10)
|
|
@@ -1294,7 +1306,13 @@ export const MagicContextConfigSchema = z
|
|
|
1294
1306
|
.boolean()
|
|
1295
1307
|
.default(false)
|
|
1296
1308
|
.describe(
|
|
1297
|
-
"Debug: keep the child sessions Magic Context spawns for its own subagents (historian, dreamer,
|
|
1309
|
+
"Debug: keep the child sessions Magic Context spawns for its own subagents (historian, dreamer, memory-migration) instead of deleting them on success. Useful for short-term inspection/data collection — their full transcript (prompt, tool calls, token usage, output) stays in the host session store. Kept sessions accumulate until manually cleared; leave false for normal use. Requires a restart to take effect.",
|
|
1310
|
+
),
|
|
1311
|
+
debug_rpc: z
|
|
1312
|
+
.boolean()
|
|
1313
|
+
.default(false)
|
|
1314
|
+
.describe(
|
|
1315
|
+
"Developer-only: enable authenticated loopback RPCs for memory counters and heap snapshots. Disabled by default. USER-LEVEL ONLY and requires a restart.",
|
|
1298
1316
|
),
|
|
1299
1317
|
fail_closed_blocking: z
|
|
1300
1318
|
.boolean()
|
|
@@ -1459,13 +1477,28 @@ export const MagicContextConfigSchema = z
|
|
|
1459
1477
|
git_commit_indexing: { enabled: false, since_days: 365, max_commits: 2000 },
|
|
1460
1478
|
})
|
|
1461
1479
|
.describe("Cross-session memory configuration"),
|
|
1462
|
-
sidekick: SidekickConfigSchema.describe(
|
|
1463
|
-
"Optional sidekick agent configuration for session-start memory retrieval",
|
|
1464
|
-
),
|
|
1465
1480
|
})
|
|
1466
1481
|
.transform((data): MagicContextConfig => {
|
|
1467
1482
|
return {
|
|
1468
1483
|
...data,
|
|
1469
|
-
protected_tags: data.protected_tags
|
|
1484
|
+
protected_tags: data.protected_tags as number | undefined,
|
|
1470
1485
|
};
|
|
1471
1486
|
});
|
|
1487
|
+
|
|
1488
|
+
/**
|
|
1489
|
+
* Derived default protected_tokens formula:
|
|
1490
|
+
* clamp(round(0.05 × usableSoft), min(16000, round(0.08 × usableSoft)), 64000)
|
|
1491
|
+
*
|
|
1492
|
+
* Sizing table:
|
|
1493
|
+
* 100k -> 8,000
|
|
1494
|
+
* 200k -> 16,000
|
|
1495
|
+
* 372k -> 18,600
|
|
1496
|
+
* 872k -> 43,600
|
|
1497
|
+
* 1M -> 50,000
|
|
1498
|
+
*/
|
|
1499
|
+
export function deriveDefaultProtectedTokens(usableSoft: number): number {
|
|
1500
|
+
const clampedUsable = Math.max(0, usableSoft);
|
|
1501
|
+
const lowerBound = Math.min(16_000, Math.round(0.08 * clampedUsable));
|
|
1502
|
+
const target = Math.round(0.05 * clampedUsable);
|
|
1503
|
+
return Math.min(64_000, Math.max(lowerBound, target));
|
|
1504
|
+
}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/// <reference types="bun-types" />
|
|
2
|
+
|
|
3
|
+
import { afterEach, describe, expect, mock, test } from "bun:test";
|
|
4
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
5
|
+
import { join, relative } from "node:path";
|
|
6
|
+
import ts from "typescript";
|
|
7
|
+
|
|
8
|
+
import { sweepOrphanedRetrospectiveChildren } from "../features/magic-context/dreamer/retrospective-orphan-sweep";
|
|
9
|
+
import { teardownChildSession } from "./child-session-teardown";
|
|
10
|
+
import { _resetKeepSubagentsForTesting, setKeepSubagents } from "./keep-subagents";
|
|
11
|
+
import { Database } from "./sqlite";
|
|
12
|
+
import { closeQuietly } from "./sqlite-helpers";
|
|
13
|
+
|
|
14
|
+
interface TeardownFixture {
|
|
15
|
+
client: {
|
|
16
|
+
session: {
|
|
17
|
+
delete: ReturnType<typeof mock>;
|
|
18
|
+
update: ReturnType<typeof mock>;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
calls: string[];
|
|
22
|
+
deleted: string[];
|
|
23
|
+
archived: string[];
|
|
24
|
+
messages: string[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function teardownFixture(): TeardownFixture {
|
|
28
|
+
const calls: string[] = [];
|
|
29
|
+
const deleted: string[] = [];
|
|
30
|
+
const archived: string[] = [];
|
|
31
|
+
const messages: string[] = [];
|
|
32
|
+
return {
|
|
33
|
+
calls,
|
|
34
|
+
deleted,
|
|
35
|
+
archived,
|
|
36
|
+
messages,
|
|
37
|
+
client: {
|
|
38
|
+
session: {
|
|
39
|
+
update: mock(async ({ path }: { path: { id: string } }) => {
|
|
40
|
+
calls.push("archive");
|
|
41
|
+
archived.push(path.id);
|
|
42
|
+
return {};
|
|
43
|
+
}),
|
|
44
|
+
delete: mock(async ({ path }: { path: { id: string } }) => {
|
|
45
|
+
calls.push("delete");
|
|
46
|
+
deleted.push(path.id);
|
|
47
|
+
return {};
|
|
48
|
+
}),
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
afterEach(() => {
|
|
55
|
+
_resetKeepSubagentsForTesting();
|
|
56
|
+
mock.restore();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
describe("teardownChildSession", () => {
|
|
60
|
+
test("deletes an ordinary child only after its prompt settles", async () => {
|
|
61
|
+
const fixture = teardownFixture();
|
|
62
|
+
await teardownChildSession({
|
|
63
|
+
client: fixture.client,
|
|
64
|
+
sessionId: "settled-ordinary",
|
|
65
|
+
sessionDirectory: "/repo",
|
|
66
|
+
promptSettled: true,
|
|
67
|
+
privacySensitive: false,
|
|
68
|
+
context: "ordinary",
|
|
69
|
+
log: (message) => fixture.messages.push(message),
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
expect(fixture.deleted).toEqual(["settled-ordinary"]);
|
|
73
|
+
expect(fixture.archived).toEqual([]);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("keeps a settled ordinary child but deletes a settled privacy child under keep_subagents", async () => {
|
|
77
|
+
setKeepSubagents(true);
|
|
78
|
+
const ordinary = teardownFixture();
|
|
79
|
+
await teardownChildSession({
|
|
80
|
+
client: ordinary.client,
|
|
81
|
+
sessionId: "kept-ordinary",
|
|
82
|
+
promptSettled: true,
|
|
83
|
+
privacySensitive: false,
|
|
84
|
+
context: "ordinary",
|
|
85
|
+
log: (message) => ordinary.messages.push(message),
|
|
86
|
+
});
|
|
87
|
+
expect(ordinary.deleted).toEqual([]);
|
|
88
|
+
|
|
89
|
+
const privacy = teardownFixture();
|
|
90
|
+
await teardownChildSession({
|
|
91
|
+
client: privacy.client,
|
|
92
|
+
sessionId: "deleted-private",
|
|
93
|
+
promptSettled: true,
|
|
94
|
+
privacySensitive: true,
|
|
95
|
+
context: "private",
|
|
96
|
+
log: (message) => privacy.messages.push(message),
|
|
97
|
+
});
|
|
98
|
+
expect(privacy.deleted).toEqual(["deleted-private"]);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test("archives an unsettled child before logging, leaves it intact, then the age gate reaps it", async () => {
|
|
102
|
+
const fixture = teardownFixture();
|
|
103
|
+
const db = new Database(":memory:");
|
|
104
|
+
db.exec(`
|
|
105
|
+
CREATE TABLE session (
|
|
106
|
+
id TEXT PRIMARY KEY,
|
|
107
|
+
title TEXT,
|
|
108
|
+
directory TEXT,
|
|
109
|
+
time_created INTEGER
|
|
110
|
+
);
|
|
111
|
+
INSERT INTO session VALUES (
|
|
112
|
+
'unsettled-private',
|
|
113
|
+
'magic-context-dream-map-memories',
|
|
114
|
+
'/repo',
|
|
115
|
+
1
|
|
116
|
+
);
|
|
117
|
+
`);
|
|
118
|
+
try {
|
|
119
|
+
await teardownChildSession({
|
|
120
|
+
client: fixture.client,
|
|
121
|
+
sessionId: "unsettled-private",
|
|
122
|
+
sessionDirectory: "/repo",
|
|
123
|
+
promptSettled: false,
|
|
124
|
+
privacySensitive: true,
|
|
125
|
+
context: "[dreamer] map-memories",
|
|
126
|
+
log: (message) => {
|
|
127
|
+
fixture.calls.push("log");
|
|
128
|
+
fixture.messages.push(message);
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
expect(fixture.calls).toEqual(["archive", "log"]);
|
|
133
|
+
expect(fixture.deleted).toEqual([]);
|
|
134
|
+
expect(fixture.messages).toEqual([
|
|
135
|
+
"[dreamer] map-memories: prompt unsettled — session unsettled-private left to the age-gated sweep",
|
|
136
|
+
]);
|
|
137
|
+
expect(
|
|
138
|
+
db.prepare("SELECT id FROM session WHERE id = ?").get("unsettled-private"),
|
|
139
|
+
).toEqual({
|
|
140
|
+
id: "unsettled-private",
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
const swept = await sweepOrphanedRetrospectiveChildren({
|
|
144
|
+
opencodeDb: db,
|
|
145
|
+
client: fixture.client as never,
|
|
146
|
+
sessionDirectory: "/repo",
|
|
147
|
+
staleMs: 1_000,
|
|
148
|
+
now: 1_002,
|
|
149
|
+
});
|
|
150
|
+
expect(swept).toBe(1);
|
|
151
|
+
expect(fixture.deleted).toEqual(["unsettled-private"]);
|
|
152
|
+
} finally {
|
|
153
|
+
closeQuietly(db);
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
function productionTypeScriptFiles(directory: string): string[] {
|
|
159
|
+
const files: string[] = [];
|
|
160
|
+
for (const entry of readdirSync(directory, { withFileTypes: true })) {
|
|
161
|
+
const path = join(directory, entry.name);
|
|
162
|
+
if (entry.isDirectory()) files.push(...productionTypeScriptFiles(path));
|
|
163
|
+
else if (entry.name.endsWith(".ts") && !entry.name.endsWith(".test.ts")) files.push(path);
|
|
164
|
+
}
|
|
165
|
+
return files;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function clientSessionDeleteOffsets(path: string, source: string): number[] {
|
|
169
|
+
const sourceFile = ts.createSourceFile(path, source, ts.ScriptTarget.Latest, true);
|
|
170
|
+
const offsets: number[] = [];
|
|
171
|
+
const visit = (node: ts.Node): void => {
|
|
172
|
+
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {
|
|
173
|
+
const deleteAccess = node.expression;
|
|
174
|
+
const sessionAccess = deleteAccess.expression;
|
|
175
|
+
if (
|
|
176
|
+
deleteAccess.name.text === "delete" &&
|
|
177
|
+
ts.isPropertyAccessExpression(sessionAccess) &&
|
|
178
|
+
sessionAccess.name.text === "session" &&
|
|
179
|
+
(ts.isIdentifier(sessionAccess.expression)
|
|
180
|
+
? sessionAccess.expression.text === "client"
|
|
181
|
+
: ts.isPropertyAccessExpression(sessionAccess.expression) &&
|
|
182
|
+
sessionAccess.expression.name.text === "client")
|
|
183
|
+
) {
|
|
184
|
+
offsets.push(node.getStart(sourceFile));
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
ts.forEachChild(node, visit);
|
|
188
|
+
};
|
|
189
|
+
visit(sourceFile);
|
|
190
|
+
return offsets;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
describe("child-session delete source fence", () => {
|
|
194
|
+
test("every client.session.delete call is the age-gated sweep or promptSettled-gated teardown", () => {
|
|
195
|
+
const sourceRoot = join(import.meta.dir, "..");
|
|
196
|
+
const sites: string[] = [];
|
|
197
|
+
for (const path of productionTypeScriptFiles(sourceRoot)) {
|
|
198
|
+
const source = readFileSync(path, "utf8");
|
|
199
|
+
for (const offset of clientSessionDeleteOffsets(path, source)) {
|
|
200
|
+
const line = source.slice(0, offset).split("\n").length;
|
|
201
|
+
sites.push(`${relative(sourceRoot, path)}:${line}`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Directory walk order differs between macOS and Linux; the fence is a set.
|
|
206
|
+
expect(sites.map((site) => site.replace(/:\d+$/, "")).sort()).toEqual([
|
|
207
|
+
"features/magic-context/dreamer/retrospective-orphan-sweep.ts",
|
|
208
|
+
"shared/child-session-teardown.ts",
|
|
209
|
+
]);
|
|
210
|
+
const teardownSource = readFileSync(
|
|
211
|
+
join(sourceRoot, "shared/child-session-teardown.ts"),
|
|
212
|
+
"utf8",
|
|
213
|
+
);
|
|
214
|
+
expect(teardownSource).toMatch(
|
|
215
|
+
/if\s*\(\s*promptSettled[\s\S]{0,200}client\.session\.delete\s*\(/,
|
|
216
|
+
);
|
|
217
|
+
});
|
|
218
|
+
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { shouldKeepSubagents } from "./keep-subagents";
|
|
2
|
+
|
|
3
|
+
interface ChildSessionRequest {
|
|
4
|
+
path: { id: string };
|
|
5
|
+
query?: { directory: string };
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface ArchiveChildSessionRequest extends ChildSessionRequest {
|
|
9
|
+
body: { time: { archived: number } };
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface ChildSessionTeardownClient {
|
|
13
|
+
session: {
|
|
14
|
+
delete(request: ChildSessionRequest): Promise<unknown>;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface TeardownChildSessionArgs {
|
|
19
|
+
client: ChildSessionTeardownClient;
|
|
20
|
+
sessionId: string | null;
|
|
21
|
+
sessionDirectory?: string;
|
|
22
|
+
promptSettled: boolean;
|
|
23
|
+
privacySensitive: boolean;
|
|
24
|
+
context: string;
|
|
25
|
+
log: (message: string) => void;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Retire a child only after its prompt helper resolves. An unresolved client call
|
|
30
|
+
* can leave OpenCode's server loop writing, so that row is archived for immediate
|
|
31
|
+
* UI hiding and retained until the age-gated sweep can delete it safely.
|
|
32
|
+
*
|
|
33
|
+
* OpenCode's generated v2 SDK models archival as `session.update` with
|
|
34
|
+
* `time.archived`; the plugin's legacy path/body client reaches the same PATCH
|
|
35
|
+
* endpoint, although its generated TypeScript body type does not yet expose time.
|
|
36
|
+
*/
|
|
37
|
+
export async function teardownChildSession(args: TeardownChildSessionArgs): Promise<void> {
|
|
38
|
+
const { client, sessionId, sessionDirectory, promptSettled, privacySensitive, context, log } =
|
|
39
|
+
args;
|
|
40
|
+
if (!sessionId) return;
|
|
41
|
+
|
|
42
|
+
const request: ChildSessionRequest = {
|
|
43
|
+
path: { id: sessionId },
|
|
44
|
+
...(sessionDirectory ? { query: { directory: sessionDirectory } } : {}),
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
if (promptSettled && (privacySensitive || !shouldKeepSubagents())) {
|
|
48
|
+
await client.session.delete(request).catch((error: unknown) => {
|
|
49
|
+
log(`${context}: session cleanup failed: ${String(error)}`);
|
|
50
|
+
});
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (!promptSettled) {
|
|
55
|
+
const archiveSession = client.session as unknown as {
|
|
56
|
+
update?: (request: ArchiveChildSessionRequest) => Promise<unknown>;
|
|
57
|
+
};
|
|
58
|
+
await archiveSession
|
|
59
|
+
.update?.({
|
|
60
|
+
...request,
|
|
61
|
+
body: { time: { archived: Date.now() } },
|
|
62
|
+
})
|
|
63
|
+
.catch(() => {});
|
|
64
|
+
log(`${context}: prompt unsettled — session ${sessionId} left to the age-gated sweep`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Debug / data-collection switch
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Debug / data-collection switch for settled ordinary child sessions
|
|
3
|
+
* (historian and memory migration). Privacy-sensitive Dreamer and
|
|
4
|
+
* smart-note children are still deleted after their prompts settle.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* inspectable in OpenCode's session store / the dashboard. Intended for
|
|
10
|
-
* short-term data collection (e.g. profiling what the dreamer actually does)
|
|
11
|
-
* before the dreamer v2 overhaul, NOT for steady-state use — kept sessions
|
|
12
|
-
* accumulate in the host's session DB until manually cleared.
|
|
6
|
+
* Unsettled children are never deleted inline because OpenCode's server loop may
|
|
7
|
+
* still be writing after a client timeout or abort. They remain for the
|
|
8
|
+
* age-gated sweep; privacy-sensitive rows are swept even when this switch is on.
|
|
13
9
|
*
|
|
14
|
-
* Process-global, set once at boot from config (mirrors `harness.ts`). A
|
|
15
|
-
*
|
|
16
|
-
* per-call args — it's a coarse, boot-time debug toggle.
|
|
10
|
+
* Process-global, set once at boot from config (mirrors `harness.ts`). A config
|
|
11
|
+
* change requires a restart to take effect.
|
|
17
12
|
*/
|
|
18
13
|
let keepSubagents = false;
|
|
19
14
|
|
|
@@ -22,7 +17,7 @@ export function setKeepSubagents(value: boolean): void {
|
|
|
22
17
|
keepSubagents = value === true;
|
|
23
18
|
}
|
|
24
19
|
|
|
25
|
-
/** True when
|
|
20
|
+
/** True when settled ordinary child sessions should be retained. */
|
|
26
21
|
export function shouldKeepSubagents(): boolean {
|
|
27
22
|
return keepSubagents;
|
|
28
23
|
}
|
|
@@ -71,7 +71,7 @@ export interface PromptRetryOptions {
|
|
|
71
71
|
fallbackModels?: readonly ModelInput[];
|
|
72
72
|
/**
|
|
73
73
|
* Identifier for structured logging (e.g. "dreamer:consolidate",
|
|
74
|
-
* "historian", "compressor", "
|
|
74
|
+
* "historian", "compressor", "dreamer"). Helps correlate fallback
|
|
75
75
|
* attempts to a specific call site in `magic-context.log`. Defaults to
|
|
76
76
|
* "subagent" if not provided.
|
|
77
77
|
*/
|