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
|
@@ -6,9 +6,13 @@ import { openInBrowser } from '../../../runtime/shared/open-url.mjs';
|
|
|
6
6
|
import { providerDetailText } from '../app-format.mjs';
|
|
7
7
|
import { forgetProviderAuth, keyConsoleUrl, providerStatusFooter } from './provider-items.mjs';
|
|
8
8
|
|
|
9
|
-
const
|
|
9
|
+
const VERTEX_EXPRESS_HINT =
|
|
10
|
+
'Express mode API keys serve Gemini models on the global location only. Claude and MaaS models need a service-account key or the gcloud login.';
|
|
11
|
+
|
|
12
|
+
const setApiKeyPrompt = (flow, providerItem, extra = {}) => {
|
|
10
13
|
if (!flow.ownsSurface()) return;
|
|
11
14
|
flow.setProviderPrompt({
|
|
15
|
+
...extra,
|
|
12
16
|
kind: 'api-key',
|
|
13
17
|
providerId: providerItem._providerId,
|
|
14
18
|
label: providerItem._providerName,
|
|
@@ -51,6 +55,28 @@ function apiKeyActions(providerItem, provider) {
|
|
|
51
55
|
return { apiActions, keyUrl };
|
|
52
56
|
}
|
|
53
57
|
|
|
58
|
+
// Vertex AI takes either a service-account key or an express-mode API key.
|
|
59
|
+
function openVertexModePicker(flow, providerItem) {
|
|
60
|
+
flow.paint({
|
|
61
|
+
title: `Provider · ${providerItem._providerName}`,
|
|
62
|
+
description: 'Choose the Vertex AI key type.',
|
|
63
|
+
help: '↑/↓ Select · Enter Choose · Esc Back',
|
|
64
|
+
indexMode: 'always',
|
|
65
|
+
labelWidth: 22,
|
|
66
|
+
pickerKey: `providers-vertex-mode:${providerItem.value}`,
|
|
67
|
+
initialIndex: 0,
|
|
68
|
+
items: [
|
|
69
|
+
{ value: 'service-account', label: 'Service account key', description: 'service-account JSON' },
|
|
70
|
+
{ value: 'api-key', label: 'API key (express mode)', description: 'Gemini only · global location' },
|
|
71
|
+
],
|
|
72
|
+
onSelect: (mode) => {
|
|
73
|
+
flow.releaseSurface();
|
|
74
|
+
setApiKeyPrompt(flow, providerItem, mode === 'api-key' ? { authMode: 'api-key', hint: VERTEX_EXPRESS_HINT } : {});
|
|
75
|
+
},
|
|
76
|
+
onCancel: () => openApiProviderActions(flow, providerItem),
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
54
80
|
export function openApiProviderActions(flow, providerItem) {
|
|
55
81
|
// Reached from acks (a failed forget-key) as well as key presses: prove
|
|
56
82
|
// ownership at the sink so every caller is covered.
|
|
@@ -69,6 +95,10 @@ export function openApiProviderActions(flow, providerItem) {
|
|
|
69
95
|
initialIndex: 0,
|
|
70
96
|
items: apiActions,
|
|
71
97
|
onSelect: (_detailValue, detail) => {
|
|
98
|
+
if (detail._action === 'set-key' && providerItem._providerId === 'vertex-ai') {
|
|
99
|
+
openVertexModePicker(flow, providerItem);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
72
102
|
flow.releaseSurface();
|
|
73
103
|
if (detail._action === 'set-key') {
|
|
74
104
|
setApiKeyPrompt(flow, providerItem);
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// progress and result panels, the interactive (code prompt) login through
|
|
4
4
|
// store.beginOAuthProviderLogin, and the legacy store.loginOAuthProvider
|
|
5
5
|
// path. `flow` is the per-open picker state built by provider-setup-picker.mjs.
|
|
6
|
+
import { canOpenBrowser } from '../../../runtime/shared/open-url.mjs';
|
|
6
7
|
import { providerDetailText } from '../app-format.mjs';
|
|
7
8
|
import { forgetProviderAuth, providerStatusFooter } from './provider-items.mjs';
|
|
8
9
|
|
|
@@ -15,11 +16,21 @@ const panelFrame = (providerItem, provider, pickerKey) => ({
|
|
|
15
16
|
initialIndex: 0,
|
|
16
17
|
});
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
// Shown with every device code: a code someone else hands you signs THEM in to your account.
|
|
20
|
+
// One row that fits 80 columns: it takes the row the status footer did, so the URL
|
|
21
|
+
// keeps its copy-hint row and the "Enter code" line is never replaced by the copy note.
|
|
22
|
+
const DEVICE_CODE_WARNING = [
|
|
23
|
+
{ glyph: '!', text: 'Continue only if you started this. Never enter a code someone sent you.' },
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
function showOAuthProgress(flow, providerItem, message, onBack, detail = '', footer = null) {
|
|
19
27
|
const provider = providerItem._provider || {};
|
|
28
|
+
const frame = panelFrame(providerItem, provider, `providers-oauth-progress:${providerItem.value}`);
|
|
20
29
|
flow.paint({
|
|
21
|
-
...
|
|
30
|
+
...frame,
|
|
31
|
+
...(footer ? { footer } : {}),
|
|
22
32
|
description: message,
|
|
33
|
+
detail,
|
|
23
34
|
help: '↑/↓ Select · Enter Choose · Esc Providers',
|
|
24
35
|
indexMode: 'never',
|
|
25
36
|
items: [
|
|
@@ -27,7 +38,7 @@ function showOAuthProgress(flow, providerItem, message, onBack) {
|
|
|
27
38
|
value: 'waiting',
|
|
28
39
|
label: 'Waiting for login',
|
|
29
40
|
meta: 'Running',
|
|
30
|
-
description: 'finish the
|
|
41
|
+
description: 'finish the sign-in shown above',
|
|
31
42
|
_action: 'waiting',
|
|
32
43
|
},
|
|
33
44
|
{
|
|
@@ -71,6 +82,21 @@ function showOAuthResult(flow, providerItem, ok, message = '') {
|
|
|
71
82
|
});
|
|
72
83
|
}
|
|
73
84
|
|
|
85
|
+
function oauthCodeHint(manualUrl, loginUrl, providerName) {
|
|
86
|
+
if (manualUrl) return 'If the browser callback does not finish, open the URL below manually and paste code#state.';
|
|
87
|
+
if (loginUrl) {
|
|
88
|
+
return `Open the URL below to sign in, then paste the authorization code or full redirect URL for ${providerName}.`;
|
|
89
|
+
}
|
|
90
|
+
return `Paste the authorization code or full redirect URL for ${providerName}.`;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// The URL goes in the picker's wrapped `detail` block, never the one-line description.
|
|
94
|
+
function pollingLoginMessage(userCode, loginUrl, opened) {
|
|
95
|
+
if (userCode) return { message: `Enter code ${userCode} at${opened}:`, detail: loginUrl };
|
|
96
|
+
if (loginUrl) return { message: `Open this URL to sign in${opened}:`, detail: loginUrl };
|
|
97
|
+
return { message: 'Finish signing in for this provider.', detail: '' };
|
|
98
|
+
}
|
|
99
|
+
|
|
74
100
|
/** Login through store.beginOAuthProviderLogin: a code-completing login hands
|
|
75
101
|
* the surface to the OAuth code prompt; the callback (or the prompt) finishes. */
|
|
76
102
|
function beginInteractiveOAuthLogin(flow, providerItem, login) {
|
|
@@ -91,26 +117,26 @@ function beginInteractiveOAuthLogin(flow, providerItem, login) {
|
|
|
91
117
|
message || (ok ? `${providerName} login complete.` : `${providerName} login failed.`)
|
|
92
118
|
);
|
|
93
119
|
};
|
|
120
|
+
// Headless machines never try a browser; the URL is shown in the panel either way.
|
|
121
|
+
const openBrowser = canOpenBrowser();
|
|
94
122
|
void flow.store
|
|
95
|
-
.beginOAuthProviderLogin(providerItem._providerId)
|
|
123
|
+
.beginOAuthProviderLogin(providerItem._providerId, { openBrowser })
|
|
96
124
|
.then((started) => {
|
|
125
|
+
const loginUrl = started?.manualUrl || started?.url || '';
|
|
97
126
|
if (typeof started?.completeCode === 'function') {
|
|
98
127
|
// Post-await handover to the OAuth code prompt: only if this flow
|
|
99
128
|
// still owns the surface (Esc during beginOAuthProviderLogin).
|
|
100
129
|
if (!flow.ownsSurface()) return;
|
|
101
130
|
flow.releaseSurface();
|
|
102
|
-
const manualUrl = started?.manualUrl || '';
|
|
103
131
|
flow.setProviderPrompt({
|
|
104
132
|
kind: 'oauth-code',
|
|
105
133
|
providerId: providerItem._providerId,
|
|
106
134
|
providerName,
|
|
107
135
|
label: `${providerName} OAuth code`,
|
|
108
|
-
hint: manualUrl
|
|
109
|
-
? 'If the browser callback does not finish, open the URL below manually and paste code#state.'
|
|
110
|
-
: `Paste the authorization code or full redirect URL for ${providerName}.`,
|
|
136
|
+
hint: oauthCodeHint(started?.manualUrl, loginUrl, providerName),
|
|
111
137
|
// Shown inside the live panel only — never written to the
|
|
112
138
|
// transcript, so it cannot linger in scrollback after the flow.
|
|
113
|
-
detail:
|
|
139
|
+
detail: loginUrl,
|
|
114
140
|
login: started,
|
|
115
141
|
afterSave: flow.returnTo,
|
|
116
142
|
successReturn: () => {
|
|
@@ -124,16 +150,24 @@ function beginInteractiveOAuthLogin(flow, providerItem, login) {
|
|
|
124
150
|
},
|
|
125
151
|
});
|
|
126
152
|
flow.store.pushNotice(
|
|
127
|
-
|
|
153
|
+
openBrowser
|
|
154
|
+
? `browser opened for ${providerName}; paste code/redirect here if callback does not finish`
|
|
155
|
+
: `open the URL shown to sign in to ${providerName}, then paste the code/redirect here`,
|
|
128
156
|
'info'
|
|
129
157
|
);
|
|
130
|
-
} else if (
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
158
|
+
} else if (!login.backedOut && flow.ownsSurface()) {
|
|
159
|
+
// Device-code and URL-only polling logins stay in the progress panel,
|
|
160
|
+
// with the code and URL, until the result panel replaces it or Back.
|
|
161
|
+
const opened = openBrowser ? ' (browser opened)' : '';
|
|
162
|
+
const { message, detail } = pollingLoginMessage(started?.userCode, loginUrl, opened);
|
|
163
|
+
showOAuthProgress(
|
|
164
|
+
flow,
|
|
165
|
+
providerItem,
|
|
166
|
+
message,
|
|
167
|
+
login.onBack,
|
|
168
|
+
detail,
|
|
169
|
+
started?.userCode ? () => DEVICE_CODE_WARNING : null
|
|
134
170
|
);
|
|
135
|
-
} else {
|
|
136
|
-
flow.store.pushNotice(`browser opened for ${providerName}; finish signing in there`, 'info');
|
|
137
171
|
}
|
|
138
172
|
started.waitForCallback
|
|
139
173
|
?.then((result) => {
|
|
@@ -171,11 +205,14 @@ function runLegacyOAuthLogin(flow, providerItem, login) {
|
|
|
171
205
|
function startOAuthLogin(flow, providerItem) {
|
|
172
206
|
// Back on the progress panel returns to the actions; a login that settles
|
|
173
207
|
// afterwards becomes a notice instead of a result panel.
|
|
174
|
-
const login = {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
208
|
+
const login = {
|
|
209
|
+
backedOut: false,
|
|
210
|
+
onBack: () => {
|
|
211
|
+
login.backedOut = true;
|
|
212
|
+
openOAuthProviderActions(flow, providerItem);
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
showOAuthProgress(flow, providerItem, 'Starting login flow…', login.onBack);
|
|
179
216
|
if (typeof flow.store.beginOAuthProviderLogin === 'function') {
|
|
180
217
|
beginInteractiveOAuthLogin(flow, providerItem, login);
|
|
181
218
|
return;
|
|
@@ -80,8 +80,14 @@ export function buildProviderItems(setup) {
|
|
|
80
80
|
if (setup.managedByClient === true) {
|
|
81
81
|
for (const p of setup.local || []) {
|
|
82
82
|
providerItems.push({
|
|
83
|
-
value: `local:${p.id}`,
|
|
84
|
-
|
|
83
|
+
value: `local:${p.id}`,
|
|
84
|
+
label: p.name,
|
|
85
|
+
meta: providerStatusLabel(p),
|
|
86
|
+
description: '',
|
|
87
|
+
_type: 'local',
|
|
88
|
+
_providerId: p.id,
|
|
89
|
+
_providerName: p.name,
|
|
90
|
+
_provider: p,
|
|
85
91
|
});
|
|
86
92
|
}
|
|
87
93
|
}
|
|
@@ -18,6 +18,25 @@ import {
|
|
|
18
18
|
|
|
19
19
|
const providerFooter = (item) => providerStatusFooter(item?._provider);
|
|
20
20
|
|
|
21
|
+
/** The rows of the main provider list: the continue row, one row per provider,
|
|
22
|
+
* and the client refresh row. */
|
|
23
|
+
function mainListItems(setup, options, canContinue) {
|
|
24
|
+
const items = [];
|
|
25
|
+
if (canContinue && !options.confirmBar) {
|
|
26
|
+
items.push({
|
|
27
|
+
value: 'continue-setup',
|
|
28
|
+
label: options.continueLabel || 'Continue setup',
|
|
29
|
+
description: options.continueDescription || 'return to setup',
|
|
30
|
+
_type: 'continue',
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
items.push(...buildProviderItems(setup));
|
|
34
|
+
if (setup.managedByClient === true) {
|
|
35
|
+
items.push({ value: 'refresh-client-providers', label: 'Refresh', _type: 'refresh-client-providers' });
|
|
36
|
+
}
|
|
37
|
+
return items;
|
|
38
|
+
}
|
|
39
|
+
|
|
21
40
|
export function createProviderSetupPicker({
|
|
22
41
|
store,
|
|
23
42
|
surface,
|
|
@@ -87,19 +106,7 @@ export function createProviderSetupPicker({
|
|
|
87
106
|
if (!setup) return;
|
|
88
107
|
}
|
|
89
108
|
|
|
90
|
-
const items =
|
|
91
|
-
if ((returnTo || onContinue) && !options.confirmBar) {
|
|
92
|
-
items.push({
|
|
93
|
-
value: 'continue-setup',
|
|
94
|
-
label: options.continueLabel || 'Continue setup',
|
|
95
|
-
description: options.continueDescription || 'return to setup',
|
|
96
|
-
_type: 'continue',
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
items.push(...buildProviderItems(setup));
|
|
100
|
-
if (setup.managedByClient === true) {
|
|
101
|
-
items.push({ value: 'refresh-client-providers', label: 'Refresh', _type: 'refresh-client-providers' });
|
|
102
|
-
}
|
|
109
|
+
const items = mainListItems(setup, options, Boolean(returnTo || onContinue));
|
|
103
110
|
|
|
104
111
|
const flow = {
|
|
105
112
|
store,
|
|
@@ -129,13 +136,17 @@ export function createProviderSetupPicker({
|
|
|
129
136
|
|
|
130
137
|
flow.paint({
|
|
131
138
|
title: options.title || 'Providers',
|
|
132
|
-
description:
|
|
133
|
-
|
|
134
|
-
|
|
139
|
+
description:
|
|
140
|
+
setup.managedByClient === true
|
|
141
|
+
? 'Manage provider sign-ins and accounts in the local desktop window. Refresh to update availability.'
|
|
142
|
+
: options.description || 'Choose a provider. Enter opens provider actions.',
|
|
135
143
|
footer: providerFooter,
|
|
136
144
|
footerGapRows: 1,
|
|
137
|
-
help: options.confirmBar
|
|
138
|
-
?
|
|
145
|
+
help: options.confirmBar
|
|
146
|
+
? undefined
|
|
147
|
+
: setup.managedByClient === true
|
|
148
|
+
? '↑/↓ Select · Enter Refresh · Esc Back'
|
|
149
|
+
: '↑/↓ Select · Enter Open · Esc Back',
|
|
139
150
|
indexMode: 'always',
|
|
140
151
|
labelWidth: 18,
|
|
141
152
|
metaWidth: 12,
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
* welcome banner, floating panel, and the layout signature that names them.
|
|
5
5
|
*/
|
|
6
6
|
import { isLiveSpinnerMetaVisible } from '../live-spinner-visibility.mjs';
|
|
7
|
-
import { promptContentRows,
|
|
7
|
+
import { promptContentRows, queuedBandRows } from '../text-layout.mjs';
|
|
8
8
|
import { questionPanelRows, questionsOf } from '../../components/question-panel-model.mjs';
|
|
9
|
+
import { signInUrlLayout } from '../../components/sign-in-url-layout.mjs';
|
|
9
10
|
import { CORE_MULTILINE_TEXT_ENTRY_KINDS } from '../panel-signature.mjs';
|
|
10
11
|
import { btwPanelRows } from '../btw-controller.mjs';
|
|
11
12
|
|
|
@@ -49,24 +50,25 @@ function promptBoxBudget(inputBoxHidden, promptLayoutValueRef, promptContentColu
|
|
|
49
50
|
|
|
50
51
|
// TextEntryPanel content is one prompt line (chrome + 1) for single-line
|
|
51
52
|
// prompts, or up to PANEL_MAX_VISIBLE wrapped rows for core memory add/edit.
|
|
52
|
-
// PLUS an optional
|
|
53
|
-
//
|
|
53
|
+
// PLUS an optional borderless sign-in URL block under the panel (the manual
|
|
54
|
+
// OAuth URL). The floating container clips from the TOP (flex-end +
|
|
54
55
|
// overflow hidden), so under-reserving here pushed the bordered title off
|
|
55
|
-
// the top of the panel.
|
|
56
|
-
//
|
|
57
|
-
|
|
56
|
+
// the top of the panel. The block gets only the rows the terminal leaves
|
|
57
|
+
// (maxFloatingPanelRows minus chrome and content) and TextEntryPanel degrades
|
|
58
|
+
// it to fit, using the same sign-in-url-layout math.
|
|
59
|
+
function textEntryBudget(textEntryPrompt, textEntryLayoutRows, frameColumns, maxFloatingPanelRows) {
|
|
58
60
|
const textEntryKind = String(textEntryPrompt?.kind || '');
|
|
59
61
|
const textEntryMultiline = CORE_MULTILINE_TEXT_ENTRY_KINDS.has(textEntryKind);
|
|
60
62
|
const textEntryDetailText = String(textEntryPrompt?.detail || '').trim();
|
|
61
|
-
const textEntryDetailRows = textEntryDetailText
|
|
62
|
-
? 1 + wrappedDetailRows(textEntryDetailText, Math.max(1, frameColumns - 4))
|
|
63
|
-
: 0;
|
|
64
63
|
const textEntryContentRows = textEntryMultiline ? textEntryLayoutRows : 1;
|
|
64
|
+
const textEntryUrlMaxRows = Math.max(0, maxFloatingPanelRows - PANEL_CHROME_ROWS - textEntryContentRows);
|
|
65
|
+
const textEntryDetailRows = signInUrlLayout(textEntryDetailText, frameColumns, textEntryUrlMaxRows).rows;
|
|
65
66
|
return {
|
|
66
67
|
textEntryKind,
|
|
67
68
|
textEntryMultiline,
|
|
68
69
|
textEntryDetailText,
|
|
69
70
|
textEntryDetailRows,
|
|
71
|
+
textEntryUrlMaxRows,
|
|
70
72
|
textEntryContentRows,
|
|
71
73
|
TEXT_ENTRY_ROWS: PANEL_CHROME_ROWS + textEntryContentRows + textEntryDetailRows,
|
|
72
74
|
};
|
|
@@ -187,7 +189,6 @@ export function computeRowBudgets({
|
|
|
187
189
|
const { textEntryPrompt, hasTextEntryPrompt, hasFloatingPanel, expandedOptionPanel, inputBoxHidden } = surfaces;
|
|
188
190
|
const { liveSpinner, liveSpinnerIsCommand, latestTranscriptItem, inputHint } = hints;
|
|
189
191
|
const prompt = promptBoxBudget(inputBoxHidden, promptLayoutValueRef, promptContentColumns);
|
|
190
|
-
const textEntry = textEntryBudget(textEntryPrompt, textEntryLayoutRows, frameColumns);
|
|
191
192
|
const OPTION_PANEL_EXTRA_ROWS = expandedOptionPanel ? 3 : 0;
|
|
192
193
|
const queuedVisible = !hasFloatingPanel && !inputBoxHidden && state.queued?.length > 0;
|
|
193
194
|
// While the slash palette is open it owns the area above the prompt, so the
|
|
@@ -214,6 +215,7 @@ export function computeRowBudgets({
|
|
|
214
215
|
const baseReserve =
|
|
215
216
|
welcome.WELCOME_ROWS + SCROLL_HINT_ROWS + LIVE_STATUS_ROWS + INPUT_BOX_ROWS + STATUSLINE_ROWS + queued.queuedRows;
|
|
216
217
|
const maxFloatingPanelRows = Math.max(0, resizeState.rows - baseReserve - 1);
|
|
218
|
+
const textEntry = textEntryBudget(textEntryPrompt, textEntryLayoutRows, frameColumns, maxFloatingPanelRows);
|
|
217
219
|
const panel = floatingPanelBudget({
|
|
218
220
|
toolApproval,
|
|
219
221
|
picker,
|
|
@@ -41,6 +41,7 @@ export const SLASH_COMMANDS = [
|
|
|
41
41
|
params: '[release <task_id> [--confirm]]',
|
|
42
42
|
description: 'List shells; release one whose termination is unconfirmed',
|
|
43
43
|
},
|
|
44
|
+
{ name: 'stop', usage: '/stop', description: 'Stop every background shell of this session' },
|
|
44
45
|
{
|
|
45
46
|
name: 'fork',
|
|
46
47
|
usage: '/fork',
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
// while a turn or session command is running.
|
|
5
5
|
import { presentErrorText } from '../../../runtime/shared/err-text.mjs';
|
|
6
6
|
import { BTW_USAGE_HINT } from '../btw-controller.mjs';
|
|
7
|
+
import { theme } from '../../theme.mjs';
|
|
7
8
|
|
|
8
9
|
function compactFailureNotice(error) {
|
|
9
10
|
if (error == null || String(error).trim() === '') return 'Compact failed.';
|
|
@@ -168,6 +169,51 @@ export const sessionCommands = {
|
|
|
168
169
|
return true;
|
|
169
170
|
},
|
|
170
171
|
|
|
172
|
+
// /stop — stop every background shell of this session (never the running
|
|
173
|
+
// foreground command, agents or other sessions) after one confirmation.
|
|
174
|
+
stop(ctx) {
|
|
175
|
+
const { store, surface } = ctx;
|
|
176
|
+
const stopAll = () =>
|
|
177
|
+
Promise.resolve(store.stopShellJobs?.())
|
|
178
|
+
.then((result) => {
|
|
179
|
+
const stopped = result?.stopped || 0;
|
|
180
|
+
const stopping = result?.stopping || 0;
|
|
181
|
+
store.pushNotice(
|
|
182
|
+
stopping
|
|
183
|
+
? `Stopped background shells: ${stopped} · still stopping: ${stopping}`
|
|
184
|
+
: `Stopped background shells: ${stopped}`,
|
|
185
|
+
stopping ? 'warn' : 'info'
|
|
186
|
+
);
|
|
187
|
+
})
|
|
188
|
+
.catch((error) => store.pushNotice(String(error?.message || error), 'error'));
|
|
189
|
+
void Promise.resolve(store.listStoppableShellJobs?.())
|
|
190
|
+
.then((result) => {
|
|
191
|
+
const jobs = Array.isArray(result?.jobs) ? result.jobs : [];
|
|
192
|
+
if (!jobs.length) {
|
|
193
|
+
store.pushNotice('No background shells are running.', 'info');
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
const own = surface.claim();
|
|
197
|
+
own.paint({
|
|
198
|
+
title: `Stop background shells (${jobs.length})?`,
|
|
199
|
+
indexMode: 'always',
|
|
200
|
+
labelWidth: 12,
|
|
201
|
+
items: [
|
|
202
|
+
{ value: 'cancel', label: 'Cancel' },
|
|
203
|
+
{ value: 'stop', label: 'Stop' },
|
|
204
|
+
],
|
|
205
|
+
footer: jobs.map((job) => ({ glyph: '·', color: theme.warning, text: job.command })),
|
|
206
|
+
onSelect: (value) => {
|
|
207
|
+
own.close();
|
|
208
|
+
if (value === 'stop') void stopAll();
|
|
209
|
+
},
|
|
210
|
+
onCancel: () => own.close(),
|
|
211
|
+
});
|
|
212
|
+
})
|
|
213
|
+
.catch((error) => store.pushNotice(String(error?.message || error), 'error'));
|
|
214
|
+
return true;
|
|
215
|
+
},
|
|
216
|
+
|
|
171
217
|
doctor(ctx) {
|
|
172
218
|
const { state, store, deps } = ctx;
|
|
173
219
|
if (state.commandBusy) {
|
|
@@ -17,7 +17,7 @@ import { createSlashPanelOpener } from './slash-dispatch/slash-panel.mjs';
|
|
|
17
17
|
const commands = { ...routeCommands, ...sessionCommands, ...panelCommands };
|
|
18
18
|
|
|
19
19
|
export function createSlashDispatch({ state, store, normalizeSlashCommandName, surface, closeUsagePanel, ...deps }) {
|
|
20
|
-
const ctx = { state, store, deps, openSlashPanel: createSlashPanelOpener({ surface, store }) };
|
|
20
|
+
const ctx = { state, store, deps, surface, openSlashPanel: createSlashPanelOpener({ surface, store }) };
|
|
21
21
|
const runSlashCommand = (cmd, arg = '') => {
|
|
22
22
|
const rawName = String(cmd || '').toLowerCase();
|
|
23
23
|
cmd = normalizeSlashCommandName(cmd);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* app/use-btw-panel.mjs — the /btw side-question panel: its state, the
|
|
3
|
+
* controller that fills it, and the controller's session/unmount lifecycle.
|
|
4
|
+
*/
|
|
5
|
+
import { useEffect, useRef, useState } from 'react';
|
|
6
|
+
import { createBtwController } from './btw-controller.mjs';
|
|
7
|
+
|
|
8
|
+
export function useBtwPanel({ store, sessionId }) {
|
|
9
|
+
const [btwPanel, setBtwPanel] = useState(null);
|
|
10
|
+
const btwRef = useRef(null);
|
|
11
|
+
const sessionIdRef = useRef('');
|
|
12
|
+
sessionIdRef.current = sessionId || '';
|
|
13
|
+
if (!btwRef.current) {
|
|
14
|
+
btwRef.current = createBtwController({
|
|
15
|
+
getStore: () => store,
|
|
16
|
+
setPanel: setBtwPanel,
|
|
17
|
+
getSessionId: () => sessionIdRef.current,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
const btw = btwRef.current;
|
|
21
|
+
// A side answer belongs to the conversation it was asked in: drop it on a
|
|
22
|
+
// session change (new/resume/clear/switch) and cancel it on unmount.
|
|
23
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies(sessionId): session-change trigger; the controller reads the id through its getter
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
btw.sync();
|
|
26
|
+
}, [btw, sessionId]);
|
|
27
|
+
useEffect(() => () => btw.dispose(), [btw]);
|
|
28
|
+
return { btwPanel, btw };
|
|
29
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* app/use-context-panel-refresh.mjs — keeps an open /context breakdown panel
|
|
3
|
+
* current: it is rebuilt whenever one of the session fields it summarizes
|
|
4
|
+
* changes.
|
|
5
|
+
*/
|
|
6
|
+
import { useEffect } from 'react';
|
|
7
|
+
|
|
8
|
+
export function useContextPanelRefresh({ contextPanelKind, state, openContextPicker }) {
|
|
9
|
+
// The deps are the refresh triggers (the fields the breakdown summarizes),
|
|
10
|
+
// not the reads; openContextPicker is rebuilt by its factory every render
|
|
11
|
+
// and must not re-trigger the rebuild.
|
|
12
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: trigger-keyed refresh over the summarized session fields
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
if (contextPanelKind === 'context') openContextPicker();
|
|
15
|
+
}, [
|
|
16
|
+
contextPanelKind,
|
|
17
|
+
state.stats,
|
|
18
|
+
state.contextWindow,
|
|
19
|
+
state.rawContextWindow,
|
|
20
|
+
state.sessionId,
|
|
21
|
+
state.toolMode,
|
|
22
|
+
state.agentWorkers,
|
|
23
|
+
state.agentJobs,
|
|
24
|
+
state.provider,
|
|
25
|
+
state.model,
|
|
26
|
+
state.effort,
|
|
27
|
+
state.fast,
|
|
28
|
+
state.cwd,
|
|
29
|
+
state.clientHostPid,
|
|
30
|
+
]);
|
|
31
|
+
}
|
|
@@ -20,16 +20,19 @@ export function useModelCatalogCache({ store, onboardingRef }) {
|
|
|
20
20
|
// provider-scope cache clear (e.g. after auth) so a stale in-flight
|
|
21
21
|
// listProviderModels() cannot repopulate the ref after invalidation.
|
|
22
22
|
const onboardingPrefetchSeqRef = useRef(0);
|
|
23
|
-
const clearModelCaches = useCallback(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
const clearModelCaches = useCallback(
|
|
24
|
+
(scope = 'all') => {
|
|
25
|
+
if (scope === 'all' || scope === 'provider') {
|
|
26
|
+
providerModelsCacheRef.current = { models: null, at: 0 };
|
|
27
|
+
onboardingRef.current.providerModels = [];
|
|
28
|
+
onboardingPrefetchSeqRef.current += 1;
|
|
29
|
+
}
|
|
30
|
+
if (scope === 'all' || scope === 'webSearch') {
|
|
31
|
+
webSearchModelsCacheRef.current = { models: null, at: 0 };
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
[onboardingRef]
|
|
35
|
+
);
|
|
33
36
|
// Boot-time catalog prefetch: warm the /model & /agents provider catalog and
|
|
34
37
|
// the /websearch catalog once at startup so those pickers open instantly from
|
|
35
38
|
// cache (openModelPicker still TTL-refreshes stale rows in the background).
|
|
@@ -316,6 +316,17 @@ export function useMouseInput({
|
|
|
316
316
|
isRawModeSupported,
|
|
317
317
|
store,
|
|
318
318
|
stdout,
|
|
319
|
+
dragRef,
|
|
320
|
+
lastClickRef,
|
|
321
|
+
slashPaletteRef,
|
|
322
|
+
scrollFocusRef,
|
|
323
|
+
promptMouseSelectionRef,
|
|
324
|
+
frameRowsRef,
|
|
325
|
+
promptBoxRectRef,
|
|
326
|
+
transcriptViewportRef,
|
|
327
|
+
scrollTargetRef,
|
|
328
|
+
setSlashIndex,
|
|
329
|
+
setMeasuredRowsVersion,
|
|
319
330
|
passthroughCtrlWheelZoom,
|
|
320
331
|
frameColumns,
|
|
321
332
|
statuslineBandRows,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* app/use-onboarding-start.mjs — first-run onboarding gate + wizard launch.
|
|
3
3
|
*/
|
|
4
|
-
import { useEffect } from 'react';
|
|
4
|
+
import { useEffect, useRef } from 'react';
|
|
5
5
|
|
|
6
6
|
// First-run gate. The daemon-backed engine store answers any method it does
|
|
7
7
|
// not implement locally with an async remote call, so a synchronous
|
|
@@ -25,10 +25,15 @@ export function useOnboardingStart({
|
|
|
25
25
|
store,
|
|
26
26
|
forceOnboarding,
|
|
27
27
|
onboardingCompleted,
|
|
28
|
-
onboardingStartedRef,
|
|
29
28
|
setOnboardingActive,
|
|
30
29
|
openOnboardingAuthStep,
|
|
31
30
|
}) {
|
|
31
|
+
// Latches the launch so the wizard opens at most once per mount.
|
|
32
|
+
const onboardingStartedRef = useRef(false);
|
|
33
|
+
// openOnboardingAuthStep is rebuilt by the picker factory every render;
|
|
34
|
+
// depending on it would re-run this launch (and cancel its deferred open)
|
|
35
|
+
// on every commit. The launch keys on the gate inputs only.
|
|
36
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies(openOnboardingAuthStep): per-render factory callback; launch keys on gate inputs
|
|
32
37
|
useEffect(() => {
|
|
33
38
|
if (onboardingStartedRef.current) return undefined;
|
|
34
39
|
if (resolveOnboardingCompleted(store, onboardingCompleted) && !forceOnboarding) return undefined;
|
|
@@ -41,5 +46,5 @@ export function useOnboardingStart({
|
|
|
41
46
|
return () => {
|
|
42
47
|
canceled = true;
|
|
43
48
|
};
|
|
44
|
-
}, [store, forceOnboarding, onboardingCompleted]);
|
|
49
|
+
}, [store, forceOnboarding, onboardingCompleted, setOnboardingActive]);
|
|
45
50
|
}
|
|
@@ -30,7 +30,16 @@ export function usePanelTransition({
|
|
|
30
30
|
if (!hadTransitionClearance) return undefined;
|
|
31
31
|
const timer = setTimeout(() => setPanelTransitionEpoch((epoch) => epoch + 1), 0);
|
|
32
32
|
return () => clearTimeout(timer);
|
|
33
|
-
}, [
|
|
33
|
+
}, [
|
|
34
|
+
panelTransitionRef,
|
|
35
|
+
panelCloseInkMaskRowsRef,
|
|
36
|
+
panelLayoutSignature,
|
|
37
|
+
bottomClusterRows,
|
|
38
|
+
panelTransitionClearRows,
|
|
39
|
+
panelTransitionGuardRows,
|
|
40
|
+
setPanelInkMaskEpoch,
|
|
41
|
+
setPanelTransitionEpoch,
|
|
42
|
+
]);
|
|
34
43
|
// Record the transcript tail id AFTER every commit so the next render's
|
|
35
44
|
// spinner-meta-collapse gate (doneTailAppendedThisCommit) can tell a freshly
|
|
36
45
|
// appended done row from a stale one that was already at the tail.
|
|
@@ -48,31 +48,39 @@ function usePastedBufferSlice({ toEntry, formatRef }) {
|
|
|
48
48
|
setBuffers(next);
|
|
49
49
|
}, []);
|
|
50
50
|
|
|
51
|
-
const register = useCallback(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
51
|
+
const register = useCallback(
|
|
52
|
+
(input) => {
|
|
53
|
+
const id = nextIdRef.current;
|
|
54
|
+
const entry = toEntry(input, id);
|
|
55
|
+
if (!entry) return '';
|
|
56
|
+
nextIdRef.current = id + 1;
|
|
57
|
+
buffersRef.current = { ...buffersRef.current, [id]: entry };
|
|
58
|
+
setBuffers(buffersRef.current);
|
|
59
|
+
return formatRef(entry);
|
|
60
|
+
},
|
|
61
|
+
[toEntry, formatRef]
|
|
62
|
+
);
|
|
60
63
|
|
|
61
64
|
return { buffersRef, nextIdRef, install, clearSnapshot, register };
|
|
62
65
|
}
|
|
63
66
|
|
|
67
|
+
// Module-level slice specs keep toEntry/formatRef identities stable, so
|
|
68
|
+
// `register` is created once per mount.
|
|
69
|
+
const IMAGE_SLICE = {
|
|
70
|
+
toEntry: (image, id) => (image?.type === 'image' && image.content ? { ...image, id } : null),
|
|
71
|
+
formatRef: (entry) => formatImageRef(entry.id),
|
|
72
|
+
};
|
|
73
|
+
const TEXT_SLICE = {
|
|
74
|
+
toEntry: (text, id) => {
|
|
75
|
+
const value = String(text ?? '');
|
|
76
|
+
return value ? { id, text: value } : null;
|
|
77
|
+
},
|
|
78
|
+
formatRef: (entry) => formatPastedTextRef(entry.id, entry.text),
|
|
79
|
+
};
|
|
80
|
+
|
|
64
81
|
export function usePastedBuffers() {
|
|
65
|
-
const images = usePastedBufferSlice(
|
|
66
|
-
|
|
67
|
-
formatRef: (entry) => formatImageRef(entry.id),
|
|
68
|
-
});
|
|
69
|
-
const texts = usePastedBufferSlice({
|
|
70
|
-
toEntry: (text, id) => {
|
|
71
|
-
const value = String(text ?? '');
|
|
72
|
-
return value ? { id, text: value } : null;
|
|
73
|
-
},
|
|
74
|
-
formatRef: (entry) => formatPastedTextRef(entry.id, entry.text),
|
|
75
|
-
});
|
|
82
|
+
const images = usePastedBufferSlice(IMAGE_SLICE);
|
|
83
|
+
const texts = usePastedBufferSlice(TEXT_SLICE);
|
|
76
84
|
|
|
77
85
|
return {
|
|
78
86
|
pastedImagesRef: images.buffersRef,
|