@cortexkit/opencode-magic-context 0.42.5 → 0.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -7
- package/dist/agents/dreamer.d.ts +7 -9
- package/dist/agents/dreamer.d.ts.map +1 -1
- package/dist/agents/hidden-agent-registrations.d.ts.map +1 -1
- package/dist/agents/magic-context-prompt.d.ts.map +1 -1
- package/dist/config/index.d.ts +10 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/live-run-config.d.ts +12 -0
- package/dist/config/live-run-config.d.ts.map +1 -0
- package/dist/config/live-snapshot.d.ts +32 -0
- package/dist/config/live-snapshot.d.ts.map +1 -0
- package/dist/config/schema/magic-context.d.ts +13 -2
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/{conflict-warning-hook-jyj54gbe.js → conflict-warning-hook-t2vb0wnx.js} +3 -3
- package/dist/{derive-budgets-v1fkhjjr.js → derive-budgets-0sg5vp61.js} +5 -2
- package/dist/features/builtin-commands/commands.d.ts +0 -4
- package/dist/features/builtin-commands/commands.d.ts.map +1 -1
- package/dist/features/magic-context/compaction-marker.d.ts +6 -0
- package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts +4 -1
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-lease.d.ts +8 -0
- package/dist/features/magic-context/compartment-lease.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-storage.d.ts +21 -0
- package/dist/features/magic-context/compartment-storage.d.ts.map +1 -1
- package/dist/features/magic-context/context-authority.d.ts +37 -3
- 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/docs-proposals.d.ts +23 -0
- package/dist/features/magic-context/dreamer/docs-proposals.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts +5 -1
- package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/hidden-single-shot.d.ts +48 -0
- package/dist/features/magic-context/dreamer/hidden-single-shot.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/manual-summary.d.ts +7 -0
- package/dist/features/magic-context/dreamer/manual-summary.d.ts.map +1 -0
- 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/promote-primers.d.ts +8 -1
- package/dist/features/magic-context/dreamer/promote-primers.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 +5 -2
- package/dist/features/magic-context/dreamer/retrospective-orphan-sweep.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/retrospective-raw-provider.d.ts +22 -13
- package/dist/features/magic-context/dreamer/retrospective-raw-provider.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/storage-task-schedule.d.ts +9 -0
- package/dist/features/magic-context/dreamer/storage-task-schedule.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-config.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-executor.d.ts +3 -0
- package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-prompts.d.ts +7 -4
- package/dist/features/magic-context/dreamer/task-prompts.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-registry.d.ts +53 -2
- package/dist/features/magic-context/dreamer/task-registry.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts +3 -0
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/tick-failure.d.ts +38 -0
- package/dist/features/magic-context/dreamer/tick-failure.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/search-git-commits.d.ts +2 -0
- package/dist/features/magic-context/git-commits/search-git-commits.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-identity.d.ts +1 -0
- package/dist/features/magic-context/memory/embedding-identity.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-local.d.ts +1 -0
- package/dist/features/magic-context/memory/embedding-local.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-diagnostics.d.ts +6 -0
- package/dist/features/magic-context/memory/memory-diagnostics.d.ts.map +1 -0
- package/dist/features/magic-context/memory/memory-selection.d.ts +12 -0
- package/dist/features/magic-context/memory/memory-selection.d.ts.map +1 -0
- package/dist/features/magic-context/memory/memory-visibility.d.ts +46 -0
- package/dist/features/magic-context/memory/memory-visibility.d.ts.map +1 -0
- package/dist/features/magic-context/memory/mirror-reembed.d.ts +22 -0
- package/dist/features/magic-context/memory/mirror-reembed.d.ts.map +1 -0
- package/dist/features/magic-context/memory/project-identity.d.ts +9 -0
- package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
- package/dist/features/magic-context/memory/storage-memory-fts.d.ts +6 -2
- package/dist/features/magic-context/memory/storage-memory-fts.d.ts.map +1 -1
- package/dist/features/magic-context/memory/storage-memory.d.ts.map +1 -1
- package/dist/features/magic-context/memory/transformers-remote-host.d.ts +6 -0
- package/dist/features/magic-context/memory/transformers-remote-host.d.ts.map +1 -0
- package/dist/features/magic-context/memory/transformers-web-entry.d.ts.map +1 -1
- package/dist/features/magic-context/message-fts-rowid-map.d.ts +3 -1
- package/dist/features/magic-context/message-fts-rowid-map.d.ts.map +1 -1
- package/dist/features/magic-context/message-index-async.d.ts +8 -3
- package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
- package/dist/features/magic-context/message-index.d.ts +7 -1
- package/dist/features/magic-context/message-index.d.ts.map +1 -1
- package/dist/features/magic-context/message-time-backfill.d.ts +19 -0
- package/dist/features/magic-context/message-time-backfill.d.ts.map +1 -0
- package/dist/features/magic-context/migrations.d.ts +16 -0
- 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/storage-mural.d.ts +5 -0
- package/dist/features/magic-context/mural/storage-mural.d.ts.map +1 -1
- package/dist/features/magic-context/opencode2-relabel.d.ts +132 -0
- package/dist/features/magic-context/opencode2-relabel.d.ts.map +1 -0
- package/dist/features/magic-context/overflow-detection.d.ts +3 -0
- package/dist/features/magic-context/overflow-detection.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts +1 -0
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/protection-window.d.ts +1 -1
- package/dist/features/magic-context/protection-window.d.ts.map +1 -1
- package/dist/features/magic-context/search.d.ts +6 -0
- package/dist/features/magic-context/search.d.ts.map +1 -1
- package/dist/features/magic-context/session-decision-calibration.d.ts +31 -0
- package/dist/features/magic-context/session-decision-calibration.d.ts.map +1 -0
- package/dist/features/magic-context/session-project-backfill.d.ts.map +1 -1
- package/dist/features/magic-context/shadow-backfill-state.d.ts +1 -1
- package/dist/features/magic-context/shadow-backfill-state.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/compiler.d.ts +5 -1
- package/dist/features/magic-context/smart-notes/compiler.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-historian-runs.d.ts +4 -2
- package/dist/features/magic-context/storage-historian-runs.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +16 -2
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-shared.d.ts +1 -1
- package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta.d.ts +1 -1
- package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
- package/dist/features/magic-context/storage-notes.d.ts +1 -0
- package/dist/features/magic-context/storage-notes.d.ts.map +1 -1
- package/dist/features/magic-context/storage-replay-document.d.ts +2 -0
- package/dist/features/magic-context/storage-replay-document.d.ts.map +1 -1
- 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 +42 -4
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +2 -2
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/features/magic-context/store-generation-rebase.d.ts +95 -0
- package/dist/features/magic-context/store-generation-rebase.d.ts.map +1 -0
- package/dist/features/magic-context/subagent-token-capture.d.ts +1 -0
- package/dist/features/magic-context/subagent-token-capture.d.ts.map +1 -1
- package/dist/features/magic-context/tagger.d.ts +2 -0
- package/dist/features/magic-context/tagger.d.ts.map +1 -1
- package/dist/features/magic-context/tool-definition-tokens.d.ts +1 -0
- package/dist/features/magic-context/tool-definition-tokens.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 +5 -1
- package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
- package/dist/hooks/auto-update-checker/index.d.ts.map +1 -1
- package/dist/hooks/magic-context/apply-operations.d.ts +10 -1
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
- package/dist/hooks/magic-context/cache-busting-signals.d.ts +19 -4
- package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -1
- package/dist/hooks/magic-context/channel2-delivery.d.ts +8 -0
- package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
- package/dist/hooks/magic-context/command-handler.d.ts +5 -4
- 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/compaction-off-transition.d.ts +1 -0
- package/dist/hooks/magic-context/compaction-off-transition.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-prompt.d.ts +1 -1
- package/dist/hooks/magic-context/compartment-prompt.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-render-epoch.d.ts +3 -1
- package/dist/hooks/magic-context/compartment-render-epoch.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts +1 -1
- package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts +1 -0
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts +19 -0
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-types.d.ts +19 -11
- package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts +4 -1
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
- package/dist/hooks/magic-context/decay-render.d.ts +1 -0
- package/dist/hooks/magic-context/decay-render.d.ts.map +1 -1
- package/dist/hooks/magic-context/decision-calibration.d.ts +24 -0
- package/dist/hooks/magic-context/decision-calibration.d.ts.map +1 -0
- package/dist/hooks/magic-context/derive-budgets.d.ts +2 -0
- package/dist/hooks/magic-context/derive-budgets.d.ts.map +1 -1
- package/dist/hooks/magic-context/dropped-input-guard.d.ts +50 -4
- package/dist/hooks/magic-context/dropped-input-guard.d.ts.map +1 -1
- package/dist/hooks/magic-context/embed-history-runner.d.ts +30 -0
- package/dist/hooks/magic-context/embed-history-runner.d.ts.map +1 -0
- package/dist/hooks/magic-context/emergency-drop.d.ts +13 -8
- package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-payloads.d.ts +2 -1
- package/dist/hooks/magic-context/event-payloads.d.ts.map +1 -1
- package/dist/hooks/magic-context/execute-status.d.ts +2 -1
- package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts +12 -4
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -1
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/historian-no-fire-cause.d.ts +5 -0
- package/dist/hooks/magic-context/historian-no-fire-cause.d.ts.map +1 -0
- package/dist/hooks/magic-context/historian-publish-stage-logger.d.ts +3 -0
- package/dist/hooks/magic-context/historian-publish-stage-logger.d.ts.map +1 -0
- package/dist/hooks/magic-context/hook-handlers.d.ts +0 -3
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts +4 -4
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/host-served-rows.d.ts +58 -0
- package/dist/hooks/magic-context/host-served-rows.d.ts.map +1 -0
- package/dist/hooks/magic-context/inject-compartments.d.ts +38 -0
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/legacy-compartments.d.ts +20 -0
- package/dist/hooks/magic-context/legacy-compartments.d.ts.map +1 -0
- package/dist/hooks/magic-context/live-session-state.d.ts +7 -7
- package/dist/hooks/magic-context/m0-token-breakdown.d.ts +6 -0
- package/dist/hooks/magic-context/m0-token-breakdown.d.ts.map +1 -1
- package/dist/hooks/magic-context/maintenance-authority.d.ts +0 -1
- package/dist/hooks/magic-context/maintenance-authority.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-state-sync.d.ts +4 -1
- package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-transport.d.ts +24 -2
- package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-wire.d.ts +43 -1
- 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/postprocess-read-cache.d.ts +8 -0
- package/dist/hooks/magic-context/postprocess-read-cache.d.ts.map +1 -0
- package/dist/hooks/magic-context/producer-window-guard.d.ts +47 -1
- package/dist/hooks/magic-context/producer-window-guard.d.ts.map +1 -1
- package/dist/hooks/magic-context/producer-window-test-support.d.ts +14 -0
- package/dist/hooks/magic-context/producer-window-test-support.d.ts.map +1 -0
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts +2 -0
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts +51 -10
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-db.d.ts +8 -0
- package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-formatting.d.ts +6 -0
- package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts +4 -0
- package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts +6 -0
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts +17 -39
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-mode-transform.d.ts +51 -0
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-refusal-recovery.d.ts +28 -0
- package/dist/hooks/magic-context/rust-refusal-recovery.d.ts.map +1 -0
- package/dist/hooks/magic-context/sentinel.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts +6 -7
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-messages.d.ts +21 -1
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts +63 -0
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
- package/dist/hooks/magic-context/tokenizer-calibration.d.ts +19 -12
- package/dist/hooks/magic-context/tokenizer-calibration.d.ts.map +1 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts +52 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/tool-sweep-policy.d.ts +50 -0
- package/dist/hooks/magic-context/tool-sweep-policy.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts +20 -1
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-context-state.d.ts +9 -0
- package/dist/hooks/magic-context/transform-context-state.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +5 -3
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +44 -4
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
- package/dist/{index-f9gem5cr.js → index-8w1skpnm.js} +85 -5
- package/dist/index-99sfbrrf.js +170 -0
- package/dist/index-9skq8m9y.js +16 -0
- package/dist/{index-3wbd8sdq.js → index-d0dh7v0f.js} +28107 -29850
- package/dist/{index-d8mgqezq.js → index-rpz2me0v.js} +133 -78
- package/dist/{index-p474rw9p.js → index-rvwvdq59.js} +1 -1
- package/dist/index-w2ety11c.js +393 -0
- package/dist/index-y5145x8k.js +619 -0
- package/dist/index-ygwdyntq.js +5407 -0
- package/dist/{index-jkrqhc7y.js → index-ykg9sdzz.js} +147 -28
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7065 -3197
- package/dist/message-time-backfill-gzjer78y.js +108 -0
- package/dist/plugin/dream-timer.d.ts +13 -0
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/embedding-bootstrap.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +5 -2
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/memory-id-translation.d.ts +109 -0
- package/dist/plugin/memory-id-translation.d.ts.map +1 -0
- package/dist/plugin/messages-transform.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts +10 -0
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/plugin/rust-note-backend.d.ts +84 -0
- package/dist/plugin/rust-note-backend.d.ts.map +1 -0
- package/dist/plugin/rust-tool-backends.d.ts +1 -1
- package/dist/plugin/rust-tool-backends.d.ts.map +1 -1
- package/dist/plugin/tool-registry.d.ts +1 -0
- package/dist/plugin/tool-registry.d.ts.map +1 -1
- package/dist/read-session-chunk-ec3jkvhg.js +61 -0
- package/dist/{recomp-orchestrator-k20sfpm2.js → recomp-orchestrator-6akjp11f.js} +8 -8
- package/dist/{send-session-notification-xnypkxpx.js → send-session-notification-f6gwkesy.js} +2 -2
- package/dist/shared/assistant-message-extractor.d.ts +6 -0
- package/dist/shared/assistant-message-extractor.d.ts.map +1 -1
- package/dist/shared/auto-update-provenance.d.ts +9 -0
- package/dist/shared/auto-update-provenance.d.ts.map +1 -0
- package/dist/shared/conflict-detector.d.ts +14 -5
- package/dist/shared/conflict-detector.d.ts.map +1 -1
- package/dist/shared/hidden-variant-warnings.d.ts +5 -0
- package/dist/shared/hidden-variant-warnings.d.ts.map +1 -0
- package/dist/shared/host-limitations.d.ts +14 -0
- package/dist/shared/host-limitations.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.map +1 -1
- package/dist/shared/models-dev-cache.d.ts +1 -0
- package/dist/shared/models-dev-cache.d.ts.map +1 -1
- package/dist/shared/opencode-config-dir.d.ts +52 -0
- package/dist/shared/opencode-config-dir.d.ts.map +1 -1
- package/dist/shared/opencode-db-path.d.ts +46 -2
- package/dist/shared/opencode-db-path.d.ts.map +1 -1
- package/dist/shared/prompt-surface-runtime.d.ts +6 -6
- package/dist/shared/prompt-surface-runtime.d.ts.map +1 -1
- package/dist/shared/rpc-server.d.ts +10 -0
- package/dist/shared/rpc-server.d.ts.map +1 -1
- package/dist/shared/rpc-types.d.ts +64 -5
- package/dist/shared/rpc-types.d.ts.map +1 -1
- package/dist/shared/status-detail-text.d.ts +1 -3
- package/dist/shared/status-detail-text.d.ts.map +1 -1
- package/dist/shared/status-summary.d.ts +7 -0
- package/dist/shared/status-summary.d.ts.map +1 -1
- package/dist/shared/status-view.d.ts +229 -0
- package/dist/shared/status-view.d.ts.map +1 -0
- package/dist/shared/tag-transcript.d.ts.map +1 -1
- package/dist/shared/tail-hygiene-status.d.ts +8 -0
- package/dist/shared/tail-hygiene-status.d.ts.map +1 -1
- package/dist/shared/user-facing-codes.d.ts +32 -7
- package/dist/shared/user-facing-codes.d.ts.map +1 -1
- package/dist/shared/window-geometry.d.ts +3 -0
- package/dist/shared/window-geometry.d.ts.map +1 -1
- package/dist/{task-config-cv8k9y8r.js → task-config-ex4nt0q0.js} +1 -1
- package/dist/tools/ctx-expand/constants.d.ts +1 -1
- package/dist/tools/ctx-expand/constants.d.ts.map +1 -1
- package/dist/tools/ctx-expand/mode.d.ts +31 -0
- package/dist/tools/ctx-expand/mode.d.ts.map +1 -0
- package/dist/tools/ctx-expand/render.d.ts.map +1 -1
- package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
- package/dist/tools/ctx-memory/constants.d.ts +3 -1
- package/dist/tools/ctx-memory/constants.d.ts.map +1 -1
- package/dist/tools/ctx-memory/tools.d.ts +1 -0
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
- package/dist/tools/ctx-memory/types.d.ts +2 -2
- 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/render.d.ts +88 -0
- package/dist/tools/ctx-note/render.d.ts.map +1 -0
- package/dist/tools/ctx-note/tools.d.ts.map +1 -1
- package/dist/tools/ctx-note/types.d.ts +1 -1
- package/dist/tools/ctx-note/types.d.ts.map +1 -1
- package/dist/tools/ctx-reduce/constants.d.ts +1 -1
- package/dist/tools/ctx-reduce/constants.d.ts.map +1 -1
- package/dist/tools/ctx-search/constants.d.ts +1 -1
- package/dist/tools/ctx-search/constants.d.ts.map +1 -1
- package/dist/tools/ctx-search/date-range.d.ts +9 -0
- package/dist/tools/ctx-search/date-range.d.ts.map +1 -0
- package/dist/tools/ctx-search/tools.d.ts.map +1 -1
- package/dist/tools/ctx-search/types.d.ts +3 -1
- package/dist/tools/ctx-search/types.d.ts.map +1 -1
- package/dist/tools/light-descriptions.d.ts +5 -5
- package/dist/tools/light-descriptions.d.ts.map +1 -1
- package/dist/tools/parameter-descriptions.d.ts +75 -0
- package/dist/tools/parameter-descriptions.d.ts.map +1 -0
- package/dist/transformers-node-wasm.js +1918 -826
- package/dist/transformers-web.js +1736 -636
- package/dist/{transformers.node-dpmf3wpx.js → transformers.node-3zqr6k1w.js} +4087 -2898
- package/dist/tui/data/context-db.d.ts +19 -7
- package/dist/tui/data/context-db.d.ts.map +1 -1
- package/dist/tui-compiled/data/context-db.d.ts +19 -7
- package/dist/tui-compiled/data/context-db.d.ts.map +1 -1
- package/dist/v2/fold/host-media.d.ts +36 -0
- package/dist/v2/fold/host-media.d.ts.map +1 -0
- package/dist/v2/fold/restore.d.ts +21 -1
- package/dist/v2/fold/restore.d.ts.map +1 -1
- package/dist/v2/hidden-completion.d.ts +114 -14
- package/dist/v2/hidden-completion.d.ts.map +1 -1
- package/dist/v2/hooks/commands.d.ts +29 -0
- package/dist/v2/hooks/commands.d.ts.map +1 -0
- package/dist/v2/hooks/context.d.ts +58 -2
- package/dist/v2/hooks/context.d.ts.map +1 -1
- package/dist/v2/hooks/deleted-session-tombstones.d.ts +10 -0
- package/dist/v2/hooks/deleted-session-tombstones.d.ts.map +1 -0
- package/dist/v2/hooks/dream-manual.d.ts +43 -0
- package/dist/v2/hooks/dream-manual.d.ts.map +1 -0
- package/dist/v2/hooks/dream-trigger.d.ts +7 -0
- package/dist/v2/hooks/dream-trigger.d.ts.map +1 -1
- package/dist/v2/hooks/hidden-child.d.ts +32 -0
- package/dist/v2/hooks/hidden-child.d.ts.map +1 -0
- package/dist/v2/hooks/model-limit-cache.d.ts +19 -0
- package/dist/v2/hooks/model-limit-cache.d.ts.map +1 -0
- package/dist/v2/hooks/payload.d.ts.map +1 -1
- package/dist/v2/hooks/provider-admission.d.ts +22 -0
- package/dist/v2/hooks/provider-admission.d.ts.map +1 -0
- package/dist/v2/hooks/rpc-live-state.d.ts +9 -0
- package/dist/v2/hooks/rpc-live-state.d.ts.map +1 -0
- package/dist/v2/hooks/store.d.ts +38 -2
- package/dist/v2/hooks/store.d.ts.map +1 -1
- package/dist/v2/hooks/tools.d.ts +8 -0
- package/dist/v2/hooks/tools.d.ts.map +1 -0
- package/dist/v2/hooks/types.d.ts +157 -19
- package/dist/v2/hooks/types.d.ts.map +1 -1
- package/dist/v2/hooks/usage-reading.d.ts +42 -0
- package/dist/v2/hooks/usage-reading.d.ts.map +1 -0
- package/dist/v2/host-service.d.ts +65 -0
- package/dist/v2/host-service.d.ts.map +1 -0
- package/dist/v2/server.d.ts +19 -0
- package/dist/v2/server.d.ts.map +1 -1
- package/dist/v2/server.js +141849 -110533
- package/dist/v2/store-reader.d.ts +78 -6
- package/dist/v2/store-reader.d.ts.map +1 -1
- package/dist/v2/tui/events.d.ts +7 -0
- package/dist/v2/tui/events.d.ts.map +1 -0
- package/dist/v2/tui/index.d.ts +33 -0
- package/dist/v2/tui/index.d.ts.map +1 -0
- package/dist/v2/tui/sidebar-mount.d.ts +40 -0
- package/dist/v2/tui/sidebar-mount.d.ts.map +1 -0
- package/dist/v2/tui/status-dialog-mount.d.ts +29 -0
- package/dist/v2/tui/status-dialog-mount.d.ts.map +1 -0
- package/dist/v2/tui/types.d.ts +148 -0
- package/dist/v2/tui/types.d.ts.map +1 -0
- package/dist/wrapup-orchestrator-5akc87gr.js +16 -0
- package/package.json +9 -7
- package/src/agents/dreamer.ts +7 -16
- package/src/agents/hidden-agent-registrations.ts +10 -22
- package/src/agents/magic-context-prompt.test.ts +29 -39
- package/src/agents/magic-context-prompt.ts +99 -122
- package/src/agents/permissions.test.ts +17 -21
- package/src/config/index.ts +39 -4
- package/src/config/live-run-config.test.ts +237 -0
- package/src/config/live-run-config.ts +80 -0
- package/src/config/live-schema-drift.test.ts +67 -0
- package/src/config/live-snapshot.test.ts +85 -0
- package/src/config/live-snapshot.ts +191 -0
- package/src/config/protected-tokens.test.ts +40 -0
- package/src/config/raw-loader.test.ts +1 -0
- package/src/config/schema/magic-context.test.ts +13 -5
- package/src/config/schema/magic-context.ts +109 -13
- package/src/features/magic-context/dreamer/task-registry.ts +137 -13
- package/src/shared/assistant-message-extractor.test.ts +21 -0
- package/src/shared/assistant-message-extractor.ts +43 -8
- package/src/shared/auto-update-provenance.ts +42 -0
- package/src/shared/child-session-teardown.test.ts +38 -3
- package/src/shared/child-session-teardown.ts +3 -3
- package/src/shared/conflict-detector.test.ts +277 -7
- package/src/shared/conflict-detector.ts +221 -80
- package/src/shared/hidden-variant-warnings.ts +21 -0
- package/src/shared/host-limitations.ts +43 -0
- package/src/shared/keep-subagents.ts +6 -6
- package/src/shared/model-suggestion-retry.test.ts +43 -0
- package/src/shared/model-suggestion-retry.ts +12 -0
- package/src/shared/models-dev-cache.test.ts +25 -0
- package/src/shared/models-dev-cache.ts +5 -0
- package/src/shared/opencode-config-dir.ts +80 -7
- package/src/shared/opencode-db-path.test.ts +174 -0
- package/src/shared/opencode-db-path.ts +193 -15
- package/src/shared/opencode-host-generation.test.ts +29 -0
- package/src/shared/prompt-surface-a1-golden.md +142 -215
- package/src/shared/prompt-surface-runtime.test.ts +20 -0
- package/src/shared/prompt-surface-runtime.ts +7 -5
- package/src/shared/rpc-server.ts +18 -0
- package/src/shared/rpc-types.ts +63 -4
- package/src/shared/status-detail-text.test.ts +52 -18
- package/src/shared/status-detail-text.ts +1 -90
- package/src/shared/status-summary.ts +37 -2
- package/src/shared/status-view.test.ts +441 -0
- package/src/shared/status-view.ts +707 -0
- package/src/shared/tag-transcript.ts +115 -16
- package/src/shared/tail-hygiene-status.ts +9 -1
- package/src/shared/user-facing-codes.test.ts +3 -4
- package/src/shared/user-facing-codes.ts +33 -8
- package/src/shared/window-geometry.test.ts +23 -5
- package/src/shared/window-geometry.ts +13 -3
- package/src/tui/data/context-db.ts +50 -15
- package/src/tui/dialogs/status-dialog-colors.test.ts +58 -0
- package/src/tui/dialogs/status-dialog.tsx +288 -0
- package/src/tui/entry.mjs +11 -1
- package/src/tui/index.tsx +7 -464
- package/src/tui/slots/sidebar-content.tsx +21 -5
- package/src/tui-compiled/data/context-db.ts +50 -15
- package/src/tui-compiled/dialogs/status-dialog.tsx +552 -0
- package/src/tui-compiled/index.tsx +43 -1025
- package/src/tui-compiled/slots/sidebar-content.tsx +173 -152
- package/src/v2/tui/__fixtures__/ga-host-theme.json +160 -0
- package/src/v2/tui/events.ts +23 -0
- package/src/v2/tui/host-contract.test.ts +251 -0
- package/src/v2/tui/index.ts +526 -0
- package/src/v2/tui/load-compiled-sidebar.d.mts +59 -0
- package/src/v2/tui/load-compiled-sidebar.mjs +24 -0
- package/src/v2/tui/load-compiled-status-dialog.d.mts +17 -0
- package/src/v2/tui/load-compiled-status-dialog.mjs +16 -0
- package/src/v2/tui/sidebar-fallback.test.ts +100 -0
- package/src/v2/tui/sidebar-mount.ts +164 -0
- package/src/v2/tui/sidebar-text.test.ts +70 -0
- package/src/v2/tui/status-dialog-fallback.test.ts +97 -0
- package/src/v2/tui/status-dialog-mount.ts +76 -0
- package/src/v2/tui/theme-mapping.test.ts +57 -0
- package/src/v2/tui/types.ts +132 -0
- package/tui.js +1 -0
- package/dist/features/magic-context/memory/memory-migration.d.ts +0 -129
- package/dist/features/magic-context/memory/memory-migration.d.ts.map +0 -1
- package/dist/hooks/magic-context/upgrade-reminder.d.ts +0 -76
- package/dist/hooks/magic-context/upgrade-reminder.d.ts.map +0 -1
- package/dist/index-1ar7b3e9.js +0 -637
- package/dist/index-4wwr6cz0.js +0 -112
- package/dist/index-avwt563y.js +0 -62
- package/dist/storage-meta-session-x3j0q9qy.js +0 -20
|
@@ -9,19 +9,64 @@ export type {
|
|
|
9
9
|
OpenCodeConfigPaths,
|
|
10
10
|
} from "./opencode-config-dir-types";
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
/**
|
|
13
|
+
* The user's home directory, preferring `$HOME` over the cached value.
|
|
14
|
+
*
|
|
15
|
+
* `os.homedir()` reads `$HOME` once when the process starts and never again,
|
|
16
|
+
* so a test (or a wrapper) that sets `HOME` afterwards would otherwise be
|
|
17
|
+
* silently ignored and we would read the developer's real config. `$HOME` is
|
|
18
|
+
* normally unset on Windows, where the cached value is the right answer.
|
|
19
|
+
*/
|
|
20
|
+
function resolveHomeDir(): string {
|
|
21
|
+
return process.env.HOME?.trim() || homedir();
|
|
22
|
+
}
|
|
17
23
|
|
|
24
|
+
/**
|
|
25
|
+
* OpenCode's GLOBAL config directory: `$XDG_CONFIG_HOME/opencode`, falling
|
|
26
|
+
* back to `~/.config/opencode` (on every platform, Windows included — OpenCode
|
|
27
|
+
* does not use %APPDATA%).
|
|
28
|
+
*
|
|
29
|
+
* This helper names the loader's XDG layer, not every OpenCode surface called
|
|
30
|
+
* "config". In 1.18.30, `Global.Path.config` is the pure-XDG path
|
|
31
|
+
* (`packages/core/src/global.ts:13`) and the loader merges it once at
|
|
32
|
+
* `packages/opencode/src/config/config.ts:412-413`. Its later directories loop
|
|
33
|
+
* accepts only `.opencode` paths or the exact `OPENCODE_CONFIG_DIR` value
|
|
34
|
+
* (`config.ts:437-441`), so the XDG layer is skipped there and the env path is
|
|
35
|
+
* merged last. The detector mirrors that loader order via
|
|
36
|
+
* {@link getOpenCodeConfigDirs}.
|
|
37
|
+
*
|
|
38
|
+
* Service consumers see a different value: `Global.make()` injects
|
|
39
|
+
* `Flag.OPENCODE_CONFIG_DIR ?? Path.config` as `config`
|
|
40
|
+
* (`packages/core/src/global.ts:64`), so setting the env var replaces the
|
|
41
|
+
* service's value even though the loader still merges the XDG layer.
|
|
42
|
+
*/
|
|
43
|
+
export function getOpenCodeGlobalConfigDir(): string {
|
|
18
44
|
if (process.platform === "win32") {
|
|
19
|
-
return join(
|
|
45
|
+
return join(resolveHomeDir(), ".config", "opencode");
|
|
20
46
|
}
|
|
21
47
|
|
|
22
|
-
return join(process.env.XDG_CONFIG_HOME || join(
|
|
48
|
+
return join(process.env.XDG_CONFIG_HOME || join(resolveHomeDir(), ".config"), "opencode");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function getEnvConfigDir(): string | undefined {
|
|
52
|
+
const envConfigDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
53
|
+
return envConfigDir ? resolve(envConfigDir) : undefined;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function getCliConfigDir(): string {
|
|
57
|
+
return getEnvConfigDir() ?? getOpenCodeGlobalConfigDir();
|
|
23
58
|
}
|
|
24
59
|
|
|
60
|
+
/**
|
|
61
|
+
* The single directory Magic Context WRITES its OpenCode-side config into.
|
|
62
|
+
*
|
|
63
|
+
* `OPENCODE_CONFIG_DIR` wins here on purpose: among the directories OpenCode
|
|
64
|
+
* reads it has the highest precedence, so a setting written there is the one
|
|
65
|
+
* that takes effect. Do NOT use this to decide what OpenCode RESOLVED — for
|
|
66
|
+
* that you must read every directory in {@link getOpenCodeConfigDirs}, because
|
|
67
|
+
* a value the user set in the global directory is still live when
|
|
68
|
+
* `OPENCODE_CONFIG_DIR` points somewhere that does not override it.
|
|
69
|
+
*/
|
|
25
70
|
export function getOpenCodeConfigDir(_options: OpenCodeConfigDirOptions): string {
|
|
26
71
|
return getCliConfigDir();
|
|
27
72
|
}
|
|
@@ -36,3 +81,31 @@ export function getOpenCodeConfigPaths(options: OpenCodeConfigDirOptions): OpenC
|
|
|
36
81
|
omoConfig: join(configDir, "magic-context.jsonc"),
|
|
37
82
|
};
|
|
38
83
|
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Every user-tier directory OpenCode reads config from, ordered from LOWEST to
|
|
87
|
+
* HIGHEST precedence — later entries override earlier ones, which is the order
|
|
88
|
+
* OpenCode merges them in.
|
|
89
|
+
*
|
|
90
|
+
* Verified against the opencode 1.18.30 binary (`ConfigPaths.directories` plus
|
|
91
|
+
* the global loader in `Config.loadInstanceState`) and confirmed on a live host
|
|
92
|
+
* with `opencode debug config`:
|
|
93
|
+
*
|
|
94
|
+
* 1. `$XDG_CONFIG_HOME/opencode` — always read, whatever the environment says
|
|
95
|
+
* 2. `~/.opencode` — always scanned, even outside a project
|
|
96
|
+
* 3. `$OPENCODE_CONFIG_DIR` — appended last, so it wins ties
|
|
97
|
+
*
|
|
98
|
+
* The important part is that entry 3 is an ADDITION, not a replacement. A
|
|
99
|
+
* launcher that exports `OPENCODE_CONFIG_DIR` to a directory holding only
|
|
100
|
+
* plugin scaffolding does not stop OpenCode from reading the user's real
|
|
101
|
+
* config in entry 1 — so neither may we.
|
|
102
|
+
*
|
|
103
|
+
* Project-level directories are deliberately not included: they depend on the
|
|
104
|
+
* working directory and are resolved by the caller that knows it.
|
|
105
|
+
*/
|
|
106
|
+
export function getOpenCodeConfigDirs(): string[] {
|
|
107
|
+
const dirs = [getOpenCodeGlobalConfigDir(), join(resolveHomeDir(), ".opencode")];
|
|
108
|
+
const envDir = getEnvConfigDir();
|
|
109
|
+
if (envDir) dirs.push(envDir);
|
|
110
|
+
return [...new Set(dirs)];
|
|
111
|
+
}
|
|
@@ -5,13 +5,18 @@ import { mkdirSync, mkdtempSync, rmSync, unlinkSync, utimesSync, writeFileSync }
|
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
import { join } from "node:path";
|
|
7
7
|
import {
|
|
8
|
+
assertOpenCodeStoreGeneration,
|
|
9
|
+
detectOpenCodeStoreGeneration,
|
|
8
10
|
formatOpenCodeDbDoctorLine,
|
|
9
11
|
formatOpenCodeDbMissingBanner,
|
|
10
12
|
formatOpenCodeDbMissingStatusLine,
|
|
13
|
+
hasV1MessageTables,
|
|
11
14
|
openCodeDbPathExists,
|
|
12
15
|
resetOpenCodeDbPathStateForTesting,
|
|
13
16
|
resolveOpenCodeDbPath,
|
|
17
|
+
sourceOpenCodeDatabaseFilename,
|
|
14
18
|
} from "./opencode-db-path";
|
|
19
|
+
import { Database } from "./sqlite";
|
|
15
20
|
|
|
16
21
|
const ORIGINAL_ENV = {
|
|
17
22
|
XDG_DATA_HOME: process.env.XDG_DATA_HOME,
|
|
@@ -173,6 +178,175 @@ describe("resolveOpenCodeDbPath", () => {
|
|
|
173
178
|
});
|
|
174
179
|
});
|
|
175
180
|
|
|
181
|
+
it("uses the verbatim v2 channel filename table without changing v1 defaults", () => {
|
|
182
|
+
const { dataHome, openCodeDir } = useDataHome();
|
|
183
|
+
for (const channel of ["latest", "dev", "beta", "next", "prod"]) {
|
|
184
|
+
expect(sourceOpenCodeDatabaseFilename("v2", channel, {})).toBe("opencode.db");
|
|
185
|
+
}
|
|
186
|
+
expect(sourceOpenCodeDatabaseFilename("v2", "a/b c!._-", {})).toBe("opencode-abc._-.db");
|
|
187
|
+
expect(
|
|
188
|
+
resolveOpenCodeDbPath("v2", {
|
|
189
|
+
dataHome,
|
|
190
|
+
channel: "local",
|
|
191
|
+
env: { OPENCODE_DB: "opencode2.db" },
|
|
192
|
+
}),
|
|
193
|
+
).toEqual({
|
|
194
|
+
path: join(openCodeDir, "opencode2.db"),
|
|
195
|
+
source: "OPENCODE_DB",
|
|
196
|
+
channel: null,
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it("detects store generations and refuses a mismatched schema before reading", () => {
|
|
201
|
+
const { openCodeDir } = useDataHome();
|
|
202
|
+
const v1Path = join(openCodeDir, "v1.db");
|
|
203
|
+
const v2Path = join(openCodeDir, "v2.db");
|
|
204
|
+
const v1 = new Database(v1Path);
|
|
205
|
+
const v2 = new Database(v2Path);
|
|
206
|
+
try {
|
|
207
|
+
v1.exec("CREATE TABLE message(id TEXT); CREATE TABLE part(id TEXT)");
|
|
208
|
+
v2.exec("CREATE TABLE session_message(id TEXT)");
|
|
209
|
+
expect(detectOpenCodeStoreGeneration(v1)).toBe("v1");
|
|
210
|
+
expect(detectOpenCodeStoreGeneration(v2)).toBe("v2");
|
|
211
|
+
expect(() => assertOpenCodeStoreGeneration(v2, "v1", v2Path)).toThrow(
|
|
212
|
+
"expected v1, found v2",
|
|
213
|
+
);
|
|
214
|
+
expect(() => assertOpenCodeStoreGeneration(v1, "v2", v1Path)).toThrow(
|
|
215
|
+
"expected v2, found v1",
|
|
216
|
+
);
|
|
217
|
+
} finally {
|
|
218
|
+
v1.close();
|
|
219
|
+
v2.close();
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
it("reads a live OpenCode 1.18.x store as v1 even though it ships session_message", () => {
|
|
224
|
+
const { openCodeDir } = useDataHome();
|
|
225
|
+
const livePath = join(openCodeDir, "live-v1.db");
|
|
226
|
+
const live = new Database(livePath);
|
|
227
|
+
try {
|
|
228
|
+
// Captured from a running OpenCode 1.18.30 store. session_message exists in v1,
|
|
229
|
+
// so a detector keyed on its presence calls a v1 host v2 and every v1 reader
|
|
230
|
+
// (historian chunk, marker discovery, message index, tool-owner backfill) then
|
|
231
|
+
// refuses. Keep this table list as observed, not as remembered.
|
|
232
|
+
for (const table of [
|
|
233
|
+
"account",
|
|
234
|
+
"event",
|
|
235
|
+
"message",
|
|
236
|
+
"part",
|
|
237
|
+
"permission",
|
|
238
|
+
"project",
|
|
239
|
+
"session",
|
|
240
|
+
"session_message",
|
|
241
|
+
"session_run_lease",
|
|
242
|
+
"todo",
|
|
243
|
+
"workspace",
|
|
244
|
+
]) {
|
|
245
|
+
live.exec(`CREATE TABLE ${table}(id TEXT)`);
|
|
246
|
+
}
|
|
247
|
+
expect(detectOpenCodeStoreGeneration(live)).toBe("v1");
|
|
248
|
+
expect(() => assertOpenCodeStoreGeneration(live, "v1", livePath)).not.toThrow();
|
|
249
|
+
expect(() => assertOpenCodeStoreGeneration(live, "v2", livePath)).toThrow(
|
|
250
|
+
"expected v2, found v1",
|
|
251
|
+
);
|
|
252
|
+
} finally {
|
|
253
|
+
live.close();
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
it("reports v1 message capability on a migrated store accepted by both readers", () => {
|
|
258
|
+
const { openCodeDir } = useDataHome();
|
|
259
|
+
const migratedPath = join(openCodeDir, "migrated-v2.db");
|
|
260
|
+
const migrated = new Database(migratedPath);
|
|
261
|
+
try {
|
|
262
|
+
// Captured from an OpenCode 2.0.7 store that the v2 host migrated from a 1.18.x
|
|
263
|
+
// store: it keeps the v1 `message`/`part` tables beside its own schema, so it
|
|
264
|
+
// carries BOTH generations. `session_v2` is written only by an OpenCode 2 host
|
|
265
|
+
// (the 1.18.31 binary never references it). Keep this table list as observed.
|
|
266
|
+
for (const table of [
|
|
267
|
+
"account",
|
|
268
|
+
"account_state",
|
|
269
|
+
"control_account",
|
|
270
|
+
"credential",
|
|
271
|
+
"event",
|
|
272
|
+
"event_sequence",
|
|
273
|
+
"instruction_blob",
|
|
274
|
+
"instruction_entry",
|
|
275
|
+
"instruction_state",
|
|
276
|
+
"kv",
|
|
277
|
+
"message",
|
|
278
|
+
"migration",
|
|
279
|
+
"part",
|
|
280
|
+
"permission",
|
|
281
|
+
"project",
|
|
282
|
+
"project_directory",
|
|
283
|
+
"session",
|
|
284
|
+
"session_inbox",
|
|
285
|
+
"session_message",
|
|
286
|
+
"session_pending",
|
|
287
|
+
"session_share",
|
|
288
|
+
"session_v2",
|
|
289
|
+
"todo",
|
|
290
|
+
"workspace",
|
|
291
|
+
"worktree",
|
|
292
|
+
]) {
|
|
293
|
+
migrated.exec(`CREATE TABLE ${table}(id TEXT)`);
|
|
294
|
+
}
|
|
295
|
+
expect(hasV1MessageTables(migrated)).toBe(true);
|
|
296
|
+
expect(() => assertOpenCodeStoreGeneration(migrated, "v2", migratedPath)).not.toThrow();
|
|
297
|
+
expect(() => assertOpenCodeStoreGeneration(migrated, "v1", migratedPath)).not.toThrow();
|
|
298
|
+
} finally {
|
|
299
|
+
migrated.close();
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
it("reads a fresh OpenCode 2 store as v2 only", () => {
|
|
304
|
+
const { openCodeDir } = useDataHome();
|
|
305
|
+
const freshV2Path = join(openCodeDir, "fresh-v2.db");
|
|
306
|
+
const freshV2 = new Database(freshV2Path);
|
|
307
|
+
try {
|
|
308
|
+
// Captured from a new OpenCode 2.0.7 data directory: no v1 message tables.
|
|
309
|
+
for (const table of [
|
|
310
|
+
"account",
|
|
311
|
+
"event",
|
|
312
|
+
"migration",
|
|
313
|
+
"permission",
|
|
314
|
+
"project",
|
|
315
|
+
"session_inbox",
|
|
316
|
+
"session_message",
|
|
317
|
+
"session_pending",
|
|
318
|
+
"session_v2",
|
|
319
|
+
"workspace",
|
|
320
|
+
]) {
|
|
321
|
+
freshV2.exec(`CREATE TABLE ${table}(id TEXT)`);
|
|
322
|
+
}
|
|
323
|
+
expect(hasV1MessageTables(freshV2)).toBe(false);
|
|
324
|
+
expect(detectOpenCodeStoreGeneration(freshV2)).toBe("v2");
|
|
325
|
+
expect(() => assertOpenCodeStoreGeneration(freshV2, "v2", freshV2Path)).not.toThrow();
|
|
326
|
+
expect(() => assertOpenCodeStoreGeneration(freshV2, "v1", freshV2Path)).toThrow(
|
|
327
|
+
"expected v1, found v2",
|
|
328
|
+
);
|
|
329
|
+
} finally {
|
|
330
|
+
freshV2.close();
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
it("treats a store with no schema yet as empty rather than as a conflicting host", () => {
|
|
335
|
+
const { openCodeDir } = useDataHome();
|
|
336
|
+
const freshPath = join(openCodeDir, "fresh.db");
|
|
337
|
+
const fresh = new Database(freshPath);
|
|
338
|
+
try {
|
|
339
|
+
// A host that has not written its first row looks like this. Readers have always
|
|
340
|
+
// seen it as empty; refusing here throws inside the historian, marker and index
|
|
341
|
+
// readers on every fresh data directory.
|
|
342
|
+
expect(detectOpenCodeStoreGeneration(fresh)).toBe("unknown");
|
|
343
|
+
expect(() => assertOpenCodeStoreGeneration(fresh, "v1", freshPath)).not.toThrow();
|
|
344
|
+
expect(() => assertOpenCodeStoreGeneration(fresh, "v2", freshPath)).not.toThrow();
|
|
345
|
+
} finally {
|
|
346
|
+
fresh.close();
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
|
|
176
350
|
it("formats the missing banner, status, and doctor lines by value", () => {
|
|
177
351
|
const { openCodeDir } = useDataHome();
|
|
178
352
|
const lookedFor = [
|
|
@@ -3,6 +3,40 @@ import { homedir } from "node:os";
|
|
|
3
3
|
import { isAbsolute, join } from "node:path";
|
|
4
4
|
|
|
5
5
|
export type OpenCodeDbPathSource = "OPENCODE_DB" | "channel" | "default" | "discovered";
|
|
6
|
+
export type OpenCodeHostGeneration = "v1" | "v2";
|
|
7
|
+
export type OpenCodeStoreGeneration = OpenCodeHostGeneration | "unknown";
|
|
8
|
+
|
|
9
|
+
export interface ResolveOpenCodeDbPathOptions {
|
|
10
|
+
dataHome?: string;
|
|
11
|
+
channel?: string;
|
|
12
|
+
env?: NodeJS.ProcessEnv;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Decide the host generation from the version the executable reports, never
|
|
17
|
+
* from its name (the public installer places OpenCode 2 at
|
|
18
|
+
* `~/.opencode/bin/opencode` with a tiny `opencode2` shim beside it). The raw
|
|
19
|
+
* `--version` stdout carries a program-name prefix ("opencode v2.0.12"), so the
|
|
20
|
+
* major is the first digit run, not `parseInt` of the whole string.
|
|
21
|
+
*
|
|
22
|
+
* OpenCode 2's pre-GA betas were published under the old scope as
|
|
23
|
+
* `@opencode-ai/*@0.0.0-beta-<n>` (verified: `0.0.0-beta-19234` ships the V2
|
|
24
|
+
* `host`/`promise`/`effect` contract and the `compaction` hook); at GA the line
|
|
25
|
+
* moved to `@opencode/*@2.0.x`. A major of 0 therefore does not mean 1.x: the
|
|
26
|
+
* beta and dev pre-release shapes are OpenCode 2.
|
|
27
|
+
*/
|
|
28
|
+
export function openCodeHostGenerationFromVersion(
|
|
29
|
+
version: string | null | undefined,
|
|
30
|
+
): OpenCodeHostGeneration {
|
|
31
|
+
const text = version ?? "";
|
|
32
|
+
if (/(?:^|\s|v)0\.0\.0-(?:beta|dev)-/.test(text)) return "v2";
|
|
33
|
+
const major = Number.parseInt(text.match(/\d+/)?.[0] ?? "", 10);
|
|
34
|
+
return Number.isFinite(major) && major >= 2 ? "v2" : "v1";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface OpenCodeStoreSchemaDatabase {
|
|
38
|
+
prepare(sql: string): { all(...params: unknown[]): unknown[] };
|
|
39
|
+
}
|
|
6
40
|
|
|
7
41
|
export interface OpenCodeDbPathResolution {
|
|
8
42
|
path: string;
|
|
@@ -24,16 +58,22 @@ let cachedResolution: CachedResolution | null = null;
|
|
|
24
58
|
let lastReadFailure: OpenCodeDbReadFailure | null = null;
|
|
25
59
|
const claimedDiagnostics = new Set<string>();
|
|
26
60
|
|
|
27
|
-
function openCodeDataDir(): string {
|
|
28
|
-
return join(
|
|
61
|
+
function openCodeDataDir(env: NodeJS.ProcessEnv = process.env, dataHome?: string): string {
|
|
62
|
+
return join(dataHome ?? env.XDG_DATA_HOME ?? join(homedir(), ".local", "share"), "opencode");
|
|
29
63
|
}
|
|
30
64
|
|
|
31
|
-
function environmentKey(
|
|
65
|
+
function environmentKey(
|
|
66
|
+
dataDir: string,
|
|
67
|
+
hostGeneration: OpenCodeHostGeneration,
|
|
68
|
+
channel: string | undefined,
|
|
69
|
+
env: NodeJS.ProcessEnv,
|
|
70
|
+
): string {
|
|
32
71
|
return [
|
|
72
|
+
hostGeneration,
|
|
33
73
|
dataDir,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
74
|
+
env.OPENCODE_DB ?? "",
|
|
75
|
+
env.OPENCODE_DISABLE_CHANNEL_DB ?? "",
|
|
76
|
+
channel ?? env.OPENCODE_CHANNEL ?? "",
|
|
37
77
|
].join("\0");
|
|
38
78
|
}
|
|
39
79
|
|
|
@@ -81,8 +121,11 @@ function discoverOpenCodeDb(dataDir: string): OpenCodeDbPathResolution {
|
|
|
81
121
|
return { path: existing.path, source: "discovered", channel };
|
|
82
122
|
}
|
|
83
123
|
|
|
84
|
-
function
|
|
85
|
-
|
|
124
|
+
function resolveV1Fresh(
|
|
125
|
+
dataDir: string,
|
|
126
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
127
|
+
): OpenCodeDbPathResolution {
|
|
128
|
+
const explicit = env.OPENCODE_DB;
|
|
86
129
|
if (explicit !== undefined && explicit.length > 0) {
|
|
87
130
|
if (explicit === ":memory:") {
|
|
88
131
|
return { path: explicit, source: "OPENCODE_DB", channel: null };
|
|
@@ -94,12 +137,12 @@ function resolveFresh(dataDir: string): OpenCodeDbPathResolution {
|
|
|
94
137
|
};
|
|
95
138
|
}
|
|
96
139
|
|
|
97
|
-
const disableChannelDb =
|
|
140
|
+
const disableChannelDb = env.OPENCODE_DISABLE_CHANNEL_DB;
|
|
98
141
|
if (disableChannelDb === "1" || disableChannelDb === "true") {
|
|
99
142
|
return { path: join(dataDir, "opencode.db"), source: "default", channel: null };
|
|
100
143
|
}
|
|
101
144
|
|
|
102
|
-
const channel =
|
|
145
|
+
const channel = env.OPENCODE_CHANNEL;
|
|
103
146
|
if (channel !== undefined && channel.length > 0) {
|
|
104
147
|
return { path: channelPath(dataDir, channel), source: "channel", channel };
|
|
105
148
|
}
|
|
@@ -107,10 +150,59 @@ function resolveFresh(dataDir: string): OpenCodeDbPathResolution {
|
|
|
107
150
|
return discoverOpenCodeDb(dataDir);
|
|
108
151
|
}
|
|
109
152
|
|
|
110
|
-
/**
|
|
111
|
-
export function
|
|
112
|
-
|
|
113
|
-
|
|
153
|
+
/** Match OpenCode 2's filename table and strip path separators from custom channels. */
|
|
154
|
+
export function sourceOpenCodeDatabaseFilename(
|
|
155
|
+
hostGeneration: OpenCodeHostGeneration,
|
|
156
|
+
channel: string,
|
|
157
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
158
|
+
): string {
|
|
159
|
+
if (hostGeneration === "v1") {
|
|
160
|
+
const explicit = env.OPENCODE_DB;
|
|
161
|
+
if (explicit !== undefined && explicit.length > 0) return explicit;
|
|
162
|
+
if (env.OPENCODE_DISABLE_CHANNEL_DB === "1" || env.OPENCODE_DISABLE_CHANNEL_DB === "true") {
|
|
163
|
+
return "opencode.db";
|
|
164
|
+
}
|
|
165
|
+
return ["latest", "beta", "prod"].includes(channel)
|
|
166
|
+
? "opencode.db"
|
|
167
|
+
: `opencode-${channel}.db`;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return (
|
|
171
|
+
env.OPENCODE_DB ??
|
|
172
|
+
(["latest", "dev", "beta", "next", "prod"].includes(channel) ||
|
|
173
|
+
env.OPENCODE_DISABLE_CHANNEL_DB === "1" ||
|
|
174
|
+
env.OPENCODE_DISABLE_CHANNEL_DB === "true"
|
|
175
|
+
? "opencode.db"
|
|
176
|
+
: `opencode-${channel.replace(/[^a-zA-Z0-9._-]/g, "")}.db`)
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function resolveV2Fresh(
|
|
181
|
+
dataDir: string,
|
|
182
|
+
channel: string,
|
|
183
|
+
env: NodeJS.ProcessEnv,
|
|
184
|
+
): OpenCodeDbPathResolution {
|
|
185
|
+
const filename = sourceOpenCodeDatabaseFilename("v2", channel, env);
|
|
186
|
+
const explicit = env.OPENCODE_DB !== undefined;
|
|
187
|
+
return {
|
|
188
|
+
path: filename === ":memory:" ? filename : join(dataDir, filename),
|
|
189
|
+
source: explicit ? "OPENCODE_DB" : env.OPENCODE_CHANNEL ? "channel" : "default",
|
|
190
|
+
channel: explicit ? null : channel,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Resolve the store for one host generation. The default is the historical v1
|
|
196
|
+
* resolver, including candidate discovery and all existing diagnostic text.
|
|
197
|
+
*/
|
|
198
|
+
export function resolveOpenCodeDbPath(
|
|
199
|
+
hostGeneration: OpenCodeHostGeneration = "v1",
|
|
200
|
+
options: ResolveOpenCodeDbPathOptions = {},
|
|
201
|
+
): OpenCodeDbPathResolution {
|
|
202
|
+
const env = options.env ?? process.env;
|
|
203
|
+
const dataDir = openCodeDataDir(env, options.dataHome);
|
|
204
|
+
const channel = options.channel ?? env.OPENCODE_CHANNEL;
|
|
205
|
+
const key = environmentKey(dataDir, hostGeneration, channel, env);
|
|
114
206
|
if (
|
|
115
207
|
cachedResolution?.key === key &&
|
|
116
208
|
(!cachedResolution.existed || existsSync(cachedResolution.resolution.path))
|
|
@@ -119,7 +211,10 @@ export function resolveOpenCodeDbPath(): OpenCodeDbPathResolution {
|
|
|
119
211
|
// An absent result is re-probed so a DB created after plugin boot is detected.
|
|
120
212
|
}
|
|
121
213
|
|
|
122
|
-
const resolution =
|
|
214
|
+
const resolution =
|
|
215
|
+
hostGeneration === "v2"
|
|
216
|
+
? resolveV2Fresh(dataDir, channel ?? "latest", env)
|
|
217
|
+
: resolveV1Fresh(dataDir, env);
|
|
123
218
|
cachedResolution = {
|
|
124
219
|
key,
|
|
125
220
|
resolution,
|
|
@@ -128,6 +223,89 @@ export function resolveOpenCodeDbPath(): OpenCodeDbPathResolution {
|
|
|
128
223
|
return resolution;
|
|
129
224
|
}
|
|
130
225
|
|
|
226
|
+
function schemaTableNames(
|
|
227
|
+
db: OpenCodeStoreSchemaDatabase,
|
|
228
|
+
schema: "main" | "oc_backfill" = "main",
|
|
229
|
+
): Set<string> {
|
|
230
|
+
const rows = db
|
|
231
|
+
.prepare(
|
|
232
|
+
`SELECT name FROM ${schema}.sqlite_master WHERE type = 'table' AND name IN ('message', 'part', 'session', 'project', 'session_message', 'session_v2')`,
|
|
233
|
+
)
|
|
234
|
+
.all() as Array<{ name?: unknown }>;
|
|
235
|
+
return new Set(rows.flatMap((row) => (typeof row.name === "string" ? [row.name] : [])));
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/** Whether the schema has the legacy message tables required by v1-only readers. */
|
|
239
|
+
export function hasV1MessageTables(
|
|
240
|
+
db: OpenCodeStoreSchemaDatabase,
|
|
241
|
+
schema: "main" | "oc_backfill" = "main",
|
|
242
|
+
): boolean {
|
|
243
|
+
const tables = schemaTableNames(db, schema);
|
|
244
|
+
return tables.has("message") && tables.has("part");
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Detect the persisted host schema.
|
|
249
|
+
*
|
|
250
|
+
* `session_message` does NOT identify v2: OpenCode 1.18.x ships that table beside `message`
|
|
251
|
+
* and `part` (verified against a live 1.18.30 store, pinned in this module's tests). Only the
|
|
252
|
+
* ABSENCE of the v1 message tables identifies a v2 store, so a v1 host is never mistaken for
|
|
253
|
+
* a v2 one. A store carrying neither is a host that has not written its schema yet.
|
|
254
|
+
*/
|
|
255
|
+
export function detectOpenCodeStoreGeneration(
|
|
256
|
+
db: OpenCodeStoreSchemaDatabase,
|
|
257
|
+
schema: "main" | "oc_backfill" = "main",
|
|
258
|
+
): OpenCodeStoreGeneration {
|
|
259
|
+
const tables = schemaTableNames(db, schema);
|
|
260
|
+
const hasV1Messages = tables.has("message") && tables.has("part");
|
|
261
|
+
if (hasV1Messages) return "v1";
|
|
262
|
+
if (tables.has("session_message")) return "v2";
|
|
263
|
+
if (tables.has("session") || tables.has("project")) return "v1";
|
|
264
|
+
return "unknown";
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* A store the OpenCode 2 host migrated from a v1 store keeps the v1 `message`/`part` tables
|
|
269
|
+
* beside its own schema, so it carries BOTH generations and `detectOpenCodeStoreGeneration`
|
|
270
|
+
* (which must keep calling a 1.18.x store v1) reports v1. `session_v2` is written only by an
|
|
271
|
+
* OpenCode 2 host (1.18.x never creates it), so a store with it and `session_message` is
|
|
272
|
+
* readable by v2 readers regardless of any v1 tables it also kept.
|
|
273
|
+
*/
|
|
274
|
+
function hasMigratedV2Schema(tables: Set<string>): boolean {
|
|
275
|
+
return tables.has("session_message") && tables.has("session_v2");
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/** A native OpenCode 2 store, or a v1 store an OpenCode 2 host has migrated. */
|
|
279
|
+
function isOpenCodeV2Store(
|
|
280
|
+
db: OpenCodeStoreSchemaDatabase,
|
|
281
|
+
schema: "main" | "oc_backfill" = "main",
|
|
282
|
+
): boolean {
|
|
283
|
+
return (
|
|
284
|
+
detectOpenCodeStoreGeneration(db, schema) === "v2" ||
|
|
285
|
+
hasMigratedV2Schema(schemaTableNames(db, schema))
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/** Refuse before a generation-specific query can read the other host's schema. */
|
|
290
|
+
export function assertOpenCodeStoreGeneration(
|
|
291
|
+
db: OpenCodeStoreSchemaDatabase,
|
|
292
|
+
expected: OpenCodeHostGeneration,
|
|
293
|
+
path: string,
|
|
294
|
+
schema: "main" | "oc_backfill" = "main",
|
|
295
|
+
): void {
|
|
296
|
+
const actual = detectOpenCodeStoreGeneration(db, schema);
|
|
297
|
+
if (actual === expected) return;
|
|
298
|
+
if (expected === "v2" && isOpenCodeV2Store(db, schema)) return;
|
|
299
|
+
// A store with none of these tables has no schema YET — a host that has not written its
|
|
300
|
+
// first row, or a fresh data directory. That is "nothing to read", not a conflicting host,
|
|
301
|
+
// and readers have always treated it as empty. Refusing here made every reader throw before
|
|
302
|
+
// OpenCode created its tables, which is how this guard took down 15 host e2e tests.
|
|
303
|
+
if (actual === "unknown") return;
|
|
304
|
+
throw new Error(
|
|
305
|
+
`OpenCode store generation mismatch at ${path}: expected ${expected}, found ${actual}; refusing generation-specific database access`,
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
|
|
131
309
|
export function openCodeDbPathExists(
|
|
132
310
|
resolution: OpenCodeDbPathResolution = resolveOpenCodeDbPath(),
|
|
133
311
|
): boolean {
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { describe, expect, it } from "bun:test";
|
|
2
|
+
import { openCodeHostGenerationFromVersion } from "./opencode-db-path";
|
|
3
|
+
|
|
4
|
+
// The generation is decided from the version the executable reports, never
|
|
5
|
+
// from its name: the public installer puts OpenCode 2 at ~/.opencode/bin/opencode
|
|
6
|
+
// with a tiny `opencode2` shim beside it, so the name says nothing. The raw
|
|
7
|
+
// `--version` stdout carries a program-name prefix ("opencode v2.0.12"); a
|
|
8
|
+
// parser that feeds that to Number.parseInt reads NaN and demotes every
|
|
9
|
+
// standalone 2.x install to 1.x (AFT hit this on a clean VM, 2026-09-21).
|
|
10
|
+
// OpenCode 2's pre-GA betas were `@opencode-ai/*@0.0.0-beta-<n>` — the V2 line
|
|
11
|
+
// wearing the old scope's version string — so a major of 0 is v2, not v1.
|
|
12
|
+
describe("OpenCode host generation from --version output", () => {
|
|
13
|
+
it.each([
|
|
14
|
+
["opencode v2.0.12", "v2"],
|
|
15
|
+
["v2.0.12", "v2"],
|
|
16
|
+
["2.0.12", "v2"],
|
|
17
|
+
["opencode v2.0.12\n", "v2"],
|
|
18
|
+
["opencode 1.18.31", "v1"],
|
|
19
|
+
["1.18.31", "v1"],
|
|
20
|
+
["0.0.0-beta-19234", "v2"],
|
|
21
|
+
["opencode v0.0.0-beta-19234", "v2"],
|
|
22
|
+
["0.0.0-dev-42", "v2"],
|
|
23
|
+
["0.9.3", "v1"],
|
|
24
|
+
[null, "v1"],
|
|
25
|
+
["", "v1"],
|
|
26
|
+
])("%p → %s", (raw, expected) => {
|
|
27
|
+
expect(openCodeHostGenerationFromVersion(raw)).toBe(expected);
|
|
28
|
+
});
|
|
29
|
+
});
|