@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,161 @@
|
|
|
1
|
+
import { afterEach, describe, expect, test } from "bun:test";
|
|
2
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { createServer } from "node:http";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { dirname, join } from "node:path";
|
|
6
|
+
import { MagicContextRpcClient } from "./rpc-client";
|
|
7
|
+
import { rpcPortFilePath } from "./rpc-utils";
|
|
8
|
+
|
|
9
|
+
interface TestServer {
|
|
10
|
+
port: number;
|
|
11
|
+
close: () => Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const tempDirs: string[] = [];
|
|
15
|
+
let servers: TestServer[] = [];
|
|
16
|
+
|
|
17
|
+
afterEach(async () => {
|
|
18
|
+
for (const server of servers.splice(0)) {
|
|
19
|
+
await server.close();
|
|
20
|
+
}
|
|
21
|
+
for (const dir of tempDirs.splice(0)) {
|
|
22
|
+
rmSync(dir, { recursive: true, force: true });
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
function makeTempDir(): string {
|
|
27
|
+
const dir = mkdtempSync(join(tmpdir(), "mc-rpc-client-"));
|
|
28
|
+
tempDirs.push(dir);
|
|
29
|
+
return dir;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function writePortFile(storageDir: string, directory: string, port: number): void {
|
|
33
|
+
const portFile = rpcPortFilePath(storageDir, directory);
|
|
34
|
+
mkdirSync(dirname(portFile), { recursive: true });
|
|
35
|
+
writeFileSync(
|
|
36
|
+
portFile,
|
|
37
|
+
JSON.stringify({ port, pid: process.pid, started_at: Date.now() }),
|
|
38
|
+
"utf-8",
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function writePortFileForPid(
|
|
43
|
+
storageDir: string,
|
|
44
|
+
directory: string,
|
|
45
|
+
port: number,
|
|
46
|
+
pid: number,
|
|
47
|
+
startedAt: number,
|
|
48
|
+
): void {
|
|
49
|
+
const portFile = rpcPortFilePath(storageDir, directory, pid);
|
|
50
|
+
mkdirSync(dirname(portFile), { recursive: true });
|
|
51
|
+
writeFileSync(portFile, JSON.stringify({ port, pid, started_at: startedAt }), "utf-8");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function startRpcServer(handler: (method: string) => Response | object): Promise<TestServer> {
|
|
55
|
+
const server = createServer(async (req, res) => {
|
|
56
|
+
if (req.method === "GET" && req.url === "/health") {
|
|
57
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
58
|
+
res.end(JSON.stringify({ ok: true }));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (req.method === "POST" && req.url?.startsWith("/rpc/")) {
|
|
63
|
+
const method = req.url.slice("/rpc/".length);
|
|
64
|
+
const result = handler(method);
|
|
65
|
+
if (result instanceof Response) {
|
|
66
|
+
res.writeHead(result.status, { "Content-Type": "application/json" });
|
|
67
|
+
res.end(await result.text());
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
71
|
+
res.end(JSON.stringify(result));
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
res.writeHead(404);
|
|
76
|
+
res.end("Not Found");
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
await new Promise<void>((resolve, reject) => {
|
|
80
|
+
server.once("error", reject);
|
|
81
|
+
server.listen(0, "127.0.0.1", () => resolve());
|
|
82
|
+
});
|
|
83
|
+
const addr = server.address();
|
|
84
|
+
if (!addr || typeof addr === "string") throw new Error("failed to bind test server");
|
|
85
|
+
|
|
86
|
+
const testServer = {
|
|
87
|
+
port: addr.port,
|
|
88
|
+
close: () =>
|
|
89
|
+
new Promise<void>((resolve, reject) => {
|
|
90
|
+
server.close((err) => (err ? reject(err) : resolve()));
|
|
91
|
+
}),
|
|
92
|
+
};
|
|
93
|
+
servers.push(testServer);
|
|
94
|
+
return testServer;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async function closeServer(server: TestServer): Promise<void> {
|
|
98
|
+
servers = servers.filter((s) => s !== server);
|
|
99
|
+
await server.close();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
describe("MagicContextRpcClient", () => {
|
|
103
|
+
test("re-reads the port file after the cached server restarts on a new port", async () => {
|
|
104
|
+
const storageDir = makeTempDir();
|
|
105
|
+
const directory = "/repo";
|
|
106
|
+
const client = new MagicContextRpcClient(storageDir, directory);
|
|
107
|
+
|
|
108
|
+
const first = await startRpcServer(() => ({ value: "first" }));
|
|
109
|
+
writePortFile(storageDir, directory, first.port);
|
|
110
|
+
expect(await client.call<{ value: string }>("value")).toEqual({ value: "first" });
|
|
111
|
+
|
|
112
|
+
await closeServer(first);
|
|
113
|
+
const second = await startRpcServer(() => ({ value: "second" }));
|
|
114
|
+
writePortFile(storageDir, directory, second.port);
|
|
115
|
+
|
|
116
|
+
expect(await client.call<{ value: string }>("value")).toEqual({ value: "second" });
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
test("gives up when the port file points at a dead server", async () => {
|
|
120
|
+
const storageDir = makeTempDir();
|
|
121
|
+
const directory = "/repo";
|
|
122
|
+
const dead = await startRpcServer(() => ({ ok: true }));
|
|
123
|
+
const port = dead.port;
|
|
124
|
+
await closeServer(dead);
|
|
125
|
+
writePortFile(storageDir, directory, port);
|
|
126
|
+
|
|
127
|
+
const client = new MagicContextRpcClient(storageDir, directory);
|
|
128
|
+
await expect(client.call("value")).rejects.toThrow(
|
|
129
|
+
"Magic Context RPC server not available",
|
|
130
|
+
);
|
|
131
|
+
}, 20_000);
|
|
132
|
+
|
|
133
|
+
test("re-resolves and retries transient 5xx responses", async () => {
|
|
134
|
+
const storageDir = makeTempDir();
|
|
135
|
+
const directory = "/repo";
|
|
136
|
+
let calls = 0;
|
|
137
|
+
const server = await startRpcServer(() => {
|
|
138
|
+
calls++;
|
|
139
|
+
if (calls === 1) {
|
|
140
|
+
return new Response(JSON.stringify({ error: "warming up" }), { status: 503 });
|
|
141
|
+
}
|
|
142
|
+
return { value: "ok" };
|
|
143
|
+
});
|
|
144
|
+
writePortFile(storageDir, directory, server.port);
|
|
145
|
+
|
|
146
|
+
const client = new MagicContextRpcClient(storageDir, directory);
|
|
147
|
+
expect(await client.call<{ value: string }>("value")).toEqual({ value: "ok" });
|
|
148
|
+
expect(calls).toBe(2);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test("ignores newer stale pid files and discovers the latest live instance", async () => {
|
|
152
|
+
const storageDir = makeTempDir();
|
|
153
|
+
const directory = "/repo";
|
|
154
|
+
const live = await startRpcServer(() => ({ value: "live" }));
|
|
155
|
+
writePortFileForPid(storageDir, directory, 65535, 999_999_999, Date.now() + 10_000);
|
|
156
|
+
writePortFileForPid(storageDir, directory, live.port, process.pid, Date.now());
|
|
157
|
+
|
|
158
|
+
const client = new MagicContextRpcClient(storageDir, directory);
|
|
159
|
+
expect(await client.call<{ value: string }>("value")).toEqual({ value: "live" });
|
|
160
|
+
});
|
|
161
|
+
});
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import {
|
|
4
|
+
isPidAlive,
|
|
5
|
+
legacyRpcPortFilePath,
|
|
6
|
+
parseRpcPortFile,
|
|
7
|
+
type RpcPortFileRecord,
|
|
8
|
+
rpcPortDir,
|
|
9
|
+
} from "./rpc-utils";
|
|
10
|
+
|
|
11
|
+
const MAX_RETRIES = 10;
|
|
12
|
+
const RETRY_DELAY_MS = 500;
|
|
13
|
+
const REQUEST_TIMEOUT_MS = 5000;
|
|
14
|
+
const MAX_RERESOLVE_ATTEMPTS = 3;
|
|
15
|
+
const NON_RETRYABLE_RPC_ERROR = Symbol("nonRetryableRpcError");
|
|
16
|
+
type NonRetryableRpcError = Error & { [NON_RETRYABLE_RPC_ERROR]: true };
|
|
17
|
+
|
|
18
|
+
export class MagicContextRpcClient {
|
|
19
|
+
private port: number | null = null;
|
|
20
|
+
private portDir: string;
|
|
21
|
+
private legacyPortFilePath: string;
|
|
22
|
+
private healthChecked = false;
|
|
23
|
+
|
|
24
|
+
constructor(storageDir: string, directory: string) {
|
|
25
|
+
this.portDir = rpcPortDir(storageDir, directory);
|
|
26
|
+
this.legacyPortFilePath = legacyRpcPortFilePath(storageDir, directory);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Call an RPC method. Retries port resolution if the server isn't ready yet. */
|
|
30
|
+
async call<T = Record<string, unknown>>(
|
|
31
|
+
method: string,
|
|
32
|
+
params: Record<string, unknown> = {},
|
|
33
|
+
): Promise<T> {
|
|
34
|
+
let lastError: unknown = null;
|
|
35
|
+
|
|
36
|
+
for (let attempt = 0; attempt < MAX_RERESOLVE_ATTEMPTS; attempt++) {
|
|
37
|
+
const port = await this.resolvePort();
|
|
38
|
+
if (!port) {
|
|
39
|
+
lastError = new Error("Magic Context RPC server not available");
|
|
40
|
+
this.reset();
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
const response = await this.fetchWithTimeout(
|
|
46
|
+
`http://127.0.0.1:${port}/rpc/${method}`,
|
|
47
|
+
{
|
|
48
|
+
method: "POST",
|
|
49
|
+
headers: { "Content-Type": "application/json" },
|
|
50
|
+
body: JSON.stringify(params),
|
|
51
|
+
},
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
if (!response.ok) {
|
|
55
|
+
const text = await response.text();
|
|
56
|
+
const error = new Error(`RPC ${method} failed (${response.status}): ${text}`);
|
|
57
|
+
if (response.status >= 500) {
|
|
58
|
+
lastError = error;
|
|
59
|
+
this.reset();
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
(error as NonRetryableRpcError)[NON_RETRYABLE_RPC_ERROR] = true;
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return (await response.json()) as T;
|
|
67
|
+
} catch (err) {
|
|
68
|
+
if (isNonRetryableRpcError(err)) {
|
|
69
|
+
throw err;
|
|
70
|
+
}
|
|
71
|
+
lastError = err;
|
|
72
|
+
this.reset();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (lastError instanceof Error) {
|
|
77
|
+
throw lastError;
|
|
78
|
+
}
|
|
79
|
+
throw new Error("Magic Context RPC server not available");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Check if the RPC server is reachable. */
|
|
83
|
+
async isAvailable(): Promise<boolean> {
|
|
84
|
+
try {
|
|
85
|
+
const port = await this.resolvePort();
|
|
86
|
+
return port !== null;
|
|
87
|
+
} catch {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private async resolvePort(): Promise<number | null> {
|
|
93
|
+
if (this.port && this.healthChecked) {
|
|
94
|
+
return this.port;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (this.port) {
|
|
98
|
+
const alive = await this.healthCheck(this.port);
|
|
99
|
+
if (alive) {
|
|
100
|
+
this.healthChecked = true;
|
|
101
|
+
return this.port;
|
|
102
|
+
}
|
|
103
|
+
this.port = null;
|
|
104
|
+
this.healthChecked = false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
|
|
108
|
+
const port = this.readPortFile();
|
|
109
|
+
if (port) {
|
|
110
|
+
const alive = await this.healthCheck(port);
|
|
111
|
+
if (alive) {
|
|
112
|
+
this.port = port;
|
|
113
|
+
this.healthChecked = true;
|
|
114
|
+
return port;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (attempt < MAX_RETRIES - 1) {
|
|
119
|
+
await new Promise((r) => setTimeout(r, RETRY_DELAY_MS));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
private readPortFile(): number | null {
|
|
127
|
+
const records: RpcPortFileRecord[] = [];
|
|
128
|
+
|
|
129
|
+
try {
|
|
130
|
+
for (const entry of readdirSync(this.portDir)) {
|
|
131
|
+
if (!entry.startsWith("port-") || !entry.endsWith(".json")) continue;
|
|
132
|
+
const record = parseRpcPortFile(readFileSync(join(this.portDir, entry), "utf-8"));
|
|
133
|
+
if (!record || !isPidAlive(record.pid)) continue;
|
|
134
|
+
records.push(record);
|
|
135
|
+
}
|
|
136
|
+
} catch {
|
|
137
|
+
// Directory may not exist yet. Fall back to the legacy file below.
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (records.length > 0) {
|
|
141
|
+
records.sort((a, b) => b.started_at - a.started_at);
|
|
142
|
+
return records[0].port;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
const record = parseRpcPortFile(readFileSync(this.legacyPortFilePath, "utf-8"));
|
|
147
|
+
if (record?.pid && !isPidAlive(record.pid)) return null;
|
|
148
|
+
return record?.port ?? null;
|
|
149
|
+
} catch {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
private async healthCheck(port: number): Promise<boolean> {
|
|
155
|
+
try {
|
|
156
|
+
const response = await this.fetchWithTimeout(`http://127.0.0.1:${port}/health`, {
|
|
157
|
+
method: "GET",
|
|
158
|
+
});
|
|
159
|
+
return response.ok;
|
|
160
|
+
} catch {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private async fetchWithTimeout(url: string, options: RequestInit): Promise<Response> {
|
|
166
|
+
const controller = new AbortController();
|
|
167
|
+
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
168
|
+
try {
|
|
169
|
+
return await fetch(url, { ...options, signal: controller.signal });
|
|
170
|
+
} finally {
|
|
171
|
+
clearTimeout(timeout);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
reset(): void {
|
|
176
|
+
this.port = null;
|
|
177
|
+
this.healthChecked = false;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function isNonRetryableRpcError(err: unknown): err is NonRetryableRpcError {
|
|
182
|
+
return typeof err === "object" && err !== null && NON_RETRYABLE_RPC_ERROR in err;
|
|
183
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { drainNotifications, pushNotification } from "./rpc-notifications";
|
|
3
|
+
|
|
4
|
+
describe("rpc notifications", () => {
|
|
5
|
+
test("keeps messages queued until the client acks their id", () => {
|
|
6
|
+
const initial = drainNotifications(Number.MAX_SAFE_INTEGER);
|
|
7
|
+
expect(initial).toEqual([]);
|
|
8
|
+
|
|
9
|
+
pushNotification("one", { ok: true }, "ses_1");
|
|
10
|
+
const firstPoll = drainNotifications();
|
|
11
|
+
expect(firstPoll).toHaveLength(1);
|
|
12
|
+
expect(firstPoll[0].type).toBe("one");
|
|
13
|
+
|
|
14
|
+
const retryPoll = drainNotifications();
|
|
15
|
+
expect(retryPoll.map((m) => m.id)).toEqual(firstPoll.map((m) => m.id));
|
|
16
|
+
|
|
17
|
+
const lastReceivedId = Math.max(...firstPoll.map((m) => m.id));
|
|
18
|
+
expect(drainNotifications(lastReceivedId)).toEqual([]);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory notification queue for server→TUI push.
|
|
3
|
+
* Replaces SQLite plugin_messages table.
|
|
4
|
+
*
|
|
5
|
+
* Also tracks whether a TUI client is actively connected (polling).
|
|
6
|
+
* The server plugin cannot use `process.env.OPENCODE_CLIENT` to detect TUI
|
|
7
|
+
* because the server runs in a separate process from the TUI client.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export interface RpcNotification {
|
|
11
|
+
id: number;
|
|
12
|
+
type: string;
|
|
13
|
+
payload: Record<string, unknown>;
|
|
14
|
+
sessionId?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let queue: RpcNotification[] = [];
|
|
18
|
+
let nextNotificationId = 1;
|
|
19
|
+
// Timestamp of last drain — used to detect if TUI is actively polling.
|
|
20
|
+
// The TUI polls every 500ms; we consider it connected if it polled within
|
|
21
|
+
// the last 3 seconds (6× the poll interval, tolerates transient delays).
|
|
22
|
+
let lastDrainAt = 0;
|
|
23
|
+
const TUI_CONNECTED_WINDOW_MS = 3_000;
|
|
24
|
+
|
|
25
|
+
/** Push a notification for TUI to pick up via polling. */
|
|
26
|
+
export function pushNotification(
|
|
27
|
+
type: string,
|
|
28
|
+
payload: Record<string, unknown>,
|
|
29
|
+
sessionId?: string,
|
|
30
|
+
): void {
|
|
31
|
+
queue.push({ id: nextNotificationId++, type, payload, sessionId });
|
|
32
|
+
// Cap queue size to prevent unbounded growth if TUI is not polling
|
|
33
|
+
if (queue.length > 100) {
|
|
34
|
+
queue = queue.slice(-50);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Return pending notifications after acking the client's last received id.
|
|
39
|
+
* Updates lastDrainAt so isTuiConnected() reflects recent activity. */
|
|
40
|
+
export function drainNotifications(lastReceivedId = 0): RpcNotification[] {
|
|
41
|
+
lastDrainAt = Date.now();
|
|
42
|
+
if (lastReceivedId > 0) {
|
|
43
|
+
queue = queue.filter((notification) => notification.id > lastReceivedId);
|
|
44
|
+
}
|
|
45
|
+
return [...queue];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Whether a TUI client is actively polling for notifications.
|
|
49
|
+
* Returns true only if the TUI has drained within the last 3 seconds.
|
|
50
|
+
* This prevents stale-connected state after TUI closes or disconnects. */
|
|
51
|
+
export function isTuiConnected(): boolean {
|
|
52
|
+
return lastDrainAt > 0 && Date.now() - lastDrainAt < TUI_CONNECTED_WINDOW_MS;
|
|
53
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import {
|
|
2
|
+
mkdirSync,
|
|
3
|
+
readdirSync,
|
|
4
|
+
readFileSync,
|
|
5
|
+
renameSync,
|
|
6
|
+
unlinkSync,
|
|
7
|
+
writeFileSync,
|
|
8
|
+
} from "node:fs";
|
|
9
|
+
import { createServer, type IncomingMessage, type Server, type ServerResponse } from "node:http";
|
|
10
|
+
import { dirname } from "node:path";
|
|
11
|
+
import { log } from "./logger";
|
|
12
|
+
import { isPidAlive, parseRpcPortFile, rpcPortDir, rpcPortFilePath } from "./rpc-utils";
|
|
13
|
+
|
|
14
|
+
type RpcHandler = (params: Record<string, unknown>) => Promise<Record<string, unknown>>;
|
|
15
|
+
|
|
16
|
+
export class MagicContextRpcServer {
|
|
17
|
+
private server: Server | null = null;
|
|
18
|
+
private port = 0;
|
|
19
|
+
private handlers = new Map<string, RpcHandler>();
|
|
20
|
+
private portFilePath: string;
|
|
21
|
+
private portDir: string;
|
|
22
|
+
private startedAt = Date.now();
|
|
23
|
+
|
|
24
|
+
constructor(storageDir: string, directory: string) {
|
|
25
|
+
this.portFilePath = rpcPortFilePath(storageDir, directory);
|
|
26
|
+
this.portDir = rpcPortDir(storageDir, directory);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Register an RPC method handler. */
|
|
30
|
+
handle(method: string, handler: RpcHandler): void {
|
|
31
|
+
this.handlers.set(method, handler);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Start the server on a random port, write port to disk. */
|
|
35
|
+
async start(): Promise<number> {
|
|
36
|
+
return new Promise((resolve, reject) => {
|
|
37
|
+
const server = createServer((req, res) => this.dispatch(req, res));
|
|
38
|
+
|
|
39
|
+
server.on("error", (err) => {
|
|
40
|
+
log(`[rpc] server error: ${err.message}`);
|
|
41
|
+
reject(err);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
server.listen(0, "127.0.0.1", () => {
|
|
45
|
+
const addr = server.address();
|
|
46
|
+
if (!addr || typeof addr === "string") {
|
|
47
|
+
reject(new Error("Failed to get server address"));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
this.port = addr.port;
|
|
51
|
+
this.server = server;
|
|
52
|
+
|
|
53
|
+
// Write a per-process port file atomically. Multi-instance
|
|
54
|
+
// OpenCode is supported: TUI discovery scans all live pid files
|
|
55
|
+
// and picks the most recent instead of cross-wiring via one
|
|
56
|
+
// shared project file.
|
|
57
|
+
try {
|
|
58
|
+
this.warnIfOtherLiveInstance();
|
|
59
|
+
const dir = dirname(this.portFilePath);
|
|
60
|
+
mkdirSync(dir, { recursive: true });
|
|
61
|
+
const tmpPath = `${this.portFilePath}.tmp`;
|
|
62
|
+
writeFileSync(
|
|
63
|
+
tmpPath,
|
|
64
|
+
JSON.stringify({
|
|
65
|
+
port: this.port,
|
|
66
|
+
pid: process.pid,
|
|
67
|
+
started_at: this.startedAt,
|
|
68
|
+
}),
|
|
69
|
+
"utf-8",
|
|
70
|
+
);
|
|
71
|
+
renameSync(tmpPath, this.portFilePath);
|
|
72
|
+
log(`[rpc] server listening on 127.0.0.1:${this.port}`);
|
|
73
|
+
} catch (err) {
|
|
74
|
+
log(`[rpc] failed to write port file: ${err}`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
resolve(this.port);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Don't keep the process alive just for the RPC server
|
|
81
|
+
server.unref();
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private warnIfOtherLiveInstance(): void {
|
|
86
|
+
try {
|
|
87
|
+
for (const entry of readdirSync(this.portDir)) {
|
|
88
|
+
if (!entry.startsWith("port-") || !entry.endsWith(".json")) continue;
|
|
89
|
+
const record = parseRpcPortFile(readFileSync(`${this.portDir}/${entry}`, "utf-8"));
|
|
90
|
+
if (!record || record.pid === process.pid || !isPidAlive(record.pid)) continue;
|
|
91
|
+
log(
|
|
92
|
+
`[rpc] another Magic Context RPC server is active for this project (pid ${record.pid}, port ${record.port}); starting separate instance on a new port`,
|
|
93
|
+
);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
} catch {
|
|
97
|
+
// No discovery directory yet, or unreadable stale file. Not fatal.
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Stop the server and clean up port file. */
|
|
102
|
+
stop(): void {
|
|
103
|
+
if (this.server) {
|
|
104
|
+
this.server.close();
|
|
105
|
+
this.server = null;
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
unlinkSync(this.portFilePath);
|
|
109
|
+
} catch {
|
|
110
|
+
// Intentional: port file may already be gone
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private dispatch(req: IncomingMessage, res: ServerResponse): void {
|
|
115
|
+
const url = req.url ?? "";
|
|
116
|
+
|
|
117
|
+
// CORS headers for same-origin fetch
|
|
118
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
119
|
+
|
|
120
|
+
if (req.method === "GET" && url === "/health") {
|
|
121
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
122
|
+
res.end(JSON.stringify({ ok: true, pid: process.pid }));
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (req.method !== "POST" || !url.startsWith("/rpc/")) {
|
|
127
|
+
res.writeHead(404);
|
|
128
|
+
res.end("Not Found");
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const method = url.slice(5); // strip "/rpc/"
|
|
133
|
+
const handler = this.handlers.get(method);
|
|
134
|
+
if (!handler) {
|
|
135
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
136
|
+
res.end(JSON.stringify({ error: `Unknown method: ${method}` }));
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
let body = "";
|
|
141
|
+
req.on("data", (chunk: Buffer) => {
|
|
142
|
+
body += chunk.toString();
|
|
143
|
+
if (body.length > 1_048_576) {
|
|
144
|
+
res.writeHead(413);
|
|
145
|
+
res.end("Request too large");
|
|
146
|
+
req.destroy();
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
req.on("end", () => {
|
|
151
|
+
let params: Record<string, unknown> = {};
|
|
152
|
+
try {
|
|
153
|
+
if (body.length > 0) {
|
|
154
|
+
params = JSON.parse(body);
|
|
155
|
+
}
|
|
156
|
+
} catch {
|
|
157
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
158
|
+
res.end(JSON.stringify({ error: "Invalid JSON" }));
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
handler(params)
|
|
163
|
+
.then((result) => {
|
|
164
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
165
|
+
res.end(JSON.stringify(result));
|
|
166
|
+
})
|
|
167
|
+
.catch((err) => {
|
|
168
|
+
log(`[rpc] handler error: ${method} => ${err}`);
|
|
169
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
170
|
+
res.end(JSON.stringify({ error: String(err) }));
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for RPC between server and TUI plugins.
|
|
3
|
+
* Both sides import these — no SQLite dependency.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface SidebarSnapshot {
|
|
7
|
+
sessionId: string;
|
|
8
|
+
usagePercentage: number;
|
|
9
|
+
inputTokens: number;
|
|
10
|
+
contextLimit: number;
|
|
11
|
+
systemPromptTokens: number;
|
|
12
|
+
compartmentCount: number;
|
|
13
|
+
factCount: number;
|
|
14
|
+
memoryCount: number;
|
|
15
|
+
memoryBlockCount: number;
|
|
16
|
+
pendingOpsCount: number;
|
|
17
|
+
historianRunning: boolean;
|
|
18
|
+
compartmentInProgress: boolean;
|
|
19
|
+
sessionNoteCount: number;
|
|
20
|
+
readySmartNoteCount: number;
|
|
21
|
+
cacheTtl: string;
|
|
22
|
+
lastDreamerRunAt: number | null;
|
|
23
|
+
projectIdentity: string | null;
|
|
24
|
+
compartmentTokens: number;
|
|
25
|
+
factTokens: number;
|
|
26
|
+
memoryTokens: number;
|
|
27
|
+
/**
|
|
28
|
+
* Token estimate of real user/assistant discussion (text + reasoning +
|
|
29
|
+
* image parts) inside messages, excluding injected <session-history>
|
|
30
|
+
* blocks. Display layer shows this as "Conversation".
|
|
31
|
+
*/
|
|
32
|
+
conversationTokens: number;
|
|
33
|
+
/**
|
|
34
|
+
* Token estimate of tool call I/O inside messages (tool_use, tool_result,
|
|
35
|
+
* tool, tool-invocation parts). Actionable — users can reduce via
|
|
36
|
+
* ctx_reduce. Display layer shows this as "Tool Calls".
|
|
37
|
+
*/
|
|
38
|
+
toolCallTokens: number;
|
|
39
|
+
/**
|
|
40
|
+
* Measured token cost of tool schemas (description + JSON-schema
|
|
41
|
+
* parameters) OpenCode sends in the request `tools` parameter. Populated
|
|
42
|
+
* by the `tool.definition` plugin hook, keyed by
|
|
43
|
+
* `{providerID, modelID, agentName}`. Zero until the first turn after
|
|
44
|
+
* plugin startup measures the current agent's tool set. Display layer
|
|
45
|
+
* shows this as "Tool Definitions".
|
|
46
|
+
*/
|
|
47
|
+
toolDefinitionTokens: number;
|
|
48
|
+
/**
|
|
49
|
+
* Effective execute-threshold percentage for this session's active model,
|
|
50
|
+
* after per-model resolution and the tokens→percentage conversion (when
|
|
51
|
+
* `execute_threshold_tokens` applies). Surfaces in the sidebar / status
|
|
52
|
+
* dialog header alongside `usagePercentage` so users can see how close
|
|
53
|
+
* the session is to triggering compaction. Defaults to `65` when no live
|
|
54
|
+
* model is known yet — matches the runtime fallback used by the
|
|
55
|
+
* scheduler and transform paths.
|
|
56
|
+
*/
|
|
57
|
+
executeThreshold: number;
|
|
58
|
+
newWorkTokens?: number | null;
|
|
59
|
+
totalInputTokens?: number | null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface StatusDetail extends SidebarSnapshot {
|
|
63
|
+
tagCounter: number;
|
|
64
|
+
activeTags: number;
|
|
65
|
+
droppedTags: number;
|
|
66
|
+
totalTags: number;
|
|
67
|
+
activeBytes: number;
|
|
68
|
+
lastResponseTime: number;
|
|
69
|
+
lastNudgeTokens: number;
|
|
70
|
+
lastNudgeBand: string;
|
|
71
|
+
lastTransformError: string | null;
|
|
72
|
+
isSubagent: boolean;
|
|
73
|
+
pendingOps: Array<{ tagId: number; operation: string }>;
|
|
74
|
+
contextLimit: number;
|
|
75
|
+
cacheTtlMs: number;
|
|
76
|
+
cacheRemainingMs: number;
|
|
77
|
+
cacheExpired: boolean;
|
|
78
|
+
executeThreshold: number;
|
|
79
|
+
/**
|
|
80
|
+
* Which config source produced `executeThreshold`. "tokens" means
|
|
81
|
+
* execute_threshold_tokens matched for this session's model and was
|
|
82
|
+
* converted to a percentage. "percentage" means percentage config was used.
|
|
83
|
+
*/
|
|
84
|
+
executeThresholdMode: "percentage" | "tokens";
|
|
85
|
+
/**
|
|
86
|
+
* When `executeThresholdMode === "tokens"`, the absolute clamped token value
|
|
87
|
+
* (≤ 80% × contextLimit) that will trigger execute. Undefined in percentage mode.
|
|
88
|
+
*/
|
|
89
|
+
executeThresholdTokens?: number;
|
|
90
|
+
protectedTagCount: number;
|
|
91
|
+
nudgeInterval: number;
|
|
92
|
+
historyBudgetPercentage: number;
|
|
93
|
+
nextNudgeAfter: number;
|
|
94
|
+
historyBlockTokens: number;
|
|
95
|
+
compressionBudget: number | null;
|
|
96
|
+
compressionUsage: string | null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface RpcNotificationMessage {
|
|
100
|
+
id: number;
|
|
101
|
+
type: string;
|
|
102
|
+
payload: Record<string, unknown>;
|
|
103
|
+
sessionId?: string;
|
|
104
|
+
}
|