@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,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
import type { StatusDetail } from "./rpc-types";
|
|
3
|
-
import { formatStatusDetailMarkdown } from "./status-detail-text";
|
|
3
|
+
import { formatStatusDetailMarkdown, formatStatusDiagnosticsMarkdown } from "./status-detail-text";
|
|
4
4
|
|
|
5
5
|
const STATUS_FIXTURE: StatusDetail = {
|
|
6
6
|
sessionId: "ses_status",
|
|
@@ -17,9 +17,11 @@ const STATUS_FIXTURE: StatusDetail = {
|
|
|
17
17
|
compartmentInProgress: true,
|
|
18
18
|
sessionNoteCount: 1,
|
|
19
19
|
readySmartNoteCount: 2,
|
|
20
|
-
cacheTtl: "
|
|
21
|
-
cacheTtlSource: "
|
|
20
|
+
cacheTtl: "1h",
|
|
21
|
+
cacheTtlSource: "config",
|
|
22
|
+
cacheTtlModelKey: "anthropic/claude-opus-5",
|
|
22
23
|
lastTransformError: null,
|
|
24
|
+
historianFailureCount: 0,
|
|
23
25
|
lastDreamerRunAt: null,
|
|
24
26
|
projectIdentity: "/repo",
|
|
25
27
|
compartmentTokens: 22_000,
|
|
@@ -61,36 +63,106 @@ const STATUS_FIXTURE: StatusDetail = {
|
|
|
61
63
|
lastErrorMessage: null,
|
|
62
64
|
lastErrorTime: null,
|
|
63
65
|
},
|
|
66
|
+
tailHygiene: {
|
|
67
|
+
u: 14_400,
|
|
68
|
+
t: 48_000,
|
|
69
|
+
severity: 0.3,
|
|
70
|
+
evaluable: true,
|
|
71
|
+
generationInvalidated: false,
|
|
72
|
+
baselineGeneration: 3,
|
|
73
|
+
computedAt: 1_730_000_000_000,
|
|
74
|
+
reclaimableToolOutputCount: 3,
|
|
75
|
+
},
|
|
76
|
+
embedding: {
|
|
77
|
+
state: "running",
|
|
78
|
+
indexed: 9,
|
|
79
|
+
total: 12,
|
|
80
|
+
},
|
|
64
81
|
storage_versions: {
|
|
65
82
|
context_db_schema_version: 79,
|
|
66
83
|
plugin_supported_version: 79,
|
|
67
84
|
},
|
|
68
85
|
};
|
|
69
86
|
|
|
70
|
-
describe("
|
|
71
|
-
test("renders the
|
|
87
|
+
describe("status detail text", () => {
|
|
88
|
+
test("renders the OpenCode summary golden", () => {
|
|
72
89
|
expect(formatStatusDetailMarkdown(STATUS_FIXTURE)).toBe(`## Magic Context Status
|
|
73
90
|
|
|
74
|
-
- **
|
|
75
|
-
- **
|
|
76
|
-
- **
|
|
77
|
-
- **
|
|
78
|
-
- **
|
|
79
|
-
- **Memory:** 8
|
|
80
|
-
- **
|
|
81
|
-
- **Execute threshold:** 65.0%`);
|
|
91
|
+
- **Context:** 75.0% of usable context (96,000 / 128,000 tokens)
|
|
92
|
+
- **Cache lifetime:** 1h (config for anthropic/claude-opus-5)
|
|
93
|
+
- **Automatic compression:** at 65.0% of usable context
|
|
94
|
+
- **History compression:** Compressing history · 12 history blocks
|
|
95
|
+
- **Reclaimable:** 3 spent tool outputs (~14k tokens)
|
|
96
|
+
- **Memory:** 8 memories · 3 notes
|
|
97
|
+
- **Search indexing:** Running · 9 / 12 history blocks indexed`);
|
|
82
98
|
});
|
|
83
99
|
|
|
84
|
-
test("
|
|
85
|
-
const
|
|
100
|
+
test("renders disabled automatic compression and an empty reclaimable set without a gauge", () => {
|
|
101
|
+
const rendered = formatStatusDetailMarkdown({
|
|
102
|
+
...STATUS_FIXTURE,
|
|
103
|
+
compaction_enabled: false,
|
|
104
|
+
tailHygiene: {
|
|
105
|
+
...STATUS_FIXTURE.tailHygiene!,
|
|
106
|
+
u: 0,
|
|
107
|
+
reclaimableToolOutputCount: 0,
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
expect(rendered).toContain("- **Automatic compression:** Off");
|
|
111
|
+
expect(rendered).toContain("- **Reclaimable:** none");
|
|
112
|
+
expect(rendered).not.toContain("Reclaimable: 0");
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test("renders summary and diagnostics from one snapshot with matching status values", () => {
|
|
116
|
+
const summary = formatStatusDetailMarkdown(STATUS_FIXTURE);
|
|
117
|
+
const diagnostics = formatStatusDiagnosticsMarkdown(STATUS_FIXTURE);
|
|
118
|
+
for (const value of ["75.0%", "65.0%", "1h (config for anthropic/claude-opus-5)"]) {
|
|
119
|
+
expect(summary).toContain(value);
|
|
120
|
+
expect(diagnostics).toContain(value);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test("keeps the previous OpenCode detail behind diagnostics", () => {
|
|
125
|
+
const diagnostics = formatStatusDiagnosticsMarkdown(STATUS_FIXTURE);
|
|
126
|
+
expect(diagnostics).toContain("- **Active profile:** work");
|
|
127
|
+
expect(diagnostics).toContain("- **Tags:** 4 active, 1 dropped; 2 pending drops");
|
|
128
|
+
expect(diagnostics).toContain("- **Execute threshold:** 65.0%");
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test("keeps internal vocabulary and identifiers out of the summary", () => {
|
|
132
|
+
const summary = formatStatusDetailMarkdown({
|
|
86
133
|
...STATUS_FIXTURE,
|
|
134
|
+
sessionId: "session-secret",
|
|
135
|
+
projectIdentity: "/Users/example/secret-project",
|
|
87
136
|
hostBackendsModuleSide: true,
|
|
137
|
+
lastTransformError: "facade MODULE drain failed in mc-store /tmp/private",
|
|
138
|
+
historianFailureCount: 2,
|
|
88
139
|
});
|
|
89
|
-
const
|
|
140
|
+
for (const forbidden of [
|
|
141
|
+
"session-secret",
|
|
142
|
+
"/Users/",
|
|
143
|
+
"tag counter",
|
|
144
|
+
"protection",
|
|
145
|
+
"formula",
|
|
146
|
+
"MODULE",
|
|
147
|
+
"mc-store",
|
|
148
|
+
"harness",
|
|
149
|
+
"compartment",
|
|
150
|
+
"facade",
|
|
151
|
+
"changefeed",
|
|
152
|
+
"drain",
|
|
153
|
+
]) {
|
|
154
|
+
expect(summary.toLowerCase()).not.toContain(forbidden.toLowerCase());
|
|
155
|
+
}
|
|
156
|
+
expect(summary).toContain("(MC-S02)");
|
|
157
|
+
expect(summary).toContain("(MC-H01)");
|
|
158
|
+
});
|
|
90
159
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
160
|
+
test("does not expose module routing in the summary", () => {
|
|
161
|
+
const rustStatus = formatStatusDetailMarkdown({
|
|
162
|
+
...STATUS_FIXTURE,
|
|
163
|
+
hostBackendsModuleSide: true,
|
|
164
|
+
});
|
|
165
|
+
expect(rustStatus).not.toContain("MODULE");
|
|
166
|
+
expect(rustStatus).not.toContain("mc-store");
|
|
95
167
|
});
|
|
96
168
|
});
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import { formatCacheTtlDisplay } from "./cache-ttl-display";
|
|
2
2
|
import { formatConfigParseStatusLine } from "./config-diagnostics";
|
|
3
|
+
import {
|
|
4
|
+
formatOpenCodeDbMissingStatusLine,
|
|
5
|
+
formatOpenCodeDbReadFailureStatusLine,
|
|
6
|
+
getOpenCodeDbReadFailure,
|
|
7
|
+
openCodeDbPathExists,
|
|
8
|
+
resolveOpenCodeDbPath,
|
|
9
|
+
} from "./opencode-db-path";
|
|
3
10
|
import type { StatusDetail } from "./rpc-types";
|
|
4
11
|
import { RUST_MODE_HOST_PATHS_LINE } from "./rust-mode-status";
|
|
12
|
+
import { renderUserStatusSummary, statusSummaryFromDetail } from "./status-summary";
|
|
13
|
+
import { renderUserFacingFailure } from "./user-facing-codes";
|
|
5
14
|
|
|
6
15
|
function formatCount(value: number): string {
|
|
7
16
|
return Math.round(value).toLocaleString();
|
|
@@ -14,8 +23,13 @@ function formatCacheLane(detail: StatusDetail): string {
|
|
|
14
23
|
return `live (${Math.round(detail.cacheRemainingMs / 1000)}s remaining); TTL ${detail.cacheTtl}`;
|
|
15
24
|
}
|
|
16
25
|
|
|
17
|
-
/** Render the
|
|
26
|
+
/** Render the default user summary for chat-only OpenCode clients. */
|
|
18
27
|
export function formatStatusDetailMarkdown(detail: StatusDetail): string {
|
|
28
|
+
return renderUserStatusSummary(statusSummaryFromDetail(detail), "markdown");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Render the opt-in operator detail that the status dialog exposes behind Diagnostics. */
|
|
32
|
+
export function formatStatusDiagnosticsMarkdown(detail: StatusDetail): string {
|
|
19
33
|
const usableLimit =
|
|
20
34
|
detail.contextLimit > 0
|
|
21
35
|
? `${formatCount(detail.contextLimit)} usable tokens`
|
|
@@ -29,12 +43,20 @@ export function formatStatusDetailMarkdown(detail: StatusDetail): string {
|
|
|
29
43
|
? undefined
|
|
30
44
|
: `coverage ${detail.coverageOrdinal === null ? "none" : detail.coverageOrdinal}`,
|
|
31
45
|
].filter((value): value is string => value !== undefined);
|
|
46
|
+
const openCodeDbResolution = resolveOpenCodeDbPath();
|
|
47
|
+
const openCodeDbReadFailure = getOpenCodeDbReadFailure();
|
|
48
|
+
const openCodeDbStatusLine = !openCodeDbPathExists(openCodeDbResolution)
|
|
49
|
+
? formatOpenCodeDbMissingStatusLine(openCodeDbResolution)
|
|
50
|
+
: openCodeDbReadFailure?.path === openCodeDbResolution.path
|
|
51
|
+
? formatOpenCodeDbReadFailureStatusLine(openCodeDbReadFailure)
|
|
52
|
+
: null;
|
|
32
53
|
const mode =
|
|
33
54
|
detail.compaction_enabled === false
|
|
34
55
|
? "native compaction (Magic Context history compaction disabled)"
|
|
35
56
|
: "Magic Context compaction";
|
|
36
57
|
|
|
37
58
|
const lines = [
|
|
59
|
+
...(openCodeDbStatusLine ? [openCodeDbStatusLine, ""] : []),
|
|
38
60
|
...(detail.configParseFailures ?? []).map(formatConfigParseStatusLine),
|
|
39
61
|
...((detail.configParseFailures?.length ?? 0) > 0 ? [""] : []),
|
|
40
62
|
"## Magic Context Status",
|
|
@@ -56,7 +78,7 @@ export function formatStatusDetailMarkdown(detail: StatusDetail): string {
|
|
|
56
78
|
);
|
|
57
79
|
}
|
|
58
80
|
if (detail.lastTransformError) {
|
|
59
|
-
lines.push(`- **
|
|
81
|
+
lines.push(`- **Warning:** ${renderUserFacingFailure("transform_update_failed")}`);
|
|
60
82
|
}
|
|
61
83
|
|
|
62
84
|
return lines.join("\n");
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { formatCacheTtlDisplay } from "./cache-ttl-display";
|
|
2
|
+
import type { StatusDetail } from "./rpc-types";
|
|
3
|
+
import { renderUserFacingFailure, type UserFacingFailureKey } from "./user-facing-codes";
|
|
4
|
+
|
|
5
|
+
export type StatusCompressionState = "off" | "compressing" | "ready" | "waiting";
|
|
6
|
+
export type StatusEmbeddingState = "off" | "running" | "paused" | "stopped" | "ready" | "waiting";
|
|
7
|
+
|
|
8
|
+
export interface UserStatusSummary {
|
|
9
|
+
inputTokens: number;
|
|
10
|
+
usableContextTokens: number;
|
|
11
|
+
usagePercentage: number;
|
|
12
|
+
cacheLifetime: string;
|
|
13
|
+
automaticCompressionThreshold: number | null;
|
|
14
|
+
compression: {
|
|
15
|
+
state: StatusCompressionState;
|
|
16
|
+
historyBlockCount: number;
|
|
17
|
+
};
|
|
18
|
+
reclaimable: {
|
|
19
|
+
toolOutputCount: number;
|
|
20
|
+
tokens: number;
|
|
21
|
+
};
|
|
22
|
+
memoryCount: number;
|
|
23
|
+
noteCount: number;
|
|
24
|
+
embedding: {
|
|
25
|
+
state: StatusEmbeddingState;
|
|
26
|
+
indexed: number;
|
|
27
|
+
total: number;
|
|
28
|
+
};
|
|
29
|
+
warnings: UserFacingFailureKey[];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function statusSummaryFromDetail(detail: StatusDetail): UserStatusSummary {
|
|
33
|
+
const compressionState: StatusCompressionState =
|
|
34
|
+
detail.compaction_enabled === false
|
|
35
|
+
? "off"
|
|
36
|
+
: detail.historianRunning ||
|
|
37
|
+
detail.compartmentInProgress ||
|
|
38
|
+
(detail.recompProgress?.phase === "recomp" &&
|
|
39
|
+
detail.recompProgress.kind !== "embed")
|
|
40
|
+
? "compressing"
|
|
41
|
+
: detail.compartmentCount > 0
|
|
42
|
+
? "ready"
|
|
43
|
+
: "waiting";
|
|
44
|
+
const warnings: UserFacingFailureKey[] = [];
|
|
45
|
+
if (detail.lastTransformError) warnings.push("transform_update_failed");
|
|
46
|
+
if ((detail.historianFailureCount ?? 0) > 0) warnings.push("historian_unavailable");
|
|
47
|
+
if ((detail.configParseFailures?.length ?? 0) > 0) warnings.push("configuration_warning");
|
|
48
|
+
if (detail.embedding?.state === "stopped") warnings.push("embedding_unavailable");
|
|
49
|
+
if ((detail.loggerDiagnostics?.swallowedWriteCount ?? 0) > 0) {
|
|
50
|
+
warnings.push("status_log_unavailable");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
inputTokens: detail.inputTokens,
|
|
55
|
+
usableContextTokens: detail.contextLimit,
|
|
56
|
+
usagePercentage: detail.usagePercentage,
|
|
57
|
+
cacheLifetime: formatCacheTtlDisplay({
|
|
58
|
+
value: detail.cacheTtl,
|
|
59
|
+
source: detail.cacheTtlSource ?? "session",
|
|
60
|
+
modelKey: detail.cacheTtlModelKey,
|
|
61
|
+
}).replace(/^Cache TTL:\s*/, ""),
|
|
62
|
+
automaticCompressionThreshold:
|
|
63
|
+
detail.compaction_enabled === false ? null : detail.executeThreshold,
|
|
64
|
+
compression: {
|
|
65
|
+
state: compressionState,
|
|
66
|
+
historyBlockCount: detail.compartmentCount,
|
|
67
|
+
},
|
|
68
|
+
reclaimable: {
|
|
69
|
+
toolOutputCount: detail.tailHygiene?.reclaimableToolOutputCount ?? 0,
|
|
70
|
+
tokens: detail.tailHygiene?.u ?? 0,
|
|
71
|
+
},
|
|
72
|
+
memoryCount: detail.memoryCount,
|
|
73
|
+
noteCount: (detail.sessionNoteCount ?? 0) + (detail.readySmartNoteCount ?? 0),
|
|
74
|
+
embedding: detail.embedding ?? {
|
|
75
|
+
state: "waiting",
|
|
76
|
+
indexed: 0,
|
|
77
|
+
total: 0,
|
|
78
|
+
},
|
|
79
|
+
warnings: [...new Set(warnings)],
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function formatCount(value: number): string {
|
|
84
|
+
return Math.round(value).toLocaleString();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function compressionText(summary: UserStatusSummary): string {
|
|
88
|
+
const historyBlocks = `${summary.compression.historyBlockCount} history block${
|
|
89
|
+
summary.compression.historyBlockCount === 1 ? "" : "s"
|
|
90
|
+
}`;
|
|
91
|
+
switch (summary.compression.state) {
|
|
92
|
+
case "off":
|
|
93
|
+
return "Off";
|
|
94
|
+
case "compressing":
|
|
95
|
+
return `Compressing history · ${historyBlocks}`;
|
|
96
|
+
case "ready":
|
|
97
|
+
return `Ready · ${historyBlocks}`;
|
|
98
|
+
case "waiting":
|
|
99
|
+
return "Waiting for enough conversation history";
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function reclaimableText(summary: UserStatusSummary): string {
|
|
104
|
+
const count = Math.max(0, Math.floor(summary.reclaimable.toolOutputCount));
|
|
105
|
+
if (count === 0) return "none";
|
|
106
|
+
const outputs = `${count} spent tool output${count === 1 ? "" : "s"}`;
|
|
107
|
+
return `${outputs} (~${Math.round(Math.max(0, summary.reclaimable.tokens) / 1000)}k tokens)`;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function embeddingText(summary: UserStatusSummary): string {
|
|
111
|
+
if (summary.embedding.state === "off") return "Off";
|
|
112
|
+
const coverage = `${formatCount(summary.embedding.indexed)} / ${formatCount(summary.embedding.total)} history blocks indexed`;
|
|
113
|
+
switch (summary.embedding.state) {
|
|
114
|
+
case "running":
|
|
115
|
+
return `Running · ${coverage}`;
|
|
116
|
+
case "paused":
|
|
117
|
+
return `Paused · ${coverage}`;
|
|
118
|
+
case "stopped":
|
|
119
|
+
return `Paused after an issue · ${coverage}`;
|
|
120
|
+
case "ready":
|
|
121
|
+
return `Ready · ${coverage}`;
|
|
122
|
+
case "waiting":
|
|
123
|
+
return `Waiting · ${coverage}`;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function renderUserStatusSummary(
|
|
128
|
+
summary: UserStatusSummary,
|
|
129
|
+
style: "markdown" | "plain",
|
|
130
|
+
): string {
|
|
131
|
+
const context = `${summary.usagePercentage.toFixed(1)}% of usable context (${formatCount(summary.inputTokens)} / ${
|
|
132
|
+
summary.usableContextTokens > 0 ? formatCount(summary.usableContextTokens) : "?"
|
|
133
|
+
} tokens)`;
|
|
134
|
+
const values = [
|
|
135
|
+
["Context", context],
|
|
136
|
+
["Cache lifetime", summary.cacheLifetime],
|
|
137
|
+
[
|
|
138
|
+
"Automatic compression",
|
|
139
|
+
summary.automaticCompressionThreshold === null
|
|
140
|
+
? "Off"
|
|
141
|
+
: `at ${summary.automaticCompressionThreshold.toFixed(1)}% of usable context`,
|
|
142
|
+
],
|
|
143
|
+
["History compression", compressionText(summary)],
|
|
144
|
+
["Reclaimable", reclaimableText(summary)],
|
|
145
|
+
[
|
|
146
|
+
"Memory",
|
|
147
|
+
`${formatCount(summary.memoryCount)} memories · ${formatCount(summary.noteCount)} notes`,
|
|
148
|
+
],
|
|
149
|
+
["Search indexing", embeddingText(summary)],
|
|
150
|
+
] as const;
|
|
151
|
+
const lines =
|
|
152
|
+
style === "markdown"
|
|
153
|
+
? [
|
|
154
|
+
"## Magic Context Status",
|
|
155
|
+
"",
|
|
156
|
+
...values.map(([label, value]) => `- **${label}:** ${value}`),
|
|
157
|
+
]
|
|
158
|
+
: ["Magic Context Status", ...values.map(([label, value]) => `${label}: ${value}`)];
|
|
159
|
+
for (const warning of summary.warnings) {
|
|
160
|
+
lines.push(
|
|
161
|
+
style === "markdown"
|
|
162
|
+
? `- **Warning:** ${renderUserFacingFailure(warning)}`
|
|
163
|
+
: `Warning: ${renderUserFacingFailure(warning)}`,
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
return lines.join("\n");
|
|
167
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cross-harness subagent runner abstraction.
|
|
3
3
|
*
|
|
4
|
-
* Magic Context spawns
|
|
4
|
+
* Magic Context spawns historian and Dreamer subagents
|
|
5
5
|
* each as a child "session" with its own model/prompt/tools. OpenCode and Pi
|
|
6
6
|
* have very different APIs for this:
|
|
7
7
|
*
|
|
@@ -15,15 +15,15 @@
|
|
|
15
15
|
* disk, optionally addressed via `--session <path>`.
|
|
16
16
|
*
|
|
17
17
|
* The runner interface below normalizes both into the same shape so the
|
|
18
|
-
* actual subagent business logic (historian XML parsing
|
|
19
|
-
*
|
|
18
|
+
* actual subagent business logic (historian XML parsing and Dreamer task loops)
|
|
19
|
+
* can stay harness-agnostic. Each harness ships its
|
|
20
20
|
* own runner implementation; agents take a `SubagentRunner` as a dep instead
|
|
21
21
|
* of reaching for `client.session.*` directly.
|
|
22
22
|
*
|
|
23
23
|
* Step 5a (this commit) defines the contract and ships `PiSubagentRunner`.
|
|
24
24
|
* Step 5b will refactor the OpenCode-side spawn paths in
|
|
25
|
-
* `compartment-runner-historian.ts
|
|
26
|
-
* `
|
|
25
|
+
* `compartment-runner-historian.ts` and `dreamer/runner.ts` onto an
|
|
26
|
+
* `OpenCodeSubagentRunner` so both harnesses
|
|
27
27
|
* share the agent business logic instead of duplicating it. Until 5b lands,
|
|
28
28
|
* OpenCode keeps its existing direct `client.session.*` calls untouched —
|
|
29
29
|
* the runner contract is purely additive on the OpenCode side.
|
|
@@ -36,11 +36,11 @@ import type { ModelInput } from "./model-resolution";
|
|
|
36
36
|
*
|
|
37
37
|
* Mirrors the union of OpenCode's `session.create` + `session.prompt` body
|
|
38
38
|
* fields and Pi's `--print` CLI flags, picking the shared subset that all
|
|
39
|
-
*
|
|
39
|
+
* the historian and Dreamer subagents actually use today.
|
|
40
40
|
*
|
|
41
41
|
* Fields:
|
|
42
42
|
* - `agent`: harness-specific agent name. OpenCode looks this up in its
|
|
43
|
-
* agent registry (`HISTORIAN_AGENT`, `DREAMER_AGENT
|
|
43
|
+
* agent registry (`HISTORIAN_AGENT`, `DREAMER_AGENT`).
|
|
44
44
|
* Pi has no concept of "agent name" beyond config, so this is ignored
|
|
45
45
|
* on the Pi side and used only by `OpenCodeSubagentRunner`.
|
|
46
46
|
* - `systemPrompt`: full system prompt for this child run. Replaces (not
|
|
@@ -88,7 +88,7 @@ export interface SubagentRunOptions {
|
|
|
88
88
|
/**
|
|
89
89
|
* Optional progress callback. The runner invokes it for milestone events
|
|
90
90
|
* during the run: spawn, first event received, terminal stop reason
|
|
91
|
-
* detected, child exit. Used by historian/dreamer
|
|
91
|
+
* detected, child exit. Used by historian/dreamer to write
|
|
92
92
|
* lifecycle entries to the magic-context.log without polluting the
|
|
93
93
|
* normal stdout stream.
|
|
94
94
|
*
|
|
@@ -104,7 +104,6 @@ export interface SubagentRunOptions {
|
|
|
104
104
|
| "historian_editor"
|
|
105
105
|
| "compressor"
|
|
106
106
|
| "dreamer"
|
|
107
|
-
| "sidekick"
|
|
108
107
|
| "user_memory_review"
|
|
109
108
|
| "recomp"
|
|
110
109
|
| undefined;
|
|
@@ -182,6 +181,11 @@ export type SubagentProgressEvent =
|
|
|
182
181
|
* here so the OpenCode runner can surface the child session ID for log
|
|
183
182
|
* correlation when Step 5b lands.
|
|
184
183
|
*/
|
|
184
|
+
export interface CompletedSubagentToolCall {
|
|
185
|
+
name: string;
|
|
186
|
+
arguments: Record<string, unknown>;
|
|
187
|
+
}
|
|
188
|
+
|
|
185
189
|
export type SubagentRunResult =
|
|
186
190
|
| {
|
|
187
191
|
ok: true;
|
|
@@ -196,6 +200,9 @@ export type SubagentRunResult =
|
|
|
196
200
|
* the real session messages.
|
|
197
201
|
*/
|
|
198
202
|
toolCallCount?: number;
|
|
203
|
+
/** Completed, non-error tool results preserved by runners that can
|
|
204
|
+
* reconstruct invocation/result pairs from their transcript. */
|
|
205
|
+
completedToolCalls?: CompletedSubagentToolCall[];
|
|
199
206
|
meta?: Record<string, unknown>;
|
|
200
207
|
}
|
|
201
208
|
| {
|
|
@@ -222,7 +229,7 @@ export type SubagentRunResult =
|
|
|
222
229
|
*
|
|
223
230
|
* Each harness ships a single instance — the OpenCode plugin wires
|
|
224
231
|
* `OpenCodeSubagentRunner` and the Pi plugin wires `PiSubagentRunner` in
|
|
225
|
-
* its `extension` boot path. Agent code (historian
|
|
232
|
+
* its `extension` boot path. Agent code (historian and dreamer)
|
|
226
233
|
* receives the runner as a dep and never reaches for harness-specific
|
|
227
234
|
* client APIs directly.
|
|
228
235
|
*/
|
|
@@ -55,6 +55,7 @@ import {
|
|
|
55
55
|
updateTagTokenCount,
|
|
56
56
|
} from "../features/magic-context/storage-tags";
|
|
57
57
|
import { makeToolCompositeKey, type Tagger } from "../features/magic-context/tagger";
|
|
58
|
+
import { droppedInputMarker } from "../hooks/magic-context/dropped-input-guard";
|
|
58
59
|
import { applyEditMarkerToInput } from "../hooks/magic-context/edit-marker";
|
|
59
60
|
import { estimateImageTokensFromDataUrl } from "../hooks/magic-context/image-token-estimate";
|
|
60
61
|
import { estimateTokens } from "../hooks/magic-context/read-session-formatting";
|
|
@@ -247,7 +248,8 @@ export function tagTranscript(
|
|
|
247
248
|
let toolResultOrdinal = 0;
|
|
248
249
|
const parts = message.parts;
|
|
249
250
|
const messageHasNativeReasoning =
|
|
250
|
-
message.
|
|
251
|
+
message.requiresToolArcSkeleton ??
|
|
252
|
+
(message.info.role === "assistant" && parts.some((part) => part.kind === "thinking"));
|
|
251
253
|
const contentDerivedTextIds =
|
|
252
254
|
messageId !== undefined && options.textIdentityDriftMessageIds?.has(messageId) === true
|
|
253
255
|
? buildContentDerivedTextIds(messageId, parts)
|
|
@@ -1056,8 +1058,20 @@ function buildAggregateTarget(
|
|
|
1056
1058
|
}
|
|
1057
1059
|
return occurrences[0]?.part.getText() ?? null;
|
|
1058
1060
|
},
|
|
1059
|
-
drop(): "removed" | "absent" {
|
|
1060
|
-
|
|
1061
|
+
drop(): "removed" | "absent" | "incomplete" {
|
|
1062
|
+
const complete =
|
|
1063
|
+
occurrences.some((occ) => occ.kind === "tool_use") &&
|
|
1064
|
+
occurrences.some((occ) => occ.kind === "tool_result");
|
|
1065
|
+
if (!complete) return "incomplete";
|
|
1066
|
+
if (
|
|
1067
|
+
!requiresToolArcSkeleton &&
|
|
1068
|
+
occurrences.every((occ) => occ.part.remove && occ.part.canRemove?.() !== false)
|
|
1069
|
+
) {
|
|
1070
|
+
let removed = false;
|
|
1071
|
+
for (const occ of occurrences) removed = occ.part.remove?.() || removed;
|
|
1072
|
+
return removed ? "removed" : "absent";
|
|
1073
|
+
}
|
|
1074
|
+
// Adapters without structural removal retain paired sentinels.
|
|
1061
1075
|
const sentinel = `[dropped \u00a7${tagId}\u00a7]`;
|
|
1062
1076
|
let any = false;
|
|
1063
1077
|
for (const occ of occurrences) {
|
|
@@ -1066,14 +1080,14 @@ function buildAggregateTarget(
|
|
|
1066
1080
|
return any ? "removed" : "absent";
|
|
1067
1081
|
},
|
|
1068
1082
|
truncate(): "truncated" | "absent" {
|
|
1069
|
-
//
|
|
1070
|
-
//
|
|
1071
|
-
// drop and to OpenCode). Frozen by the dropMode column → replays
|
|
1072
|
-
// the same string every pass. The tool_use call survives intact.
|
|
1083
|
+
// Keep the paired call shell, but replace its arguments with one
|
|
1084
|
+
// non-executable marker; result halves carry the matching sentinel.
|
|
1073
1085
|
const sentinel = `[dropped \u00a7${tagId}\u00a7]`;
|
|
1074
1086
|
let any = false;
|
|
1075
1087
|
for (const occ of occurrences) {
|
|
1076
|
-
if (
|
|
1088
|
+
if (occ.kind === "tool_use" && occ.part.setToolInput) {
|
|
1089
|
+
if (occ.part.setToolInput(droppedInputMarker(tagId))) any = true;
|
|
1090
|
+
} else if (setToolContentOrText(occ.part, sentinel)) {
|
|
1077
1091
|
any = true;
|
|
1078
1092
|
}
|
|
1079
1093
|
}
|
|
@@ -1101,12 +1115,12 @@ function buildAggregateTarget(
|
|
|
1101
1115
|
}
|
|
1102
1116
|
return any ? "truncated" : "absent";
|
|
1103
1117
|
},
|
|
1104
|
-
//
|
|
1105
|
-
// Pi sentinelizes BOTH halves, so unlike OpenCode there's no
|
|
1106
|
-
// result-part requirement — a target reclaims as long as it still has
|
|
1107
|
-
// at least one live occurrence to sentinelize.
|
|
1118
|
+
// Open invocations still belong to the current turn; only complete arcs reclaim.
|
|
1108
1119
|
canDrop(): boolean {
|
|
1109
|
-
return
|
|
1120
|
+
return (
|
|
1121
|
+
occurrences.some((occ) => occ.kind === "tool_use") &&
|
|
1122
|
+
occurrences.some((occ) => occ.kind === "tool_result")
|
|
1123
|
+
);
|
|
1110
1124
|
},
|
|
1111
1125
|
requiresToolArcSkeleton,
|
|
1112
1126
|
// Non-mutating read of the invocation input (the tool_use occurrence
|
|
@@ -1162,8 +1176,8 @@ function buildTextTarget(
|
|
|
1162
1176
|
* TagTarget for a tag-eligible tool part. Tool parts get full-drop or
|
|
1163
1177
|
* skeleton-drop treatment from `applyFlushedStatuses` based on the stored
|
|
1164
1178
|
* `drop_mode` column. Both render the SAME canonical `[dropped §N§]`
|
|
1165
|
-
* placeholder — full-drop replaces the whole pair, skeleton-drop keeps
|
|
1166
|
-
* tool_use call
|
|
1179
|
+
* placeholder — full-drop replaces the whole pair, while skeleton-drop keeps
|
|
1180
|
+
* the tool_use call with only a dropped-input marker. Marker bytes are
|
|
1167
1181
|
* byte-identical across passes and across harnesses.
|
|
1168
1182
|
*/
|
|
1169
1183
|
function buildToolTarget(
|
|
@@ -1190,12 +1204,10 @@ function buildToolTarget(
|
|
|
1190
1204
|
return replaced ? "removed" : "absent";
|
|
1191
1205
|
},
|
|
1192
1206
|
truncate(): "truncated" | "absent" {
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
const ok = setToolContentOrText(part, `[dropped \u00a7${tagId}\u00a7]`);
|
|
1198
|
-
return ok ? "truncated" : "absent";
|
|
1207
|
+
const changed = part.setToolInput
|
|
1208
|
+
? part.setToolInput(droppedInputMarker(tagId))
|
|
1209
|
+
: setToolContentOrText(part, `[dropped \u00a7${tagId}\u00a7]`);
|
|
1210
|
+
return changed ? "truncated" : "absent";
|
|
1199
1211
|
},
|
|
1200
1212
|
message: {
|
|
1201
1213
|
info: { id: message.info.id, role: message.info.role },
|
|
@@ -9,6 +9,7 @@ export interface WireTailHygieneBaseline {
|
|
|
9
9
|
generation_invalidated?: boolean;
|
|
10
10
|
baseline_generation?: number;
|
|
11
11
|
computed_at_ms?: number;
|
|
12
|
+
reclaimable_tool_output_count?: number;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
function finiteNumber(value: unknown, fallback = 0): number {
|
|
@@ -34,6 +35,10 @@ export function resolveTailHygieneStatus(
|
|
|
34
35
|
generationInvalidated: rustBaseline.generation_invalidated === true,
|
|
35
36
|
baselineGeneration: Math.max(0, finiteNumber(rustBaseline.baseline_generation)),
|
|
36
37
|
computedAt: Math.max(0, finiteNumber(rustBaseline.computed_at_ms)),
|
|
38
|
+
reclaimableToolOutputCount: Math.max(
|
|
39
|
+
0,
|
|
40
|
+
Math.floor(finiteNumber(rustBaseline.reclaimable_tool_output_count)),
|
|
41
|
+
),
|
|
37
42
|
};
|
|
38
43
|
}
|
|
39
44
|
if (tsBaseline === undefined) return undefined;
|
|
@@ -47,6 +52,9 @@ export function resolveTailHygieneStatus(
|
|
|
47
52
|
generationInvalidated: tsBaseline.generationInvalidated,
|
|
48
53
|
baselineGeneration: Math.max(0, tsBaseline.baselineGeneration),
|
|
49
54
|
computedAt: Math.max(0, tsBaseline.computedAt),
|
|
55
|
+
reclaimableToolOutputCount: tsBaseline.baselineParts.filter(
|
|
56
|
+
(part) => part.kind === "toolOutput" && part.uTokens > 0,
|
|
57
|
+
).length,
|
|
50
58
|
};
|
|
51
59
|
}
|
|
52
60
|
|
package/src/shared/transcript.ts
CHANGED
|
@@ -167,6 +167,11 @@ export interface TranscriptPart {
|
|
|
167
167
|
*/
|
|
168
168
|
replaceWithSentinel(sentinelText: string): boolean;
|
|
169
169
|
|
|
170
|
+
/** Remove one half of a complete tool arc. Callers must remove both halves together. */
|
|
171
|
+
remove?(): boolean;
|
|
172
|
+
/** Refuse structural deletion when the adapter cannot match provider-native identity safely. */
|
|
173
|
+
canRemove?(): boolean;
|
|
174
|
+
|
|
170
175
|
/**
|
|
171
176
|
* Optional: serialized byte size of the part's REAL payload, including
|
|
172
177
|
* non-text content (images, structured data) that `getText()` can't
|
|
@@ -187,6 +192,8 @@ export interface TranscriptPart {
|
|
|
187
192
|
* use `info.id` for cross-pass correlation, never the message reference.
|
|
188
193
|
*/
|
|
189
194
|
export interface TranscriptMessage {
|
|
195
|
+
/** Override when the receiving protocol does not merge adjacent assistant reasoning turns. */
|
|
196
|
+
requiresToolArcSkeleton?: boolean;
|
|
190
197
|
/**
|
|
191
198
|
* Lightweight metadata exposed for tagging, sentinel persistence, and
|
|
192
199
|
* cross-pass correlation. Adapters fill these from harness-native
|