@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,72 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
export interface RpcPortFileRecord {
|
|
5
|
+
port: number;
|
|
6
|
+
pid: number;
|
|
7
|
+
started_at: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Stable hash for a project directory — scopes RPC port files per-project
|
|
12
|
+
* so multiple OpenCode instances don't collide.
|
|
13
|
+
*/
|
|
14
|
+
export function projectHash(directory: string): string {
|
|
15
|
+
const normalized = directory.replace(/\/+$/, "");
|
|
16
|
+
return createHash("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Directory containing per-process RPC discovery files for a project. */
|
|
20
|
+
export function rpcPortDir(storageDir: string, directory: string): string {
|
|
21
|
+
return join(storageDir, "rpc", projectHash(directory));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Per-process RPC port file path. */
|
|
25
|
+
export function rpcPortFilePath(storageDir: string, directory: string, pid = process.pid): string {
|
|
26
|
+
return join(rpcPortDir(storageDir, directory), `port-${pid}.json`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Legacy single-port file used by v0.18.0 and earlier. */
|
|
30
|
+
export function legacyRpcPortFilePath(storageDir: string, directory: string): string {
|
|
31
|
+
return join(rpcPortDir(storageDir, directory), "port");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function isPidAlive(pid: number): boolean {
|
|
35
|
+
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
36
|
+
try {
|
|
37
|
+
process.kill(pid, 0);
|
|
38
|
+
return true;
|
|
39
|
+
} catch (err) {
|
|
40
|
+
return (err as NodeJS.ErrnoException).code === "EPERM";
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function parseRpcPortFile(content: string, fallbackPid = 0): RpcPortFileRecord | null {
|
|
45
|
+
const trimmed = content.trim();
|
|
46
|
+
if (!trimmed) return null;
|
|
47
|
+
|
|
48
|
+
if (trimmed.startsWith("{")) {
|
|
49
|
+
try {
|
|
50
|
+
const parsed = JSON.parse(trimmed) as Partial<RpcPortFileRecord>;
|
|
51
|
+
const port = Number(parsed.port);
|
|
52
|
+
const pid = Number(parsed.pid);
|
|
53
|
+
const startedAt = Number(parsed.started_at);
|
|
54
|
+
if (!isValidPort(port) || !Number.isInteger(pid) || pid <= 0) return null;
|
|
55
|
+
return {
|
|
56
|
+
port,
|
|
57
|
+
pid,
|
|
58
|
+
started_at: Number.isFinite(startedAt) ? startedAt : 0,
|
|
59
|
+
};
|
|
60
|
+
} catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const port = Number.parseInt(trimmed, 10);
|
|
66
|
+
if (!isValidPort(port)) return null;
|
|
67
|
+
return { port, pid: fallbackPid, started_at: 0 };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function isValidPort(port: number): boolean {
|
|
71
|
+
return Number.isInteger(port) && port > 0 && port <= 65535;
|
|
72
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/// <reference types="bun-types" />
|
|
2
|
+
|
|
3
|
+
// Regression guard: every `client.session.messages(...)` call in plugin code
|
|
4
|
+
// must include `limit` in its `query`. Without `limit`, OpenCode's legacy
|
|
5
|
+
// messages endpoint hydrates the ENTIRE session into RAM — catastrophic on
|
|
6
|
+
// huge sessions (10k+ messages) which is exactly when Magic Context shines.
|
|
7
|
+
//
|
|
8
|
+
// Background: the plugin only ever needs the latest assistant message of a
|
|
9
|
+
// helper subagent (historian / dreamer / sidekick / key-files / user-memory)
|
|
10
|
+
// or a bounded tail of the active session (conflict-warning cleanup). Both
|
|
11
|
+
// fit comfortably in `limit: 50` with massive headroom.
|
|
12
|
+
//
|
|
13
|
+
// If you add a new `session.messages(...)` call, this test fails until you
|
|
14
|
+
// include a `limit` in the query. The test does a static source-text scan
|
|
15
|
+
// so it catches the issue at lint-time without runtime mocking overhead.
|
|
16
|
+
|
|
17
|
+
import { describe, expect, it } from "bun:test";
|
|
18
|
+
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
19
|
+
import { join } from "node:path";
|
|
20
|
+
|
|
21
|
+
const PLUGIN_SRC = join(__dirname, "..", "..", "src");
|
|
22
|
+
|
|
23
|
+
/** Recursively walk a directory and return paths of all `.ts` files
|
|
24
|
+
* excluding `.test.ts`, `.gen.ts`, and node_modules. */
|
|
25
|
+
function walkSourceFiles(dir: string, out: string[] = []): string[] {
|
|
26
|
+
for (const entry of readdirSync(dir)) {
|
|
27
|
+
if (entry === "node_modules" || entry === "dist") continue;
|
|
28
|
+
const full = join(dir, entry);
|
|
29
|
+
const s = statSync(full);
|
|
30
|
+
if (s.isDirectory()) {
|
|
31
|
+
walkSourceFiles(full, out);
|
|
32
|
+
} else if (
|
|
33
|
+
s.isFile() &&
|
|
34
|
+
entry.endsWith(".ts") &&
|
|
35
|
+
!entry.endsWith(".test.ts") &&
|
|
36
|
+
!entry.endsWith(".gen.ts")
|
|
37
|
+
) {
|
|
38
|
+
out.push(full);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return out;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Find call expressions matching `session.messages(...)` and return the
|
|
45
|
+
* source text of each call (from "session.messages(" to its matching ")"). */
|
|
46
|
+
function findSessionMessagesCalls(source: string): string[] {
|
|
47
|
+
const calls: string[] = [];
|
|
48
|
+
const needle = "session.messages(";
|
|
49
|
+
let i = 0;
|
|
50
|
+
while (true) {
|
|
51
|
+
const idx = source.indexOf(needle, i);
|
|
52
|
+
if (idx === -1) break;
|
|
53
|
+
// Skip comments — if the line starts with `*` or `//` we ignore.
|
|
54
|
+
const lineStart = source.lastIndexOf("\n", idx) + 1;
|
|
55
|
+
const linePrefix = source.slice(lineStart, idx).trimStart();
|
|
56
|
+
if (linePrefix.startsWith("//") || linePrefix.startsWith("*")) {
|
|
57
|
+
i = idx + needle.length;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
// Walk forward to find the matching closing paren, respecting
|
|
61
|
+
// brace/bracket/paren nesting.
|
|
62
|
+
let depth = 1;
|
|
63
|
+
let j = idx + needle.length;
|
|
64
|
+
while (j < source.length && depth > 0) {
|
|
65
|
+
const ch = source[j];
|
|
66
|
+
if (ch === "(" || ch === "{" || ch === "[") depth++;
|
|
67
|
+
else if (ch === ")" || ch === "}" || ch === "]") depth--;
|
|
68
|
+
j++;
|
|
69
|
+
}
|
|
70
|
+
if (depth === 0) {
|
|
71
|
+
calls.push(source.slice(idx, j));
|
|
72
|
+
}
|
|
73
|
+
i = j;
|
|
74
|
+
}
|
|
75
|
+
return calls;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
describe("session.messages() callsites must include query.limit", () => {
|
|
79
|
+
const files = walkSourceFiles(PLUGIN_SRC);
|
|
80
|
+
const violations: Array<{ file: string; callText: string }> = [];
|
|
81
|
+
|
|
82
|
+
for (const file of files) {
|
|
83
|
+
// Skip the regression test itself
|
|
84
|
+
if (file.endsWith("session-messages-bounded.test.ts")) continue;
|
|
85
|
+
const source = readFileSync(file, "utf-8");
|
|
86
|
+
const calls = findSessionMessagesCalls(source);
|
|
87
|
+
for (const call of calls) {
|
|
88
|
+
// The call text spans from "session.messages(" to the closing
|
|
89
|
+
// ")". A correct call must mention `limit` (the SDK key) somewhere
|
|
90
|
+
// inside that span — typically `query: { ..., limit: N }`.
|
|
91
|
+
if (!/\blimit\b/.test(call)) {
|
|
92
|
+
violations.push({ file: file.replace(PLUGIN_SRC, "<plugin>/src"), callText: call });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
it("has no unbounded session.messages() calls in plugin code", () => {
|
|
98
|
+
if (violations.length > 0) {
|
|
99
|
+
const report = violations
|
|
100
|
+
.map(
|
|
101
|
+
(v) =>
|
|
102
|
+
`\n in ${v.file}:\n ${v.callText.replace(/\n/g, "\n ").slice(0, 300)}`,
|
|
103
|
+
)
|
|
104
|
+
.join("\n");
|
|
105
|
+
throw new Error(
|
|
106
|
+
`Found ${violations.length} unbounded session.messages() call(s). ` +
|
|
107
|
+
`Add \`limit: 50\` (or appropriate bound) to query.${report}`,
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
expect(violations).toEqual([]);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-runtime helpers that smooth over the small bun:sqlite ↔ better-sqlite3
|
|
3
|
+
* API differences without leaking either library into call sites.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Database } from "./sqlite";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Close a database, ignoring errors.
|
|
10
|
+
*
|
|
11
|
+
* bun:sqlite supports `db.close(throwOnError = false)`. better-sqlite3 has
|
|
12
|
+
* only `db.close()` and throws on already-closed databases. This helper
|
|
13
|
+
* mirrors the bun "swallow errors" semantics for both runtimes — useful in
|
|
14
|
+
* test teardown and `finally` blocks where the caller doesn't care whether
|
|
15
|
+
* the close succeeded.
|
|
16
|
+
*/
|
|
17
|
+
export function closeQuietly(db: Database | null | undefined): void {
|
|
18
|
+
if (!db) return;
|
|
19
|
+
// Just attempt close and swallow errors. bun:sqlite has no `open` property,
|
|
20
|
+
// and better-sqlite3 throws TypeError on already-closed databases — both
|
|
21
|
+
// are handled by the bare try/catch.
|
|
22
|
+
try {
|
|
23
|
+
db.close();
|
|
24
|
+
} catch {
|
|
25
|
+
// intentional: caller wants quiet close
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite chokepoint — runtime-detected backend selection.
|
|
3
|
+
*
|
|
4
|
+
* The same shipped plugin artifact must run under two different runtimes:
|
|
5
|
+
* - Bun (current OpenCode releases) → uses `bun:sqlite` (built-in, fast)
|
|
6
|
+
* - Node (OpenCode beta + future Pi plugin) → uses `better-sqlite3`
|
|
7
|
+
*
|
|
8
|
+
* Bun cannot load `better-sqlite3` (oven-sh/bun#4290), and Node has no
|
|
9
|
+
* `bun:sqlite` module. Static imports of either would crash at parse time
|
|
10
|
+
* in the wrong runtime, so we use dynamic imports gated by runtime detection.
|
|
11
|
+
*
|
|
12
|
+
* The Function-constructor wrapper around `import()` defeats bundler static
|
|
13
|
+
* analysis — without it, esbuild/bun build would try to resolve both modules
|
|
14
|
+
* during the bundle step, including the one that doesn't exist in the build
|
|
15
|
+
* runtime.
|
|
16
|
+
*
|
|
17
|
+
* Both libraries expose ~95% API parity:
|
|
18
|
+
* - new Database(path, { readonly?: boolean })
|
|
19
|
+
* - db.prepare(sql).run/get/all
|
|
20
|
+
* - db.exec(multistatement)
|
|
21
|
+
* - db.transaction(fn) → wrapped function
|
|
22
|
+
* - db.close()
|
|
23
|
+
*
|
|
24
|
+
* The 5% that differs (db.query, db.run, db.close(boolean), Database.open)
|
|
25
|
+
* is either rewritten to common-subset patterns or hidden behind the helpers
|
|
26
|
+
* in `./sqlite-helpers.ts`.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
// Type import only — better-sqlite3's runtime is loaded dynamically below.
|
|
30
|
+
// @types/better-sqlite3 has richer definitions than @types/bun's bun:sqlite
|
|
31
|
+
// types, and bun:sqlite is a structural superset for the API surface we use,
|
|
32
|
+
// so calls typed against BetterSqlite3 work under both runtimes at runtime.
|
|
33
|
+
import type BetterSqlite3 from "better-sqlite3";
|
|
34
|
+
|
|
35
|
+
// Detect Bun via process.versions.bun. Both globalThis.Bun and
|
|
36
|
+
// process.versions.bun are set by the Bun runtime, but process.versions
|
|
37
|
+
// is a lower-level surface less likely to be sandboxed by host runtimes
|
|
38
|
+
// (e.g. Electron in OpenCode desktop apps that re-expose a Bun-flavored
|
|
39
|
+
// environment). Real Node and Electron never set this field.
|
|
40
|
+
const isBun = typeof process !== "undefined" && typeof process.versions?.bun === "string";
|
|
41
|
+
|
|
42
|
+
// IMPORTANT: bundler-evading dynamic imports.
|
|
43
|
+
//
|
|
44
|
+
// We can't write `await import("better-sqlite3")` directly because esbuild/bun
|
|
45
|
+
// would try to resolve both modules at build time, and one of them won't exist
|
|
46
|
+
// in the build runtime (bun:sqlite is missing in Node, better-sqlite3 isn't
|
|
47
|
+
// shipped in Bun-only environments). Earlier versions used
|
|
48
|
+
// `new Function("p", "return import(p)")("modname")` to defeat static
|
|
49
|
+
// analysis, but that breaks Pi's vm-based extension loader: a Function
|
|
50
|
+
// constructed at runtime has no module record, so `import()` inside it has
|
|
51
|
+
// no referrer module and Node throws "A dynamic import callback was not
|
|
52
|
+
// specified".
|
|
53
|
+
//
|
|
54
|
+
// The /* @vite-ignore */ + variable indirection pattern hides the specifier
|
|
55
|
+
// from static analyzers while keeping a real referrer module for the
|
|
56
|
+
// dynamic import — Pi's loader, esbuild, and bun build all accept it.
|
|
57
|
+
const bunSpec = "bun:" + "sqlite";
|
|
58
|
+
const betterSpec = "better-" + "sqlite3";
|
|
59
|
+
|
|
60
|
+
// Under Electron, the npm-installed better-sqlite3 binary has the wrong ABI
|
|
61
|
+
// (it's a Node prebuild but Electron embeds a different NODE_MODULE_VERSION).
|
|
62
|
+
// resolveBetterSqliteNativeBinding() detects this and downloads + caches the
|
|
63
|
+
// matching Electron prebuild, then returns its absolute path so we can pass
|
|
64
|
+
// it to better-sqlite3 via the `nativeBinding` constructor option (a
|
|
65
|
+
// documented public API). Returns null outside Electron OR when the on-disk
|
|
66
|
+
// binary already matches the runtime ABI — in those cases the default
|
|
67
|
+
// bindings() lookup just works.
|
|
68
|
+
const electronNativeBinding = isBun
|
|
69
|
+
? null
|
|
70
|
+
: await (async () => {
|
|
71
|
+
const mod = await import("./native-binding");
|
|
72
|
+
return mod.resolveBetterSqliteNativeBinding();
|
|
73
|
+
})();
|
|
74
|
+
|
|
75
|
+
const sqliteModule = isBun
|
|
76
|
+
? await import(/* @vite-ignore */ bunSpec)
|
|
77
|
+
: await import(/* @vite-ignore */ betterSpec);
|
|
78
|
+
|
|
79
|
+
// Different export shapes between the two libraries:
|
|
80
|
+
// - bun:sqlite → named export `Database`
|
|
81
|
+
// - better-sqlite3 → default export
|
|
82
|
+
const RawDatabaseImpl = isBun ? sqliteModule.Database : sqliteModule.default;
|
|
83
|
+
|
|
84
|
+
// When we resolved a non-default Electron-compatible native binding above,
|
|
85
|
+
// transparently inject it into every `new Database(...)` call. This is the
|
|
86
|
+
// public `nativeBinding` constructor option that better-sqlite3 ships
|
|
87
|
+
// specifically for cross-runtime extension scenarios — it makes
|
|
88
|
+
// better-sqlite3 `require()` the binary at the supplied path directly,
|
|
89
|
+
// bypassing the default bindings() resolver.
|
|
90
|
+
//
|
|
91
|
+
// Subclassing keeps the call sites untouched: existing
|
|
92
|
+
// `new Database(filename, { readonly: true })` invocations work as-is.
|
|
93
|
+
// Callers can still override `nativeBinding` explicitly if they need to.
|
|
94
|
+
//
|
|
95
|
+
// The TypeScript type intentionally references @types/better-sqlite3 because
|
|
96
|
+
// its definitions are richer than @types/bun's bun:sqlite types and bun:sqlite
|
|
97
|
+
// is a structural superset for the API surface we use. Calls written against
|
|
98
|
+
// this type work correctly under both runtimes at runtime.
|
|
99
|
+
//
|
|
100
|
+
// @types/better-sqlite3 uses `export = Database` (CommonJS interop), which
|
|
101
|
+
// surfaces in TypeScript as `import Database = require("better-sqlite3")`.
|
|
102
|
+
// We capture the DatabaseConstructor type from the namespace re-export.
|
|
103
|
+
const DatabaseImpl: typeof BetterSqlite3 =
|
|
104
|
+
electronNativeBinding == null
|
|
105
|
+
? (RawDatabaseImpl as typeof BetterSqlite3)
|
|
106
|
+
: (class DatabaseWithElectronBinding extends (RawDatabaseImpl as typeof BetterSqlite3) {
|
|
107
|
+
constructor(filename?: string | Buffer, options?: BetterSqlite3.Options) {
|
|
108
|
+
// Type narrowing: the surrounding ternary already proved
|
|
109
|
+
// electronNativeBinding is non-null in this branch, but
|
|
110
|
+
// TypeScript can't follow that across the class boundary.
|
|
111
|
+
const fallback = electronNativeBinding as string;
|
|
112
|
+
super(filename, {
|
|
113
|
+
...options,
|
|
114
|
+
nativeBinding: options?.nativeBinding ?? fallback,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
} as typeof BetterSqlite3);
|
|
118
|
+
|
|
119
|
+
export const Database: typeof BetterSqlite3 = DatabaseImpl;
|
|
120
|
+
|
|
121
|
+
/** Instance type alias used by helpers and storage modules. */
|
|
122
|
+
export type Database = BetterSqlite3.Database;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Statement instance type used for WeakMap caches throughout the codebase.
|
|
126
|
+
*
|
|
127
|
+
* We deliberately use the variadic Statement<unknown[], unknown> shape rather
|
|
128
|
+
* than `ReturnType<Database["prepare"]>` because the latter resolves through
|
|
129
|
+
* a conditional return type in @types/better-sqlite3 that confuses TypeScript
|
|
130
|
+
* about how many arguments .run/.get/.all accept. With this explicit type,
|
|
131
|
+
* cached statements accept any number of bind args (matching bun:sqlite's
|
|
132
|
+
* historical behavior in this codebase).
|
|
133
|
+
*/
|
|
134
|
+
export type Statement = BetterSqlite3.Statement<unknown[], unknown>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { stableStringify } from "./stable-json";
|
|
3
|
+
|
|
4
|
+
describe("stableStringify", () => {
|
|
5
|
+
test("primitive values match JSON.stringify", () => {
|
|
6
|
+
expect(stableStringify("hello")).toBe('"hello"');
|
|
7
|
+
expect(stableStringify(42)).toBe("42");
|
|
8
|
+
expect(stableStringify(true)).toBe("true");
|
|
9
|
+
expect(stableStringify(false)).toBe("false");
|
|
10
|
+
expect(stableStringify(null)).toBe("null");
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test("undefined renders as literal string", () => {
|
|
14
|
+
expect(stableStringify(undefined)).toBe("undefined");
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test("object keys sort by code-point order, not locale", () => {
|
|
18
|
+
// 'Z' (0x5a) sorts before 'a' (0x61) by code-point.
|
|
19
|
+
// localeCompare would sort 'a' before 'Z' in many locales.
|
|
20
|
+
// We want code-point semantics.
|
|
21
|
+
const input = { Z: 1, a: 2 };
|
|
22
|
+
expect(stableStringify(input)).toBe('{"Z":1,"a":2}');
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test("nested objects sort recursively", () => {
|
|
26
|
+
const input = { b: { y: 1, x: 2 }, a: { z: 3, w: 4 } };
|
|
27
|
+
expect(stableStringify(input)).toBe('{"a":{"w":4,"z":3},"b":{"x":2,"y":1}}');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("arrays preserve order", () => {
|
|
31
|
+
const input = [3, 1, 2];
|
|
32
|
+
expect(stableStringify(input)).toBe("[3,1,2]");
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("arrays of objects sort keys per element", () => {
|
|
36
|
+
const input = [
|
|
37
|
+
{ b: 1, a: 2 },
|
|
38
|
+
{ d: 3, c: 4 },
|
|
39
|
+
];
|
|
40
|
+
expect(stableStringify(input)).toBe('[{"a":2,"b":1},{"c":4,"d":3}]');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test("identical objects with different key insertion order produce same string", () => {
|
|
44
|
+
const a = { foo: 1, bar: 2 };
|
|
45
|
+
const b = { bar: 2, foo: 1 };
|
|
46
|
+
expect(stableStringify(a)).toBe(stableStringify(b));
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test("circular references render as marker, do not throw", () => {
|
|
50
|
+
const a: Record<string, unknown> = { x: 1 };
|
|
51
|
+
a.self = a;
|
|
52
|
+
expect(stableStringify(a)).toBe('{"self":"[Circular]","x":1}');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test("mixed cycle through array does not crash", () => {
|
|
56
|
+
const arr: unknown[] = [];
|
|
57
|
+
arr.push(arr);
|
|
58
|
+
expect(stableStringify(arr)).toBe('["[Circular]"]');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("empty object and array", () => {
|
|
62
|
+
expect(stableStringify({})).toBe("{}");
|
|
63
|
+
expect(stableStringify([])).toBe("[]");
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test("special string characters JSON-escaped in keys", () => {
|
|
67
|
+
const input = { 'with "quotes"': 1 };
|
|
68
|
+
expect(stableStringify(input)).toBe('{"with \\"quotes\\"":1}');
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test("Unicode key sort by code-point, not by collation", () => {
|
|
72
|
+
// 'ä' (U+00E4) sorts AFTER 'z' (U+007A) by code-point.
|
|
73
|
+
// localeCompare in many locales would put 'ä' near 'a'.
|
|
74
|
+
const input = { z: 1, ä: 2 };
|
|
75
|
+
const result = stableStringify(input);
|
|
76
|
+
expect(result).toBe('{"z":1,"ä":2}');
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test("deterministic across multiple calls", () => {
|
|
80
|
+
const input = { c: 3, a: 1, b: 2 };
|
|
81
|
+
const first = stableStringify(input);
|
|
82
|
+
const second = stableStringify(input);
|
|
83
|
+
const third = stableStringify(input);
|
|
84
|
+
expect(first).toBe(second);
|
|
85
|
+
expect(second).toBe(third);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process-local deterministic JSON serialization for JSON-like plain
|
|
3
|
+
* objects. Keys are sorted by code-point order (NOT locale-sensitive).
|
|
4
|
+
*
|
|
5
|
+
* Contract:
|
|
6
|
+
* - Stable for plain objects, arrays, primitives, and `null`.
|
|
7
|
+
* - `undefined` serialized as the string "undefined".
|
|
8
|
+
* - Circular references serialized as the string `"[Circular]"`.
|
|
9
|
+
* - **NOT** a canonical cross-runtime / cross-locale JSON serializer.
|
|
10
|
+
* Two different runtimes that disagree on `JSON.stringify` of primitives
|
|
11
|
+
* (none known today) would produce different output.
|
|
12
|
+
*
|
|
13
|
+
* Used for:
|
|
14
|
+
* - `tool_definition_measurements` fingerprint hashing
|
|
15
|
+
* - `pending_compaction_marker_state` CAS comparison
|
|
16
|
+
*
|
|
17
|
+
* If a future use case needs true canonical JSON (e.g. cross-process
|
|
18
|
+
* signing), build a separate utility — do NOT widen this contract.
|
|
19
|
+
*/
|
|
20
|
+
export function stableStringify(value: unknown, seen = new WeakSet<object>()): string {
|
|
21
|
+
if (value === undefined) return "undefined";
|
|
22
|
+
if (value === null || typeof value !== "object") return JSON.stringify(value) ?? String(value);
|
|
23
|
+
if (seen.has(value)) return '"[Circular]"';
|
|
24
|
+
seen.add(value);
|
|
25
|
+
if (Array.isArray(value)) {
|
|
26
|
+
return `[${value.map((item) => stableStringify(item, seen)).join(",")}]`;
|
|
27
|
+
}
|
|
28
|
+
// Code-point sort (NOT localeCompare). Stable across runtimes/locales.
|
|
29
|
+
const entries = Object.entries(value as Record<string, unknown>).sort(([a], [b]) => {
|
|
30
|
+
if (a < b) return -1;
|
|
31
|
+
if (a > b) return 1;
|
|
32
|
+
return 0;
|
|
33
|
+
});
|
|
34
|
+
return `{${entries
|
|
35
|
+
.map(([key, child]) => `${JSON.stringify(key)}:${stableStringify(child, seen)}`)
|
|
36
|
+
.join(",")}}`;
|
|
37
|
+
}
|