mixdog 1.4.0 → 1.4.2
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/package.json +3 -2
- package/scripts/build-shipped-history.mjs +115 -33
- package/scripts/check-voice-runtime-inputs.mjs +25 -0
- package/scripts/gate-local.mjs +183 -63
- package/scripts/latest-guard.mjs +21 -9
- package/scripts/lib/gate-scheduler.mjs +138 -32
- package/scripts/lib/gate-timing-reporter.mjs +16 -0
- package/scripts/lib/isolated-test-env.mjs +10 -5
- package/scripts/lib/run-node-tests.mjs +91 -66
- package/scripts/lib/scoped-temp.d.mts +16 -0
- package/scripts/lib/scoped-temp.mjs +124 -0
- package/scripts/lib/stale-temp.mjs +44 -0
- package/scripts/lib/test-failure-records.mjs +14 -1
- package/scripts/lib/test-failure-summary.mjs +16 -4
- package/scripts/lib/test-spawn-ledger.mjs +12 -3
- package/scripts/post-release-check.mjs +1 -6
- package/scripts/pptx-kit-index.mjs +17 -5
- package/scripts/suite-health.mjs +115 -24
- package/scripts/test-data-dir.mjs +10 -7
- package/scripts/test.mjs +9 -14
- package/src/agents/advisor/AGENT.md +4 -4
- package/src/agents/advisor/agent.json +1 -1
- package/src/agents/explore/AGENT.md +22 -0
- package/src/agents/explore/agent.json +6 -0
- package/src/app.mjs +4 -0
- package/src/cli.mjs +7 -0
- package/src/defaults/agents.json +7 -0
- package/src/defaults/shipped-history.json +23 -2
- package/src/defaults/skills/browser-use/SKILL.md +10 -5
- package/src/defaults/skills/code-tidy/SKILL.md +71 -102
- package/src/defaults/skills/code-tidy/references/agent-cleanup.md +66 -114
- package/src/defaults/skills/code-tidy/references/cleanup-report.md +19 -35
- package/src/defaults/skills/code-tidy/references/dead-code.md +3 -9
- package/src/defaults/skills/code-tidy/references/test-suite-slop.md +16 -27
- package/src/defaults/skills/computer-use/SKILL.md +16 -4
- package/src/defaults/skills/goal-management/SKILL.md +1 -1
- package/src/defaults/skills/setup/references/actions.md +12 -6
- package/src/defaults/skills/setup/references/surfaces.md +2 -2
- package/src/defaults/skills/setup-guide/SKILL.md +5 -2
- package/src/defaults/skills/setup-guide/model-recommendations.json +13 -0
- package/src/defaults/skills/skill-creator/SKILL.md +85 -190
- package/src/defaults/skills/skill-creator/references/design.md +70 -162
- package/src/defaults/skills/skill-creator/references/evaluation.md +33 -92
- package/src/defaults/skills/test-suite/SKILL.md +194 -0
- package/src/defaults/skills/test-suite/references/case-management.md +51 -0
- package/src/defaults/skills/test-suite/references/flaky-policy.md +39 -0
- package/src/defaults/skills/test-suite/references/reliability.md +49 -0
- package/src/defaults/skills/test-suite/references/suite-design.md +78 -0
- package/src/defaults/skills/test-suite/scripts/inventory.mjs +335 -0
- package/src/defaults/skills/visualize/SKILL.md +6 -2
- package/src/lib/rules-builder.cjs +35 -42
- package/src/output-styles/common.md +2 -2
- package/src/output-styles/simple.md +1 -1
- package/src/rules/agent/AGENT.md +5 -4
- package/src/rules/lead/LEAD.md +12 -7
- package/src/rules/shared/10-tool-workflow.md +3 -1
- package/src/rules/shared/20-research.md +3 -6
- package/src/rules/shared/40-editing.md +1 -0
- package/src/rules/shared/45-destructive.md +0 -2
- package/src/rules/shared/50-execution.md +2 -0
- package/src/rules/shared/60-verification.md +10 -9
- package/src/rules/shared/70-delivery.md +8 -9
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/abort-link.mjs +5 -1
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +10 -1
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +156 -24
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +13 -0
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +4 -1
- package/src/runtime/agent/orchestrator/cache-break-trace.mjs +2 -0
- package/src/runtime/agent/orchestrator/config.mjs +12 -7
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +8 -8
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +5 -26
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +3 -1
- package/src/runtime/agent/orchestrator/internal-agents.mjs +3 -14
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +122 -12
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +5 -3
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +13 -2
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +152 -58
- package/src/runtime/agent/orchestrator/mcp/client.mjs +51 -18
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +88 -54
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +42 -26
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +54 -8
- package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +37 -31
- package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +8 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +31 -21
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +14 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +6 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +40 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider-keys.mjs +34 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +14 -7
- package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/devin.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +248 -41
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -11
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +45 -6
- package/src/runtime/agent/orchestrator/providers/lib/first-output-window.mjs +58 -0
- package/src/runtime/agent/orchestrator/providers/lib/listen-on.mjs +14 -0
- package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +0 -18
- package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +138 -6
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/model-cache.mjs +100 -33
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/oauth-secret-fields.fixtures.mjs +45 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +14 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +5 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +16 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +13 -3
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +13 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +81 -42
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +8 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +160 -31
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +22 -12
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +49 -22
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/registry.mjs +45 -2
- package/src/runtime/agent/orchestrator/providers/vertex-ai-auth.mjs +622 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai-maas.mjs +185 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai-models.mjs +445 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +567 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +41 -13
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +2 -0
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +8 -6
- package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +7 -3
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +6 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +14 -5
- package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -0
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -5
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +171 -37
- package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +1 -3
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +102 -12
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -8
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +23 -0
- package/src/runtime/agent/orchestrator/session/compact/observation-supersession.mjs +103 -23
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +160 -36
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +164 -23
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +139 -19
- package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +38 -7
- package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +100 -22
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -3
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -6
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +33 -3
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +9 -2
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +13 -5
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +14 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +23 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +23 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +39 -21
- package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +13 -8
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +50 -28
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +30 -13
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +63 -6
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +7 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +35 -13
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +24 -14
- package/src/runtime/agent/orchestrator/session/manager/session-scratch-environment.mjs +70 -0
- package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +0 -3
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +10 -6
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +56 -29
- package/src/runtime/agent/orchestrator/session/manager/turn-reap.mjs +125 -0
- package/src/runtime/agent/orchestrator/session/mixy-name.mjs +11 -5
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +30 -7
- package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +154 -0
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +7 -0
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +37 -8
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +252 -39
- package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +163 -64
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +164 -4
- package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +142 -18
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +61 -2
- package/src/runtime/agent/orchestrator/stall-policy.mjs +23 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +46 -20
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +67 -31
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +25 -13
- package/src/runtime/agent/orchestrator/tools/builtin/lib/scoped-search-flight.mjs +9 -5
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +58 -20
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +6 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +23 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +1 -8
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +20 -15
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +96 -20
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +59 -10
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/federation.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/lib/isolated-test-env.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.mjs +99 -2
- package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +103 -13
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +49 -15
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +45 -27
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +34 -10
- package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +28 -4
- package/src/runtime/agent/orchestrator/tools/lib/wait-until-fixture.mjs +26 -0
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -2
- package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
- package/src/runtime/channels/lib/webhook/signature.mjs +4 -1
- package/src/runtime/channels/lib/whisper-port.mjs +29 -11
- package/src/runtime/channels/lib/whisper-server.mjs +10 -1
- package/src/runtime/computer-bridge/action-schema.mjs +2 -2
- package/src/runtime/computer-bridge/core-actions.mjs +2 -2
- package/src/runtime/computer-bridge/error-recovery.mjs +5 -4
- package/src/runtime/computer-bridge/linux-action-capabilities.mjs +24 -5
- package/src/runtime/computer-bridge/linux-readiness.d.mts +7 -2
- package/src/runtime/connectors/connector-accounts-mcp.mjs +236 -103
- package/src/runtime/connectors/gmail-app-password.mjs +3 -3
- package/src/runtime/explore/explorer.mjs +93 -0
- package/src/runtime/explore/tool-defs.mjs +35 -0
- package/src/runtime/explore/tool.mjs +123 -0
- package/src/runtime/local-provider/server-process.mjs +2 -1
- package/src/runtime/media/adapters/gemini-video.mjs +4 -1
- package/src/runtime/media/adapters/xai-media.mjs +2 -1
- package/src/runtime/memory/index.mjs +4 -0
- package/src/runtime/memory/lib/embedding-provider.mjs +4 -1
- package/src/runtime/memory/lib/embedding-worker.mjs +10 -3
- package/src/runtime/memory/lib/memory-action-handlers/cycle-backfill-action.mjs +1 -7
- package/src/runtime/memory/lib/memory-chunk-quality.mjs +1 -6
- package/src/runtime/office/authoring/pdf-author-action.mjs +1 -6
- package/src/runtime/office/design/design-art-direction.mjs +29 -27
- package/src/runtime/office/pdf/pdf-writer.mjs +6 -1
- package/src/runtime/office/portable/portable-snapshot-docx.mjs +7 -1
- package/src/runtime/office/portable/portable-snapshot-shared.mjs +6 -1
- package/src/runtime/office/quality/assurance-rendered.mjs +9 -2
- package/src/runtime/office/quality/assurance-structure-docx.mjs +4 -2
- package/src/runtime/office/quality/design-review.mjs +1 -5
- package/src/runtime/office/quality/document-brief.mjs +1 -5
- package/src/runtime/office/quality/forced-break-pages.mjs +9 -6
- package/src/runtime/office/quality/quality-pipeline.mjs +1 -1
- package/src/runtime/shared/agent-route-config.mjs +17 -2
- package/src/runtime/shared/atomic-file.mjs +103 -2
- package/src/runtime/shared/background-tasks.mjs +15 -6
- package/src/runtime/shared/bot-owned-work.mjs +56 -0
- package/src/runtime/shared/connector-accounts.mjs +5 -5
- package/src/runtime/shared/connector-catalog.d.mts +11 -4
- package/src/runtime/shared/connector-catalog.mjs +60 -52
- package/src/runtime/shared/custom-provider-keys.mjs +20 -0
- package/src/runtime/shared/defaults-separation.mjs +1 -4
- package/src/runtime/shared/fetch-safe-listen.d.mts +16 -0
- package/src/runtime/shared/fetch-safe-listen.mjs +50 -0
- package/src/runtime/shared/file-has-data.mjs +26 -2
- package/src/runtime/shared/file-lock.mjs +13 -15
- package/src/runtime/shared/git-launch.d.mts +9 -0
- package/src/runtime/shared/git-launch.mjs +213 -0
- package/src/runtime/shared/git-runner-worker.mjs +2 -1
- package/src/runtime/shared/handoff-artifacts.d.mts +2 -1
- package/src/runtime/shared/handoff-artifacts.mjs +18 -8
- package/src/runtime/shared/idle-auto-clear-gate.mjs +29 -7
- package/src/runtime/shared/llm/cost.mjs +11 -2
- package/src/runtime/shared/llm/http-agent.mjs +313 -29
- package/src/runtime/shared/llm/model-catalog-projection.mjs +3 -2
- package/src/runtime/shared/llm/model-catalog.mjs +46 -6
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +3 -0
- package/src/runtime/shared/llm/system-proxy.mjs +452 -0
- package/src/runtime/shared/loopback-listener.mjs +25 -2
- package/src/runtime/shared/model-route-chain.d.mts +7 -2
- package/src/runtime/shared/model-route-chain.mjs +22 -4
- package/src/runtime/shared/open-url.mjs +10 -0
- package/src/runtime/shared/provider-accounts.mjs +52 -2
- package/src/runtime/shared/session-activity-signal.mjs +14 -0
- package/src/runtime/shared/session-scratch.mjs +37 -0
- package/src/runtime/shared/staged-install-worker.mjs +5 -0
- package/src/runtime/shared/staged-update.mjs +47 -2
- package/src/runtime/shared/tool-card-model/agent-surface.mjs +1 -3
- package/src/runtime/shared/tool-card-model/card-status.mjs +15 -2
- package/src/runtime/shared/tool-result-summary.mjs +1 -1
- package/src/runtime/shared/tool-surface.mjs +113 -36
- package/src/runtime/shared/tool-work-units.mjs +6 -0
- package/src/runtime/shared/turn-snapshot-store.mjs +13 -6
- package/src/runtime/shared/turn-worktree-snapshot.mjs +414 -54
- package/src/runtime/shared/worktrees/activity-gate.mjs +215 -318
- package/src/runtime/shared/worktrees/activity-ledger-worker.mjs +56 -0
- package/src/runtime/shared/worktrees/activity-ledger.mjs +391 -0
- package/src/runtime/shared/worktrees/branch-management.mjs +9 -3
- package/src/runtime/shared/worktrees/contract.mjs +4 -1
- package/src/runtime/shared/worktrees/git.mjs +72 -0
- package/src/runtime/shared/worktrees/manager.mjs +285 -168
- package/src/runtime/shared/worktrees/test-support.mjs +6 -10
- package/src/runtime/tidy/install.mjs +95 -15
- package/src/runtime/tidy/languages.mjs +17 -15
- package/src/runtime/tidy/process.mjs +7 -4
- package/src/runtime/tidy/resolve.mjs +19 -16
- package/src/runtime/tidy/runners/biome.mjs +3 -3
- package/src/runtime/tidy/tool.mjs +1 -1
- package/src/runtime/tidy/worktree.mjs +10 -6
- package/src/runtime/visualize-bridge/client.mjs +6 -1
- package/src/runtime/visualize-bridge/tool-defs.mjs +7 -2
- package/src/runtime/web-search/index.mjs +1 -1
- package/src/session-runtime/agent-home-delivery.mjs +41 -0
- package/src/session-runtime/agent-task-sessions.mjs +458 -312
- package/src/session-runtime/agent-tool-routing.mjs +8 -41
- package/src/session-runtime/boot/tools.mjs +7 -1
- package/src/session-runtime/bot-status.mjs +107 -101
- package/src/session-runtime/bot-target.mjs +38 -0
- package/src/session-runtime/channel-config-api.mjs +6 -1
- package/src/session-runtime/connector-merge-migration.mjs +18 -15
- package/src/session-runtime/conversation-import/codex-titles.mjs +88 -0
- package/src/session-runtime/conversation-import/discovery.mjs +401 -36
- package/src/session-runtime/conversation-import/service.mjs +35 -8
- package/src/session-runtime/handoff-attachments.mjs +82 -31
- package/src/session-runtime/held-requests.mjs +3 -1
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +12 -13
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +1 -0
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +2 -0
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +8 -0
- package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +4 -1
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +145 -112
- package/src/session-runtime/lifecycle/cold-heir.mjs +11 -6
- package/src/session-runtime/lifecycle/session-catalog.mjs +9 -1
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +6 -1
- package/src/session-runtime/lifecycle/teardown.mjs +1 -1
- package/src/session-runtime/mcp-glue/server-catalog.mjs +16 -10
- package/src/session-runtime/mcp-glue/server-input.mjs +4 -1
- package/src/session-runtime/mixy-heartbeat.mjs +1 -1
- package/src/session-runtime/model-route/set-route.mjs +11 -2
- package/src/session-runtime/provider-auth/login.mjs +2 -2
- package/src/session-runtime/provider-catalog-cache.mjs +82 -36
- package/src/session-runtime/provider-models/catalog-load.mjs +23 -6
- package/src/session-runtime/provider-models.mjs +4 -2
- package/src/session-runtime/resource-mcp-api.mjs +98 -35
- package/src/session-runtime/resource-mcp-connector-accounts.mjs +44 -31
- package/src/session-runtime/resource-mcp-secrets.mjs +28 -11
- package/src/session-runtime/resource-mcp-servers.mjs +5 -4
- package/src/session-runtime/resource-recall-api.mjs +6 -1
- package/src/session-runtime/runtime-feature-gates.mjs +5 -1
- package/src/session-runtime/services/agent-tool/execute.mjs +14 -9
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +20 -4
- package/src/session-runtime/services/agent-tool/model-select.mjs +48 -7
- package/src/session-runtime/services/agent-tool/render.mjs +71 -17
- package/src/session-runtime/services/agent-tool/send-flow.mjs +10 -2
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +8 -3
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +4 -1
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +6 -2
- package/src/session-runtime/services/agent-tool/tool-def.mjs +9 -9
- package/src/session-runtime/services/agent-watchdog-registry.mjs +32 -4
- package/src/session-runtime/services/channel-worker/daemon-spawn.mjs +2 -0
- package/src/session-runtime/services/daemon-candidate.mjs +4 -1
- package/src/session-runtime/services/memory-runtime-proxy/daemon-spawn.mjs +4 -0
- package/src/session-runtime/services/plugin-admin.mjs +10 -6
- package/src/session-runtime/services/provider-admin.mjs +283 -11
- package/src/session-runtime/session-turn-api.mjs +2 -0
- package/src/session-runtime/settings-builtin-tools-api.mjs +4 -1
- package/src/session-runtime/settings-system-api.mjs +1 -1
- package/src/session-runtime/setup-tool/agent-settings-actions.mjs +13 -3
- package/src/session-runtime/setup-tool/connector-widen-approval.mjs +96 -0
- package/src/session-runtime/setup-tool/executor.mjs +6 -2
- package/src/session-runtime/setup-tool/tool-defs.mjs +2 -1
- package/src/session-runtime/tool-policy/policy-stage.mjs +1 -0
- package/src/session-runtime/turn/agent-ops.mjs +23 -0
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +49 -11
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +5 -1
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +25 -5
- package/src/session-runtime/workflow-agents-api/onboarding.mjs +3 -3
- package/src/session-runtime/workspace/activity-guards.mjs +176 -0
- package/src/session-runtime/workspace/session-view.mjs +149 -0
- package/src/session-runtime/workspace/side-checkouts.mjs +203 -0
- package/src/session-runtime/workspace/transition-runner.mjs +188 -0
- package/src/session-runtime/workspace/transitions.mjs +108 -1041
- package/src/session-runtime/workspace/workspace-merge.mjs +132 -0
- package/src/session-runtime/workspace/worktree-intents.mjs +242 -0
- package/src/session-runtime/workspace/worktree-maintenance.mjs +80 -0
- package/src/session-runtime/workspace/worktree-setup.mjs +85 -0
- package/src/session-runtime/workspace/worktree-tool.mjs +73 -56
- package/src/standalone/daemon-desktop-runtime.mjs +2 -0
- package/src/standalone/daemon-session-control.mjs +169 -138
- package/src/standalone/daemon.mjs +7 -0
- package/src/standalone/desktop-service-registry.mjs +9 -0
- package/src/standalone/local-session-runtime.mjs +5 -1
- package/src/standalone/session-client/daemon-unavailable.mjs +3 -0
- package/src/standalone/session-client.mjs +5 -1
- package/src/standalone/session-frame-stream.mjs +83 -11
- package/src/standalone/session-protocol.mjs +4 -0
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +16 -12
- package/src/standalone/session-service/agent-tree.mjs +45 -9
- package/src/standalone/session-service/projection/transcript-window.mjs +700 -64
- package/src/standalone/session-service/session-calls/session-action.mjs +10 -3
- package/src/standalone/session-service/session-calls/session-views.mjs +160 -104
- package/src/standalone/session-service/stored-reader.mjs +127 -40
- package/src/standalone/session-transport/client-registry/client-grace.mjs +12 -9
- package/src/tui/App.jsx +154 -164
- package/src/tui/app/app-view/floating-panel.jsx +10 -4
- package/src/tui/app/app-view/text-entry-labels.mjs +1 -0
- package/src/tui/app/clipboard.mjs +21 -10
- package/src/tui/app/model-picker/route-selection/fast-parameters.mjs +1 -3
- package/src/tui/app/model-picker/route-selection.mjs +5 -6
- package/src/tui/app/prompt-handlers/use-prompt-history-nav.mjs +1 -1
- package/src/tui/app/prompt-handlers/use-prompt-interrupt.mjs +3 -0
- package/src/tui/app/prompt-submit/provider-prompts.mjs +3 -1
- package/src/tui/app/provider-setup/api-key-actions.mjs +31 -1
- package/src/tui/app/provider-setup/oauth-actions.mjs +58 -21
- package/src/tui/app/provider-setup/provider-items.mjs +8 -2
- package/src/tui/app/provider-setup-picker.mjs +29 -18
- package/src/tui/app/shell-layout/row-budgets.mjs +12 -10
- package/src/tui/app/slash-commands.mjs +1 -0
- package/src/tui/app/slash-dispatch/session-commands.mjs +46 -0
- package/src/tui/app/slash-dispatch.mjs +1 -1
- package/src/tui/app/use-btw-panel.mjs +29 -0
- package/src/tui/app/use-context-panel-refresh.mjs +31 -0
- package/src/tui/app/use-model-catalog-cache.mjs +13 -10
- package/src/tui/app/use-mouse-input.mjs +11 -0
- package/src/tui/app/use-onboarding-start.mjs +8 -3
- package/src/tui/app/use-panel-transition.mjs +10 -1
- package/src/tui/app/use-pasted-buffers.mjs +28 -20
- package/src/tui/app/use-prompt-draft-flow.mjs +7 -0
- package/src/tui/app/use-prompt-layout-rows.mjs +3 -3
- package/src/tui/app/use-prompt-queue-history.mjs +3 -2
- package/src/tui/app/use-selection-focus.mjs +11 -2
- package/src/tui/app/use-selection-geometry.mjs +18 -9
- package/src/tui/app/use-selection-paint.mjs +4 -4
- package/src/tui/app/use-selection-stitch.mjs +3 -3
- package/src/tui/app/use-slash-palette.mjs +62 -0
- package/src/tui/app/use-terminal-chrome.mjs +2 -2
- package/src/tui/app/use-transcript-activity.mjs +47 -32
- package/src/tui/app/use-transcript-follow.mjs +12 -4
- package/src/tui/app/use-transcript-scroll.mjs +46 -17
- package/src/tui/app/use-transcript-swap-reset.mjs +27 -0
- package/src/tui/app/use-transcript-window/geometry.mjs +19 -5
- package/src/tui/app/use-transcript-window/instance-state.mjs +4 -0
- package/src/tui/app/use-transcript-window/selection-shift.mjs +5 -1
- package/src/tui/app/use-transcript-window.mjs +21 -11
- package/src/tui/app/use-tui-ready.mjs +18 -0
- package/src/tui/app/use-welcome-prompt-hint.mjs +5 -0
- package/src/tui/app/use-workflow-tab-cycle.mjs +5 -3
- package/src/tui/components/Picker.jsx +27 -3
- package/src/tui/components/QuestionPanel.jsx +13 -4
- package/src/tui/components/SignInUrl.jsx +68 -0
- package/src/tui/components/TextEntryPanel.jsx +76 -46
- package/src/tui/components/sign-in-url-layout.mjs +24 -0
- package/src/tui/dist/index.mjs +1963 -1361
- package/src/tui/session/goal-turn-state.mjs +6 -2
- package/src/tui/session/session-api/controls.mjs +4 -0
- package/src/tui/session/session-api/extensions.mjs +8 -0
- package/src/tui/session/session-api/intake/abort.mjs +2 -1
- package/src/tui/session/session-api/intake.mjs +2 -0
- package/src/tui/session/session-api/integrations.mjs +2 -2
- package/src/tui/session/session-api/routes-agent-definitions.mjs +1 -0
- package/src/tui/session/session-api/settings.mjs +2 -2
- package/src/tui/session/session-flow/queue/take-entries.mjs +11 -0
- package/src/tui/session/transcript-spill/spill-writer.mjs +15 -0
- package/src/tui/session/transcript-spill.mjs +92 -4
- package/src/tui/session/transcript-store.mjs +2 -0
- package/src/ui/statusline-agents.mjs +1 -3
- package/src/defaults/skills/skill-creator/references/source-review.md +0 -94
|
@@ -65,6 +65,13 @@ export function usePromptDraftFlow({
|
|
|
65
65
|
showPromptHint,
|
|
66
66
|
slashDismissedFor,
|
|
67
67
|
syncPromptLayoutRows,
|
|
68
|
+
promptHistoryDraftChangeRef,
|
|
69
|
+
promptHistoryNavRef,
|
|
70
|
+
setPromptDraft,
|
|
71
|
+
setPromptDraftOverride,
|
|
72
|
+
promptHintActiveRef,
|
|
73
|
+
promptHintTimerRef,
|
|
74
|
+
setSlashDismissedFor,
|
|
68
75
|
]
|
|
69
76
|
);
|
|
70
77
|
|
|
@@ -21,11 +21,11 @@ export function usePromptLayoutRows({
|
|
|
21
21
|
const nextRows = promptContentRows(text, promptContentColumns);
|
|
22
22
|
setPromptLayoutRows((prev) => (prev === nextRows ? prev : nextRows));
|
|
23
23
|
},
|
|
24
|
-
[promptContentColumns]
|
|
24
|
+
[promptContentColumns, promptLayoutValueRef, setPromptLayoutRows]
|
|
25
25
|
);
|
|
26
26
|
useEffect(() => {
|
|
27
27
|
syncPromptLayoutRows(promptLayoutValueRef.current);
|
|
28
|
-
}, [syncPromptLayoutRows]);
|
|
28
|
+
}, [syncPromptLayoutRows, promptLayoutValueRef]);
|
|
29
29
|
useEffect(() => {
|
|
30
30
|
const kind = String(settingsPrompt?.kind || '');
|
|
31
31
|
if (!CORE_MULTILINE_TEXT_ENTRY_KINDS.has(kind)) {
|
|
@@ -34,6 +34,6 @@ export function usePromptLayoutRows({
|
|
|
34
34
|
}
|
|
35
35
|
const cols = Math.max(1, frameColumns - 4 - stringWidth('Sentence > '));
|
|
36
36
|
setTextEntryLayoutRows(textEntryReservedRows(settingsPrompt?.initialValue, cols, 8));
|
|
37
|
-
}, [settingsPrompt?.kind, settingsPrompt?.initialValue, frameColumns]);
|
|
37
|
+
}, [settingsPrompt?.kind, settingsPrompt?.initialValue, frameColumns, setTextEntryLayoutRows]);
|
|
38
38
|
return syncPromptLayoutRows;
|
|
39
39
|
}
|
|
@@ -53,7 +53,7 @@ export function usePromptQueueHistory({
|
|
|
53
53
|
exit();
|
|
54
54
|
});
|
|
55
55
|
}, 60);
|
|
56
|
-
}, [store, exit]);
|
|
56
|
+
}, [store, exit, exitRequestedRef, setExiting]);
|
|
57
57
|
|
|
58
58
|
const restoreQueuedToPrompt = useCallback(
|
|
59
59
|
(options = {}) =>
|
|
@@ -74,6 +74,7 @@ export function usePromptQueueHistory({
|
|
|
74
74
|
store,
|
|
75
75
|
state?.queued,
|
|
76
76
|
promptDraft,
|
|
77
|
+
promptValueRef,
|
|
77
78
|
showPromptHint,
|
|
78
79
|
clearPromptHint,
|
|
79
80
|
installPastedImages,
|
|
@@ -94,7 +95,7 @@ export function usePromptQueueHistory({
|
|
|
94
95
|
|
|
95
96
|
const resetPromptHistoryNav = useCallback(() => {
|
|
96
97
|
promptHistoryNavRef.current = { active: false, index: -1, seed: '', lastValue: '' };
|
|
97
|
-
}, []);
|
|
98
|
+
}, [promptHistoryNavRef]);
|
|
98
99
|
|
|
99
100
|
return { requestExit, restoreQueuedToPrompt, recentPromptHistory, resetPromptHistoryNav };
|
|
100
101
|
}
|
|
@@ -31,7 +31,7 @@ export function useSelectionFocusMove({
|
|
|
31
31
|
const shiftedRect = dragRef.current.rect;
|
|
32
32
|
return { anchor: shiftedRect ? { x: shiftedRect.x1, y: shiftedRect.y1 } : null };
|
|
33
33
|
},
|
|
34
|
-
[scrollTranscriptRows]
|
|
34
|
+
[dragRef, scrollTargetRef, scrollTranscriptRows]
|
|
35
35
|
);
|
|
36
36
|
|
|
37
37
|
const moveSelectionFocus = useCallback(
|
|
@@ -120,7 +120,16 @@ export function useSelectionFocusMove({
|
|
|
120
120
|
dragNow.last = { x: col, y: row };
|
|
121
121
|
return true;
|
|
122
122
|
},
|
|
123
|
-
[
|
|
123
|
+
[
|
|
124
|
+
dragRef,
|
|
125
|
+
scrollTargetRef,
|
|
126
|
+
transcriptBottomSlackRowsRef,
|
|
127
|
+
applySelectionRect,
|
|
128
|
+
statusBandRows,
|
|
129
|
+
transcriptViewportRows,
|
|
130
|
+
selectionMaxColAtRow,
|
|
131
|
+
scrollFocusPastEdge,
|
|
132
|
+
]
|
|
124
133
|
);
|
|
125
134
|
|
|
126
135
|
return moveSelectionFocus;
|
|
@@ -22,13 +22,16 @@ export function useSelectionGeometry({
|
|
|
22
22
|
transcriptViewportRef,
|
|
23
23
|
dragRef,
|
|
24
24
|
}) {
|
|
25
|
-
const selectionPointAtCurrentScroll = useCallback(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
const selectionPointAtCurrentScroll = useCallback(
|
|
26
|
+
(point, pointScroll = 0) => {
|
|
27
|
+
if (!point) return null;
|
|
28
|
+
return {
|
|
29
|
+
x: point.x,
|
|
30
|
+
y: point.y + (Number(scrollTargetRef.current) || 0) - (Number(pointScroll) || 0),
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
[scrollTargetRef]
|
|
34
|
+
);
|
|
32
35
|
|
|
33
36
|
// Grow a word/line multi-click selection from its anchor span out to the
|
|
34
37
|
// word/line under the cursor. Shared by the mouse handler (motion/release)
|
|
@@ -68,9 +71,15 @@ export function useSelectionGeometry({
|
|
|
68
71
|
[store, frameColumns, selectionPointAtCurrentScroll]
|
|
69
72
|
);
|
|
70
73
|
|
|
71
|
-
const transcriptViewportRows = useCallback(
|
|
74
|
+
const transcriptViewportRows = useCallback(
|
|
75
|
+
() => transcriptViewportRowRange(transcriptViewportRef.current),
|
|
76
|
+
[transcriptViewportRef]
|
|
77
|
+
);
|
|
72
78
|
|
|
73
|
-
const statusBandRows = useCallback(
|
|
79
|
+
const statusBandRows = useCallback(
|
|
80
|
+
() => statusBandRowRange(frameRowsRef.current, statuslineBandRows),
|
|
81
|
+
[frameRowsRef, statuslineBandRows]
|
|
82
|
+
);
|
|
74
83
|
|
|
75
84
|
const selectionMaxColAtRow = useCallback(
|
|
76
85
|
(row) => {
|
|
@@ -54,12 +54,12 @@ export function useSelectionPaint({
|
|
|
54
54
|
.catch(() => {
|
|
55
55
|
/* best-effort capture: Ctrl+C falls back to the render-time text */
|
|
56
56
|
});
|
|
57
|
-
}, [store]);
|
|
57
|
+
}, [store, selectionTextRef]);
|
|
58
58
|
|
|
59
59
|
// Clip band + theming: use-selection-paint/selection-clip.mjs.
|
|
60
60
|
const selectionClip = useCallback(
|
|
61
61
|
() => selectionClipBand({ dragRef, frameRowsRef, transcriptViewportRef, statuslineBandRows }),
|
|
62
|
-
[statuslineBandRows]
|
|
62
|
+
[dragRef, frameRowsRef, transcriptViewportRef, statuslineBandRows]
|
|
63
63
|
);
|
|
64
64
|
|
|
65
65
|
const withSelectionClip = useCallback(
|
|
@@ -98,7 +98,7 @@ export function useSelectionPaint({
|
|
|
98
98
|
cancelPendingSelectionPaint();
|
|
99
99
|
paintSelectionRect(clippedRect, { rememberText: true });
|
|
100
100
|
},
|
|
101
|
-
[paintSelectionRect, withSelectionClip, clearStitchBuffer, cancelPendingSelectionPaint]
|
|
101
|
+
[dragRef, selectionTextRef, paintSelectionRect, withSelectionClip, clearStitchBuffer, cancelPendingSelectionPaint]
|
|
102
102
|
);
|
|
103
103
|
|
|
104
104
|
const applySelectionRectThrottled = useCallback(
|
|
@@ -111,7 +111,7 @@ export function useSelectionPaint({
|
|
|
111
111
|
cancelPending: cancelPendingSelectionPaint,
|
|
112
112
|
});
|
|
113
113
|
},
|
|
114
|
-
[paintSelectionRect, withSelectionClip, cancelPendingSelectionPaint]
|
|
114
|
+
[dragRef, paintSelectionRect, withSelectionClip, cancelPendingSelectionPaint]
|
|
115
115
|
);
|
|
116
116
|
|
|
117
117
|
return {
|
|
@@ -64,7 +64,7 @@ export function useSelectionStitchBuffer({ store, dragRef, scrollTargetRef }) {
|
|
|
64
64
|
if (!Array.isArray(rows)) return;
|
|
65
65
|
storeStitchRows(stitchBufferRef.current, rows, stitchHarvestScrollRef.current);
|
|
66
66
|
}, 0);
|
|
67
|
-
}, [store]);
|
|
67
|
+
}, [store, dragRef, scrollTargetRef]);
|
|
68
68
|
|
|
69
69
|
// Synchronous sibling: snapshot the rows CURRENTLY under the selection
|
|
70
70
|
// immediately, keyed by the given (pre-scroll) offset. Called right before
|
|
@@ -80,7 +80,7 @@ export function useSelectionStitchBuffer({ store, dragRef, scrollTargetRef }) {
|
|
|
80
80
|
if (!Array.isArray(rows)) return;
|
|
81
81
|
storeStitchRows(stitchBufferRef.current, rows, Number(scroll) || 0);
|
|
82
82
|
},
|
|
83
|
-
[store]
|
|
83
|
+
[store, dragRef]
|
|
84
84
|
);
|
|
85
85
|
|
|
86
86
|
// Map the CURRENT rect + current scrollTarget onto the content-key range and
|
|
@@ -122,7 +122,7 @@ export function useSelectionStitchBuffer({ store, dragRef, scrollTargetRef }) {
|
|
|
122
122
|
}
|
|
123
123
|
const text = logical.map((l) => l.replace(/\s+$/u, '')).join('\n');
|
|
124
124
|
return text.trim() ? { text, complete } : empty;
|
|
125
|
-
}, []);
|
|
125
|
+
}, [dragRef, scrollTargetRef]);
|
|
126
126
|
|
|
127
127
|
return { clearStitchBuffer, harvestStitchRowsSoon, harvestStitchRowsNow, getStitchedSelectionText };
|
|
128
128
|
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* app/use-slash-palette.mjs — the slash / `$skill` palette above the prompt.
|
|
3
|
+
*
|
|
4
|
+
* useSlashPaletteState owns the selection index, the dismissed-draft marker
|
|
5
|
+
* and the live open/count ref the mouse handler reads; it is declared early
|
|
6
|
+
* because the mouse and draft hooks need the setters. useSlashPalette derives
|
|
7
|
+
* the palette for this render from the prompt and the surfaces that suppress
|
|
8
|
+
* it, publishes it to that ref, and keeps the index inside the list.
|
|
9
|
+
*/
|
|
10
|
+
import { useEffect, useRef, useState } from 'react';
|
|
11
|
+
import { deriveSlashPalette } from './slash-palette.mjs';
|
|
12
|
+
import { skillMentionQuery, useSkillMentionSkills } from './skill-mention-palette.mjs';
|
|
13
|
+
|
|
14
|
+
export function useSlashPaletteState() {
|
|
15
|
+
const [slashIndex, setSlashIndex] = useState(0);
|
|
16
|
+
const [slashDismissedFor, setSlashDismissedFor] = useState('');
|
|
17
|
+
const slashPaletteRef = useRef({ open: false, count: 0 });
|
|
18
|
+
return { slashIndex, setSlashIndex, slashDismissedFor, setSlashDismissedFor, slashPaletteRef };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function useSlashPalette({
|
|
22
|
+
store,
|
|
23
|
+
slashPaletteRef,
|
|
24
|
+
setSlashIndex,
|
|
25
|
+
slashDismissedFor,
|
|
26
|
+
promptDraft,
|
|
27
|
+
promptCaret,
|
|
28
|
+
providerPrompt,
|
|
29
|
+
settingsPrompt,
|
|
30
|
+
toolApproval,
|
|
31
|
+
contextPanel,
|
|
32
|
+
usagePanel,
|
|
33
|
+
picker,
|
|
34
|
+
exiting,
|
|
35
|
+
commandBusy,
|
|
36
|
+
}) {
|
|
37
|
+
const mentionSkills = useSkillMentionSkills(store, skillMentionQuery(promptDraft, promptCaret) !== null);
|
|
38
|
+
const palette = deriveSlashPalette({
|
|
39
|
+
providerPrompt,
|
|
40
|
+
settingsPrompt,
|
|
41
|
+
toolApproval,
|
|
42
|
+
contextPanel,
|
|
43
|
+
usagePanel,
|
|
44
|
+
picker,
|
|
45
|
+
exiting,
|
|
46
|
+
commandBusy,
|
|
47
|
+
promptDraft,
|
|
48
|
+
slashDismissedFor,
|
|
49
|
+
skills: mentionSkills,
|
|
50
|
+
promptCaret,
|
|
51
|
+
});
|
|
52
|
+
const { activeSlashQuery, slashCommands, slashPaletteOpen } = palette;
|
|
53
|
+
slashPaletteRef.current = { open: slashPaletteOpen, count: slashCommands.length };
|
|
54
|
+
|
|
55
|
+
// A query change re-clamps even when the list length stays the same.
|
|
56
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies(activeSlashQuery): query-change re-clamp trigger
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
setSlashIndex((index) => Math.min(index, Math.max(0, slashCommands.length - 1)));
|
|
59
|
+
}, [slashCommands.length, activeSlashQuery, setSlashIndex]);
|
|
60
|
+
|
|
61
|
+
return palette;
|
|
62
|
+
}
|
|
@@ -47,7 +47,7 @@ export function useTerminalChrome({ stdout, isRawModeSupported, setResizeState }
|
|
|
47
47
|
if (trailing) clearTimeout(trailing);
|
|
48
48
|
stdout.off('resize', onResize);
|
|
49
49
|
};
|
|
50
|
-
}, [stdout]);
|
|
50
|
+
}, [stdout, setResizeState]);
|
|
51
51
|
|
|
52
52
|
// Enable extended keyboard reporting (kitty + xterm modifyOtherKeys)
|
|
53
53
|
// SYNCHRONOUSLY, ONCE, with NO query/round-trip. ink
|
|
@@ -61,7 +61,7 @@ export function useTerminalChrome({ stdout, isRawModeSupported, setResizeState }
|
|
|
61
61
|
// \x1b[27;5;13~ (or kitty \x1b[13;5u) instead of a bare \r — fixing the old
|
|
62
62
|
// "first Ctrl+Enter submits, second works" race. Teardown lives in index.jsx's
|
|
63
63
|
// restoreTerminal(). The empty dep array makes this run exactly once on mount.
|
|
64
|
-
//
|
|
64
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: one-shot mount enable; teardown is owned by restoreTerminal()
|
|
65
65
|
useEffect(() => {
|
|
66
66
|
if (!isRawModeSupported || !stdout?.write) return;
|
|
67
67
|
if (!supportsExtendedKeys()) return;
|
|
@@ -105,38 +105,53 @@ export function useTranscriptActivity({ state }) {
|
|
|
105
105
|
// StatusLine only reads a small stats subset; engine clones the full stats
|
|
106
106
|
// object on many updates. Memoize by field value so identical usage keeps
|
|
107
107
|
// the same object reference and React.memo / effect deps stay quiet.
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
108
|
+
const {
|
|
109
|
+
currentContextSource,
|
|
110
|
+
currentEstimatedContextTokens,
|
|
111
|
+
currentContextTokens,
|
|
112
|
+
contextTokens,
|
|
113
|
+
latestPromptTokens,
|
|
114
|
+
latestInputTokens,
|
|
115
|
+
latestCachedTokens,
|
|
116
|
+
latestCacheWriteTokens,
|
|
117
|
+
inputTokens,
|
|
118
|
+
cachedTokens,
|
|
119
|
+
cacheWriteTokens,
|
|
120
|
+
promptTokens,
|
|
121
|
+
turns,
|
|
122
|
+
} = state.stats || {};
|
|
123
|
+
const statuslineStats = useMemo(
|
|
124
|
+
() => ({
|
|
125
|
+
currentContextSource: currentContextSource ?? null,
|
|
126
|
+
currentEstimatedContextTokens: currentEstimatedContextTokens ?? 0,
|
|
127
|
+
currentContextTokens: currentContextTokens ?? null,
|
|
128
|
+
contextTokens: contextTokens ?? 0,
|
|
129
|
+
latestPromptTokens: latestPromptTokens ?? 0,
|
|
130
|
+
latestInputTokens: latestInputTokens ?? 0,
|
|
131
|
+
latestCachedTokens: latestCachedTokens ?? 0,
|
|
132
|
+
latestCacheWriteTokens: latestCacheWriteTokens ?? 0,
|
|
133
|
+
inputTokens: inputTokens ?? 0,
|
|
134
|
+
cachedTokens: cachedTokens ?? 0,
|
|
135
|
+
cacheWriteTokens: cacheWriteTokens ?? 0,
|
|
136
|
+
promptTokens: promptTokens ?? 0,
|
|
137
|
+
turns: turns ?? 0,
|
|
138
|
+
}),
|
|
139
|
+
[
|
|
140
|
+
currentContextSource,
|
|
141
|
+
currentEstimatedContextTokens,
|
|
142
|
+
currentContextTokens,
|
|
143
|
+
contextTokens,
|
|
144
|
+
latestPromptTokens,
|
|
145
|
+
latestInputTokens,
|
|
146
|
+
latestCachedTokens,
|
|
147
|
+
latestCacheWriteTokens,
|
|
148
|
+
inputTokens,
|
|
149
|
+
cachedTokens,
|
|
150
|
+
cacheWriteTokens,
|
|
151
|
+
promptTokens,
|
|
152
|
+
turns,
|
|
153
|
+
]
|
|
154
|
+
);
|
|
140
155
|
|
|
141
156
|
return { agentRevision, activeTools, statuslineStats };
|
|
142
157
|
}
|
|
@@ -44,11 +44,11 @@ export function useTranscriptFollow({
|
|
|
44
44
|
setScrollOffset(Math.max(0, Math.round(scrollPositionRef.current)));
|
|
45
45
|
}, 16);
|
|
46
46
|
scrollAnimationRef.current.unref?.();
|
|
47
|
-
}, [stopSmoothScroll]);
|
|
47
|
+
}, [scrollPositionRef, scrollTargetRef, followingRef, setScrollOffset, stopSmoothScroll]);
|
|
48
48
|
|
|
49
49
|
const cancelTranscriptFollow = useCallback(() => {
|
|
50
50
|
followingRef.current = false;
|
|
51
|
-
}, []);
|
|
51
|
+
}, [followingRef]);
|
|
52
52
|
|
|
53
53
|
const resetTranscriptScroll = useCallback(() => {
|
|
54
54
|
stopSmoothScroll();
|
|
@@ -65,7 +65,15 @@ export function useTranscriptFollow({
|
|
|
65
65
|
// and every new row piled up below the fold.
|
|
66
66
|
followingRef.current = true;
|
|
67
67
|
setScrollOffset(0);
|
|
68
|
-
}, [
|
|
68
|
+
}, [
|
|
69
|
+
scrollPositionRef,
|
|
70
|
+
scrollTargetRef,
|
|
71
|
+
followingRef,
|
|
72
|
+
transcriptAnchorRef,
|
|
73
|
+
transcriptAnchorDirtyRef,
|
|
74
|
+
setScrollOffset,
|
|
75
|
+
stopSmoothScroll,
|
|
76
|
+
]);
|
|
69
77
|
|
|
70
78
|
const armTranscriptFollow = useCallback(() => {
|
|
71
79
|
// Do not mutate scrollOffset here. During prompt submit the transcript rows
|
|
@@ -78,7 +86,7 @@ export function useTranscriptFollow({
|
|
|
78
86
|
pendingReadbackRowsRef.current = 0;
|
|
79
87
|
followingRef.current = true;
|
|
80
88
|
stopSmoothScroll();
|
|
81
|
-
}, [stopSmoothScroll]);
|
|
89
|
+
}, [followingRef, transcriptAnchorRef, transcriptAnchorDirtyRef, stopSmoothScroll]);
|
|
82
90
|
|
|
83
91
|
return {
|
|
84
92
|
pendingReadbackRowsRef,
|
|
@@ -141,7 +141,7 @@ export function useTranscriptScroll({
|
|
|
141
141
|
if (!anchor) return;
|
|
142
142
|
transcriptAnchorRef.current = anchor;
|
|
143
143
|
transcriptAnchorDirtyRef.current = false;
|
|
144
|
-
}, []);
|
|
144
|
+
}, [transcriptGeomRef, scrollTargetRef, transcriptAnchorRef, transcriptAnchorDirtyRef]);
|
|
145
145
|
|
|
146
146
|
// A manual scroll moves the reading position. Capture the new anchor
|
|
147
147
|
// SYNCHRONOUSLY from the latest published geometry so the very next render
|
|
@@ -149,20 +149,23 @@ export function useTranscriptScroll({
|
|
|
149
149
|
// streaming growth could lurch the view. Only at the true bottom drop the
|
|
150
150
|
// anchor so the bottom-follow path owns the viewport again: a positive
|
|
151
151
|
// wheel offset is an explicit reading position, even inside the old slack.
|
|
152
|
-
const captureReadingAnchor = useCallback(
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
152
|
+
const captureReadingAnchor = useCallback(
|
|
153
|
+
(target) => {
|
|
154
|
+
if (target === 0) {
|
|
155
|
+
transcriptAnchorRef.current = null;
|
|
156
|
+
transcriptAnchorDirtyRef.current = false;
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const anchor = readingAnchorAt(transcriptGeomRef.current || {}, target);
|
|
160
|
+
if (anchor) {
|
|
161
|
+
transcriptAnchorRef.current = anchor;
|
|
162
|
+
transcriptAnchorDirtyRef.current = false;
|
|
163
|
+
} else {
|
|
164
|
+
transcriptAnchorDirtyRef.current = true;
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
[transcriptGeomRef, transcriptAnchorRef, transcriptAnchorDirtyRef]
|
|
168
|
+
);
|
|
166
169
|
|
|
167
170
|
// Scrolling past the oldest/newest loaded edge pages transcript history
|
|
168
171
|
// instead of moving the target. Returns true when the edge owned the
|
|
@@ -190,7 +193,15 @@ export function useTranscriptScroll({
|
|
|
190
193
|
}
|
|
191
194
|
return true;
|
|
192
195
|
},
|
|
193
|
-
[
|
|
196
|
+
[
|
|
197
|
+
store,
|
|
198
|
+
scrollTargetRef,
|
|
199
|
+
scrollPositionRef,
|
|
200
|
+
setScrollOffset,
|
|
201
|
+
captureRestoreAnchor,
|
|
202
|
+
stopSmoothScroll,
|
|
203
|
+
cancelTranscriptFollow,
|
|
204
|
+
]
|
|
194
205
|
);
|
|
195
206
|
|
|
196
207
|
// Keep a live selection on its content after the viewport moved. An active
|
|
@@ -229,7 +240,14 @@ export function useTranscriptScroll({
|
|
|
229
240
|
// (Ctrl+C after scrolling then copied just that fragment).
|
|
230
241
|
paintSelectionRect(clippedRect, { rememberText: false });
|
|
231
242
|
},
|
|
232
|
-
[
|
|
243
|
+
[
|
|
244
|
+
dragRef,
|
|
245
|
+
buildSpanRect,
|
|
246
|
+
selectionPointAtCurrentScroll,
|
|
247
|
+
withSelectionClip,
|
|
248
|
+
cancelPendingSelectionPaint,
|
|
249
|
+
paintSelectionRect,
|
|
250
|
+
]
|
|
233
251
|
);
|
|
234
252
|
|
|
235
253
|
const scrollTranscriptRows = useCallback(
|
|
@@ -294,6 +312,17 @@ export function useTranscriptScroll({
|
|
|
294
312
|
setScrollOffset(Math.round(target));
|
|
295
313
|
},
|
|
296
314
|
[
|
|
315
|
+
maxScrollRowsRef,
|
|
316
|
+
transcriptGeomRef,
|
|
317
|
+
scrollTargetRef,
|
|
318
|
+
scrollPositionRef,
|
|
319
|
+
pendingReadbackRowsRef,
|
|
320
|
+
dragRef,
|
|
321
|
+
transcriptAnchorRef,
|
|
322
|
+
transcriptAnchorDirtyRef,
|
|
323
|
+
followingRef,
|
|
324
|
+
selectionLayoutRef,
|
|
325
|
+
setScrollOffset,
|
|
297
326
|
pageTranscriptHistory,
|
|
298
327
|
captureReadingAnchor,
|
|
299
328
|
rebuildSelectionAfterScroll,
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* app/use-transcript-swap-reset.mjs — returns the viewport to the live tail
|
|
3
|
+
* when the transcript items are bulk-swapped.
|
|
4
|
+
*
|
|
5
|
+
* Item-count changes never infer follow permission from scrollTarget=0. A
|
|
6
|
+
* first read-back input can be waiting one frame for committed row geometry;
|
|
7
|
+
* only prompt submit, session reset, or an explicit return to bottom arms
|
|
8
|
+
* follow. Pure streaming height growth is handled in the row-delta effect.
|
|
9
|
+
*/
|
|
10
|
+
import { useLayoutEffect } from 'react';
|
|
11
|
+
import { transcriptSwapReturnsToTail } from './transcript-window.mjs';
|
|
12
|
+
|
|
13
|
+
export function useTranscriptSwapReset({ items, lastItemsCountRef, lastFirstItemIdRef, resetTranscriptScroll }) {
|
|
14
|
+
useLayoutEffect(() => {
|
|
15
|
+
const count = items.length;
|
|
16
|
+
const previousCount = lastItemsCountRef.current;
|
|
17
|
+
lastItemsCountRef.current = count;
|
|
18
|
+
const firstId = count > 0 ? (items[0]?.id ?? null) : null;
|
|
19
|
+
const previousFirstId = lastFirstItemIdRef.current;
|
|
20
|
+
lastFirstItemIdRef.current = firstId;
|
|
21
|
+
// A bulk swap (compaction included) is an explicit return to the tail: the
|
|
22
|
+
// rows the reader was anchored to no longer exist.
|
|
23
|
+
if (transcriptSwapReturnsToTail({ count, previousCount, firstId, previousFirstId })) {
|
|
24
|
+
resetTranscriptScroll();
|
|
25
|
+
}
|
|
26
|
+
}, [items, lastItemsCountRef, lastFirstItemIdRef, resetTranscriptScroll]);
|
|
27
|
+
}
|
|
@@ -81,7 +81,12 @@ export function useTranscriptGeometry(state, props) {
|
|
|
81
81
|
// settled-prefix row-index instead of re-walking all N items. Any structural
|
|
82
82
|
// change misses the cache and falls back to a full rebuild, so the prefix
|
|
83
83
|
// table is byte-identical to a full rebuild for the settled prefix. All those
|
|
84
|
-
// invalidators are folded into the memo deps
|
|
84
|
+
// invalidators are folded into the memo deps: revision + tailSig stand in
|
|
85
|
+
// for the items/tail identities, and measuredRowsVersion folds in measured
|
|
86
|
+
// corrections.
|
|
87
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies(transcriptItems): keyed by revision + tailSig
|
|
88
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies(streamingTailItem): keyed by tailSig
|
|
89
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies(tailSig): tail id + height recompute key
|
|
85
90
|
const transcriptRowIndex = useMemo(
|
|
86
91
|
() =>
|
|
87
92
|
buildTranscriptRowIndexIncremental(transcriptItems, {
|
|
@@ -92,9 +97,8 @@ export function useTranscriptGeometry(state, props) {
|
|
|
92
97
|
cacheRef: state.incrementalRowIndexCacheRef,
|
|
93
98
|
prefixRevision: revision,
|
|
94
99
|
streamingTailItem,
|
|
95
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps -- revision/tail height capture structural geometry; measuredRowsVersion folds in measured corrections
|
|
96
100
|
}),
|
|
97
|
-
[revision, tailSig, frameColumns, toolOutputExpanded, measuredRowsVersion]
|
|
101
|
+
[revision, tailSig, frameColumns, toolOutputExpanded, measuredRowsVersion, state.incrementalRowIndexCacheRef]
|
|
98
102
|
);
|
|
99
103
|
const renderScrollOffset = resolveRenderScrollOffset({
|
|
100
104
|
scrollOffset,
|
|
@@ -109,6 +113,10 @@ export function useTranscriptGeometry(state, props) {
|
|
|
109
113
|
geomRef: transcriptGeomRef,
|
|
110
114
|
prevViewportRef: state.prevViewportGeomRef,
|
|
111
115
|
});
|
|
116
|
+
// transcriptStructureSig stands in for the items identity (it also encodes
|
|
117
|
+
// frameColumns and toolOutputExpanded); scroll/viewport capture the rest.
|
|
118
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies(transcriptItems): keyed by transcriptStructureSig
|
|
119
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies(transcriptStructureSig): items recompute key
|
|
112
120
|
const transcriptWindow = useMemo(
|
|
113
121
|
() =>
|
|
114
122
|
transcriptRenderWindow(transcriptItems, {
|
|
@@ -117,9 +125,15 @@ export function useTranscriptGeometry(state, props) {
|
|
|
117
125
|
columns: frameColumns,
|
|
118
126
|
toolOutputExpanded,
|
|
119
127
|
rowIndex: transcriptRowIndex,
|
|
120
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps -- intentional: sig+scroll/viewport capture the relevant changes
|
|
121
128
|
}),
|
|
122
|
-
[
|
|
129
|
+
[
|
|
130
|
+
transcriptStructureSig,
|
|
131
|
+
renderScrollOffset,
|
|
132
|
+
transcriptContentHeight,
|
|
133
|
+
transcriptRowIndex,
|
|
134
|
+
frameColumns,
|
|
135
|
+
toolOutputExpanded,
|
|
136
|
+
]
|
|
123
137
|
);
|
|
124
138
|
publishMaxScrollRows(state, transcriptWindow, { maxScrollRowsRef, frameColumns, toolOutputExpanded });
|
|
125
139
|
// Publish this frame's geometry so a manual scroll can capture the reading
|
|
@@ -65,6 +65,10 @@ export function useTranscriptInstanceState({ sessionKey, scrollOffset, setScroll
|
|
|
65
65
|
followingRef.current = true;
|
|
66
66
|
selectionLayoutRef.current = null;
|
|
67
67
|
}
|
|
68
|
+
// Runs on a session switch only: normalizedSessionKey is the trigger, and
|
|
69
|
+
// scrollOffset is read (not tracked) so scrolling never re-runs the reset.
|
|
70
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies(normalizedSessionKey): session-switch trigger
|
|
71
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies(scrollOffset): read at switch time only
|
|
68
72
|
useLayoutEffect(() => {
|
|
69
73
|
if (scrollOffset !== 0) setScrollOffset(0);
|
|
70
74
|
}, [normalizedSessionKey, setScrollOffset]);
|
|
@@ -40,12 +40,16 @@ export function useSelectionLayoutShift({
|
|
|
40
40
|
// with only the still-visible fragment (partial Ctrl+C after scrolling).
|
|
41
41
|
paintSelectionRect(clippedRect, { rememberText: false });
|
|
42
42
|
}, [
|
|
43
|
+
transcriptViewportRef,
|
|
44
|
+
selectionLayoutRef,
|
|
45
|
+
dragRef,
|
|
43
46
|
transcriptContentHeight,
|
|
44
47
|
transcriptWindow.totalRows,
|
|
45
48
|
transcriptWindow.effectiveScrollOffset,
|
|
46
49
|
withSelectionClip,
|
|
47
50
|
paintSelectionRect,
|
|
48
51
|
]);
|
|
52
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies(themeEpoch): theme-change repaint trigger
|
|
49
53
|
useEffect(() => {
|
|
50
54
|
if (!dragRef.current.rect) return;
|
|
51
55
|
const clippedRect = withSelectionClip(dragRef.current.rect);
|
|
@@ -53,5 +57,5 @@ export function useSelectionLayoutShift({
|
|
|
53
57
|
// Theme repaint: same cells, same text — no need to re-harvest (and a
|
|
54
58
|
// clipped rect would clobber the remembered full text with a fragment).
|
|
55
59
|
paintSelectionRect(clippedRect, { rememberText: false });
|
|
56
|
-
}, [themeEpoch, withSelectionClip, paintSelectionRect]);
|
|
60
|
+
}, [themeEpoch, dragRef, withSelectionClip, paintSelectionRect]);
|
|
57
61
|
}
|