@wolfx/opencode-magic-context 0.21.8-patch.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/dist/agents/dreamer.d.ts +2 -0
- package/dist/agents/dreamer.d.ts.map +1 -0
- package/dist/agents/historian.d.ts +3 -0
- package/dist/agents/historian.d.ts.map +1 -0
- package/dist/agents/magic-context-prompt.d.ts +3 -0
- package/dist/agents/magic-context-prompt.d.ts.map +1 -0
- package/dist/agents/permissions.d.ts +142 -0
- package/dist/agents/permissions.d.ts.map +1 -0
- package/dist/agents/sidekick.d.ts +2 -0
- package/dist/agents/sidekick.d.ts.map +1 -0
- package/dist/config/agent-disable.d.ts +26 -0
- package/dist/config/agent-disable.d.ts.map +1 -0
- package/dist/config/index.d.ts +33 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/schema/agent-overrides.d.ts +55 -0
- package/dist/config/schema/agent-overrides.d.ts.map +1 -0
- package/dist/config/schema/magic-context.d.ts +841 -0
- package/dist/config/schema/magic-context.d.ts.map +1 -0
- package/dist/config/schema.d.ts +3 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/variable.d.ts +48 -0
- package/dist/config/variable.d.ts.map +1 -0
- package/dist/features/builtin-commands/commands.d.ts +3 -0
- package/dist/features/builtin-commands/commands.d.ts.map +1 -0
- package/dist/features/builtin-commands/types.d.ts +5 -0
- package/dist/features/builtin-commands/types.d.ts.map +1 -0
- package/dist/features/magic-context/compaction-marker.d.ts +91 -0
- package/dist/features/magic-context/compaction-marker.d.ts.map +1 -0
- package/dist/features/magic-context/compaction.d.ts +7 -0
- package/dist/features/magic-context/compaction.d.ts.map +1 -0
- package/dist/features/magic-context/compartment-lease.d.ts +14 -0
- package/dist/features/magic-context/compartment-lease.d.ts.map +1 -0
- package/dist/features/magic-context/compartment-storage.d.ts +130 -0
- package/dist/features/magic-context/compartment-storage.d.ts.map +1 -0
- package/dist/features/magic-context/compression-depth-storage.d.ts +14 -0
- package/dist/features/magic-context/compression-depth-storage.d.ts.map +1 -0
- package/dist/features/magic-context/defaults.d.ts +2 -0
- package/dist/features/magic-context/defaults.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/index.d.ts +8 -0
- package/dist/features/magic-context/dreamer/index.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/lease.d.ts +8 -0
- package/dist/features/magic-context/dreamer/lease.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/queue.d.ts +44 -0
- package/dist/features/magic-context/dreamer/queue.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/runner.d.ts +81 -0
- package/dist/features/magic-context/dreamer/runner.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/scheduler.d.ts +33 -0
- package/dist/features/magic-context/dreamer/scheduler.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts +41 -0
- package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/storage-dream-state.d.ts +5 -0
- package/dist/features/magic-context/dreamer/storage-dream-state.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/task-prompts.d.ts +26 -0
- package/dist/features/magic-context/dreamer/task-prompts.d.ts.map +1 -0
- package/dist/features/magic-context/git-commits/git-log-reader.d.ts +57 -0
- package/dist/features/magic-context/git-commits/git-log-reader.d.ts.map +1 -0
- package/dist/features/magic-context/git-commits/index.d.ts +7 -0
- package/dist/features/magic-context/git-commits/index.d.ts.map +1 -0
- package/dist/features/magic-context/git-commits/indexer.d.ts +43 -0
- package/dist/features/magic-context/git-commits/indexer.d.ts.map +1 -0
- package/dist/features/magic-context/git-commits/search-git-commits.d.ts +32 -0
- package/dist/features/magic-context/git-commits/search-git-commits.d.ts.map +1 -0
- package/dist/features/magic-context/git-commits/storage-git-commit-embeddings.d.ts +19 -0
- package/dist/features/magic-context/git-commits/storage-git-commit-embeddings.d.ts.map +1 -0
- package/dist/features/magic-context/git-commits/storage-git-commits.d.ts +47 -0
- package/dist/features/magic-context/git-commits/storage-git-commits.d.ts.map +1 -0
- package/dist/features/magic-context/index.d.ts +12 -0
- package/dist/features/magic-context/index.d.ts.map +1 -0
- package/dist/features/magic-context/key-files/aft-availability.d.ts +11 -0
- package/dist/features/magic-context/key-files/aft-availability.d.ts.map +1 -0
- package/dist/features/magic-context/key-files/identify-key-files.d.ts +84 -0
- package/dist/features/magic-context/key-files/identify-key-files.d.ts.map +1 -0
- package/dist/features/magic-context/key-files/project-key-files.d.ts +42 -0
- package/dist/features/magic-context/key-files/project-key-files.d.ts.map +1 -0
- package/dist/features/magic-context/key-files/read-history.d.ts +26 -0
- package/dist/features/magic-context/key-files/read-history.d.ts.map +1 -0
- package/dist/features/magic-context/key-files/read-stats.d.ts +20 -0
- package/dist/features/magic-context/key-files/read-stats.d.ts.map +1 -0
- package/dist/features/magic-context/key-files/storage-key-files.d.ts +25 -0
- package/dist/features/magic-context/key-files/storage-key-files.d.ts.map +1 -0
- package/dist/features/magic-context/memory/constants.d.ts +5 -0
- package/dist/features/magic-context/memory/constants.d.ts.map +1 -0
- package/dist/features/magic-context/memory/cosine-similarity.d.ts +2 -0
- package/dist/features/magic-context/memory/cosine-similarity.d.ts.map +1 -0
- package/dist/features/magic-context/memory/embedding-backfill.d.ts +9 -0
- package/dist/features/magic-context/memory/embedding-backfill.d.ts.map +1 -0
- package/dist/features/magic-context/memory/embedding-cache.d.ts +8 -0
- package/dist/features/magic-context/memory/embedding-cache.d.ts.map +1 -0
- package/dist/features/magic-context/memory/embedding-identity.d.ts +11 -0
- package/dist/features/magic-context/memory/embedding-identity.d.ts.map +1 -0
- package/dist/features/magic-context/memory/embedding-local.d.ts +20 -0
- package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -0
- package/dist/features/magic-context/memory/embedding-openai.d.ts +44 -0
- package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -0
- package/dist/features/magic-context/memory/embedding-probe.d.ts +69 -0
- package/dist/features/magic-context/memory/embedding-probe.d.ts.map +1 -0
- package/dist/features/magic-context/memory/embedding-provider.d.ts +15 -0
- package/dist/features/magic-context/memory/embedding-provider.d.ts.map +1 -0
- package/dist/features/magic-context/memory/embedding.d.ts +39 -0
- package/dist/features/magic-context/memory/embedding.d.ts.map +1 -0
- package/dist/features/magic-context/memory/index.d.ts +12 -0
- package/dist/features/magic-context/memory/index.d.ts.map +1 -0
- package/dist/features/magic-context/memory/normalize-hash.d.ts +3 -0
- package/dist/features/magic-context/memory/normalize-hash.d.ts.map +1 -0
- package/dist/features/magic-context/memory/project-identity.d.ts +23 -0
- package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -0
- package/dist/features/magic-context/memory/promotion.d.ts +13 -0
- package/dist/features/magic-context/memory/promotion.d.ts.map +1 -0
- package/dist/features/magic-context/memory/storage-memory-embeddings.d.ts +8 -0
- package/dist/features/magic-context/memory/storage-memory-embeddings.d.ts.map +1 -0
- package/dist/features/magic-context/memory/storage-memory-fts.d.ts +12 -0
- package/dist/features/magic-context/memory/storage-memory-fts.d.ts.map +1 -0
- package/dist/features/magic-context/memory/storage-memory.d.ts +31 -0
- package/dist/features/magic-context/memory/storage-memory.d.ts.map +1 -0
- package/dist/features/magic-context/memory/types.d.ts +37 -0
- package/dist/features/magic-context/memory/types.d.ts.map +1 -0
- package/dist/features/magic-context/message-index-async.d.ts +12 -0
- package/dist/features/magic-context/message-index-async.d.ts.map +1 -0
- package/dist/features/magic-context/message-index.d.ts +10 -0
- package/dist/features/magic-context/message-index.d.ts.map +1 -0
- package/dist/features/magic-context/migrations.d.ts +33 -0
- package/dist/features/magic-context/migrations.d.ts.map +1 -0
- package/dist/features/magic-context/mock-database.d.ts +3 -0
- package/dist/features/magic-context/mock-database.d.ts.map +1 -0
- package/dist/features/magic-context/overflow-detection.d.ts +51 -0
- package/dist/features/magic-context/overflow-detection.d.ts.map +1 -0
- package/dist/features/magic-context/plugin-messages.d.ts +75 -0
- package/dist/features/magic-context/plugin-messages.d.ts.map +1 -0
- package/dist/features/magic-context/project-embedding-registry.d.ts +44 -0
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -0
- package/dist/features/magic-context/range-parser.d.ts +13 -0
- package/dist/features/magic-context/range-parser.d.ts.map +1 -0
- package/dist/features/magic-context/resolve-subagent-fallback.d.ts +40 -0
- package/dist/features/magic-context/resolve-subagent-fallback.d.ts.map +1 -0
- package/dist/features/magic-context/scheduler.d.ts +18 -0
- package/dist/features/magic-context/scheduler.d.ts.map +1 -0
- package/dist/features/magic-context/search.d.ts +69 -0
- package/dist/features/magic-context/search.d.ts.map +1 -0
- package/dist/features/magic-context/sidekick/agent.d.ts +13 -0
- package/dist/features/magic-context/sidekick/agent.d.ts.map +1 -0
- package/dist/features/magic-context/sidekick/core.d.ts +38 -0
- package/dist/features/magic-context/sidekick/core.d.ts.map +1 -0
- package/dist/features/magic-context/sidekick/index.d.ts +3 -0
- package/dist/features/magic-context/sidekick/index.d.ts.map +1 -0
- package/dist/features/magic-context/storage-db.d.ts +48 -0
- package/dist/features/magic-context/storage-db.d.ts.map +1 -0
- package/dist/features/magic-context/storage-meta-persisted.d.ts +246 -0
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -0
- package/dist/features/magic-context/storage-meta-session.d.ts +6 -0
- package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -0
- package/dist/features/magic-context/storage-meta-shared.d.ts +31 -0
- package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -0
- package/dist/features/magic-context/storage-meta.d.ts +3 -0
- package/dist/features/magic-context/storage-meta.d.ts.map +1 -0
- package/dist/features/magic-context/storage-notes.d.ts +62 -0
- package/dist/features/magic-context/storage-notes.d.ts.map +1 -0
- package/dist/features/magic-context/storage-ops.d.ts +7 -0
- package/dist/features/magic-context/storage-ops.d.ts.map +1 -0
- package/dist/features/magic-context/storage-source.d.ts +5 -0
- package/dist/features/magic-context/storage-source.d.ts.map +1 -0
- package/dist/features/magic-context/storage-subagent-invocations.d.ts +52 -0
- package/dist/features/magic-context/storage-subagent-invocations.d.ts.map +1 -0
- package/dist/features/magic-context/storage-tags.d.ts +206 -0
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -0
- package/dist/features/magic-context/storage.d.ts +11 -0
- package/dist/features/magic-context/storage.d.ts.map +1 -0
- package/dist/features/magic-context/subagent-token-capture.d.ts +33 -0
- package/dist/features/magic-context/subagent-token-capture.d.ts.map +1 -0
- package/dist/features/magic-context/tagger.d.ts +64 -0
- package/dist/features/magic-context/tagger.d.ts.map +1 -0
- package/dist/features/magic-context/tool-definition-tokens.d.ts +79 -0
- package/dist/features/magic-context/tool-definition-tokens.d.ts.map +1 -0
- package/dist/features/magic-context/tool-owner-backfill.d.ts +90 -0
- package/dist/features/magic-context/tool-owner-backfill.d.ts.map +1 -0
- package/dist/features/magic-context/types.d.ts +72 -0
- package/dist/features/magic-context/types.d.ts.map +1 -0
- package/dist/features/magic-context/user-memory/review-user-memories.d.ts +22 -0
- package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -0
- package/dist/features/magic-context/user-memory/storage-user-memory.d.ts +33 -0
- package/dist/features/magic-context/user-memory/storage-user-memory.d.ts.map +1 -0
- package/dist/features/magic-context/work-metrics.d.ts +13 -0
- package/dist/features/magic-context/work-metrics.d.ts.map +1 -0
- package/dist/hooks/auto-update-checker/cache.d.ts +23 -0
- package/dist/hooks/auto-update-checker/cache.d.ts.map +1 -0
- package/dist/hooks/auto-update-checker/checker.d.ts +13 -0
- package/dist/hooks/auto-update-checker/checker.d.ts.map +1 -0
- package/dist/hooks/auto-update-checker/constants.d.ts +10 -0
- package/dist/hooks/auto-update-checker/constants.d.ts.map +1 -0
- package/dist/hooks/auto-update-checker/index.d.ts +40 -0
- package/dist/hooks/auto-update-checker/index.d.ts.map +1 -0
- package/dist/hooks/auto-update-checker/types.d.ts +50 -0
- package/dist/hooks/auto-update-checker/types.d.ts.map +1 -0
- package/dist/hooks/is-anthropic-provider.d.ts +2 -0
- package/dist/hooks/is-anthropic-provider.d.ts.map +1 -0
- package/dist/hooks/magic-context/apply-context-nudge.d.ts +5 -0
- package/dist/hooks/magic-context/apply-context-nudge.d.ts.map +1 -0
- package/dist/hooks/magic-context/apply-operations.d.ts +7 -0
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -0
- package/dist/hooks/magic-context/auto-search-hint.d.ts +34 -0
- package/dist/hooks/magic-context/auto-search-hint.d.ts.map +1 -0
- package/dist/hooks/magic-context/auto-search-runner.d.ts +53 -0
- package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -0
- package/dist/hooks/magic-context/boundary-execution.d.ts +24 -0
- package/dist/hooks/magic-context/boundary-execution.d.ts.map +1 -0
- package/dist/hooks/magic-context/cache-busting-signals.d.ts +10 -0
- package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -0
- package/dist/hooks/magic-context/caveman-cleanup.d.ts +86 -0
- package/dist/hooks/magic-context/caveman-cleanup.d.ts.map +1 -0
- package/dist/hooks/magic-context/caveman.d.ts +35 -0
- package/dist/hooks/magic-context/caveman.d.ts.map +1 -0
- package/dist/hooks/magic-context/command-handler.d.ts +89 -0
- package/dist/hooks/magic-context/command-handler.d.ts.map +1 -0
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts +106 -0
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-parser.d.ts +18 -0
- package/dist/hooks/magic-context/compartment-parser.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-prompt.d.ts +19 -0
- package/dist/hooks/magic-context/compartment-prompt.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-compressor.d.ts +87 -0
- package/dist/hooks/magic-context/compartment-runner-compressor.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts +26 -0
- package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts +42 -0
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts +6 -0
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-mapping.d.ts +33 -0
- package/dist/hooks/magic-context/compartment-runner-mapping.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts +29 -0
- package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts +3 -0
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-state-xml.d.ts +21 -0
- package/dist/hooks/magic-context/compartment-runner-state-xml.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-types.d.ts +102 -0
- package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts +28 -0
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner.d.ts +54 -0
- package/dist/hooks/magic-context/compartment-runner.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-trigger.d.ts +17 -0
- package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -0
- package/dist/hooks/magic-context/derive-budgets.d.ts +57 -0
- package/dist/hooks/magic-context/derive-budgets.d.ts.map +1 -0
- package/dist/hooks/magic-context/drop-stale-reduce-calls.d.ts +4 -0
- package/dist/hooks/magic-context/drop-stale-reduce-calls.d.ts.map +1 -0
- package/dist/hooks/magic-context/event-handler.d.ts +49 -0
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -0
- package/dist/hooks/magic-context/event-payloads.d.ts +62 -0
- package/dist/hooks/magic-context/event-payloads.d.ts.map +1 -0
- package/dist/hooks/magic-context/event-resolvers.d.ts +72 -0
- package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -0
- package/dist/hooks/magic-context/execute-flush.d.ts +3 -0
- package/dist/hooks/magic-context/execute-flush.d.ts.map +1 -0
- package/dist/hooks/magic-context/execute-status.d.ts +12 -0
- package/dist/hooks/magic-context/execute-status.d.ts.map +1 -0
- package/dist/hooks/magic-context/format-bytes.d.ts +2 -0
- package/dist/hooks/magic-context/format-bytes.d.ts.map +1 -0
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts +22 -0
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -0
- package/dist/hooks/magic-context/historian-state-file.d.ts +43 -0
- package/dist/hooks/magic-context/historian-state-file.d.ts.map +1 -0
- package/dist/hooks/magic-context/hook-handlers.d.ts +165 -0
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -0
- package/dist/hooks/magic-context/hook.d.ts +118 -0
- package/dist/hooks/magic-context/hook.d.ts.map +1 -0
- package/dist/hooks/magic-context/image-token-estimate.d.ts +6 -0
- package/dist/hooks/magic-context/image-token-estimate.d.ts.map +1 -0
- package/dist/hooks/magic-context/index.d.ts +3 -0
- package/dist/hooks/magic-context/index.d.ts.map +1 -0
- package/dist/hooks/magic-context/inject-compartments.d.ts +52 -0
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -0
- package/dist/hooks/magic-context/key-files-block.d.ts +27 -0
- package/dist/hooks/magic-context/key-files-block.d.ts.map +1 -0
- package/dist/hooks/magic-context/live-session-state.d.ts +42 -0
- package/dist/hooks/magic-context/live-session-state.d.ts.map +1 -0
- package/dist/hooks/magic-context/note-nudger.d.ts +71 -0
- package/dist/hooks/magic-context/note-nudger.d.ts.map +1 -0
- package/dist/hooks/magic-context/note-visibility.d.ts +43 -0
- package/dist/hooks/magic-context/note-visibility.d.ts.map +1 -0
- package/dist/hooks/magic-context/nudge-bands.d.ts +6 -0
- package/dist/hooks/magic-context/nudge-bands.d.ts.map +1 -0
- package/dist/hooks/magic-context/nudge-injection.d.ts +7 -0
- package/dist/hooks/magic-context/nudge-injection.d.ts.map +1 -0
- package/dist/hooks/magic-context/nudge-placement-store.d.ts +15 -0
- package/dist/hooks/magic-context/nudge-placement-store.d.ts.map +1 -0
- package/dist/hooks/magic-context/nudger.d.ts +21 -0
- package/dist/hooks/magic-context/nudger.d.ts.map +1 -0
- package/dist/hooks/magic-context/read-session-chunk.d.ts +99 -0
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -0
- package/dist/hooks/magic-context/read-session-db.d.ts +21 -0
- package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -0
- package/dist/hooks/magic-context/read-session-formatting.d.ts +35 -0
- package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -0
- package/dist/hooks/magic-context/read-session-raw.d.ts +10 -0
- package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -0
- package/dist/hooks/magic-context/send-session-notification.d.ts +13 -0
- package/dist/hooks/magic-context/send-session-notification.d.ts.map +1 -0
- package/dist/hooks/magic-context/sentinel.d.ts +102 -0
- package/dist/hooks/magic-context/sentinel.d.ts.map +1 -0
- package/dist/hooks/magic-context/strip-content.d.ts +140 -0
- package/dist/hooks/magic-context/strip-content.d.ts.map +1 -0
- package/dist/hooks/magic-context/strip-structural-noise.d.ts +17 -0
- package/dist/hooks/magic-context/strip-structural-noise.d.ts.map +1 -0
- package/dist/hooks/magic-context/system-injection-stripper.d.ts +2 -0
- package/dist/hooks/magic-context/system-injection-stripper.d.ts.map +1 -0
- package/dist/hooks/magic-context/system-prompt-hash.d.ts +85 -0
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -0
- package/dist/hooks/magic-context/tag-content-primitives.d.ts +6 -0
- package/dist/hooks/magic-context/tag-content-primitives.d.ts.map +1 -0
- package/dist/hooks/magic-context/tag-id-fallback.d.ts +9 -0
- package/dist/hooks/magic-context/tag-id-fallback.d.ts.map +1 -0
- package/dist/hooks/magic-context/tag-messages.d.ts +48 -0
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -0
- package/dist/hooks/magic-context/tag-part-guards.d.ts +23 -0
- package/dist/hooks/magic-context/tag-part-guards.d.ts.map +1 -0
- package/dist/hooks/magic-context/temporal-awareness.d.ts +73 -0
- package/dist/hooks/magic-context/temporal-awareness.d.ts.map +1 -0
- package/dist/hooks/magic-context/text-complete.d.ts +8 -0
- package/dist/hooks/magic-context/text-complete.d.ts.map +1 -0
- package/dist/hooks/magic-context/todo-view.d.ts +102 -0
- package/dist/hooks/magic-context/todo-view.d.ts.map +1 -0
- package/dist/hooks/magic-context/tokenizer-calibration.d.ts +85 -0
- package/dist/hooks/magic-context/tokenizer-calibration.d.ts.map +1 -0
- package/dist/hooks/magic-context/tool-drop-target.d.ts +48 -0
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts +66 -0
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-context-state.d.ts +12 -0
- package/dist/hooks/magic-context/transform-context-state.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-message-helpers.d.ts +29 -0
- package/dist/hooks/magic-context/transform-message-helpers.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-operations.d.ts +5 -0
- package/dist/hooks/magic-context/transform-operations.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +100 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-stage-logger.d.ts +2 -0
- package/dist/hooks/magic-context/transform-stage-logger.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform.d.ts +145 -0
- package/dist/hooks/magic-context/transform.d.ts.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +179800 -0
- package/dist/plugin/conflict-warning-hook.d.ts +34 -0
- package/dist/plugin/conflict-warning-hook.d.ts.map +1 -0
- package/dist/plugin/dream-timer.d.ts +44 -0
- package/dist/plugin/dream-timer.d.ts.map +1 -0
- package/dist/plugin/embedding-bootstrap-helpers.d.ts +35 -0
- package/dist/plugin/embedding-bootstrap-helpers.d.ts.map +1 -0
- package/dist/plugin/embedding-bootstrap.d.ts +3 -0
- package/dist/plugin/embedding-bootstrap.d.ts.map +1 -0
- package/dist/plugin/event.d.ts +13 -0
- package/dist/plugin/event.d.ts.map +1 -0
- package/dist/plugin/hooks/create-session-hooks.d.ts +44 -0
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -0
- package/dist/plugin/messages-transform.d.ts +46 -0
- package/dist/plugin/messages-transform.d.ts.map +1 -0
- package/dist/plugin/normalize-tool-arg-schemas.d.ts +7 -0
- package/dist/plugin/normalize-tool-arg-schemas.d.ts.map +1 -0
- package/dist/plugin/rpc-handlers.d.ts +21 -0
- package/dist/plugin/rpc-handlers.d.ts.map +1 -0
- package/dist/plugin/sidebar-snapshot-cache.d.ts +19 -0
- package/dist/plugin/sidebar-snapshot-cache.d.ts.map +1 -0
- package/dist/plugin/tool-registry.d.ts +8 -0
- package/dist/plugin/tool-registry.d.ts.map +1 -0
- package/dist/plugin/types.d.ts +3 -0
- package/dist/plugin/types.d.ts.map +1 -0
- package/dist/shared/announcement.d.ts +55 -0
- package/dist/shared/announcement.d.ts.map +1 -0
- package/dist/shared/assistant-message-extractor.d.ts +2 -0
- package/dist/shared/assistant-message-extractor.d.ts.map +1 -0
- package/dist/shared/bounded-session-map.d.ts +45 -0
- package/dist/shared/bounded-session-map.d.ts.map +1 -0
- package/dist/shared/conflict-detector.d.ts +74 -0
- package/dist/shared/conflict-detector.d.ts.map +1 -0
- package/dist/shared/conflict-fixer.d.ts +3 -0
- package/dist/shared/conflict-fixer.d.ts.map +1 -0
- package/dist/shared/data-path.d.ts +121 -0
- package/dist/shared/data-path.d.ts.map +1 -0
- package/dist/shared/error-message.d.ts +32 -0
- package/dist/shared/error-message.d.ts.map +1 -0
- package/dist/shared/format-bytes.d.ts +2 -0
- package/dist/shared/format-bytes.d.ts.map +1 -0
- package/dist/shared/format-threshold.d.ts +24 -0
- package/dist/shared/format-threshold.d.ts.map +1 -0
- package/dist/shared/harness.d.ts +43 -0
- package/dist/shared/harness.d.ts.map +1 -0
- package/dist/shared/index.d.ts +6 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/internal-initiator-marker.d.ts +2 -0
- package/dist/shared/internal-initiator-marker.d.ts.map +1 -0
- package/dist/shared/jsonc-parser.d.ts +8 -0
- package/dist/shared/jsonc-parser.d.ts.map +1 -0
- package/dist/shared/logger.d.ts +10 -0
- package/dist/shared/logger.d.ts.map +1 -0
- package/dist/shared/model-requirements.d.ts +26 -0
- package/dist/shared/model-requirements.d.ts.map +1 -0
- package/dist/shared/model-suggestion-retry.d.ts +68 -0
- package/dist/shared/model-suggestion-retry.d.ts.map +1 -0
- package/dist/shared/models-dev-cache.d.ts +65 -0
- package/dist/shared/models-dev-cache.d.ts.map +1 -0
- package/dist/shared/native-binding.d.ts +87 -0
- package/dist/shared/native-binding.d.ts.map +1 -0
- package/dist/shared/normalize-sdk-response.d.ts +5 -0
- package/dist/shared/normalize-sdk-response.d.ts.map +1 -0
- package/dist/shared/opencode-compaction-detector.d.ts +2 -0
- package/dist/shared/opencode-compaction-detector.d.ts.map +1 -0
- package/dist/shared/opencode-config-dir-types.d.ts +14 -0
- package/dist/shared/opencode-config-dir-types.d.ts.map +1 -0
- package/dist/shared/opencode-config-dir.d.ts +5 -0
- package/dist/shared/opencode-config-dir.d.ts.map +1 -0
- package/dist/shared/record-type-guard.d.ts +2 -0
- package/dist/shared/record-type-guard.d.ts.map +1 -0
- package/dist/shared/resolve-fallbacks.d.ts +32 -0
- package/dist/shared/resolve-fallbacks.d.ts.map +1 -0
- package/dist/shared/rpc-client.d.ts +17 -0
- package/dist/shared/rpc-client.d.ts.map +1 -0
- package/dist/shared/rpc-notifications.d.ts +24 -0
- package/dist/shared/rpc-notifications.d.ts.map +1 -0
- package/dist/shared/rpc-server.d.ts +20 -0
- package/dist/shared/rpc-server.d.ts.map +1 -0
- package/dist/shared/rpc-types.d.ts +105 -0
- package/dist/shared/rpc-types.d.ts.map +1 -0
- package/dist/shared/rpc-utils.d.ts +19 -0
- package/dist/shared/rpc-utils.d.ts.map +1 -0
- package/dist/shared/sqlite-helpers.d.ts +16 -0
- package/dist/shared/sqlite-helpers.d.ts.map +1 -0
- package/dist/shared/sqlite.d.ts +43 -0
- package/dist/shared/sqlite.d.ts.map +1 -0
- package/dist/shared/stable-json.d.ts +21 -0
- package/dist/shared/stable-json.d.ts.map +1 -0
- package/dist/shared/subagent-runner.d.ts +208 -0
- package/dist/shared/subagent-runner.d.ts.map +1 -0
- package/dist/shared/system-directive.d.ts +3 -0
- package/dist/shared/system-directive.d.ts.map +1 -0
- package/dist/shared/tag-transcript.d.ts +66 -0
- package/dist/shared/tag-transcript.d.ts.map +1 -0
- package/dist/shared/transcript-opencode.d.ts +71 -0
- package/dist/shared/transcript-opencode.d.ts.map +1 -0
- package/dist/shared/transcript.d.ts +212 -0
- package/dist/shared/transcript.d.ts.map +1 -0
- package/dist/shared/tui-config.d.ts +10 -0
- package/dist/shared/tui-config.d.ts.map +1 -0
- package/dist/tools/ctx-expand/constants.d.ts +3 -0
- package/dist/tools/ctx-expand/constants.d.ts.map +1 -0
- package/dist/tools/ctx-expand/index.d.ts +2 -0
- package/dist/tools/ctx-expand/index.d.ts.map +1 -0
- package/dist/tools/ctx-expand/tools.d.ts +3 -0
- package/dist/tools/ctx-expand/tools.d.ts.map +1 -0
- package/dist/tools/ctx-expand/types.d.ts +5 -0
- package/dist/tools/ctx-expand/types.d.ts.map +1 -0
- package/dist/tools/ctx-memory/constants.d.ts +4 -0
- package/dist/tools/ctx-memory/constants.d.ts.map +1 -0
- package/dist/tools/ctx-memory/index.d.ts +4 -0
- package/dist/tools/ctx-memory/index.d.ts.map +1 -0
- package/dist/tools/ctx-memory/tools.d.ts +4 -0
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -0
- package/dist/tools/ctx-memory/types.d.ts +35 -0
- package/dist/tools/ctx-memory/types.d.ts.map +1 -0
- package/dist/tools/ctx-note/constants.d.ts +2 -0
- package/dist/tools/ctx-note/constants.d.ts.map +1 -0
- package/dist/tools/ctx-note/index.d.ts +4 -0
- package/dist/tools/ctx-note/index.d.ts.map +1 -0
- package/dist/tools/ctx-note/tools.d.ts +15 -0
- package/dist/tools/ctx-note/tools.d.ts.map +1 -0
- package/dist/tools/ctx-note/types.d.ts +9 -0
- package/dist/tools/ctx-note/types.d.ts.map +1 -0
- package/dist/tools/ctx-reduce/constants.d.ts +2 -0
- package/dist/tools/ctx-reduce/constants.d.ts.map +1 -0
- package/dist/tools/ctx-reduce/index.d.ts +4 -0
- package/dist/tools/ctx-reduce/index.d.ts.map +1 -0
- package/dist/tools/ctx-reduce/tools.d.ts +9 -0
- package/dist/tools/ctx-reduce/tools.d.ts.map +1 -0
- package/dist/tools/ctx-reduce/types.d.ts +4 -0
- package/dist/tools/ctx-reduce/types.d.ts.map +1 -0
- package/dist/tools/ctx-search/constants.d.ts +4 -0
- package/dist/tools/ctx-search/constants.d.ts.map +1 -0
- package/dist/tools/ctx-search/index.d.ts +4 -0
- package/dist/tools/ctx-search/index.d.ts.map +1 -0
- package/dist/tools/ctx-search/tools.d.ts +4 -0
- package/dist/tools/ctx-search/tools.d.ts.map +1 -0
- package/dist/tools/ctx-search/types.d.ts +34 -0
- package/dist/tools/ctx-search/types.d.ts.map +1 -0
- package/dist/tools/index.d.ts +6 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tui/data/context-db.d.ts +36 -0
- package/dist/tui/data/context-db.d.ts.map +1 -0
- package/package.json +80 -0
- package/src/shared/announcement.test.ts +143 -0
- package/src/shared/announcement.ts +97 -0
- package/src/shared/assistant-message-extractor.ts +74 -0
- package/src/shared/bounded-session-map.test.ts +97 -0
- package/src/shared/bounded-session-map.ts +84 -0
- package/src/shared/conflict-detector.test.ts +232 -0
- package/src/shared/conflict-detector.ts +371 -0
- package/src/shared/conflict-fixer.test.ts +124 -0
- package/src/shared/conflict-fixer.ts +222 -0
- package/src/shared/data-path.test.ts +159 -0
- package/src/shared/data-path.ts +155 -0
- package/src/shared/error-message.test.ts +94 -0
- package/src/shared/error-message.ts +115 -0
- package/src/shared/format-bytes.ts +5 -0
- package/src/shared/format-threshold.ts +28 -0
- package/src/shared/harness.ts +61 -0
- package/src/shared/index.ts +5 -0
- package/src/shared/internal-initiator-marker.ts +1 -0
- package/src/shared/jsonc-parser.ts +138 -0
- package/src/shared/logger.ts +94 -0
- package/src/shared/model-requirements.ts +86 -0
- package/src/shared/model-suggestion-retry.test.ts +251 -0
- package/src/shared/model-suggestion-retry.ts +348 -0
- package/src/shared/models-dev-cache.test.ts +394 -0
- package/src/shared/models-dev-cache.ts +337 -0
- package/src/shared/native-binding.ts +311 -0
- package/src/shared/normalize-sdk-response.ts +40 -0
- package/src/shared/opencode-compaction-detector.test.ts +222 -0
- package/src/shared/opencode-compaction-detector.ts +81 -0
- package/src/shared/opencode-config-dir-types.ts +15 -0
- package/src/shared/opencode-config-dir.ts +38 -0
- package/src/shared/record-type-guard.ts +3 -0
- package/src/shared/resolve-fallbacks.test.ts +136 -0
- package/src/shared/resolve-fallbacks.ts +76 -0
- package/src/shared/rpc-client.test.ts +161 -0
- package/src/shared/rpc-client.ts +183 -0
- package/src/shared/rpc-notifications.test.ts +20 -0
- package/src/shared/rpc-notifications.ts +53 -0
- package/src/shared/rpc-server.ts +174 -0
- package/src/shared/rpc-types.ts +104 -0
- package/src/shared/rpc-utils.ts +72 -0
- package/src/shared/session-messages-bounded.test.ts +112 -0
- package/src/shared/sqlite-helpers.ts +27 -0
- package/src/shared/sqlite.ts +134 -0
- package/src/shared/stable-json.test.ts +87 -0
- package/src/shared/stable-json.ts +37 -0
- package/src/shared/subagent-runner.ts +222 -0
- package/src/shared/system-directive.ts +9 -0
- package/src/shared/tag-transcript.ts +553 -0
- package/src/shared/transcript-opencode.ts +259 -0
- package/src/shared/transcript.ts +226 -0
- package/src/shared/tui-config.ts +99 -0
- package/src/tui/data/context-db.ts +303 -0
- package/src/tui/index.tsx +692 -0
- package/src/tui/slots/sidebar-content.tsx +482 -0
- package/src/tui/types/opencode-plugin-tui.d.ts +232 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/// <reference types="bun-types" />
|
|
2
|
+
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, it } from "bun:test";
|
|
4
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { tmpdir } from "node:os";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { detectConflicts } from "./conflict-detector";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Regression tests for plugin-conflict detection. The previous substring-
|
|
11
|
+
* based matcher misclassified `oh-my-opencode-slim` and `opencode-dcp-fork`
|
|
12
|
+
* as the canonical plugins, causing magic-context to disable itself with
|
|
13
|
+
* a false-positive conflict warning. See issue #43.
|
|
14
|
+
*/
|
|
15
|
+
describe("detectConflicts", () => {
|
|
16
|
+
let projectDir: string;
|
|
17
|
+
let userConfigDir: string;
|
|
18
|
+
let originalEnv: Record<string, string | undefined>;
|
|
19
|
+
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
const root = mkdtempSync(join(tmpdir(), "mc-conflict-"));
|
|
22
|
+
projectDir = join(root, "project");
|
|
23
|
+
mkdirSync(projectDir, { recursive: true });
|
|
24
|
+
userConfigDir = join(root, "user-config", "opencode");
|
|
25
|
+
mkdirSync(userConfigDir, { recursive: true });
|
|
26
|
+
|
|
27
|
+
// Save and override every env var that affects config-path resolution.
|
|
28
|
+
// OPENCODE_CONFIG_DIR takes precedence over XDG_CONFIG_HOME, so we set
|
|
29
|
+
// it directly and clear XDG to fully isolate from any inherited or
|
|
30
|
+
// test-leaked state.
|
|
31
|
+
originalEnv = {
|
|
32
|
+
OPENCODE_CONFIG_DIR: process.env.OPENCODE_CONFIG_DIR,
|
|
33
|
+
XDG_CONFIG_HOME: process.env.XDG_CONFIG_HOME,
|
|
34
|
+
OPENCODE_DISABLE_AUTOCOMPACT: process.env.OPENCODE_DISABLE_AUTOCOMPACT,
|
|
35
|
+
};
|
|
36
|
+
process.env.OPENCODE_CONFIG_DIR = userConfigDir;
|
|
37
|
+
delete process.env.XDG_CONFIG_HOME;
|
|
38
|
+
// Disable auto-compaction default during tests so we isolate plugin
|
|
39
|
+
// detection from compaction detection.
|
|
40
|
+
process.env.OPENCODE_DISABLE_AUTOCOMPACT = "1";
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
afterEach(() => {
|
|
44
|
+
for (const [k, v] of Object.entries(originalEnv)) {
|
|
45
|
+
if (v === undefined) delete process.env[k];
|
|
46
|
+
else process.env[k] = v;
|
|
47
|
+
}
|
|
48
|
+
// Test directories live under tmpdir(); cleanup is best-effort.
|
|
49
|
+
rmSync(projectDir, { recursive: true, force: true });
|
|
50
|
+
rmSync(userConfigDir, { recursive: true, force: true });
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
function writeProjectConfig(plugins: Array<string | [string, unknown]>): void {
|
|
54
|
+
writeFileSync(join(projectDir, "opencode.json"), JSON.stringify({ plugin: plugins }));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// --- DCP detection ---
|
|
58
|
+
|
|
59
|
+
describe("DCP detection", () => {
|
|
60
|
+
it("matches the canonical @tarquinen/opencode-dcp package", () => {
|
|
61
|
+
writeProjectConfig(["@tarquinen/opencode-dcp"]);
|
|
62
|
+
const result = detectConflicts(projectDir);
|
|
63
|
+
expect(result.conflicts.dcpPlugin).toBe(true);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("matches the canonical package with a version suffix", () => {
|
|
67
|
+
writeProjectConfig(["@tarquinen/opencode-dcp@latest"]);
|
|
68
|
+
const result = detectConflicts(projectDir);
|
|
69
|
+
expect(result.conflicts.dcpPlugin).toBe(true);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("matches with a semver range suffix", () => {
|
|
73
|
+
writeProjectConfig(["@tarquinen/opencode-dcp@^3.1.0"]);
|
|
74
|
+
const result = detectConflicts(projectDir);
|
|
75
|
+
expect(result.conflicts.dcpPlugin).toBe(true);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("does NOT match a fork with a different package name", () => {
|
|
79
|
+
writeProjectConfig(["@some-fork/opencode-dcp-fork"]);
|
|
80
|
+
const result = detectConflicts(projectDir);
|
|
81
|
+
expect(result.conflicts.dcpPlugin).toBe(false);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it("does NOT match a file:// path that contains 'opencode-dcp'", () => {
|
|
85
|
+
writeProjectConfig(["file:///home/user/work/opencode-dcp-fork"]);
|
|
86
|
+
const result = detectConflicts(projectDir);
|
|
87
|
+
expect(result.conflicts.dcpPlugin).toBe(false);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// --- OMO detection (the issue #43 case) ---
|
|
92
|
+
|
|
93
|
+
describe("OMO detection", () => {
|
|
94
|
+
it("matches the canonical oh-my-opencode package", () => {
|
|
95
|
+
writeProjectConfig(["oh-my-opencode"]);
|
|
96
|
+
const result = detectConflicts(projectDir);
|
|
97
|
+
// No OMO config = hooks default ACTIVE = all three flagged
|
|
98
|
+
expect(result.conflicts.omoPreemptiveCompaction).toBe(true);
|
|
99
|
+
expect(result.conflicts.omoContextWindowMonitor).toBe(true);
|
|
100
|
+
expect(result.conflicts.omoAnthropicRecovery).toBe(true);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it("matches the canonical oh-my-openagent package alias", () => {
|
|
104
|
+
writeProjectConfig(["oh-my-openagent"]);
|
|
105
|
+
const result = detectConflicts(projectDir);
|
|
106
|
+
expect(result.conflicts.omoPreemptiveCompaction).toBe(true);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("matches a canonical OMO with a version suffix", () => {
|
|
110
|
+
writeProjectConfig(["oh-my-opencode@3.17.5", "oh-my-openagent@latest"]);
|
|
111
|
+
const result = detectConflicts(projectDir);
|
|
112
|
+
expect(result.conflicts.omoPreemptiveCompaction).toBe(true);
|
|
113
|
+
expect(result.conflicts.omoContextWindowMonitor).toBe(true);
|
|
114
|
+
expect(result.conflicts.omoAnthropicRecovery).toBe(true);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it("does NOT match oh-my-opencode-slim (issue #43)", () => {
|
|
118
|
+
writeProjectConfig(["oh-my-opencode-slim"]);
|
|
119
|
+
const result = detectConflicts(projectDir);
|
|
120
|
+
expect(result.hasConflict).toBe(false);
|
|
121
|
+
expect(result.conflicts.omoPreemptiveCompaction).toBe(false);
|
|
122
|
+
expect(result.conflicts.omoContextWindowMonitor).toBe(false);
|
|
123
|
+
expect(result.conflicts.omoAnthropicRecovery).toBe(false);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it("does NOT match oh-my-opencode-slim with a version suffix (issue #43)", () => {
|
|
127
|
+
writeProjectConfig(["oh-my-opencode-slim@latest", "oh-my-opencode-slim@1.0.3"]);
|
|
128
|
+
const result = detectConflicts(projectDir);
|
|
129
|
+
expect(result.hasConflict).toBe(false);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("does NOT match a file:// path containing 'oh-my-opencode' (issue #43)", () => {
|
|
133
|
+
writeProjectConfig(["file:///home/user/workspace/oh-my-opencode-slim-dev"]);
|
|
134
|
+
const result = detectConflicts(projectDir);
|
|
135
|
+
expect(result.hasConflict).toBe(false);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it("does NOT match other forks under different package names", () => {
|
|
139
|
+
writeProjectConfig([
|
|
140
|
+
"oh-my-opencode-cli",
|
|
141
|
+
"@some-org/oh-my-opencode-fork",
|
|
142
|
+
"my-oh-my-opencode-customizations",
|
|
143
|
+
]);
|
|
144
|
+
const result = detectConflicts(projectDir);
|
|
145
|
+
expect(result.hasConflict).toBe(false);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it("still detects canonical OMO when slim is also installed", () => {
|
|
149
|
+
// A user running both slim and the real OMO should still get
|
|
150
|
+
// the conflict warning for the real one.
|
|
151
|
+
writeProjectConfig(["oh-my-opencode-slim", "oh-my-opencode@latest"]);
|
|
152
|
+
const result = detectConflicts(projectDir);
|
|
153
|
+
expect(result.conflicts.omoPreemptiveCompaction).toBe(true);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it("respects disabled_hooks in project-level OMO config", () => {
|
|
157
|
+
writeProjectConfig(["oh-my-opencode"]);
|
|
158
|
+
// Use project-scoped OMO config to avoid relying on user
|
|
159
|
+
// config-path resolution, which can be leaked across files
|
|
160
|
+
// by `spyOn(getOpenCodeConfigPaths)` mocks in sibling tests.
|
|
161
|
+
writeFileSync(
|
|
162
|
+
join(projectDir, "oh-my-opencode.json"),
|
|
163
|
+
JSON.stringify({
|
|
164
|
+
disabled_hooks: [
|
|
165
|
+
"preemptive-compaction",
|
|
166
|
+
"context-window-monitor",
|
|
167
|
+
"anthropic-context-window-limit-recovery",
|
|
168
|
+
],
|
|
169
|
+
}),
|
|
170
|
+
);
|
|
171
|
+
const result = detectConflicts(projectDir);
|
|
172
|
+
expect(result.hasConflict).toBe(false);
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// --- Combined / control cases ---
|
|
177
|
+
|
|
178
|
+
it("returns no conflicts for an empty plugin list", () => {
|
|
179
|
+
writeProjectConfig([]);
|
|
180
|
+
const result = detectConflicts(projectDir);
|
|
181
|
+
expect(result.hasConflict).toBe(false);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it("returns no conflicts for unrelated plugins", () => {
|
|
185
|
+
writeProjectConfig(["@wolfx/opencode-magic-context@latest", "some-other-plugin"]);
|
|
186
|
+
const result = detectConflicts(projectDir);
|
|
187
|
+
expect(result.hasConflict).toBe(false);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// --- Tuple plugin entries (issue #49) ---
|
|
191
|
+
// OpenCode supports ["pkg@version", { ...options }] tuple form.
|
|
192
|
+
// The old code spread the raw array into the plugin list, causing
|
|
193
|
+
// matchesPackageName to receive an array instead of a string → crash.
|
|
194
|
+
|
|
195
|
+
describe("tuple plugin entries (issue #49)", () => {
|
|
196
|
+
it("does not crash when a plugin is defined as a [name, options] tuple", () => {
|
|
197
|
+
writeProjectConfig([
|
|
198
|
+
"@wolfx/opencode-magic-context@latest",
|
|
199
|
+
["@plannotator/opencode@latest", { workflow: "plan-agent" }],
|
|
200
|
+
]);
|
|
201
|
+
expect(() => detectConflicts(projectDir)).not.toThrow();
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it("detects DCP conflict when DCP is expressed as a tuple", () => {
|
|
205
|
+
writeProjectConfig([
|
|
206
|
+
"@wolfx/opencode-magic-context@latest",
|
|
207
|
+
["@tarquinen/opencode-dcp@latest", {}],
|
|
208
|
+
]);
|
|
209
|
+
const result = detectConflicts(projectDir);
|
|
210
|
+
expect(result.conflicts.dcpPlugin).toBe(true);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it("detects OMO conflict when OMO is expressed as a tuple", () => {
|
|
214
|
+
writeProjectConfig([["oh-my-opencode@latest", {}]]);
|
|
215
|
+
const result = detectConflicts(projectDir);
|
|
216
|
+
expect(result.conflicts.omoPreemptiveCompaction).toBe(true);
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it("does not crash on mixed string and tuple entries with unrelated packages", () => {
|
|
220
|
+
writeProjectConfig([
|
|
221
|
+
"oh-my-opencode-slim",
|
|
222
|
+
[
|
|
223
|
+
"@plannotator/opencode@latest",
|
|
224
|
+
{ workflow: "plan-agent", planningAgents: ["plan"] },
|
|
225
|
+
],
|
|
226
|
+
"@wolfx/opencode-magic-context@latest",
|
|
227
|
+
]);
|
|
228
|
+
const result = detectConflicts(projectDir);
|
|
229
|
+
expect(result.hasConflict).toBe(false);
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
});
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { readJsoncFile } from "./jsonc-parser";
|
|
3
|
+
import { getOpenCodeConfigPaths } from "./opencode-config-dir";
|
|
4
|
+
|
|
5
|
+
interface OpenCodeConfig {
|
|
6
|
+
compaction?: {
|
|
7
|
+
auto?: boolean;
|
|
8
|
+
prune?: boolean;
|
|
9
|
+
};
|
|
10
|
+
// OpenCode allows plugins as plain strings or [name, options] tuples.
|
|
11
|
+
plugin?: Array<string | [string, unknown]>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface OmoConfig {
|
|
15
|
+
disabled_hooks?: string[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ConflictResult {
|
|
19
|
+
/** Whether any blocking conflict was found */
|
|
20
|
+
hasConflict: boolean;
|
|
21
|
+
/** Human-readable reasons for each conflict */
|
|
22
|
+
reasons: string[];
|
|
23
|
+
/** Which conflicts were found — used for targeted fixes */
|
|
24
|
+
conflicts: {
|
|
25
|
+
compactionAuto: boolean;
|
|
26
|
+
compactionPrune: boolean;
|
|
27
|
+
dcpPlugin: boolean;
|
|
28
|
+
omoPreemptiveCompaction: boolean;
|
|
29
|
+
omoContextWindowMonitor: boolean;
|
|
30
|
+
omoAnthropicRecovery: boolean;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Detect all conflicts that would prevent magic-context from working correctly.
|
|
36
|
+
* Checks: OpenCode compaction, DCP plugin, OMO conflicting hooks.
|
|
37
|
+
*/
|
|
38
|
+
export function detectConflicts(directory: string): ConflictResult {
|
|
39
|
+
const conflicts: ConflictResult["conflicts"] = {
|
|
40
|
+
compactionAuto: false,
|
|
41
|
+
compactionPrune: false,
|
|
42
|
+
dcpPlugin: false,
|
|
43
|
+
omoPreemptiveCompaction: false,
|
|
44
|
+
omoContextWindowMonitor: false,
|
|
45
|
+
omoAnthropicRecovery: false,
|
|
46
|
+
};
|
|
47
|
+
const reasons: string[] = [];
|
|
48
|
+
|
|
49
|
+
// --- Check OpenCode compaction config ---
|
|
50
|
+
const compactionResult = checkCompaction(directory);
|
|
51
|
+
if (compactionResult.auto) {
|
|
52
|
+
conflicts.compactionAuto = true;
|
|
53
|
+
reasons.push("OpenCode auto-compaction is enabled (compaction.auto=true)");
|
|
54
|
+
}
|
|
55
|
+
if (compactionResult.prune) {
|
|
56
|
+
conflicts.compactionPrune = true;
|
|
57
|
+
reasons.push("OpenCode prune is enabled (compaction.prune=true)");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// --- Check for DCP plugin ---
|
|
61
|
+
const dcpFound = checkDcpPlugin(directory);
|
|
62
|
+
if (dcpFound) {
|
|
63
|
+
conflicts.dcpPlugin = true;
|
|
64
|
+
reasons.push(
|
|
65
|
+
"opencode-dcp plugin is installed — it conflicts with Magic Context's context management",
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// --- Check OMO conflicting hooks ---
|
|
70
|
+
const omoResult = checkOmoHooks(directory);
|
|
71
|
+
if (omoResult.preemptiveCompaction) {
|
|
72
|
+
conflicts.omoPreemptiveCompaction = true;
|
|
73
|
+
reasons.push(
|
|
74
|
+
"oh-my-opencode preemptive-compaction hook is active — it triggers compaction that conflicts with historian",
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
if (omoResult.contextWindowMonitor) {
|
|
78
|
+
conflicts.omoContextWindowMonitor = true;
|
|
79
|
+
reasons.push(
|
|
80
|
+
"oh-my-opencode context-window-monitor hook is active — it injects usage warnings that overlap with Magic Context nudges",
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
if (omoResult.anthropicRecovery) {
|
|
84
|
+
conflicts.omoAnthropicRecovery = true;
|
|
85
|
+
reasons.push(
|
|
86
|
+
"oh-my-opencode anthropic-context-window-limit-recovery hook is active — it triggers emergency compaction that bypasses historian",
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
hasConflict: reasons.length > 0,
|
|
92
|
+
reasons,
|
|
93
|
+
conflicts,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// --- Compaction detection (extracted from opencode-compaction-detector.ts) ---
|
|
98
|
+
|
|
99
|
+
function checkCompaction(directory: string): { auto: boolean; prune: boolean } {
|
|
100
|
+
if (process.env.OPENCODE_DISABLE_AUTOCOMPACT) {
|
|
101
|
+
return { auto: false, prune: false };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Check project-level config first (higher precedence)
|
|
105
|
+
const projectResult = readProjectCompaction(directory);
|
|
106
|
+
if (projectResult.resolved) return projectResult;
|
|
107
|
+
|
|
108
|
+
// Fall back to user-level config
|
|
109
|
+
const userResult = readUserCompaction();
|
|
110
|
+
if (userResult.resolved) return userResult;
|
|
111
|
+
|
|
112
|
+
// Default: OpenCode has compaction enabled by default
|
|
113
|
+
return { auto: true, prune: false };
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function readProjectCompaction(directory: string): {
|
|
117
|
+
auto: boolean;
|
|
118
|
+
prune: boolean;
|
|
119
|
+
resolved: boolean;
|
|
120
|
+
} {
|
|
121
|
+
// .opencode/ config has higher precedence
|
|
122
|
+
const dotOcJsonc = join(directory, ".opencode", "opencode.jsonc");
|
|
123
|
+
const dotOcJson = join(directory, ".opencode", "opencode.json");
|
|
124
|
+
const dotOcConfig =
|
|
125
|
+
readJsoncFile<OpenCodeConfig>(dotOcJsonc) ?? readJsoncFile<OpenCodeConfig>(dotOcJson);
|
|
126
|
+
|
|
127
|
+
if (dotOcConfig?.compaction) {
|
|
128
|
+
const c = dotOcConfig.compaction;
|
|
129
|
+
if (c.auto !== undefined || c.prune !== undefined) {
|
|
130
|
+
return { auto: c.auto === true, prune: c.prune === true, resolved: true };
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Root-level project config
|
|
135
|
+
const rootJsonc = join(directory, "opencode.jsonc");
|
|
136
|
+
const rootJson = join(directory, "opencode.json");
|
|
137
|
+
const rootConfig =
|
|
138
|
+
readJsoncFile<OpenCodeConfig>(rootJsonc) ?? readJsoncFile<OpenCodeConfig>(rootJson);
|
|
139
|
+
|
|
140
|
+
if (rootConfig?.compaction) {
|
|
141
|
+
const c = rootConfig.compaction;
|
|
142
|
+
if (c.auto !== undefined || c.prune !== undefined) {
|
|
143
|
+
return { auto: c.auto === true, prune: c.prune === true, resolved: true };
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return { auto: false, prune: false, resolved: false };
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function readUserCompaction(): { auto: boolean; prune: boolean; resolved: boolean } {
|
|
151
|
+
try {
|
|
152
|
+
const paths = getOpenCodeConfigPaths({ binary: "opencode" });
|
|
153
|
+
const config =
|
|
154
|
+
readJsoncFile<OpenCodeConfig>(paths.configJsonc) ??
|
|
155
|
+
readJsoncFile<OpenCodeConfig>(paths.configJson);
|
|
156
|
+
|
|
157
|
+
if (config?.compaction) {
|
|
158
|
+
const c = config.compaction;
|
|
159
|
+
if (c.auto !== undefined || c.prune !== undefined) {
|
|
160
|
+
return { auto: c.auto === true, prune: c.prune === true, resolved: true };
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
} catch {
|
|
164
|
+
// Intentional: config read is best-effort
|
|
165
|
+
}
|
|
166
|
+
return { auto: false, prune: false, resolved: false };
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// --- DCP detection ---
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Canonical npm package names that represent the conflicting plugin.
|
|
173
|
+
* Matched against the npm-style segment of each plugin entry, so:
|
|
174
|
+
* - "@tarquinen/opencode-dcp" ✓ direct match
|
|
175
|
+
* - "@tarquinen/opencode-dcp@latest" ✓ version suffix stripped
|
|
176
|
+
* - "@tarquinen/opencode-dcp@^3.1.0" ✓ semver suffix stripped
|
|
177
|
+
* - "file:///path/to/opencode-dcp-fork" ✗ unrelated path
|
|
178
|
+
*
|
|
179
|
+
* forks/renames that don't ship the conflicting transform/system hooks are
|
|
180
|
+
* intentionally NOT matched.
|
|
181
|
+
*/
|
|
182
|
+
export const DCP_PACKAGE_NAMES = new Set(["@tarquinen/opencode-dcp"]);
|
|
183
|
+
|
|
184
|
+
function checkDcpPlugin(directory: string): boolean {
|
|
185
|
+
const plugins = collectPluginEntries(directory);
|
|
186
|
+
return plugins.some((p) => matchesPackageName(p, DCP_PACKAGE_NAMES));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Match a plugin entry against a set of canonical npm package names.
|
|
191
|
+
*
|
|
192
|
+
* A plugin entry can be:
|
|
193
|
+
* - "pkg-name"
|
|
194
|
+
* - "pkg-name@version"
|
|
195
|
+
* - "@scope/pkg-name"
|
|
196
|
+
* - "@scope/pkg-name@version"
|
|
197
|
+
* - "file://..." or other URL/path forms (never matched here)
|
|
198
|
+
*
|
|
199
|
+
* For the canonical-name path we only match the exact package name (with
|
|
200
|
+
* optional version suffix). file:// paths and forks with different
|
|
201
|
+
* package names are intentionally NOT matched — even if a path string
|
|
202
|
+
* happens to contain a substring like "oh-my-opencode" (e.g. forks like
|
|
203
|
+
* "oh-my-opencode-slim" published under a different package name).
|
|
204
|
+
*/
|
|
205
|
+
export function matchesPackageName(entry: string, canonicalNames: Set<string>): boolean {
|
|
206
|
+
// Skip URL/path forms — only npm-style entries can be canonically matched.
|
|
207
|
+
// (Local file:// checkouts of canonical plugins are rare; users running
|
|
208
|
+
// those need to ensure the path itself doesn't match a fork's name.)
|
|
209
|
+
if (
|
|
210
|
+
entry.startsWith("file:") ||
|
|
211
|
+
entry.startsWith("http:") ||
|
|
212
|
+
entry.startsWith("https:") ||
|
|
213
|
+
entry.startsWith("/") ||
|
|
214
|
+
entry.startsWith("./") ||
|
|
215
|
+
entry.startsWith("../")
|
|
216
|
+
) {
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Strip version suffix: "@scope/pkg@1.2.3" → "@scope/pkg"
|
|
221
|
+
// Careful with scoped packages: the leading "@" is part of the name.
|
|
222
|
+
const lastAt = entry.lastIndexOf("@");
|
|
223
|
+
const nameOnly = lastAt > 0 ? entry.slice(0, lastAt) : entry;
|
|
224
|
+
return canonicalNames.has(nameOnly);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** Extract the package-name string from a plugin entry.
|
|
228
|
+
* OpenCode supports two forms:
|
|
229
|
+
* - plain string: "@scope/pkg@latest"
|
|
230
|
+
* - tuple [name, opts]: ["@scope/pkg@latest", { ... }]
|
|
231
|
+
* Returns null for any other shape (numbers, objects, etc.). */
|
|
232
|
+
export function extractPluginName(entry: unknown): string | null {
|
|
233
|
+
if (typeof entry === "string") return entry;
|
|
234
|
+
if (Array.isArray(entry) && typeof entry[0] === "string") return entry[0];
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function collectPluginEntries(directory: string): string[] {
|
|
239
|
+
const plugins: string[] = [];
|
|
240
|
+
|
|
241
|
+
const pushFrom = (entries: Array<string | [string, unknown]> | undefined) => {
|
|
242
|
+
if (!entries) return;
|
|
243
|
+
for (const entry of entries) {
|
|
244
|
+
const name = extractPluginName(entry);
|
|
245
|
+
if (name) plugins.push(name);
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
// Project-level configs
|
|
250
|
+
for (const configPath of [
|
|
251
|
+
join(directory, ".opencode", "opencode.jsonc"),
|
|
252
|
+
join(directory, ".opencode", "opencode.json"),
|
|
253
|
+
join(directory, "opencode.jsonc"),
|
|
254
|
+
join(directory, "opencode.json"),
|
|
255
|
+
]) {
|
|
256
|
+
const config = readJsoncFile<OpenCodeConfig>(configPath);
|
|
257
|
+
pushFrom(config?.plugin);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// User-level config
|
|
261
|
+
try {
|
|
262
|
+
const paths = getOpenCodeConfigPaths({ binary: "opencode" });
|
|
263
|
+
for (const configPath of [paths.configJsonc, paths.configJson]) {
|
|
264
|
+
const config = readJsoncFile<OpenCodeConfig>(configPath);
|
|
265
|
+
pushFrom(config?.plugin);
|
|
266
|
+
}
|
|
267
|
+
} catch {
|
|
268
|
+
// best-effort
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return plugins;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// --- OMO hook detection ---
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Canonical OMO npm package names. The plugin publishes under both names as
|
|
278
|
+
* a versioned alias (latest 3.17.5 on npm at time of writing).
|
|
279
|
+
*
|
|
280
|
+
* Forks under a different package name (e.g. `oh-my-opencode-slim`,
|
|
281
|
+
* `oh-my-opencode-cli`, etc.) are intentionally NOT matched here — they
|
|
282
|
+
* don't ship the `preemptive-compaction`, `context-window-monitor`, or
|
|
283
|
+
* `anthropic-context-window-limit-recovery` hooks that conflict with
|
|
284
|
+
* Magic Context. See https://github.com/cortexkit/magic-context/issues/43.
|
|
285
|
+
*
|
|
286
|
+
* The legacy `@code-yeongyu/` scope is no longer used — both names are
|
|
287
|
+
* unscoped on npm.
|
|
288
|
+
*/
|
|
289
|
+
export const OMO_PACKAGE_NAMES = new Set(["oh-my-opencode", "oh-my-openagent"]);
|
|
290
|
+
|
|
291
|
+
function checkOmoHooks(directory: string): {
|
|
292
|
+
preemptiveCompaction: boolean;
|
|
293
|
+
contextWindowMonitor: boolean;
|
|
294
|
+
anthropicRecovery: boolean;
|
|
295
|
+
} {
|
|
296
|
+
const result = {
|
|
297
|
+
preemptiveCompaction: false,
|
|
298
|
+
contextWindowMonitor: false,
|
|
299
|
+
anthropicRecovery: false,
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
// First check if OMO is even installed
|
|
303
|
+
const plugins = collectPluginEntries(directory);
|
|
304
|
+
const hasOmo = plugins.some((p) => matchesPackageName(p, OMO_PACKAGE_NAMES));
|
|
305
|
+
if (!hasOmo) return result;
|
|
306
|
+
|
|
307
|
+
// Read OMO config to check disabled_hooks
|
|
308
|
+
const disabledHooks = readOmoDisabledHooks(directory);
|
|
309
|
+
|
|
310
|
+
// Hooks are ACTIVE unless explicitly in disabled_hooks
|
|
311
|
+
result.preemptiveCompaction = !disabledHooks.has("preemptive-compaction");
|
|
312
|
+
result.contextWindowMonitor = !disabledHooks.has("context-window-monitor");
|
|
313
|
+
result.anthropicRecovery = !disabledHooks.has("anthropic-context-window-limit-recovery");
|
|
314
|
+
|
|
315
|
+
return result;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function readOmoDisabledHooks(directory: string): Set<string> {
|
|
319
|
+
const disabled = new Set<string>();
|
|
320
|
+
|
|
321
|
+
// Check both old and new OMO config names
|
|
322
|
+
const configNames = [
|
|
323
|
+
"oh-my-opencode.jsonc",
|
|
324
|
+
"oh-my-opencode.json",
|
|
325
|
+
"oh-my-openagent.jsonc",
|
|
326
|
+
"oh-my-openagent.json",
|
|
327
|
+
];
|
|
328
|
+
|
|
329
|
+
try {
|
|
330
|
+
const paths = getOpenCodeConfigPaths({ binary: "opencode" });
|
|
331
|
+
for (const name of configNames) {
|
|
332
|
+
const configPath = join(paths.configDir, name);
|
|
333
|
+
const config = readJsoncFile<OmoConfig>(configPath);
|
|
334
|
+
if (config?.disabled_hooks) {
|
|
335
|
+
for (const hook of config.disabled_hooks) {
|
|
336
|
+
disabled.add(hook);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
} catch {
|
|
341
|
+
// best-effort
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// Also check project-level OMO configs
|
|
345
|
+
for (const name of configNames) {
|
|
346
|
+
const config = readJsoncFile<OmoConfig>(join(directory, name));
|
|
347
|
+
if (config?.disabled_hooks) {
|
|
348
|
+
for (const hook of config.disabled_hooks) {
|
|
349
|
+
disabled.add(hook);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
return disabled;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Generate a short conflict summary for ignored message display.
|
|
359
|
+
*/
|
|
360
|
+
export function formatConflictShort(result: ConflictResult): string {
|
|
361
|
+
if (!result.hasConflict) return "";
|
|
362
|
+
|
|
363
|
+
const lines = [
|
|
364
|
+
"⚠️ Magic Context is disabled due to conflicting configuration:",
|
|
365
|
+
"",
|
|
366
|
+
...result.reasons.map((r) => `• ${r}`),
|
|
367
|
+
"",
|
|
368
|
+
"Fix: run `npx @wolfx/opencode-magic-context@latest doctor`",
|
|
369
|
+
];
|
|
370
|
+
return lines.join("\n");
|
|
371
|
+
}
|