@bastani/atomic 0.9.13 → 0.9.14-alpha.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/CHANGELOG.md +58 -0
- package/README.md +3 -3
- package/dist/builtin/intercom/package.json +2 -2
- package/dist/builtin/mcp/package.json +3 -3
- package/dist/builtin/subagents/CHANGELOG.md +14 -0
- package/dist/builtin/subagents/README.md +6 -4
- package/dist/builtin/subagents/agents/code-simplifier.md +1 -1
- package/dist/builtin/subagents/agents/codebase-analyzer.md +1 -1
- package/dist/builtin/subagents/agents/codebase-locator.md +1 -1
- package/dist/builtin/subagents/agents/codebase-online-researcher.md +1 -1
- package/dist/builtin/subagents/agents/codebase-pattern-finder.md +1 -1
- package/dist/builtin/subagents/agents/codebase-research-analyzer.md +1 -1
- package/dist/builtin/subagents/agents/codebase-research-locator.md +1 -1
- package/dist/builtin/subagents/agents/debugger.md +1 -1
- package/dist/builtin/subagents/agents/worker.md +1 -1
- package/dist/builtin/subagents/package.json +6 -5
- package/dist/builtin/subagents/src/agents/agent-discovery.ts +17 -11
- package/dist/builtin/subagents/src/agents/agent-loaders.ts +115 -43
- package/dist/builtin/subagents/src/agents/agent-management-helpers.ts +10 -8
- package/dist/builtin/subagents/src/agents/agent-management.ts +8 -7
- package/dist/builtin/subagents/src/agents/agent-overrides.ts +2 -2
- package/dist/builtin/subagents/src/agents/agent-scope.ts +1 -1
- package/dist/builtin/subagents/src/agents/agent-selection.ts +1 -1
- package/dist/builtin/subagents/src/agents/agent-serializer.ts +24 -3
- package/dist/builtin/subagents/src/agents/agent-types.ts +3 -1
- package/dist/builtin/subagents/src/agents/agents.ts +7 -5
- package/dist/builtin/subagents/src/agents/frontmatter.ts +67 -22
- package/dist/builtin/subagents/src/agents/identity.ts +1 -1
- package/dist/builtin/subagents/src/agents/skills-paths.ts +1 -1
- package/dist/builtin/subagents/src/agents/skills.ts +64 -6
- package/dist/builtin/subagents/src/extension/config.ts +1 -1
- package/dist/builtin/subagents/src/extension/control-notices.ts +2 -2
- package/dist/builtin/subagents/src/extension/doctor.ts +15 -5
- package/dist/builtin/subagents/src/extension/fanout-child.ts +12 -12
- package/dist/builtin/subagents/src/extension/index.ts +23 -23
- package/dist/builtin/subagents/src/extension/notification-content.ts +1 -1
- package/dist/builtin/subagents/src/extension/schemas.ts +1 -1
- package/dist/builtin/subagents/src/extension/startup-maintenance.ts +3 -3
- package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +3 -3
- package/dist/builtin/subagents/src/intercom/result-intercom.ts +1 -1
- package/dist/builtin/subagents/src/intercom/supervisor-authorization.ts +1 -1
- package/dist/builtin/subagents/src/runs/foreground/completion-notification.ts +2 -2
- package/dist/builtin/subagents/src/runs/foreground/execution-detach-reservations.ts +1 -1
- package/dist/builtin/subagents/src/runs/foreground/execution-intercom-detach.ts +3 -3
- package/dist/builtin/subagents/src/runs/foreground/execution-run-sync.ts +1 -1
- package/dist/builtin/subagents/src/runs/foreground/execution-updates.ts +2 -2
- package/dist/builtin/subagents/src/runs/foreground/execution-utils.ts +1 -1
- package/dist/builtin/subagents/src/runs/foreground/execution.ts +2 -2
- package/dist/builtin/subagents/src/runs/foreground/inprocess-run-sync.ts +27 -11
- package/dist/builtin/subagents/src/runs/foreground/notify.ts +3 -3
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-context.ts +11 -11
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-input.ts +3 -3
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +15 -14
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +19 -19
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-runtime.ts +2 -2
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +14 -13
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-status.ts +9 -9
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-types.ts +7 -7
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-worktree.ts +6 -6
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +24 -23
- package/dist/builtin/subagents/src/runs/inprocess/control-registry.ts +1 -1
- package/dist/builtin/subagents/src/runs/inprocess/control-status.ts +3 -3
- package/dist/builtin/subagents/src/runs/inprocess/index.ts +3 -3
- package/dist/builtin/subagents/src/runs/inprocess/prompt-behavior.ts +17 -8
- package/dist/builtin/subagents/src/runs/inprocess/runner.ts +60 -12
- package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-api.ts +8 -8
- package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-control.ts +3 -3
- package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-core.ts +4 -4
- package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-projection.ts +4 -4
- package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-registry.ts +5 -5
- package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-rendering.ts +3 -3
- package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-sanitize.ts +3 -3
- package/dist/builtin/subagents/src/runs/inprocess.ts +1 -1
- package/dist/builtin/subagents/src/runs/shared/long-running-guard.ts +1 -1
- package/dist/builtin/subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +1 -1
- package/dist/builtin/subagents/src/runs/shared/model-candidate-filter.ts +3 -3
- package/dist/builtin/subagents/src/runs/shared/model-fallback.ts +2 -2
- package/dist/builtin/subagents/src/runs/shared/parallel-utils.ts +1 -1
- package/dist/builtin/subagents/src/runs/shared/single-output.ts +1 -1
- package/dist/builtin/subagents/src/runs/shared/subagent-control.ts +1 -1
- package/dist/builtin/subagents/src/shared/artifacts.ts +2 -2
- package/dist/builtin/subagents/src/shared/event-jsonl-writer.ts +1 -1
- package/dist/builtin/subagents/src/shared/fast-mode.ts +1 -1
- package/dist/builtin/subagents/src/shared/formatters.ts +2 -2
- package/dist/builtin/subagents/src/shared/jsonl-writer.ts +1 -1
- package/dist/builtin/subagents/src/shared/model-resolution.ts +1 -1
- package/dist/builtin/subagents/src/shared/session-tokens.ts +1 -1
- package/dist/builtin/subagents/src/shared/settings.ts +4 -4
- package/dist/builtin/subagents/src/shared/status-format.ts +1 -1
- package/dist/builtin/subagents/src/shared/types-config.ts +16 -4
- package/dist/builtin/subagents/src/shared/types-depth.ts +1 -1
- package/dist/builtin/subagents/src/shared/types-nested.ts +1 -1
- package/dist/builtin/subagents/src/shared/types-output.ts +1 -1
- package/dist/builtin/subagents/src/shared/types-results.ts +1 -1
- package/dist/builtin/subagents/src/shared/types-runtime.ts +1 -1
- package/dist/builtin/subagents/src/shared/types.ts +6 -6
- package/dist/builtin/subagents/src/shared/utils.ts +3 -3
- package/dist/builtin/subagents/src/slash/prompt-template-bridge.ts +1 -1
- package/dist/builtin/subagents/src/slash/slash-bridge.ts +3 -3
- package/dist/builtin/subagents/src/slash/slash-commands.ts +6 -6
- package/dist/builtin/subagents/src/slash/slash-live-state.ts +3 -3
- package/dist/builtin/subagents/src/tui/render-event-formatting.ts +2 -2
- package/dist/builtin/subagents/src/tui/render-layout.ts +1 -1
- package/dist/builtin/subagents/src/tui/render-progress.ts +2 -2
- package/dist/builtin/subagents/src/tui/render-result-compact.ts +7 -7
- package/dist/builtin/subagents/src/tui/render-result.ts +10 -10
- package/dist/builtin/subagents/src/tui/render-stable-output.ts +1 -1
- package/dist/builtin/subagents/src/tui/render-status-progress.ts +5 -5
- package/dist/builtin/subagents/src/tui/render.ts +4 -4
- package/dist/builtin/web-access/package.json +2 -2
- package/dist/builtin/workflows/CHANGELOG.md +57 -0
- package/dist/builtin/workflows/README.md +39 -8
- package/dist/builtin/workflows/builtin/adversarial-verification-runner.ts +16 -5
- package/dist/builtin/workflows/builtin/adversarial-verification.ts +4 -0
- package/dist/builtin/workflows/builtin/classify-and-act.ts +4 -0
- package/dist/builtin/workflows/builtin/fan-out-and-synthesize.ts +4 -0
- package/dist/builtin/workflows/builtin/generate-and-filter-runner.ts +12 -4
- package/dist/builtin/workflows/builtin/generate-and-filter.ts +4 -0
- package/dist/builtin/workflows/builtin/goal-models.ts +8 -10
- package/dist/builtin/workflows/builtin/goal.ts +4 -0
- package/dist/builtin/workflows/builtin/index.d.ts +0 -4
- package/dist/builtin/workflows/builtin/loop-until-done-runner.ts +4 -2
- package/dist/builtin/workflows/builtin/loop-until-done.ts +4 -0
- package/dist/builtin/workflows/builtin/open-claude-design-live-protocol.ts +305 -0
- package/dist/builtin/workflows/builtin/open-claude-design-phases.ts +115 -171
- package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +9 -25
- package/dist/builtin/workflows/builtin/open-claude-design-setup.ts +19 -86
- package/dist/builtin/workflows/builtin/open-claude-design-utils.ts +0 -6
- package/dist/builtin/workflows/builtin/open-claude-design.d.ts +0 -5
- package/dist/builtin/workflows/builtin/open-claude-design.ts +11 -15
- package/dist/builtin/workflows/builtin/ralph-models.ts +24 -29
- package/dist/builtin/workflows/builtin/ralph.ts +4 -0
- package/dist/builtin/workflows/builtin/tournament-runner.ts +6 -3
- package/dist/builtin/workflows/builtin/tournament.ts +4 -0
- package/dist/builtin/workflows/package.json +2 -2
- package/dist/builtin/workflows/skills/impeccable/SKILL.md +3 -3
- package/dist/builtin/workflows/skills/impeccable/agents/impeccable_asset_producer.toml +25 -31
- package/dist/builtin/workflows/skills/impeccable/agents/impeccable_documenter.toml +1 -0
- package/dist/builtin/workflows/skills/impeccable/agents/impeccable_finish_reviewer.toml +16 -10
- package/dist/builtin/workflows/skills/impeccable/agents/impeccable_manual_edit_applier.toml +2 -2
- package/dist/builtin/workflows/skills/impeccable/reference/android.md +6 -0
- package/dist/builtin/workflows/skills/impeccable/reference/animate.md +3 -0
- package/dist/builtin/workflows/skills/impeccable/reference/bolder.md +3 -1
- package/dist/builtin/workflows/skills/impeccable/reference/craft-floor.md +6 -1
- package/dist/builtin/workflows/skills/impeccable/reference/critique.md +18 -2
- package/dist/builtin/workflows/skills/impeccable/reference/degraded/asset-producer.md +24 -30
- package/dist/builtin/workflows/skills/impeccable/reference/degraded/documenter.md +1 -0
- package/dist/builtin/workflows/skills/impeccable/reference/degraded/finish-reviewer.md +16 -10
- package/dist/builtin/workflows/skills/impeccable/reference/degraded/manual-edit-applier.md +2 -2
- package/dist/builtin/workflows/skills/impeccable/reference/distill.md +1 -1
- package/dist/builtin/workflows/skills/impeccable/reference/doctor.md +1 -0
- package/dist/builtin/workflows/skills/impeccable/reference/document.md +1 -1
- package/dist/builtin/workflows/skills/impeccable/reference/extract.md +1 -1
- package/dist/builtin/workflows/skills/impeccable/reference/hooks.md +12 -6
- package/dist/builtin/workflows/skills/impeccable/reference/init.md +12 -3
- package/dist/builtin/workflows/skills/impeccable/reference/ios.md +6 -0
- package/dist/builtin/workflows/skills/impeccable/reference/live-setup.md +102 -0
- package/dist/builtin/workflows/skills/impeccable/reference/live.md +113 -521
- package/dist/builtin/workflows/skills/impeccable/reference/new-work.md +39 -26
- package/dist/builtin/workflows/skills/impeccable/reference/overdrive.md +1 -1
- package/dist/builtin/workflows/skills/impeccable/reference/polish.md +3 -3
- package/dist/builtin/workflows/skills/impeccable/reference/quieter.md +1 -1
- package/dist/builtin/workflows/skills/impeccable/reference/visualize.md +25 -11
- package/dist/builtin/workflows/skills/impeccable/scripts/concept-seed.mjs +332 -221
- package/dist/builtin/workflows/skills/impeccable/scripts/context-signals.mjs +10 -19
- package/dist/builtin/workflows/skills/impeccable/scripts/context.mjs +91 -38
- package/dist/builtin/workflows/skills/impeccable/scripts/critique-storage.mjs +19 -10
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/browser/injected/index.mjs +56 -6
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/cli/main.mjs +10 -16
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/design-system.mjs +140 -2
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/detect-antipatterns-browser.js +1174 -694
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/detect-antipatterns.mjs +1 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/browser/detect-url.mjs +5 -1
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +431 -45
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/static-html/css-cascade.mjs +10 -1
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/static-html/detect-html.mjs +47 -6
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/node/file-system.mjs +23 -22
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/registry/antipatterns.mjs +0 -10
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/rules/checks.mjs +384 -384
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/color.mjs +466 -2
- package/dist/builtin/workflows/skills/impeccable/scripts/doctor.mjs +2 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/embed-prompt.mjs +270 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/generate-image.mjs +51 -6
- package/dist/builtin/workflows/skills/impeccable/scripts/hook-admin.mjs +70 -10
- package/dist/builtin/workflows/skills/impeccable/scripts/hook-lib.mjs +336 -90
- package/dist/builtin/workflows/skills/impeccable/scripts/lib/composition-catalog.mjs +38 -3
- package/dist/builtin/workflows/skills/impeccable/scripts/lib/concept-catalog.mjs +77 -11
- package/dist/builtin/workflows/skills/impeccable/scripts/lib/design-parser.mjs +102 -19
- package/dist/builtin/workflows/skills/impeccable/scripts/lib/impeccable-config.mjs +44 -59
- package/dist/builtin/workflows/skills/impeccable/scripts/lib/is-generated.mjs +3 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/lib/open-system-browser.mjs +57 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/lib/roll-selection.mjs +369 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/lib/staleness-deep.mjs +31 -3
- package/dist/builtin/workflows/skills/impeccable/scripts/lib/staleness.mjs +73 -2
- package/dist/builtin/workflows/skills/impeccable/scripts/live/accept-css.mjs +617 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/live/accept-verify.mjs +71 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/live/browser-script-parts.mjs +29 -2
- package/dist/builtin/workflows/skills/impeccable/scripts/live/event-validation.mjs +54 -7
- package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/astro.mjs +47 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/detect-utils.mjs +157 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/index.mjs +143 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/journal.mjs +205 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/nextjs.mjs +49 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/nuxt.mjs +170 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/script-src.mjs +26 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/static-html.mjs +26 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/sveltekit.mjs +71 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/tag-strategy.mjs +247 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/tanstack-start.mjs +70 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/vite-generic.mjs +42 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/live/instructions.mjs +169 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/live/roots.mjs +670 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/live/session-store.mjs +232 -35
- package/dist/builtin/workflows/skills/impeccable/scripts/live/svelte-ast.mjs +969 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/live/svelte-component.mjs +621 -74
- package/dist/builtin/workflows/skills/impeccable/scripts/live/sveltekit-adapter.mjs +66 -28
- package/dist/builtin/workflows/skills/impeccable/scripts/live/tanstack-adapter.mjs +12 -12
- package/dist/builtin/workflows/skills/impeccable/scripts/live/ui-surfaces.mjs +75 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/live/vocabulary.mjs +135 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/live-accept.mjs +23 -37
- package/dist/builtin/workflows/skills/impeccable/scripts/live-browser.js +945 -115
- package/dist/builtin/workflows/skills/impeccable/scripts/live-complete.mjs +33 -1
- package/dist/builtin/workflows/skills/impeccable/scripts/live-copy-edit-agent.mjs +132 -15
- package/dist/builtin/workflows/skills/impeccable/scripts/live-inject.mjs +173 -425
- package/dist/builtin/workflows/skills/impeccable/scripts/live-insert.mjs +2 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/live-poll.mjs +16 -3
- package/dist/builtin/workflows/skills/impeccable/scripts/live-resume.mjs +39 -10
- package/dist/builtin/workflows/skills/impeccable/scripts/live-server.mjs +194 -27
- package/dist/builtin/workflows/skills/impeccable/scripts/live-status.mjs +10 -4
- package/dist/builtin/workflows/skills/impeccable/scripts/live-wrap.mjs +50 -31
- package/dist/builtin/workflows/skills/impeccable/scripts/live.mjs +91 -28
- package/dist/builtin/workflows/skills/impeccable/scripts/pin.mjs +8 -5
- package/dist/builtin/workflows/skills/impeccable/scripts/serve-question.mjs +759 -109
- package/dist/builtin/workflows/src/authoring/workflow.ts +9 -0
- package/dist/builtin/workflows/src/authoring.d.ts +3 -0
- package/dist/builtin/workflows/src/durable/completed-catalog.ts +23 -2
- package/dist/builtin/workflows/src/durable/dbos-backend.ts +30 -17
- package/dist/builtin/workflows/src/durable/dbos-envelope.ts +14 -0
- package/dist/builtin/workflows/src/durable/dbos-lifecycle.ts +60 -57
- package/dist/builtin/workflows/src/durable/dbos-process-owner.ts +87 -0
- package/dist/builtin/workflows/src/durable/dbos-registration-diagnostics.ts +113 -0
- package/dist/builtin/workflows/src/durable/factory.ts +11 -8
- package/dist/builtin/workflows/src/durable/tool-failure-checkpoint.ts +5 -0
- package/dist/builtin/workflows/src/durable/tool-primitive.ts +186 -20
- package/dist/builtin/workflows/src/durable/types.ts +4 -0
- package/dist/builtin/workflows/src/durable/workflow-heartbeat-anchor.ts +153 -0
- package/dist/builtin/workflows/src/engine/run-durable-stage-session.ts +28 -0
- package/dist/builtin/workflows/src/engine/run-tool-control-registry.ts +9 -1
- package/dist/builtin/workflows/src/engine/run.ts +1 -0
- package/dist/builtin/workflows/src/extension/adopt-session-run-state.ts +20 -0
- package/dist/builtin/workflows/src/extension/background-ui-adapter.ts +9 -30
- package/dist/builtin/workflows/src/extension/extension-factory.ts +3 -0
- package/dist/builtin/workflows/src/extension/extension-lifecycle.ts +28 -10
- package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +138 -0
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +3365 -1341
- package/dist/builtin/workflows/src/extension/workflow-heartbeat-delivery.ts +197 -0
- package/dist/builtin/workflows/src/extension/workflow-heartbeat-notice.ts +115 -0
- package/dist/builtin/workflows/src/extension/workflow-heartbeat-scheduler.ts +962 -0
- package/dist/builtin/workflows/src/extension/workflow-prompts.ts +4 -1
- package/dist/builtin/workflows/src/extension/workflow-schema.ts +29 -5
- package/dist/builtin/workflows/src/extension/workflow-tool-send.ts +32 -1
- package/dist/builtin/workflows/src/runs/background/cancellation-registry.ts +10 -1
- package/dist/builtin/workflows/src/runs/background/job-tracker.ts +10 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-prompt-nodes.ts +16 -11
- package/dist/builtin/workflows/src/runs/foreground/stage-control-registry.ts +31 -1
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-context.ts +41 -10
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-messages.ts +48 -0
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-output.ts +4 -1
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-structured-output.ts +45 -12
- package/dist/builtin/workflows/src/sdk-surface.ts +9 -0
- package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +10 -0
- package/dist/builtin/workflows/src/shared/authoring-contract-ui.ts +10 -0
- package/dist/builtin/workflows/src/shared/graph-store-snapshot.ts +14 -2
- package/dist/builtin/workflows/src/shared/persistence-restore.ts +12 -0
- package/dist/builtin/workflows/src/shared/prompt-answer.ts +130 -0
- package/dist/builtin/workflows/src/shared/session-scoped-singleton.ts +98 -0
- package/dist/builtin/workflows/src/shared/stage-ui-broker.ts +9 -1
- package/dist/builtin/workflows/src/shared/store-factory.ts +9 -1
- package/dist/builtin/workflows/src/shared/store-public-types.ts +2 -1
- package/dist/builtin/workflows/src/shared/store-tool-node-methods.ts +7 -0
- package/dist/builtin/workflows/src/shared/store-types.ts +18 -1
- package/dist/builtin/workflows/src/shared/tool-payload-bounds.ts +576 -0
- package/dist/builtin/workflows/src/shared/workflow-authoring-types.d.ts +1 -0
- package/dist/builtin/workflows/src/shared/workflow-authoring-types.ts +1 -0
- package/dist/builtin/workflows/src/shared/workflow-heartbeat-contract.d.ts +21 -0
- package/dist/builtin/workflows/src/shared/workflow-heartbeat-contract.ts +25 -0
- package/dist/builtin/workflows/src/tui/graph-theme.ts +8 -1
- package/dist/builtin/workflows/src/tui/graph-view-constants.ts +11 -0
- package/dist/builtin/workflows/src/tui/graph-view-input.ts +100 -5
- package/dist/builtin/workflows/src/tui/graph-view-layout.ts +42 -11
- package/dist/builtin/workflows/src/tui/graph-view-render-helpers.ts +55 -6
- package/dist/builtin/workflows/src/tui/graph-view-render.ts +71 -6
- package/dist/builtin/workflows/src/tui/graph-view-state.ts +43 -0
- package/dist/builtin/workflows/src/tui/keybindings-adapter.ts +2 -0
- package/dist/builtin/workflows/src/tui/node-card.ts +5 -1
- package/dist/builtin/workflows/src/tui/stage-chat-view-archive-history.ts +11 -2
- package/dist/builtin/workflows/src/tui/stage-chat-view.ts +36 -10
- package/dist/builtin/workflows/src/tui/switcher.ts +11 -4
- package/dist/builtin/workflows/src/tui/tool-detail.ts +348 -0
- package/dist/builtin/workflows/src/tui/workflow-status.ts +5 -2
- package/dist/cli/args.d.ts +1 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +11 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/auth-check.d.ts +1 -1
- package/dist/cli/auth-check.js.map +1 -1
- package/dist/cli/credential-print.d.ts +1 -1
- package/dist/cli/credential-print.js.map +1 -1
- package/dist/cli/list-models.d.ts +1 -1
- package/dist/cli/list-models.js.map +1 -1
- package/dist/cli/startup-ui.d.ts +9 -0
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +7 -1
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/core/agent-session-custom-message-commit.js +2 -2
- package/dist/core/agent-session-custom-message-commit.js.map +1 -1
- package/dist/core/agent-session-export.d.ts +6 -1
- package/dist/core/agent-session-export.d.ts.map +1 -1
- package/dist/core/agent-session-export.js +6 -3
- package/dist/core/agent-session-export.js.map +1 -1
- package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
- package/dist/core/agent-session-extension-bindings.js +6 -4
- package/dist/core/agent-session-extension-bindings.js.map +1 -1
- package/dist/core/agent-session-methods.d.ts +5 -2
- package/dist/core/agent-session-methods.d.ts.map +1 -1
- package/dist/core/agent-session-methods.js.map +1 -1
- package/dist/core/agent-session-prompt.d.ts +12 -1
- package/dist/core/agent-session-prompt.d.ts.map +1 -1
- package/dist/core/agent-session-prompt.js +31 -10
- package/dist/core/agent-session-prompt.js.map +1 -1
- package/dist/core/agent-session-runtime-auth.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +1 -1
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session-skill-block.d.ts +1 -0
- package/dist/core/agent-session-skill-block.d.ts.map +1 -1
- package/dist/core/agent-session-skill-block.js +18 -2
- package/dist/core/agent-session-skill-block.js.map +1 -1
- package/dist/core/agent-session-state.d.ts.map +1 -1
- package/dist/core/agent-session-state.js +2 -1
- package/dist/core/agent-session-state.js.map +1 -1
- package/dist/core/agent-session-types.d.ts +2 -1
- package/dist/core/agent-session-types.d.ts.map +1 -1
- package/dist/core/agent-session-types.js.map +1 -1
- package/dist/core/agent-session.d.ts +1 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/atomic-guide-command.js +2 -2
- package/dist/core/atomic-guide-command.js.map +1 -1
- package/dist/core/builtin-packages.d.ts.map +1 -1
- package/dist/core/builtin-packages.js +0 -6
- package/dist/core/builtin-packages.js.map +1 -1
- package/dist/core/cloudflare-gateway-binding.d.ts +11 -0
- package/dist/core/cloudflare-gateway-binding.d.ts.map +1 -0
- package/dist/core/cloudflare-gateway-binding.js +11 -0
- package/dist/core/cloudflare-gateway-binding.js.map +1 -0
- package/dist/core/codex-fast-mode-transport.d.ts +12 -0
- package/dist/core/codex-fast-mode-transport.d.ts.map +1 -0
- package/dist/core/codex-fast-mode-transport.js +130 -0
- package/dist/core/codex-fast-mode-transport.js.map +1 -0
- package/dist/core/codex-fast-mode.d.ts +20 -6
- package/dist/core/codex-fast-mode.d.ts.map +1 -1
- package/dist/core/codex-fast-mode.js +111 -3
- package/dist/core/codex-fast-mode.js.map +1 -1
- package/dist/core/diagnostics.d.ts +4 -0
- package/dist/core/diagnostics.d.ts.map +1 -1
- package/dist/core/diagnostics.js.map +1 -1
- package/dist/core/event-bus.d.ts +12 -0
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js +22 -0
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/experimental.d.ts +25 -0
- package/dist/core/experimental.d.ts.map +1 -1
- package/dist/core/experimental.js +24 -0
- package/dist/core/experimental.js.map +1 -1
- package/dist/core/export-html/template-js/tree-filter-render.js +4 -3
- package/dist/core/export-html/template.js +4 -3
- package/dist/core/extension-session-state.d.ts +28 -0
- package/dist/core/extension-session-state.d.ts.map +1 -0
- package/dist/core/extension-session-state.js +55 -0
- package/dist/core/extension-session-state.js.map +1 -0
- package/dist/core/extensions/api-types.d.ts +6 -0
- package/dist/core/extensions/api-types.d.ts.map +1 -1
- package/dist/core/extensions/api-types.js.map +1 -1
- package/dist/core/extensions/context-types.d.ts +4 -0
- package/dist/core/extensions/context-types.d.ts.map +1 -1
- package/dist/core/extensions/context-types.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -0
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +1 -0
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader-api.d.ts +1 -1
- package/dist/core/extensions/loader-api.d.ts.map +1 -1
- package/dist/core/extensions/loader-api.js +16 -10
- package/dist/core/extensions/loader-api.js.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.js +12 -1
- package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
- package/dist/core/extensions/runner-context.d.ts +2 -0
- package/dist/core/extensions/runner-context.d.ts.map +1 -1
- package/dist/core/extensions/runner-context.js +8 -0
- package/dist/core/extensions/runner-context.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +1 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +3 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/runtime-types.d.ts +3 -0
- package/dist/core/extensions/runtime-types.d.ts.map +1 -1
- package/dist/core/extensions/runtime-types.js.map +1 -1
- package/dist/core/extensions/ui-types.d.ts +26 -0
- package/dist/core/extensions/ui-types.d.ts.map +1 -1
- package/dist/core/extensions/ui-types.js +17 -1
- package/dist/core/extensions/ui-types.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +5 -0
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/keybindings.d.ts +24 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +6 -0
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/model-config.d.ts +5 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +1 -0
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-registry.d.ts +1 -1
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver-cli.d.ts +1 -1
- package/dist/core/model-resolver-cli.js.map +1 -1
- package/dist/core/model-resolver-defaults.js +3 -3
- package/dist/core/model-resolver-defaults.js.map +1 -1
- package/dist/core/model-resolver-initial.d.ts +1 -1
- package/dist/core/model-resolver-initial.js.map +1 -1
- package/dist/core/model-resolver-scope.d.ts +1 -1
- package/dist/core/model-resolver-scope.js.map +1 -1
- package/dist/core/model-runtime.d.ts +54 -0
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +96 -13
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/oauth-login.js.map +1 -1
- package/dist/core/project-trust.d.ts +10 -0
- package/dist/core/project-trust.d.ts.map +1 -1
- package/dist/core/project-trust.js +12 -0
- package/dist/core/project-trust.js.map +1 -1
- package/dist/core/resource-loader-assets.d.ts.map +1 -1
- package/dist/core/resource-loader-assets.js +14 -5
- package/dist/core/resource-loader-assets.js.map +1 -1
- package/dist/core/resource-loader-core.d.ts +3 -0
- package/dist/core/resource-loader-core.d.ts.map +1 -1
- package/dist/core/resource-loader-core.js +5 -0
- package/dist/core/resource-loader-core.js.map +1 -1
- package/dist/core/resource-loader-internals.d.ts +2 -0
- package/dist/core/resource-loader-internals.d.ts.map +1 -1
- package/dist/core/resource-loader-internals.js.map +1 -1
- package/dist/core/resource-loader-reload.d.ts.map +1 -1
- package/dist/core/resource-loader-reload.js +2 -0
- package/dist/core/resource-loader-reload.js.map +1 -1
- package/dist/core/resource-loader-types.d.ts +2 -0
- package/dist/core/resource-loader-types.d.ts.map +1 -1
- package/dist/core/resource-loader-types.js.map +1 -1
- package/dist/core/resource-loader.d.ts +2 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +1 -0
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk-types.d.ts +7 -6
- package/dist/core/sdk-types.d.ts.map +1 -1
- package/dist/core/sdk-types.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +17 -6
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager-core.d.ts +7 -1
- package/dist/core/session-manager-core.d.ts.map +1 -1
- package/dist/core/session-manager-core.js +11 -2
- package/dist/core/session-manager-core.js.map +1 -1
- package/dist/core/session-manager-entries.d.ts +2 -2
- package/dist/core/session-manager-entries.d.ts.map +1 -1
- package/dist/core/session-manager-entries.js +6 -4
- package/dist/core/session-manager-entries.js.map +1 -1
- package/dist/core/session-manager-list.d.ts.map +1 -1
- package/dist/core/session-manager-list.js +5 -1
- package/dist/core/session-manager-list.js.map +1 -1
- package/dist/core/session-manager-types.d.ts +25 -2
- package/dist/core/session-manager-types.d.ts.map +1 -1
- package/dist/core/session-manager-types.js.map +1 -1
- package/dist/core/session-manager.d.ts +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager-basic-accessors.d.ts +1 -0
- package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
- package/dist/core/settings-manager-basic-accessors.js +8 -0
- package/dist/core/settings-manager-basic-accessors.js.map +1 -1
- package/dist/core/settings-manager-ui-accessors.d.ts +3 -1
- package/dist/core/settings-manager-ui-accessors.d.ts.map +1 -1
- package/dist/core/settings-manager-ui-accessors.js +9 -0
- package/dist/core/settings-manager-ui-accessors.js.map +1 -1
- package/dist/core/settings-manager.d.ts +1 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/settings-types.d.ts +4 -0
- package/dist/core/settings-types.d.ts.map +1 -1
- package/dist/core/settings-types.js.map +1 -1
- package/dist/core/skill-catalog.d.ts +35 -0
- package/dist/core/skill-catalog.d.ts.map +1 -0
- package/dist/core/skill-catalog.js +264 -0
- package/dist/core/skill-catalog.js.map +1 -0
- package/dist/core/skills-async.d.ts.map +1 -1
- package/dist/core/skills-async.js +12 -6
- package/dist/core/skills-async.js.map +1 -1
- package/dist/core/skills.d.ts +2 -0
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +8 -5
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -5
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.js +2 -2
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/ask-user-question/ask-user-question.d.ts +25 -2
- package/dist/core/tools/ask-user-question/ask-user-question.d.ts.map +1 -1
- package/dist/core/tools/ask-user-question/ask-user-question.js +47 -18
- package/dist/core/tools/ask-user-question/ask-user-question.js.map +1 -1
- package/dist/core/tools/ask-user-question/view/components/multi-select-view.d.ts.map +1 -1
- package/dist/core/tools/ask-user-question/view/components/multi-select-view.js +5 -2
- package/dist/core/tools/ask-user-question/view/components/multi-select-view.js.map +1 -1
- package/dist/core/tools/ask-user-question/view/components/submit-picker.d.ts.map +1 -1
- package/dist/core/tools/ask-user-question/view/components/submit-picker.js +3 -1
- package/dist/core/tools/ask-user-question/view/components/submit-picker.js.map +1 -1
- package/dist/core/tools/ask-user-question/view/components/wrapping-select.d.ts.map +1 -1
- package/dist/core/tools/ask-user-question/view/components/wrapping-select.js +8 -1
- package/dist/core/tools/ask-user-question/view/components/wrapping-select.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +2 -0
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +2 -0
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +3 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.js +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/hashline-engine/format.d.ts +2 -0
- package/dist/core/tools/hashline-engine/format.d.ts.map +1 -1
- package/dist/core/tools/hashline-engine/format.js +4 -2
- package/dist/core/tools/hashline-engine/format.js.map +1 -1
- package/dist/core/tools/hashline-engine/messages.d.ts +2 -0
- package/dist/core/tools/hashline-engine/messages.d.ts.map +1 -1
- package/dist/core/tools/hashline-engine/messages.js +4 -2
- package/dist/core/tools/hashline-engine/messages.js.map +1 -1
- package/dist/core/tools/hashline-engine/parser.d.ts.map +1 -1
- package/dist/core/tools/hashline-engine/parser.js +16 -4
- package/dist/core/tools/hashline-engine/parser.js.map +1 -1
- package/dist/core/tools/hashline-engine/tokenizer.d.ts.map +1 -1
- package/dist/core/tools/hashline-engine/tokenizer.js +37 -27
- package/dist/core/tools/hashline-engine/tokenizer.js.map +1 -1
- package/dist/core/tools/hashline.d.ts.map +1 -1
- package/dist/core/tools/hashline.js +8 -2
- package/dist/core/tools/hashline.js.map +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +2 -0
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +8 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/search.d.ts.map +1 -1
- package/dist/core/tools/search.js +2 -0
- package/dist/core/tools/search.js.map +1 -1
- package/dist/core/tools/todos.d.ts +3 -12
- package/dist/core/tools/todos.d.ts.map +1 -1
- package/dist/core/tools/todos.js +19 -4
- package/dist/core/tools/todos.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +2 -0
- package/dist/core/tools/write.js.map +1 -1
- package/dist/index-extensions.d.ts +1 -1
- package/dist/index-extensions.d.ts.map +1 -1
- package/dist/index-extensions.js +1 -1
- package/dist/index-extensions.js.map +1 -1
- package/dist/index.d.ts +8 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/main-runtime-api-key.d.ts +1 -1
- package/dist/main-runtime-api-key.js.map +1 -1
- package/dist/main-session-options.d.ts +1 -1
- package/dist/main-session-options.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +10 -2
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-rendering.js +1 -1
- package/dist/modes/interactive/components/chat-session-host-rendering.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-state.d.ts +8 -0
- package/dist/modes/interactive/components/chat-session-host-state.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-state.js +8 -0
- package/dist/modes/interactive/components/chat-session-host-state.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host.d.ts +26 -0
- package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host.js +38 -0
- package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
- package/dist/modes/interactive/components/chat-transcript.d.ts +37 -0
- package/dist/modes/interactive/components/chat-transcript.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-transcript.js +54 -1
- package/dist/modes/interactive/components/chat-transcript.js.map +1 -1
- package/dist/modes/interactive/components/fast-mode-selector.js +1 -1
- package/dist/modes/interactive/components/fast-mode-selector.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +2 -1
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts +1 -1
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/reserved-bottom-overlay.d.ts +95 -0
- package/dist/modes/interactive/components/reserved-bottom-overlay.d.ts.map +1 -0
- package/dist/modes/interactive/components/reserved-bottom-overlay.js +234 -0
- package/dist/modes/interactive/components/reserved-bottom-overlay.js.map +1 -0
- package/dist/modes/interactive/components/session-selector-search.d.ts +4 -0
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.js +4 -0
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector-handlers.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector-handlers.js +3 -0
- package/dist/modes/interactive/components/settings-selector-handlers.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector-items.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector-items.js +7 -0
- package/dist/modes/interactive/components/settings-selector-items.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector-types.d.ts +3 -1
- package/dist/modes/interactive/components/settings-selector-types.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector-types.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +12 -1
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-auth-login.js.map +1 -1
- package/dist/modes/interactive/interactive-auth-routing.js.map +1 -1
- package/dist/modes/interactive/interactive-autocomplete.js +5 -4
- package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
- package/dist/modes/interactive/interactive-bash-compact.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-bash-compact.js +2 -2
- package/dist/modes/interactive/interactive-bash-compact.js.map +1 -1
- package/dist/modes/interactive/interactive-extension-custom-ui.js +94 -6
- package/dist/modes/interactive/interactive-extension-custom-ui.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.d.ts +41 -3
- package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.js +80 -11
- package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.d.ts +9 -1
- package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-types.d.ts +2 -0
- package/dist/modes/interactive/interactive-mode-types.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-types.js.map +1 -1
- package/dist/modes/interactive/interactive-model-catalog-startup.d.ts +8 -1
- package/dist/modes/interactive/interactive-model-catalog-startup.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-model-catalog-startup.js +13 -3
- package/dist/modes/interactive/interactive-model-catalog-startup.js.map +1 -1
- package/dist/modes/interactive/interactive-model-routing.js +3 -4
- package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
- package/dist/modes/interactive/interactive-render-chat.js +6 -0
- package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
- package/dist/modes/interactive/interactive-resource-disclosure.js +2 -2
- package/dist/modes/interactive/interactive-resource-disclosure.js.map +1 -1
- package/dist/modes/interactive/interactive-selectors.js +7 -3
- package/dist/modes/interactive/interactive-selectors.js.map +1 -1
- package/dist/modes/interactive/interactive-session-runtime.js +7 -1
- package/dist/modes/interactive/interactive-session-runtime.js.map +1 -1
- package/dist/modes/interactive/interactive-slash-commands.js +2 -2
- package/dist/modes/interactive/interactive-slash-commands.js.map +1 -1
- package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-startup.js +34 -9
- package/dist/modes/interactive/interactive-startup.js.map +1 -1
- package/dist/modes/interactive/interactive-tui.d.ts +21 -1
- package/dist/modes/interactive/interactive-tui.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-tui.js +140 -38
- package/dist/modes/interactive/interactive-tui.js.map +1 -1
- package/dist/modes/interactive/model-catalog-refresh.d.ts +17 -0
- package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -0
- package/dist/modes/interactive/model-catalog-refresh.js +84 -0
- package/dist/modes/interactive/model-catalog-refresh.js.map +1 -0
- package/dist/modes/interactive/theme/dark.json +2 -0
- package/dist/modes/interactive/theme/light.json +2 -0
- package/dist/modes/interactive/theme/theme-class.d.ts +12 -3
- package/dist/modes/interactive/theme/theme-class.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-class.js +6 -1
- package/dist/modes/interactive/theme/theme-class.js.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.d.ts +10 -2
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.js +23 -10
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
- package/dist/modes/interactive/theme/theme-loading.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-loading.js +1 -0
- package/dist/modes/interactive/theme/theme-loading.js.map +1 -1
- package/dist/modes/interactive/theme/theme-schema.d.ts +8 -0
- package/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-schema.js +3 -1
- package/dist/modes/interactive/theme/theme-schema.js.map +1 -1
- package/dist/modes/interactive/theme/theme-schema.json +9 -1
- package/dist/modes/interactive-engine/engine-custom-ui.d.ts +2 -0
- package/dist/modes/interactive-engine/engine-custom-ui.d.ts.map +1 -1
- package/dist/modes/interactive-engine/engine-custom-ui.js +1 -0
- package/dist/modes/interactive-engine/engine-custom-ui.js.map +1 -1
- package/dist/modes/interactive-engine/protocol.d.ts +1 -0
- package/dist/modes/interactive-engine/protocol.d.ts.map +1 -1
- package/dist/modes/interactive-engine/protocol.js +1 -0
- package/dist/modes/interactive-engine/protocol.js.map +1 -1
- package/dist/modes/interactive-engine/remote-component.d.ts +3 -1
- package/dist/modes/interactive-engine/remote-component.d.ts.map +1 -1
- package/dist/modes/interactive-engine/remote-component.js +3 -2
- package/dist/modes/interactive-engine/remote-component.js.map +1 -1
- package/dist/modes/json-event.d.ts +6 -1
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +17 -2
- package/dist/modes/json-event.js.map +1 -1
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-command-handler.js +5 -4
- package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
- package/dist/modes/rpc/rpc-provider-auth.js.map +1 -1
- package/dist/modes/rpc/rpc-responses.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/server/create-harness.d.ts.map +1 -1
- package/dist/server/create-harness.js +11 -0
- package/dist/server/create-harness.js.map +1 -1
- package/dist/utils/abort.d.ts +9 -0
- package/dist/utils/abort.d.ts.map +1 -0
- package/dist/utils/abort.js +19 -0
- package/dist/utils/abort.js.map +1 -0
- package/dist/utils/tools-manager.d.ts +16 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +19 -19
- package/dist/utils/tools-manager.js.map +1 -1
- package/docs/custom-provider.md +9 -8
- package/docs/development.md +0 -1
- package/docs/docs.json +0 -1
- package/docs/environment-variables.md +3 -0
- package/docs/extensions.md +100 -2
- package/docs/json.md +3 -1
- package/docs/keybindings.md +8 -3
- package/docs/models/artificial-analysis-index.md +2 -2
- package/docs/models/model-selection.md +32 -23
- package/docs/models/pareto-efficiency.md +25 -24
- package/docs/providers.md +95 -2
- package/docs/quickstart.md +4 -2
- package/docs/rpc.md +21 -7
- package/docs/sdk.md +26 -1
- package/docs/session-format.md +5 -2
- package/docs/settings.md +34 -3
- package/docs/skills.md +16 -1
- package/docs/terminal-setup.md +15 -2
- package/docs/themes.md +22 -4
- package/docs/tools.md +3 -1
- package/docs/tui.md +2 -0
- package/docs/usage.md +5 -4
- package/docs/workflows.md +96 -19
- package/npm-shrinkwrap.json +211 -232
- package/package.json +8 -8
- package/dist/builtin/i-have-adhd/CHANGELOG.md +0 -30
- package/dist/builtin/i-have-adhd/LICENSE +0 -21
- package/dist/builtin/i-have-adhd/README.md +0 -18
- package/dist/builtin/i-have-adhd/index.ts +0 -238
- package/dist/builtin/i-have-adhd/package.json +0 -56
- package/dist/builtin/i-have-adhd/skills/i-have-adhd/SKILL.md +0 -140
- package/dist/builtin/workflows/builtin/open-claude-design-feedback.ts +0 -359
- package/dist/builtin/workflows/skills/impeccable/scripts/live/ui-core.mjs +0 -180
- package/docs/i-have-adhd.md +0 -36
|
@@ -95,6 +95,36 @@ export class ChatSessionHost {
|
|
|
95
95
|
renderBody(width, budget) {
|
|
96
96
|
return renderChatSessionBody(this.state, width, budget);
|
|
97
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Rows the body occupies at `width`, whether or not they are on screen.
|
|
100
|
+
*
|
|
101
|
+
* Pair with `renderBodyRows` to read the whole transcript, not only the
|
|
102
|
+
* window the reader is parked on. Both measure the component stack the last
|
|
103
|
+
* `renderBody` installed, so call them after at least one body render.
|
|
104
|
+
*/
|
|
105
|
+
bodyRowCount(width) {
|
|
106
|
+
return this.state.bodyViewport.rowCount(width);
|
|
107
|
+
}
|
|
108
|
+
/** Body rows `startRow` (inclusive) to `endRow` (exclusive), unscrolled. */
|
|
109
|
+
renderBodyRows(width, startRow, endRow) {
|
|
110
|
+
return this.state.bodyViewport.renderRows(width, startRow, endRow);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Render a live assistant entry whole, or only its tail (the default).
|
|
114
|
+
*
|
|
115
|
+
* The tail window keeps a fast-streaming turn cheap for a reader following
|
|
116
|
+
* the bottom of the body; it also drops everything above the last 240 lines
|
|
117
|
+
* from what `bodyRowCount` and `renderBodyRows` report. Returns whether the
|
|
118
|
+
* setting changed, so the caller can invalidate the rows that were rendered
|
|
119
|
+
* under the old rule.
|
|
120
|
+
*/
|
|
121
|
+
setStreamingTailWindowEnabled(enabled) {
|
|
122
|
+
if (this.state.streamingTailWindowEnabled === enabled)
|
|
123
|
+
return false;
|
|
124
|
+
this.state.streamingTailWindowEnabled = enabled;
|
|
125
|
+
this.invalidate();
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
98
128
|
renderPendingMessages(width) {
|
|
99
129
|
return renderChatSessionPendingMessages(this.state, width);
|
|
100
130
|
}
|
|
@@ -158,6 +188,14 @@ export class ChatSessionHost {
|
|
|
158
188
|
scrollToBottom() {
|
|
159
189
|
this.state.bodyViewport.scrollToBottom();
|
|
160
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* Park the body with absolute row `row` at the top of its window, clamped
|
|
193
|
+
* to the last rendered layout. Used to reveal a search match the reader
|
|
194
|
+
* cannot currently see.
|
|
195
|
+
*/
|
|
196
|
+
scrollBodyTo(row) {
|
|
197
|
+
this.state.bodyViewport.scrollTo(row);
|
|
198
|
+
}
|
|
161
199
|
syncAnimationTick() {
|
|
162
200
|
syncChatSessionAnimationTick(this.state);
|
|
163
201
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-session-host.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/chat-session-host.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Component, Focusable } from \"@earendil-works/pi-tui\";\nimport type { AgentSessionEvent, CompactionReason } from \"../../../core/agent-session.ts\";\nimport { repairOrphanToolResults } from \"../../../core/messages.ts\";\nimport { SessionManager } from \"../../../core/session-manager.ts\";\nimport {\n\tabortChatSessionBash,\n\tabortChatSessionCompaction,\n\tinterruptChatSession,\n\trestoreQueuedMessagesToEditor,\n\tsubmitChatSession,\n} from \"./chat-session-host-actions.ts\";\nimport {\n\tcreateChatSessionEditor,\n\thandleChatSessionInput,\n\tsetChatSessionEditorText,\n} from \"./chat-session-host-editor.ts\";\nimport { applyChatSessionAgentEvent, compactionStatusMessage } from \"./chat-session-host-events.ts\";\nimport {\n\trenderChatSessionBody,\n\trenderChatSessionEditor,\n\trenderChatSessionEntry,\n\trenderChatSessionFooter,\n\trenderChatSessionPendingMessages,\n\trenderChatSessionUsage,\n\trenderChatSessionWorkingStatus,\n\ttranscriptCacheKey,\n} from \"./chat-session-host-rendering.ts\";\nimport {\n\tclearChatSessionBusyForTerminalWorkflowStage,\n\tdisposeChatSession,\n\tisChatSessionBashRunning,\n\tisChatSessionStreaming,\n\treassertChatSessionExternalPromptLifecycle,\n\tsettleChatSessionPromptLifecycle,\n\tstartChatSessionExternalPromptLifecycle,\n\tsyncChatSessionAnimationTick,\n} from \"./chat-session-host-runtime.ts\";\nimport { ChatSessionHostState } from \"./chat-session-host-state.ts\";\nimport type {\n\tAgentSnapshotMessage,\n\tChatSessionHostEntry,\n\tChatSessionHostOpts,\n\tChatSessionSubmitMode,\n} from \"./chat-session-host-types.ts\";\nimport type { ChatTranscriptEntryLike } from \"./chat-transcript.ts\";\n\nexport type {\n\tChatSessionHostBashRequest,\n\tChatSessionHostCommands,\n\tChatSessionHostEntry,\n\tChatSessionHostOpts,\n\tChatSessionHostStyle,\n\tChatSessionSubmitMode,\n} from \"./chat-session-host-types.ts\";\n\nexport class ChatSessionHost<TExtraEntry extends ChatTranscriptEntryLike = never> implements Component, Focusable {\n\tfocused = true;\n\n\tprivate readonly state: ChatSessionHostState<TExtraEntry>;\n\n\tconstructor(opts: ChatSessionHostOpts<TExtraEntry>) {\n\t\tthis.state = new ChatSessionHostState(opts, {\n\t\t\trenderEntry: (state, entry) => renderChatSessionEntry(state, entry),\n\t\t\ttranscriptCacheKey: (state, entry, index) => transcriptCacheKey(state, entry, index),\n\t\t});\n\t\tthis.state.editor = createChatSessionEditor(\n\t\t\tthis.state,\n\t\t\topts.tui,\n\t\t\topts.keybindings,\n\t\t\topts.editorTheme,\n\t\t\topts.editorFactory,\n\t\t\tthis.editorCallbacks(),\n\t\t);\n\t\tthis.syncAnimationTick();\n\t}\n\n\tappendMessages(messages: readonly AgentSnapshotMessage[]): void {\n\t\tthis.state.liveChat.appendMessages(messages);\n\t}\n\n\t/**\n\t * Adopt the assistant message a live session is part-way through streaming.\n\t *\n\t * A host mounted mid-turn missed the `message_start` and every delta that\n\t * came before it, and delta-only updates never restate them, so the session's\n\t * in-flight message is the only place that text still exists. Ignored once\n\t * this host is already following a stream of its own.\n\t */\n\thydrateStreamingAssistantMessage(message: AgentSnapshotMessage | undefined): void {\n\t\tif (message === undefined) return;\n\t\tif (this.state.liveChat.hydrateStreamingAssistantMessage(message)) this.state.requestRender?.();\n\t}\n\n\tloadSessionFile(sessionFile: string | undefined): void {\n\t\tif (this.state.transcript.length > 0 || sessionFile === undefined) return;\n\t\tlet messages: readonly AgentSnapshotMessage[];\n\t\ttry {\n\t\t\tmessages = repairOrphanToolResults(SessionManager.open(sessionFile).buildSessionContext().messages, {\n\t\t\t\trepairTrailing: true,\n\t\t\t}) as readonly AgentSnapshotMessage[];\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\t\tthis.state.liveChat.appendMessages(messages);\n\t}\n\n\tappendExtraEntry(entry: TExtraEntry): void {\n\t\tthis.state.extraEntries.push(entry);\n\t\tthis.state.transcript.push(entry);\n\t}\n\n\tentries(): readonly ChatSessionHostEntry<TExtraEntry>[] {\n\t\treturn this.state.transcript;\n\t}\n\n\tapplyAgentEvent(event: AgentSessionEvent): boolean {\n\t\treturn applyChatSessionAgentEvent(this.state, event);\n\t}\n\n\t/**\n\t * Restore the factual compaction indicator on a host mounted after the\n\t * `compaction_start` it never saw. The label resolves through the same\n\t * mapping the live event path uses, so the two cannot drift.\n\t *\n\t * Branch summaries deliberately do not paint here: their label belongs to\n\t * a retry lifecycle this re-attached host is not inside, and no event exists\n\t * to clear it after the summary finishes. An absent paintable reason is a\n\t * no-op unless this host is actively showing a compaction label, so unrelated\n\t * workflow delivery busy state is preserved.\n\t */\n\thydrateCompactionStatus(reason: CompactionReason | undefined): void {\n\t\tconst compactionReason = reason === \"branchSummary\" ? undefined : reason;\n\t\tif (compactionReason === undefined) {\n\t\t\tif (!this.state.compacting) return;\n\t\t\tthis.state.compacting = false;\n\t\t\tthis.state.statusMessage = \"\";\n\t\t} else {\n\t\t\tthis.state.compacting = true;\n\t\t\tthis.state.sdkBusy = true;\n\t\t\tthis.state.statusMessage = compactionStatusMessage(compactionReason);\n\t\t}\n\t\tthis.syncAnimationTick();\n\t\tthis.state.requestRender?.();\n\t}\n\n\trender(width: number): string[] {\n\t\treturn this.renderBody(width, 1);\n\t}\n\n\tinvalidate(): void {\n\t\tthis.state.transcriptComponent.invalidate();\n\t\tthis.state.bodyViewport.invalidate();\n\t\tthis.state.editor?.invalidate();\n\t}\n\n\trenderBody(width: number, budget: number): string[] {\n\t\treturn renderChatSessionBody(this.state, width, budget);\n\t}\n\n\trenderPendingMessages(width: number): string[] {\n\t\treturn renderChatSessionPendingMessages(this.state, width);\n\t}\n\n\trenderWorkingStatus(width: number): string[] {\n\t\treturn renderChatSessionWorkingStatus(this.state, width);\n\t}\n\n\trenderUsage(width: number): string[] {\n\t\treturn renderChatSessionUsage(this.state, width);\n\t}\n\n\trenderEditor(width: number): string[] {\n\t\treturn renderChatSessionEditor(this.state, width, this.focused);\n\t}\n\n\trenderFooter(width: number): string[] {\n\t\treturn renderChatSessionFooter(this.state, width);\n\t}\n\n\thandleScrollInput(data: string): boolean {\n\t\treturn this.state.bodyViewport.handleInput(data);\n\t}\n\n\thandleInput(data: string): boolean {\n\t\treturn handleChatSessionInput(this.state, data, this.editorCallbacks());\n\t}\n\n\tasync interrupt(options?: { restoreQueuedMessages?: boolean }): Promise<void> {\n\t\tawait interruptChatSession(this.state, options);\n\t}\n\n\tasync submit(mode: ChatSessionSubmitMode = \"auto\", submittedText?: string): Promise<void> {\n\t\tawait submitChatSession(this.state, mode, submittedText);\n\t}\n\n\tisStreaming(): boolean {\n\t\treturn isChatSessionStreaming(this.state);\n\t}\n\n\tisBashRunning(): boolean {\n\t\treturn isChatSessionBashRunning(this.state);\n\t}\n\n\tisEditingBashCommand(): boolean {\n\t\treturn this.state.isBashMode;\n\t}\n\n\tisCompacting(): boolean {\n\t\treturn this.state.compacting;\n\t}\n\n\thasInputText(): boolean {\n\t\treturn this.state.inputBuffer.length > 0;\n\t}\n\n\thasAnimationTick(): boolean {\n\t\treturn this.state.animationTimer !== undefined;\n\t}\n\n\tbodyScrollFromBottom(): number {\n\t\treturn this.state.bodyViewport.getScrollFromBottom();\n\t}\n\n\tbodyMaxScroll(): number {\n\t\treturn this.state.bodyViewport.getMaxScroll();\n\t}\n\n\tinputText(): string {\n\t\treturn this.state.inputBuffer;\n\t}\n\tsetInputText(text: string): void {\n\t\tsetChatSessionEditorText(this.state, text);\n\t}\n\n\tstatusText(): string {\n\t\treturn this.state.statusMessage;\n\t}\n\n\tscrollToBottom(): void {\n\t\tthis.state.bodyViewport.scrollToBottom();\n\t}\n\n\tsyncAnimationTick(): void {\n\t\tsyncChatSessionAnimationTick(this.state);\n\t}\n\n\tclearBusyForTerminalWorkflowStage(): void {\n\t\tclearChatSessionBusyForTerminalWorkflowStage(this.state);\n\t}\n\n\t/**\n\t * Start Working for an accepted prompt delivered outside this host — a\n\t * workflow definition auto-sending to its own retained stage. Returns the\n\t * lifecycle token to hand back to `settleExternalPromptLifecycle`.\n\t */\n\tbeginExternalPromptLifecycle(): number | undefined {\n\t\treturn startChatSessionExternalPromptLifecycle(this.state);\n\t}\n\n\t/**\n\t * Reopen Working for a delivery still active after a temporary overlay — a\n\t * pre-turn compaction — cleared it. Preserves factual status text.\n\t */\n\treassertExternalPromptLifecycle(): number | undefined {\n\t\treturn reassertChatSessionExternalPromptLifecycle(this.state);\n\t}\n\n\t/** Settle a lifecycle from `beginExternalPromptLifecycle`. Stale tokens no-op. */\n\tsettleExternalPromptLifecycle(generation: number | undefined): void {\n\t\tsettleChatSessionPromptLifecycle(this.state, generation);\n\t\tsyncChatSessionAnimationTick(this.state);\n\t\tthis.state.requestRender?.();\n\t}\n\n\tdispose(): void {\n\t\tdisposeChatSession(this.state);\n\t}\n\n\trestoreQueuedMessagesToEditor(): boolean {\n\t\treturn restoreQueuedMessagesToEditor(this.state);\n\t}\n\n\tprivate editorCallbacks(): {\n\t\tsubmit: (mode: \"auto\" | \"followUp\", submittedText?: string) => void | Promise<void>;\n\t\trestoreQueuedMessagesToEditor: () => boolean;\n\t\tabortCompaction: () => void | Promise<void>;\n\t\tinterrupt: (options?: { restoreQueuedMessages?: boolean }) => void | Promise<void>;\n\t\tabortBash: () => void | Promise<void>;\n\t} {\n\t\treturn {\n\t\t\tsubmit: (mode, submittedText) => this.submit(mode, submittedText),\n\t\t\trestoreQueuedMessagesToEditor: () => this.restoreQueuedMessagesToEditor(),\n\t\t\tabortCompaction: () => abortChatSessionCompaction(this.state),\n\t\t\tinterrupt: (options) => this.interrupt(options),\n\t\t\tabortBash: () => abortChatSessionBash(this.state),\n\t\t};\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"chat-session-host.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/chat-session-host.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Component, Focusable } from \"@earendil-works/pi-tui\";\nimport type { AgentSessionEvent, CompactionReason } from \"../../../core/agent-session.ts\";\nimport { repairOrphanToolResults } from \"../../../core/messages.ts\";\nimport { SessionManager } from \"../../../core/session-manager.ts\";\nimport {\n\tabortChatSessionBash,\n\tabortChatSessionCompaction,\n\tinterruptChatSession,\n\trestoreQueuedMessagesToEditor,\n\tsubmitChatSession,\n} from \"./chat-session-host-actions.ts\";\nimport {\n\tcreateChatSessionEditor,\n\thandleChatSessionInput,\n\tsetChatSessionEditorText,\n} from \"./chat-session-host-editor.ts\";\nimport { applyChatSessionAgentEvent, compactionStatusMessage } from \"./chat-session-host-events.ts\";\nimport {\n\trenderChatSessionBody,\n\trenderChatSessionEditor,\n\trenderChatSessionEntry,\n\trenderChatSessionFooter,\n\trenderChatSessionPendingMessages,\n\trenderChatSessionUsage,\n\trenderChatSessionWorkingStatus,\n\ttranscriptCacheKey,\n} from \"./chat-session-host-rendering.ts\";\nimport {\n\tclearChatSessionBusyForTerminalWorkflowStage,\n\tdisposeChatSession,\n\tisChatSessionBashRunning,\n\tisChatSessionStreaming,\n\treassertChatSessionExternalPromptLifecycle,\n\tsettleChatSessionPromptLifecycle,\n\tstartChatSessionExternalPromptLifecycle,\n\tsyncChatSessionAnimationTick,\n} from \"./chat-session-host-runtime.ts\";\nimport { ChatSessionHostState } from \"./chat-session-host-state.ts\";\nimport type {\n\tAgentSnapshotMessage,\n\tChatSessionHostEntry,\n\tChatSessionHostOpts,\n\tChatSessionSubmitMode,\n} from \"./chat-session-host-types.ts\";\nimport type { ChatTranscriptEntryLike } from \"./chat-transcript.ts\";\n\nexport type {\n\tChatSessionHostBashRequest,\n\tChatSessionHostCommands,\n\tChatSessionHostEntry,\n\tChatSessionHostOpts,\n\tChatSessionHostStyle,\n\tChatSessionSubmitMode,\n} from \"./chat-session-host-types.ts\";\n\nexport class ChatSessionHost<TExtraEntry extends ChatTranscriptEntryLike = never> implements Component, Focusable {\n\tfocused = true;\n\n\tprivate readonly state: ChatSessionHostState<TExtraEntry>;\n\n\tconstructor(opts: ChatSessionHostOpts<TExtraEntry>) {\n\t\tthis.state = new ChatSessionHostState(opts, {\n\t\t\trenderEntry: (state, entry) => renderChatSessionEntry(state, entry),\n\t\t\ttranscriptCacheKey: (state, entry, index) => transcriptCacheKey(state, entry, index),\n\t\t});\n\t\tthis.state.editor = createChatSessionEditor(\n\t\t\tthis.state,\n\t\t\topts.tui,\n\t\t\topts.keybindings,\n\t\t\topts.editorTheme,\n\t\t\topts.editorFactory,\n\t\t\tthis.editorCallbacks(),\n\t\t);\n\t\tthis.syncAnimationTick();\n\t}\n\n\tappendMessages(messages: readonly AgentSnapshotMessage[]): void {\n\t\tthis.state.liveChat.appendMessages(messages);\n\t}\n\n\t/**\n\t * Adopt the assistant message a live session is part-way through streaming.\n\t *\n\t * A host mounted mid-turn missed the `message_start` and every delta that\n\t * came before it, and delta-only updates never restate them, so the session's\n\t * in-flight message is the only place that text still exists. Ignored once\n\t * this host is already following a stream of its own.\n\t */\n\thydrateStreamingAssistantMessage(message: AgentSnapshotMessage | undefined): void {\n\t\tif (message === undefined) return;\n\t\tif (this.state.liveChat.hydrateStreamingAssistantMessage(message)) this.state.requestRender?.();\n\t}\n\n\tloadSessionFile(sessionFile: string | undefined): void {\n\t\tif (this.state.transcript.length > 0 || sessionFile === undefined) return;\n\t\tlet messages: readonly AgentSnapshotMessage[];\n\t\ttry {\n\t\t\tmessages = repairOrphanToolResults(SessionManager.open(sessionFile).buildSessionContext().messages, {\n\t\t\t\trepairTrailing: true,\n\t\t\t}) as readonly AgentSnapshotMessage[];\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\t\tthis.state.liveChat.appendMessages(messages);\n\t}\n\n\tappendExtraEntry(entry: TExtraEntry): void {\n\t\tthis.state.extraEntries.push(entry);\n\t\tthis.state.transcript.push(entry);\n\t}\n\n\tentries(): readonly ChatSessionHostEntry<TExtraEntry>[] {\n\t\treturn this.state.transcript;\n\t}\n\n\tapplyAgentEvent(event: AgentSessionEvent): boolean {\n\t\treturn applyChatSessionAgentEvent(this.state, event);\n\t}\n\n\t/**\n\t * Restore the factual compaction indicator on a host mounted after the\n\t * `compaction_start` it never saw. The label resolves through the same\n\t * mapping the live event path uses, so the two cannot drift.\n\t *\n\t * Branch summaries deliberately do not paint here: their label belongs to\n\t * a retry lifecycle this re-attached host is not inside, and no event exists\n\t * to clear it after the summary finishes. An absent paintable reason is a\n\t * no-op unless this host is actively showing a compaction label, so unrelated\n\t * workflow delivery busy state is preserved.\n\t */\n\thydrateCompactionStatus(reason: CompactionReason | undefined): void {\n\t\tconst compactionReason = reason === \"branchSummary\" ? undefined : reason;\n\t\tif (compactionReason === undefined) {\n\t\t\tif (!this.state.compacting) return;\n\t\t\tthis.state.compacting = false;\n\t\t\tthis.state.statusMessage = \"\";\n\t\t} else {\n\t\t\tthis.state.compacting = true;\n\t\t\tthis.state.sdkBusy = true;\n\t\t\tthis.state.statusMessage = compactionStatusMessage(compactionReason);\n\t\t}\n\t\tthis.syncAnimationTick();\n\t\tthis.state.requestRender?.();\n\t}\n\n\trender(width: number): string[] {\n\t\treturn this.renderBody(width, 1);\n\t}\n\n\tinvalidate(): void {\n\t\tthis.state.transcriptComponent.invalidate();\n\t\tthis.state.bodyViewport.invalidate();\n\t\tthis.state.editor?.invalidate();\n\t}\n\n\trenderBody(width: number, budget: number): string[] {\n\t\treturn renderChatSessionBody(this.state, width, budget);\n\t}\n\n\t/**\n\t * Rows the body occupies at `width`, whether or not they are on screen.\n\t *\n\t * Pair with `renderBodyRows` to read the whole transcript, not only the\n\t * window the reader is parked on. Both measure the component stack the last\n\t * `renderBody` installed, so call them after at least one body render.\n\t */\n\tbodyRowCount(width: number): number {\n\t\treturn this.state.bodyViewport.rowCount(width);\n\t}\n\n\t/** Body rows `startRow` (inclusive) to `endRow` (exclusive), unscrolled. */\n\trenderBodyRows(width: number, startRow: number, endRow: number): string[] {\n\t\treturn this.state.bodyViewport.renderRows(width, startRow, endRow);\n\t}\n\n\t/**\n\t * Render a live assistant entry whole, or only its tail (the default).\n\t *\n\t * The tail window keeps a fast-streaming turn cheap for a reader following\n\t * the bottom of the body; it also drops everything above the last 240 lines\n\t * from what `bodyRowCount` and `renderBodyRows` report. Returns whether the\n\t * setting changed, so the caller can invalidate the rows that were rendered\n\t * under the old rule.\n\t */\n\tsetStreamingTailWindowEnabled(enabled: boolean): boolean {\n\t\tif (this.state.streamingTailWindowEnabled === enabled) return false;\n\t\tthis.state.streamingTailWindowEnabled = enabled;\n\t\tthis.invalidate();\n\t\treturn true;\n\t}\n\n\trenderPendingMessages(width: number): string[] {\n\t\treturn renderChatSessionPendingMessages(this.state, width);\n\t}\n\n\trenderWorkingStatus(width: number): string[] {\n\t\treturn renderChatSessionWorkingStatus(this.state, width);\n\t}\n\n\trenderUsage(width: number): string[] {\n\t\treturn renderChatSessionUsage(this.state, width);\n\t}\n\n\trenderEditor(width: number): string[] {\n\t\treturn renderChatSessionEditor(this.state, width, this.focused);\n\t}\n\n\trenderFooter(width: number): string[] {\n\t\treturn renderChatSessionFooter(this.state, width);\n\t}\n\n\thandleScrollInput(data: string): boolean {\n\t\treturn this.state.bodyViewport.handleInput(data);\n\t}\n\n\thandleInput(data: string): boolean {\n\t\treturn handleChatSessionInput(this.state, data, this.editorCallbacks());\n\t}\n\n\tasync interrupt(options?: { restoreQueuedMessages?: boolean }): Promise<void> {\n\t\tawait interruptChatSession(this.state, options);\n\t}\n\n\tasync submit(mode: ChatSessionSubmitMode = \"auto\", submittedText?: string): Promise<void> {\n\t\tawait submitChatSession(this.state, mode, submittedText);\n\t}\n\n\tisStreaming(): boolean {\n\t\treturn isChatSessionStreaming(this.state);\n\t}\n\n\tisBashRunning(): boolean {\n\t\treturn isChatSessionBashRunning(this.state);\n\t}\n\n\tisEditingBashCommand(): boolean {\n\t\treturn this.state.isBashMode;\n\t}\n\n\tisCompacting(): boolean {\n\t\treturn this.state.compacting;\n\t}\n\n\thasInputText(): boolean {\n\t\treturn this.state.inputBuffer.length > 0;\n\t}\n\n\thasAnimationTick(): boolean {\n\t\treturn this.state.animationTimer !== undefined;\n\t}\n\n\tbodyScrollFromBottom(): number {\n\t\treturn this.state.bodyViewport.getScrollFromBottom();\n\t}\n\n\tbodyMaxScroll(): number {\n\t\treturn this.state.bodyViewport.getMaxScroll();\n\t}\n\n\tinputText(): string {\n\t\treturn this.state.inputBuffer;\n\t}\n\tsetInputText(text: string): void {\n\t\tsetChatSessionEditorText(this.state, text);\n\t}\n\n\tstatusText(): string {\n\t\treturn this.state.statusMessage;\n\t}\n\n\tscrollToBottom(): void {\n\t\tthis.state.bodyViewport.scrollToBottom();\n\t}\n\n\t/**\n\t * Park the body with absolute row `row` at the top of its window, clamped\n\t * to the last rendered layout. Used to reveal a search match the reader\n\t * cannot currently see.\n\t */\n\tscrollBodyTo(row: number): void {\n\t\tthis.state.bodyViewport.scrollTo(row);\n\t}\n\n\tsyncAnimationTick(): void {\n\t\tsyncChatSessionAnimationTick(this.state);\n\t}\n\n\tclearBusyForTerminalWorkflowStage(): void {\n\t\tclearChatSessionBusyForTerminalWorkflowStage(this.state);\n\t}\n\n\t/**\n\t * Start Working for an accepted prompt delivered outside this host — a\n\t * workflow definition auto-sending to its own retained stage. Returns the\n\t * lifecycle token to hand back to `settleExternalPromptLifecycle`.\n\t */\n\tbeginExternalPromptLifecycle(): number | undefined {\n\t\treturn startChatSessionExternalPromptLifecycle(this.state);\n\t}\n\n\t/**\n\t * Reopen Working for a delivery still active after a temporary overlay — a\n\t * pre-turn compaction — cleared it. Preserves factual status text.\n\t */\n\treassertExternalPromptLifecycle(): number | undefined {\n\t\treturn reassertChatSessionExternalPromptLifecycle(this.state);\n\t}\n\n\t/** Settle a lifecycle from `beginExternalPromptLifecycle`. Stale tokens no-op. */\n\tsettleExternalPromptLifecycle(generation: number | undefined): void {\n\t\tsettleChatSessionPromptLifecycle(this.state, generation);\n\t\tsyncChatSessionAnimationTick(this.state);\n\t\tthis.state.requestRender?.();\n\t}\n\n\tdispose(): void {\n\t\tdisposeChatSession(this.state);\n\t}\n\n\trestoreQueuedMessagesToEditor(): boolean {\n\t\treturn restoreQueuedMessagesToEditor(this.state);\n\t}\n\n\tprivate editorCallbacks(): {\n\t\tsubmit: (mode: \"auto\" | \"followUp\", submittedText?: string) => void | Promise<void>;\n\t\trestoreQueuedMessagesToEditor: () => boolean;\n\t\tabortCompaction: () => void | Promise<void>;\n\t\tinterrupt: (options?: { restoreQueuedMessages?: boolean }) => void | Promise<void>;\n\t\tabortBash: () => void | Promise<void>;\n\t} {\n\t\treturn {\n\t\t\tsubmit: (mode, submittedText) => this.submit(mode, submittedText),\n\t\t\trestoreQueuedMessagesToEditor: () => this.restoreQueuedMessagesToEditor(),\n\t\t\tabortCompaction: () => abortChatSessionCompaction(this.state),\n\t\t\tinterrupt: (options) => this.interrupt(options),\n\t\t\tabortBash: () => abortChatSessionBash(this.state),\n\t\t};\n\t}\n}\n"]}
|
|
@@ -82,6 +82,11 @@ export declare class ScrollableComponentViewport implements Component {
|
|
|
82
82
|
private lastComponentRowCounts;
|
|
83
83
|
private lastWidth;
|
|
84
84
|
private maxScroll;
|
|
85
|
+
/**
|
|
86
|
+
* Absolute row `scrollTo` asked for, still waiting for the render that can
|
|
87
|
+
* honour it. See `scrollTo` for why the request has to outlive the call.
|
|
88
|
+
*/
|
|
89
|
+
private pendingScrollRow;
|
|
85
90
|
setComponents(components: readonly Component[]): void;
|
|
86
91
|
setVisibleRows(rows: number): void;
|
|
87
92
|
getScrollFromBottom(): number;
|
|
@@ -89,6 +94,38 @@ export declare class ScrollableComponentViewport implements Component {
|
|
|
89
94
|
scrollToBottom(): void;
|
|
90
95
|
scrollToTop(): void;
|
|
91
96
|
scrollBy(deltaRows: number): void;
|
|
97
|
+
/**
|
|
98
|
+
* Park the viewport with `row` as its first visible row.
|
|
99
|
+
*
|
|
100
|
+
* The absolute counterpart of `scrollBy`, for a caller that already knows
|
|
101
|
+
* which row it wants on screen.
|
|
102
|
+
*
|
|
103
|
+
* The request is *also* recorded for the next render, and that is the half
|
|
104
|
+
* that matters. `scrollFromBottom` is a distance from the bottom, so the
|
|
105
|
+
* row it names moves whenever the stack grows; and the render that follows
|
|
106
|
+
* re-derives the offset from the previous frame's layout to hold a
|
|
107
|
+
* scrolled-up reader's content still, which would drag this request back
|
|
108
|
+
* with it. A caller who has just measured rows the last render never saw
|
|
109
|
+
* would otherwise be answered with the old layout's clamp and the old
|
|
110
|
+
* frame's anchor. The next render resolves the row against the layout it
|
|
111
|
+
* actually paints; any other scroll before then withdraws the request.
|
|
112
|
+
*/
|
|
113
|
+
scrollTo(row: number): void;
|
|
114
|
+
/**
|
|
115
|
+
* Total rows the component stack occupies at `width`, on and off screen.
|
|
116
|
+
*
|
|
117
|
+
* This measures rather than paints: it is what lets a search read the whole
|
|
118
|
+
* transcript instead of the window the reader happens to be parked on.
|
|
119
|
+
*/
|
|
120
|
+
rowCount(width: number): number;
|
|
121
|
+
/**
|
|
122
|
+
* Rows `startRow` (inclusive) through `endRow` (exclusive) of the whole
|
|
123
|
+
* stack, independent of the current scroll offset. Deliberately not paired
|
|
124
|
+
* with `supportsRowWindow`: a viewport is a scroll container rather than a
|
|
125
|
+
* windowed component, and an enclosing viewport must keep measuring it by
|
|
126
|
+
* its visible height.
|
|
127
|
+
*/
|
|
128
|
+
renderRows(width: number, startRow: number, endRow: number): string[];
|
|
92
129
|
handleInput(data: string): boolean;
|
|
93
130
|
render(width: number): string[];
|
|
94
131
|
invalidate(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-transcript.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/chat-transcript.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAsB,MAAM,wBAAwB,CAAC;AAE5F;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAC3B,WAAW,GACX,UAAU,GACV,MAAM,GACN,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,SAAS,CAAC;AAEb,MAAM,WAAW,uBAAuB;IACvC,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;CAClC;AAED,MAAM,MAAM,sBAAsB,CAAC,MAAM,SAAS,uBAAuB,IAAI,CAAC,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;AAE1G,MAAM,MAAM,sBAAsB,CAAC,MAAM,SAAS,uBAAuB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;AAYtH;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAmCD,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,kBAAkB,GAAG,IAAI,CAKjH;AAMD;;;;;;;GAOG;AACH,qBAAa,uBAAuB,CAAC,MAAM,SAAS,uBAAuB,CAAE,YAAW,SAAS;IAChG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAC5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiC;IAC7D,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IAEpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6C;IACtE,OAAO,CAAC,UAAU,CAA4D;IAC9E,qEAAqE;IACrE,OAAO,CAAC,cAAc,CAAmC;IACzD,gFAAgF;IAChF,OAAO,CAAC,mBAAmB,CAAqB;IAEhD,YACC,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,WAAW,EAAE,sBAAsB,CAAC,MAAM,CAAC,EAC3C,QAAQ,CAAC,EAAE,sBAAsB,CAAC,MAAM,CAAC,EAMzC;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAG9B;IAED,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQ9B;IAED;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,gBAAgB,EAAE,CAgBtD;IAED,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAuBpE;IAED,UAAU,IAAI,IAAI,CAGjB;IAED,OAAO,CAAC,gBAAgB;IA2BxB;;;;;;;;OAQG;IACH,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,gBAAgB;CAMxB;AAQD;;;;;;GAMG;AACH,qBAAa,2BAA4B,YAAW,SAAS;IAC5D,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,qBAAqB,CAA4D;IACzF,OAAO,CAAC,sBAAsB,CAAyB;IACvD,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,SAAS,CAAK;
|
|
1
|
+
{"version":3,"file":"chat-transcript.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/chat-transcript.ts"],"names":[],"mappings":"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"}
|
|
@@ -190,18 +190,63 @@ export class ScrollableComponentViewport {
|
|
|
190
190
|
return this.maxScroll;
|
|
191
191
|
}
|
|
192
192
|
scrollToBottom() {
|
|
193
|
+
this.pendingScrollRow = undefined;
|
|
193
194
|
this.scrollFromBottom = 0;
|
|
194
195
|
}
|
|
195
196
|
scrollToTop() {
|
|
197
|
+
this.pendingScrollRow = undefined;
|
|
196
198
|
this.scrollFromBottom = this.maxScroll;
|
|
197
199
|
}
|
|
198
200
|
scrollBy(deltaRows) {
|
|
199
201
|
// Positive deltas move toward newer content; negative deltas move up
|
|
200
202
|
// into older history. Store the offset from the sticky bottom so new
|
|
201
203
|
// streaming output can keep following when the offset is zero.
|
|
204
|
+
this.pendingScrollRow = undefined;
|
|
202
205
|
this.scrollFromBottom -= deltaRows;
|
|
203
206
|
this.clampScroll();
|
|
204
207
|
}
|
|
208
|
+
/**
|
|
209
|
+
* Park the viewport with `row` as its first visible row.
|
|
210
|
+
*
|
|
211
|
+
* The absolute counterpart of `scrollBy`, for a caller that already knows
|
|
212
|
+
* which row it wants on screen.
|
|
213
|
+
*
|
|
214
|
+
* The request is *also* recorded for the next render, and that is the half
|
|
215
|
+
* that matters. `scrollFromBottom` is a distance from the bottom, so the
|
|
216
|
+
* row it names moves whenever the stack grows; and the render that follows
|
|
217
|
+
* re-derives the offset from the previous frame's layout to hold a
|
|
218
|
+
* scrolled-up reader's content still, which would drag this request back
|
|
219
|
+
* with it. A caller who has just measured rows the last render never saw
|
|
220
|
+
* would otherwise be answered with the old layout's clamp and the old
|
|
221
|
+
* frame's anchor. The next render resolves the row against the layout it
|
|
222
|
+
* actually paints; any other scroll before then withdraws the request.
|
|
223
|
+
*/
|
|
224
|
+
scrollTo(row) {
|
|
225
|
+
const requestedRow = Number.isNaN(row) ? 0 : Math.max(0, Math.floor(row));
|
|
226
|
+
this.pendingScrollRow = requestedRow;
|
|
227
|
+
const target = Math.min(this.maxScroll, requestedRow);
|
|
228
|
+
this.scrollFromBottom = this.maxScroll - target;
|
|
229
|
+
this.clampScroll();
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Total rows the component stack occupies at `width`, on and off screen.
|
|
233
|
+
*
|
|
234
|
+
* This measures rather than paints: it is what lets a search read the whole
|
|
235
|
+
* transcript instead of the window the reader happens to be parked on.
|
|
236
|
+
*/
|
|
237
|
+
rowCount(width) {
|
|
238
|
+
return this.measureComponentRows(width).reduce((sum, rows) => sum + rows.rowCount, 0);
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Rows `startRow` (inclusive) through `endRow` (exclusive) of the whole
|
|
242
|
+
* stack, independent of the current scroll offset. Deliberately not paired
|
|
243
|
+
* with `supportsRowWindow`: a viewport is a scroll container rather than a
|
|
244
|
+
* windowed component, and an enclosing viewport must keep measuring it by
|
|
245
|
+
* its visible height.
|
|
246
|
+
*/
|
|
247
|
+
renderRows(width, startRow, endRow) {
|
|
248
|
+
return this.renderVisibleRows(this.measureComponentRows(width), width, startRow, endRow);
|
|
249
|
+
}
|
|
205
250
|
handleInput(data) {
|
|
206
251
|
const wheelDeltaRows = mouseWheelDeltaRows(data);
|
|
207
252
|
if (wheelDeltaRows !== 0) {
|
|
@@ -256,7 +301,15 @@ export class ScrollableComponentViewport {
|
|
|
256
301
|
// transcript built without a cache key is not windowed, but it is still
|
|
257
302
|
// one component spanning the anchor and still knows its own rows.
|
|
258
303
|
const segments = componentRows.map((rows) => rows.segments);
|
|
259
|
-
|
|
304
|
+
const pendingScrollRow = this.pendingScrollRow;
|
|
305
|
+
this.pendingScrollRow = undefined;
|
|
306
|
+
if (pendingScrollRow !== undefined) {
|
|
307
|
+
// An absolute request outranks the anchor: the caller measured this
|
|
308
|
+
// frame's rows and named one of them. Re-deriving the anchor here
|
|
309
|
+
// would answer with the previous frame's layout instead.
|
|
310
|
+
this.scrollFromBottom = maxScroll - Math.min(maxScroll, pendingScrollRow);
|
|
311
|
+
}
|
|
312
|
+
else if (this.scrollFromBottom > 0 && this.lastWidth === width) {
|
|
260
313
|
const previousMaxScroll = Math.max(0, this.lastLineCount - this.visibleRows);
|
|
261
314
|
const anchorRow = Math.max(0, previousMaxScroll - this.scrollFromBottom);
|
|
262
315
|
const shift = rowsShiftedAboveAnchor({ rowCounts: this.lastComponentRowCounts, segments: this.lastComponentSegments }, { rowCounts, segments }, anchorRow);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-transcript.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/chat-transcript.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Component, type Container, matchesKey, Spacer } from \"@earendil-works/pi-tui\";\n\n/**\n * Roles that participate in pi's chat spacing contract.\n *\n * Assistant turns own their leading whitespace internally, and tool rows attach\n * directly under the assistant/tool-call row they belong to. User-like rows get\n * one blank line when they are not the first row in the transcript.\n */\nexport type ChatTranscriptRole =\n\t| \"assistant\"\n\t| \"thinking\"\n\t| \"tool\"\n\t| \"user\"\n\t| \"custom\"\n\t| \"notice\"\n\t| \"system\"\n\t| \"summary\";\n\nexport interface ChatTranscriptEntryLike {\n\treadonly role: ChatTranscriptRole;\n}\n\nexport type ChatTranscriptRenderer<TEntry extends ChatTranscriptEntryLike> = (entry: TEntry) => Component;\n\nexport type ChatTranscriptCacheKey<TEntry extends ChatTranscriptEntryLike> = (entry: TEntry, index: number) => string;\n\ninterface CachedChatTranscriptBlock<TEntry extends ChatTranscriptEntryLike> {\n\treadonly entry: TEntry;\n\treadonly key: string;\n\treadonly width: number;\n\treadonly component: Component;\n\treadonly lines: readonly string[];\n}\n\ntype DisposableComponent = Component & { dispose?: () => void };\n\n/**\n * A run of rows inside a windowed component, tagged with the identity of the\n * thing that produced them.\n *\n * `id` is compared with `===` only, and is never rendered. Entry *objects* are\n * the natural id for a transcript: cache keys carry the entry's index and so\n * change for every survivor of a splice, while the entry objects themselves are\n * moved, not rebuilt.\n */\nexport interface RowWindowSegment {\n\treadonly id: unknown;\n\treadonly rows: number;\n}\n\ninterface RowWindowComponent extends Component {\n\treadonly supportsRowWindow: true;\n\trowCount(width: number): number;\n\trenderRows(width: number, startRow: number, endRow: number): string[];\n\t/**\n\t * Optional row map, letting the viewport keep a scroll anchor that sits\n\t * *inside* this component when its interior changes height.\n\t */\n\trowSegments?(width: number): readonly RowWindowSegment[];\n}\n\ninterface WindowedComponentRows {\n\treadonly kind: \"windowed\";\n\treadonly component: RowWindowComponent;\n\treadonly rowCount: number;\n\treadonly segments: readonly RowWindowSegment[] | undefined;\n}\n\ninterface StaticComponentRows {\n\treadonly kind: \"static\";\n\treadonly lines: readonly string[];\n\treadonly rowCount: number;\n\t/**\n\t * Present when a static component can still identify its own rows. A\n\t * transcript built without a cache key renders every row each frame rather\n\t * than windowing, but it knows just as well which entry produced which rows,\n\t * and the anchor needs that whenever it is the component spanning the anchor.\n\t */\n\treadonly segments?: readonly RowWindowSegment[] | undefined;\n}\n\ntype ComponentRows = WindowedComponentRows | StaticComponentRows;\n\nexport function addChatTranscriptEntry(container: Container, component: Component, role: ChatTranscriptRole): void {\n\tif (needsLeadingSpacer(role) && container.children.length > 0) {\n\t\tcontainer.addChild(new Spacer(1));\n\t}\n\tcontainer.addChild(component);\n}\n\nfunction needsLeadingSpacer(role: ChatTranscriptRole): boolean {\n\treturn role === \"user\" || role === \"custom\" || role === \"notice\" || role === \"system\" || role === \"summary\";\n}\n\n/**\n * Reusable pi chat transcript scaffold for extension surfaces.\n *\n * This intentionally mirrors InteractiveMode.addMessageToChat spacing without\n * coupling consumers to a full AgentSession. Extension UIs can bring their own\n * message model while still rendering inside the same Container/Spacer rhythm\n * as the main chat.\n */\nexport class ChatTranscriptComponent<TEntry extends ChatTranscriptEntryLike> implements Component {\n\tprivate readonly entries: readonly TEntry[];\n\tprivate readonly renderEntry: ChatTranscriptRenderer<TEntry>;\n\treadonly supportsRowWindow: boolean;\n\n\tprivate readonly cacheKey: ChatTranscriptCacheKey<TEntry> | undefined;\n\tprivate blockCache: Array<CachedChatTranscriptBlock<TEntry> | undefined> = [];\n\t/** Per-entry heights recorded by the most recent `renderAllRows`. */\n\tprivate staticSegments: readonly RowWindowSegment[] = [];\n\t/** Width those heights were measured at; they mean nothing at another width. */\n\tprivate staticSegmentsWidth: number | undefined;\n\n\tconstructor(\n\t\tentries: readonly TEntry[],\n\t\trenderEntry: ChatTranscriptRenderer<TEntry>,\n\t\tcacheKey?: ChatTranscriptCacheKey<TEntry>,\n\t) {\n\t\tthis.entries = entries;\n\t\tthis.renderEntry = renderEntry;\n\t\tthis.cacheKey = cacheKey;\n\t\tthis.supportsRowWindow = cacheKey !== undefined;\n\t}\n\n\trender(width: number): string[] {\n\t\tif (!this.supportsRowWindow) return this.renderAllRows(width);\n\t\treturn this.renderRows(width, 0, this.rowCount(width));\n\t}\n\n\trowCount(width: number): number {\n\t\tif (!this.supportsRowWindow) return this.renderAllRows(width).length;\n\t\tthis.ensureBlockCache(width);\n\t\tlet count = 0;\n\t\tfor (const block of this.blockCache) {\n\t\t\tif (block !== undefined) count += block.lines.length;\n\t\t}\n\t\treturn count;\n\t}\n\n\t/**\n\t * One segment per cached entry block, identified by the entry object itself.\n\t */\n\trowSegments(width: number): readonly RowWindowSegment[] {\n\t\tif (!this.supportsRowWindow) {\n\t\t\t// Recorded by the last renderAllRows. The viewport measures a static\n\t\t\t// component by rendering it and only then reads its segments, so this\n\t\t\t// is populated for the frame being measured. A width mismatch means the\n\t\t\t// heights describe a different layout, and reporting them would move the\n\t\t\t// anchor by a stale delta; the caller falls back to whole-component\n\t\t\t// accounting instead.\n\t\t\treturn this.staticSegmentsWidth === width ? this.staticSegments : [];\n\t\t}\n\t\tthis.ensureBlockCache(width);\n\t\tconst segments: RowWindowSegment[] = [];\n\t\tfor (const block of this.blockCache) {\n\t\t\tif (block !== undefined) segments.push({ id: block.entry, rows: block.lines.length });\n\t\t}\n\t\treturn segments;\n\t}\n\n\trenderRows(width: number, startRow: number, endRow: number): string[] {\n\t\tconst start = Math.max(0, Math.floor(startRow));\n\t\tconst end = Math.max(start, Math.floor(endRow));\n\t\tif (end <= start) return [];\n\t\tif (!this.supportsRowWindow) return this.renderAllRows(width).slice(start, end);\n\n\t\tthis.ensureBlockCache(width);\n\t\tconst lines: string[] = [];\n\t\tlet cursor = 0;\n\t\tfor (let index = 0; index < this.entries.length; index += 1) {\n\t\t\tconst block = this.blockCache[index];\n\t\t\tif (block === undefined) continue;\n\t\t\tconst blockStart = cursor;\n\t\t\tconst blockEnd = blockStart + block.lines.length;\n\t\t\tif (blockEnd > start && blockStart < end) {\n\t\t\t\tconst localStart = Math.max(0, start - blockStart);\n\t\t\t\tconst localEnd = Math.min(block.lines.length, end - blockStart);\n\t\t\t\tlines.push(...block.lines.slice(localStart, localEnd));\n\t\t\t}\n\t\t\tcursor = blockEnd;\n\t\t\tif (cursor >= end) break;\n\t\t}\n\t\treturn lines;\n\t}\n\n\tinvalidate(): void {\n\t\tfor (const block of this.blockCache) disposeComponent(block?.component);\n\t\tthis.blockCache = [];\n\t}\n\n\tprivate ensureBlockCache(width: number): void {\n\t\tif (this.blockCache.length > this.entries.length) {\n\t\t\tfor (let index = this.entries.length; index < this.blockCache.length; index += 1) {\n\t\t\t\tdisposeComponent(this.blockCache[index]?.component);\n\t\t\t}\n\t\t\tthis.blockCache.length = this.entries.length;\n\t\t}\n\t\tfor (let index = 0; index < this.entries.length; index += 1) {\n\t\t\tconst entry = this.entries[index];\n\t\t\tif (entry === undefined) continue;\n\t\t\tconst key = this.cacheKey?.(entry, index) ?? `${index}:${entry.role}`;\n\t\t\tconst cached = this.blockCache[index];\n\t\t\tif (cached !== undefined && cached.entry === entry && cached.key === key && cached.width === width) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tdisposeComponent(cached?.component);\n\t\t\tconst component = this.renderEntry(entry);\n\t\t\tthis.blockCache[index] = {\n\t\t\t\tentry,\n\t\t\t\tkey,\n\t\t\t\twidth,\n\t\t\t\tcomponent,\n\t\t\t\tlines: this.renderEntryBlock(component, entry, index, width),\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Render every entry, recording each one's height as it goes.\n\t *\n\t * The heights are what `rowSegments` reports on this path. They are a\n\t * by-product of work this method already does, so identifying rows costs\n\t * nothing extra and, unlike a cache key, cannot miss an entry mutated in\n\t * place -- which is the behaviour a transcript without a cache key exists to\n\t * provide.\n\t */\n\tprivate renderAllRows(width: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tconst segments: RowWindowSegment[] = [];\n\t\tfor (let index = 0; index < this.entries.length; index += 1) {\n\t\t\tconst entry = this.entries[index];\n\t\t\tif (entry === undefined) continue;\n\t\t\tconst block = this.renderEntryBlock(this.renderEntry(entry), entry, index, width);\n\t\t\tsegments.push({ id: entry, rows: block.length });\n\t\t\tlines.push(...block);\n\t\t}\n\t\tthis.staticSegments = segments;\n\t\tthis.staticSegmentsWidth = width;\n\t\treturn lines;\n\t}\n\n\tprivate renderEntryBlock(component: Component, entry: TEntry, index: number, width: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tif (index > 0 && needsLeadingSpacer(entry.role)) lines.push(\"\");\n\t\tlines.push(...component.render(width));\n\t\treturn lines;\n\t}\n}\n\nfunction disposeComponent(component: Component | undefined): void {\n\t(component as DisposableComponent | undefined)?.dispose?.();\n}\n\nconst DEFAULT_SCROLL_STEP_ROWS = 4;\n\n/**\n * Sticky-bottom, scrollable viewport for chat-like component stacks.\n *\n * Pi's main interactive chat gets terminal scrollback for free. Extension\n * overlays render into a fixed rectangle, so they need an explicit viewport\n * with the same sticky-bottom default plus keyboard and mouse history controls.\n */\nexport class ScrollableComponentViewport implements Component {\n\tprivate components: readonly Component[] = [];\n\tprivate visibleRows = 1;\n\tprivate scrollFromBottom = 0;\n\tprivate lastLineCount = 0;\n\tprivate lastComponentSegments: readonly (readonly RowWindowSegment[] | undefined)[] = [];\n\tprivate lastComponentRowCounts: readonly number[] = [];\n\tprivate lastWidth = 0;\n\tprivate maxScroll = 0;\n\n\tsetComponents(components: readonly Component[]): void {\n\t\tthis.components = components;\n\t}\n\n\tsetVisibleRows(rows: number): void {\n\t\tthis.visibleRows = Math.max(1, Math.floor(rows));\n\t\tthis.clampScroll();\n\t}\n\n\tgetScrollFromBottom(): number {\n\t\treturn this.scrollFromBottom;\n\t}\n\n\tgetMaxScroll(): number {\n\t\treturn this.maxScroll;\n\t}\n\n\tscrollToBottom(): void {\n\t\tthis.scrollFromBottom = 0;\n\t}\n\n\tscrollToTop(): void {\n\t\tthis.scrollFromBottom = this.maxScroll;\n\t}\n\n\tscrollBy(deltaRows: number): void {\n\t\t// Positive deltas move toward newer content; negative deltas move up\n\t\t// into older history. Store the offset from the sticky bottom so new\n\t\t// streaming output can keep following when the offset is zero.\n\t\tthis.scrollFromBottom -= deltaRows;\n\t\tthis.clampScroll();\n\t}\n\n\thandleInput(data: string): boolean {\n\t\tconst wheelDeltaRows = mouseWheelDeltaRows(data);\n\t\tif (wheelDeltaRows !== 0) {\n\t\t\tthis.scrollBy(wheelDeltaRows);\n\t\t\treturn true;\n\t\t}\n\t\tif (isMouseSequence(data)) return true;\n\t\tif (matchesKey(data, \"pageUp\")) {\n\t\t\tthis.scrollBy(-this.pageSize());\n\t\t\treturn true;\n\t\t}\n\t\tif (matchesKey(data, \"pageDown\")) {\n\t\t\tthis.scrollBy(this.pageSize());\n\t\t\treturn true;\n\t\t}\n\t\tif (matchesKey(data, \"home\")) {\n\t\t\tthis.scrollToTop();\n\t\t\treturn true;\n\t\t}\n\t\tif (matchesKey(data, \"end\")) {\n\t\t\tthis.scrollToBottom();\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\trender(width: number): string[] {\n\t\tconst componentRows = this.measureComponentRows(width);\n\t\tconst rowCounts = componentRows.map((rows) => rows.rowCount);\n\t\tconst lineCount = rowCounts.reduce((sum, count) => sum + count, 0);\n\t\tconst maxScroll = Math.max(0, lineCount - this.visibleRows);\n\t\t// The offset is a distance from the bottom, so the first visible row is\n\t\t// `maxScroll - scrollFromBottom`. Rows appearing or disappearing move the\n\t\t// content a scrolled-up viewer is reading unless the offset moves with\n\t\t// them -- a live subagent widget does exactly that every time it gains or\n\t\t// drops its current-tool row.\n\t\t//\n\t\t// Which way the offset must move depends on where the rows changed, so a\n\t\t// plain `scrollFromBottom += lineCount - lastLineCount` is wrong half the\n\t\t// time. Rows changing *below* the anchor need the offset adjusted by that\n\t\t// delta; rows changing *above* it need the offset left alone, because the\n\t\t// bottom-relative distance to the anchored content did not change. Anchor\n\t\t// on the row the viewer is actually reading and re-derive the offset from\n\t\t// it. A viewer already at the bottom keeps scrollFromBottom === 0 and is\n\t\t// skipped entirely, so sticky-bottom following is untouched.\n\t\t//\n\t\t// Per-component row counts alone cannot place a change that happens\n\t\t// inside the component holding the anchor -- and in the chat host the\n\t\t// whole transcript is one component, so that is the normal case. A\n\t\t// component that can hand over a row map turns the \"where\" question into\n\t\t// \"where did the anchored segment go\". Both kinds may supply one: a\n\t\t// transcript built without a cache key is not windowed, but it is still\n\t\t// one component spanning the anchor and still knows its own rows.\n\t\tconst segments = componentRows.map((rows) => rows.segments);\n\t\tif (this.scrollFromBottom > 0 && this.lastWidth === width) {\n\t\t\tconst previousMaxScroll = Math.max(0, this.lastLineCount - this.visibleRows);\n\t\t\tconst anchorRow = Math.max(0, previousMaxScroll - this.scrollFromBottom);\n\t\t\tconst shift = rowsShiftedAboveAnchor(\n\t\t\t\t{ rowCounts: this.lastComponentRowCounts, segments: this.lastComponentSegments },\n\t\t\t\t{ rowCounts, segments },\n\t\t\t\tanchorRow,\n\t\t\t);\n\t\t\tconst nextAnchorRow = Math.max(0, Math.min(maxScroll, anchorRow + shift));\n\t\t\tthis.scrollFromBottom = maxScroll - nextAnchorRow;\n\t\t}\n\t\tthis.lastLineCount = lineCount;\n\t\tthis.lastComponentRowCounts = rowCounts;\n\t\tthis.lastComponentSegments = segments;\n\t\tthis.lastWidth = width;\n\t\tthis.maxScroll = maxScroll;\n\t\tthis.clampScroll();\n\n\t\tconst start = Math.max(0, maxScroll - this.scrollFromBottom);\n\t\tconst visible = this.renderVisibleRows(componentRows, width, start, start + this.visibleRows);\n\t\twhile (visible.length < this.visibleRows) visible.push(\" \".repeat(width));\n\t\treturn visible;\n\t}\n\n\tinvalidate(): void {\n\t\tfor (const component of this.components) component.invalidate();\n\t}\n\n\tprivate measureComponentRows(width: number): ComponentRows[] {\n\t\treturn this.components.map((component) => {\n\t\t\tif (isRowWindowComponent(component)) {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"windowed\",\n\t\t\t\t\tcomponent,\n\t\t\t\t\trowCount: component.rowCount(width),\n\t\t\t\t\tsegments: component.rowSegments?.(width),\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst lines = component.render(width);\n\t\t\t// Read segments only after rendering: a static transcript records its\n\t\t\t// per-entry heights as a by-product of that render, so asking first\n\t\t\t// would return the previous frame's layout.\n\t\t\tconst segments = segmentReporter(component)?.rowSegments(width);\n\t\t\treturn {\n\t\t\t\tkind: \"static\",\n\t\t\t\tlines,\n\t\t\t\trowCount: lines.length,\n\t\t\t\tsegments: segments !== undefined && segments.length > 0 ? segments : undefined,\n\t\t\t};\n\t\t});\n\t}\n\n\tprivate renderVisibleRows(\n\t\tcomponentRows: readonly ComponentRows[],\n\t\twidth: number,\n\t\tstartRow: number,\n\t\tendRow: number,\n\t): string[] {\n\t\tconst lines: string[] = [];\n\t\tlet cursor = 0;\n\t\tfor (const rows of componentRows) {\n\t\t\tconst componentStart = cursor;\n\t\t\tconst componentEnd = componentStart + rows.rowCount;\n\t\t\tif (componentEnd > startRow && componentStart < endRow) {\n\t\t\t\tconst localStart = Math.max(0, startRow - componentStart);\n\t\t\t\tconst localEnd = Math.min(rows.rowCount, endRow - componentStart);\n\t\t\t\tif (rows.kind === \"windowed\") {\n\t\t\t\t\tlines.push(...rows.component.renderRows(width, localStart, localEnd));\n\t\t\t\t} else {\n\t\t\t\t\tlines.push(...rows.lines.slice(localStart, localEnd));\n\t\t\t\t}\n\t\t\t}\n\t\t\tcursor = componentEnd;\n\t\t\tif (cursor >= endRow) break;\n\t\t}\n\t\treturn lines;\n\t}\n\n\tprivate pageSize(): number {\n\t\treturn Math.max(4, this.visibleRows - 2);\n\t}\n\n\tprivate clampScroll(): void {\n\t\tthis.scrollFromBottom = Math.max(0, Math.min(this.maxScroll, this.scrollFromBottom));\n\t}\n}\n\n/** One rendered frame's row layout, as the viewport measured it. */\ninterface ComponentRowLayout {\n\treadonly rowCounts: readonly number[];\n\treadonly segments: readonly (readonly RowWindowSegment[] | undefined)[];\n}\n\n/**\n * Rows gained or lost above `anchorRow`, measured in the previous frame's rows.\n *\n * The anchored row moves down by exactly this many rows, so adding it to the\n * anchor keeps the same content under the viewer.\n *\n * Components entirely above the anchor contribute their whole height delta.\n * The component that *spans* the anchor contributes only what changed above the\n * anchored row, which needs its row map (`rowSegments`); without one it\n * contributes nothing, which is the old behaviour and is right for the\n * append-and-mutate-at-the-tail widgets that have no interior.\n *\n * Row counts are compared positionally over the shared prefix, which is what the\n * chat stacks this viewport drives actually do — they append and mutate at the\n * tail. A component inserted or removed *ahead* of the anchor would be\n * misattributed; the anchor then lands one component off rather than drifting on\n * every frame, and the next user scroll re-establishes it.\n */\nfunction rowsShiftedAboveAnchor(previous: ComponentRowLayout, next: ComponentRowLayout, anchorRow: number): number {\n\tlet cursor = 0;\n\tlet shift = 0;\n\tconst shared = Math.min(previous.rowCounts.length, next.rowCounts.length);\n\tfor (let index = 0; index < shared; index += 1) {\n\t\tconst previousRows = previous.rowCounts[index] ?? 0;\n\t\tconst componentEnd = cursor + previousRows;\n\t\tif (componentEnd > anchorRow) {\n\t\t\treturn shift + rowsShiftedInsideComponent(previous.segments[index], next.segments[index], anchorRow - cursor);\n\t\t}\n\t\tshift += (next.rowCounts[index] ?? 0) - previousRows;\n\t\tcursor = componentEnd;\n\t}\n\treturn shift;\n}\n\n/**\n * Rows gained or lost above `anchorRow` *within* one windowed component.\n *\n * Rather than diffing heights, this finds the segment the viewer is parked on\n * and reports how far that same segment moved. Segments are matched by `===` on\n * their id, so a transcript splice that renumbers every cache key still lines\n * up: the entry objects survive it. If the anchored segment itself is gone\n * (the viewer was reading rows that were compacted away) the nearest surviving\n * neighbour above it — then below it — stands in, so the viewer lands on the\n * closest content that still exists instead of drifting by the whole delta.\n */\nfunction rowsShiftedInsideComponent(\n\tpreviousSegments: readonly RowWindowSegment[] | undefined,\n\tnextSegments: readonly RowWindowSegment[] | undefined,\n\tanchorRow: number,\n): number {\n\tif (previousSegments === undefined || nextSegments === undefined) return 0;\n\tconst nextStarts = new Map<unknown, number>();\n\tlet cursor = 0;\n\tfor (const segment of nextSegments) {\n\t\tif (!nextStarts.has(segment.id)) nextStarts.set(segment.id, cursor);\n\t\tcursor += segment.rows;\n\t}\n\tconst previousStarts: number[] = [];\n\tlet anchorIndex = -1;\n\tcursor = 0;\n\tfor (let index = 0; index < previousSegments.length; index += 1) {\n\t\tpreviousStarts.push(cursor);\n\t\tcursor += previousSegments[index]?.rows ?? 0;\n\t\tif (anchorIndex < 0 && cursor > anchorRow) anchorIndex = index;\n\t}\n\tif (anchorIndex < 0) return 0;\n\tfor (let index = anchorIndex; index >= 0; index -= 1) {\n\t\tconst nextStart = nextStarts.get(previousSegments[index]?.id);\n\t\tif (nextStart !== undefined) return nextStart - (previousStarts[index] ?? 0);\n\t}\n\tfor (let index = anchorIndex + 1; index < previousSegments.length; index += 1) {\n\t\tconst nextStart = nextStarts.get(previousSegments[index]?.id);\n\t\tif (nextStart !== undefined) return nextStart - (previousStarts[index] ?? 0);\n\t}\n\treturn 0;\n}\n\nfunction isRowWindowComponent(component: Component): component is RowWindowComponent {\n\tconst candidate = component as Partial<RowWindowComponent>;\n\treturn (\n\t\tcandidate.supportsRowWindow === true &&\n\t\ttypeof candidate.rowCount === \"function\" &&\n\t\ttypeof candidate.renderRows === \"function\"\n\t);\n}\n\n/**\n * A component that can identify its own rows without being windowed.\n *\n * `ScrollableChatTranscriptComponent` builds its transcript without a cache key\n * — deliberately, because that is what lets it reflect entries mutated in place\n * — so it is not a `RowWindowComponent` and renders every row each frame. It\n * still knows which entry produced which rows, and it is still the component\n * spanning the anchor, so the anchor needs to ask.\n */\nfunction segmentReporter(\n\tcomponent: Component,\n): { rowSegments(width: number): readonly RowWindowSegment[] } | undefined {\n\tconst candidate = component as Partial<RowWindowComponent>;\n\treturn typeof candidate.rowSegments === \"function\"\n\t\t? (candidate as { rowSegments(width: number): readonly RowWindowSegment[] })\n\t\t: undefined;\n}\n\nexport class ScrollableChatTranscriptComponent<TEntry extends ChatTranscriptEntryLike> implements Component {\n\tprivate readonly viewport = new ScrollableComponentViewport();\n\tprivate readonly transcript: ChatTranscriptComponent<TEntry>;\n\n\tconstructor(entries: readonly TEntry[], renderEntry: ChatTranscriptRenderer<TEntry>) {\n\t\tthis.transcript = new ChatTranscriptComponent(entries, renderEntry);\n\t\tthis.viewport.setComponents([this.transcript]);\n\t}\n\n\tsetVisibleRows(rows: number): void {\n\t\tthis.viewport.setVisibleRows(rows);\n\t}\n\n\thandleInput(data: string): boolean {\n\t\treturn this.viewport.handleInput(data);\n\t}\n\n\trender(width: number): string[] {\n\t\treturn this.viewport.render(width);\n\t}\n\n\tinvalidate(): void {\n\t\tthis.viewport.invalidate();\n\t}\n\n\tgetScrollFromBottom(): number {\n\t\treturn this.viewport.getScrollFromBottom();\n\t}\n\n\tgetMaxScroll(): number {\n\t\treturn this.viewport.getMaxScroll();\n\t}\n\n\tscrollToBottom(): void {\n\t\tthis.viewport.scrollToBottom();\n\t}\n}\n\nfunction mouseWheelDeltaRows(data: string): number {\n\tconst sgr = data.match(/^\\x1b\\[<(\\d+);\\d+;\\d+M$/);\n\tif (sgr) return wheelDeltaForButtonCode(Number.parseInt(sgr[1]!, 10));\n\tif (data.startsWith(\"\\x1b[M\") && data.length >= 6) {\n\t\treturn wheelDeltaForButtonCode(data.charCodeAt(3) - 32);\n\t}\n\treturn 0;\n}\n\nfunction wheelDeltaForButtonCode(code: number): number {\n\tif ((code & 64) === 0) return 0;\n\tconst direction = code & 3;\n\tif (direction === 0) return -DEFAULT_SCROLL_STEP_ROWS;\n\tif (direction === 1) return DEFAULT_SCROLL_STEP_ROWS;\n\treturn 0;\n}\n\nfunction isMouseSequence(data: string): boolean {\n\treturn /^\\x1b\\[<\\d+;\\d+;\\d+[mM]$/.test(data) || data.startsWith(\"\\x1b[M\");\n}\n"]}
|
|
1
|
+
{"version":3,"file":"chat-transcript.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/chat-transcript.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkC,UAAU,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAoF5F,MAAM,UAAU,sBAAsB,CAAC,SAAoB,EAAE,SAAoB,EAAE,IAAwB;IAC1G,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/D,SAAS,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC;IACD,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAwB;IACnD,OAAO,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,SAAS,CAAC;AAC7G,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,uBAAuB;IAYnC,YACC,OAA0B,EAC1B,WAA2C,EAC3C,QAAyC;QATlC,eAAU,GAAyD,EAAE,CAAC;QAC9E,qEAAqE;QAC7D,mBAAc,GAAgC,EAAE,CAAC;QASxD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,iBAAiB,GAAG,QAAQ,KAAK,SAAS,CAAC;IACjD,CAAC;IAED,MAAM,CAAC,KAAa;QACnB,IAAI,CAAC,IAAI,CAAC,iBAAiB;YAAE,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,QAAQ,CAAC,KAAa;QACrB,IAAI,CAAC,IAAI,CAAC,iBAAiB;YAAE,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;QACrE,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACrC,IAAI,KAAK,KAAK,SAAS;gBAAE,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;QACtD,CAAC;QACD,OAAO,KAAK,CAAC;IACd,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,KAAa;QACxB,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC7B,qEAAqE;YACrE,sEAAsE;YACtE,wEAAwE;YACxE,yEAAyE;YACzE,oEAAoE;YACpE,sBAAsB;YACtB,OAAO,IAAI,CAAC,mBAAmB,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,CAAC;QACD,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC7B,MAAM,QAAQ,GAAuB,EAAE,CAAC;QACxC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACrC,IAAI,KAAK,KAAK,SAAS;gBAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QACvF,CAAC;QACD,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED,UAAU,CAAC,KAAa,EAAE,QAAgB,EAAE,MAAc;QACzD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;QAChD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAChD,IAAI,GAAG,IAAI,KAAK;YAAE,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,iBAAiB;YAAE,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAEhF,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC7B,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;YAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACrC,IAAI,KAAK,KAAK,SAAS;gBAAE,SAAS;YAClC,MAAM,UAAU,GAAG,MAAM,CAAC;YAC1B,MAAM,QAAQ,GAAG,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;YACjD,IAAI,QAAQ,GAAG,KAAK,IAAI,UAAU,GAAG,GAAG,EAAE,CAAC;gBAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,UAAU,CAAC,CAAC;gBACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,GAAG,UAAU,CAAC,CAAC;gBAChE,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;YACxD,CAAC;YACD,MAAM,GAAG,QAAQ,CAAC;YAClB,IAAI,MAAM,IAAI,GAAG;gBAAE,MAAM;QAC1B,CAAC;QACD,OAAO,KAAK,CAAC;IACd,CAAC;IAED,UAAU;QACT,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,UAAU;YAAE,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QACxE,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;IACtB,CAAC;IAEO,gBAAgB,CAAC,KAAa;QACrC,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YAClD,KAAK,IAAI,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;gBAClF,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;YACrD,CAAC;YACD,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QAC9C,CAAC;QACD,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;YAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAClC,IAAI,KAAK,KAAK,SAAS;gBAAE,SAAS;YAClC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,GAAG,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACtE,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACtC,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,KAAK,KAAK,KAAK,IAAI,MAAM,CAAC,GAAG,KAAK,GAAG,IAAI,MAAM,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;gBACpG,SAAS;YACV,CAAC;YACD,gBAAgB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YACpC,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YAC1C,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG;gBACxB,KAAK;gBACL,GAAG;gBACH,KAAK;gBACL,SAAS;gBACT,KAAK,EAAE,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;aAC5D,CAAC;QACH,CAAC;IACF,CAAC;IAED;;;;;;;;OAQG;IACK,aAAa,CAAC,KAAa;QAClC,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAuB,EAAE,CAAC;QACxC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;YAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAClC,IAAI,KAAK,KAAK,SAAS;gBAAE,SAAS;YAClC,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YAClF,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;YACjD,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;QACtB,CAAC;QACD,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC;QAC/B,IAAI,CAAC,mBAAmB,GAAG,KAAK,CAAC;QACjC,OAAO,KAAK,CAAC;IACd,CAAC;IAEO,gBAAgB,CAAC,SAAoB,EAAE,KAAa,EAAE,KAAa,EAAE,KAAa;QACzF,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,KAAK,GAAG,CAAC,IAAI,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChE,KAAK,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACvC,OAAO,KAAK,CAAC;IACd,CAAC;CACD;AAED,SAAS,gBAAgB,CAAC,SAAgC;IACxD,SAA6C,EAAE,OAAO,EAAE,EAAE,CAAC;AAC7D,CAAC;AAED,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAEnC;;;;;;GAMG;AACH,MAAM,OAAO,2BAA2B;IAAxC;QACS,eAAU,GAAyB,EAAE,CAAC;QACtC,gBAAW,GAAG,CAAC,CAAC;QAChB,qBAAgB,GAAG,CAAC,CAAC;QACrB,kBAAa,GAAG,CAAC,CAAC;QAClB,0BAAqB,GAAyD,EAAE,CAAC;QACjF,2BAAsB,GAAsB,EAAE,CAAC;QAC/C,cAAS,GAAG,CAAC,CAAC;QACd,cAAS,GAAG,CAAC,CAAC;IA0OvB,CAAC;IAnOA,aAAa,CAAC,UAAgC;QAC7C,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC9B,CAAC;IAED,cAAc,CAAC,IAAY;QAC1B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QACjD,IAAI,CAAC,WAAW,EAAE,CAAC;IACpB,CAAC;IAED,mBAAmB;QAClB,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC9B,CAAC;IAED,YAAY;QACX,OAAO,IAAI,CAAC,SAAS,CAAC;IACvB,CAAC;IAED,cAAc;QACb,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;QAClC,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED,WAAW;QACV,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;QAClC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,SAAS,CAAC;IACxC,CAAC;IAED,QAAQ,CAAC,SAAiB;QACzB,qEAAqE;QACrE,qEAAqE;QACrE,+DAA+D;QAC/D,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;QAClC,IAAI,CAAC,gBAAgB,IAAI,SAAS,CAAC;QACnC,IAAI,CAAC,WAAW,EAAE,CAAC;IACpB,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,GAAW;QACnB,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1E,IAAI,CAAC,gBAAgB,GAAG,YAAY,CAAC;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QACtD,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC;QAChD,IAAI,CAAC,WAAW,EAAE,CAAC;IACpB,CAAC;IAED;;;;;OAKG;IACH,QAAQ,CAAC,KAAa;QACrB,OAAO,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IACvF,CAAC;IAED;;;;;;OAMG;IACH,UAAU,CAAC,KAAa,EAAE,QAAgB,EAAE,MAAc;QACzD,OAAO,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC1F,CAAC;IAED,WAAW,CAAC,IAAY;QACvB,MAAM,cAAc,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,cAAc,KAAK,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;YAC9B,OAAO,IAAI,CAAC;QACb,CAAC;QACD,IAAI,eAAe,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACvC,IAAI,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;YAChC,OAAO,IAAI,CAAC;QACb,CAAC;QACD,IAAI,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC/B,OAAO,IAAI,CAAC;QACb,CAAC;QACD,IAAI,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,WAAW,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC;QACb,CAAC;QACD,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC,cAAc,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC;QACb,CAAC;QACD,OAAO,KAAK,CAAC;IACd,CAAC;IAED,MAAM,CAAC,KAAa;QACnB,MAAM,aAAa,GAAG,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;QACvD,MAAM,SAAS,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC7D,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC;QACnE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC;QAC5D,wEAAwE;QACxE,0EAA0E;QAC1E,uEAAuE;QACvE,0EAA0E;QAC1E,8BAA8B;QAC9B,EAAE;QACF,yEAAyE;QACzE,0EAA0E;QAC1E,0EAA0E;QAC1E,0EAA0E;QAC1E,0EAA0E;QAC1E,0EAA0E;QAC1E,yEAAyE;QACzE,6DAA6D;QAC7D,EAAE;QACF,oEAAoE;QACpE,sEAAsE;QACtE,mEAAmE;QACnE,yEAAyE;QACzE,oEAAoE;QACpE,wEAAwE;QACxE,kEAAkE;QAClE,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5D,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC;QAC/C,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;QAClC,IAAI,gBAAgB,KAAK,SAAS,EAAE,CAAC;YACpC,oEAAoE;YACpE,kEAAkE;YAClE,yDAAyD;YACzD,IAAI,CAAC,gBAAgB,GAAG,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;QAC3E,CAAC;aAAM,IAAI,IAAI,CAAC,gBAAgB,GAAG,CAAC,IAAI,IAAI,CAAC,SAAS,KAAK,KAAK,EAAE,CAAC;YAClE,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC;YAC7E,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACzE,MAAM,KAAK,GAAG,sBAAsB,CACnC,EAAE,SAAS,EAAE,IAAI,CAAC,sBAAsB,EAAE,QAAQ,EAAE,IAAI,CAAC,qBAAqB,EAAE,EAChF,EAAE,SAAS,EAAE,QAAQ,EAAE,EACvB,SAAS,CACT,CAAC;YACF,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC;YAC1E,IAAI,CAAC,gBAAgB,GAAG,SAAS,GAAG,aAAa,CAAC;QACnD,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;QAC/B,IAAI,CAAC,sBAAsB,GAAG,SAAS,CAAC;QACxC,IAAI,CAAC,qBAAqB,GAAG,QAAQ,CAAC;QACtC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,WAAW,EAAE,CAAC;QAEnB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC7D,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC;QAC9F,OAAO,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW;YAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1E,OAAO,OAAO,CAAC;IAChB,CAAC;IAED,UAAU;QACT,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU;YAAE,SAAS,CAAC,UAAU,EAAE,CAAC;IACjE,CAAC;IAEO,oBAAoB,CAAC,KAAa;QACzC,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE;YACxC,IAAI,oBAAoB,CAAC,SAAS,CAAC,EAAE,CAAC;gBACrC,OAAO;oBACN,IAAI,EAAE,UAAU;oBAChB,SAAS;oBACT,QAAQ,EAAE,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC;oBACnC,QAAQ,EAAE,SAAS,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC;iBACxC,CAAC;YACH,CAAC;YACD,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACtC,sEAAsE;YACtE,oEAAoE;YACpE,4CAA4C;YAC5C,MAAM,QAAQ,GAAG,eAAe,CAAC,SAAS,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC;YAChE,OAAO;gBACN,IAAI,EAAE,QAAQ;gBACd,KAAK;gBACL,QAAQ,EAAE,KAAK,CAAC,MAAM;gBACtB,QAAQ,EAAE,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;aAC9E,CAAC;QACH,CAAC,CAAC,CAAC;IACJ,CAAC;IAEO,iBAAiB,CACxB,aAAuC,EACvC,KAAa,EACb,QAAgB,EAChB,MAAc;QAEd,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;YAClC,MAAM,cAAc,GAAG,MAAM,CAAC;YAC9B,MAAM,YAAY,GAAG,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC;YACpD,IAAI,YAAY,GAAG,QAAQ,IAAI,cAAc,GAAG,MAAM,EAAE,CAAC;gBACxD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,cAAc,CAAC,CAAC;gBAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC;gBAClE,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;oBAC9B,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;gBACvE,CAAC;qBAAM,CAAC;oBACP,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;gBACvD,CAAC;YACF,CAAC;YACD,MAAM,GAAG,YAAY,CAAC;YACtB,IAAI,MAAM,IAAI,MAAM;gBAAE,MAAM;QAC7B,CAAC;QACD,OAAO,KAAK,CAAC;IACd,CAAC;IAEO,QAAQ;QACf,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;IAC1C,CAAC;IAEO,WAAW;QAClB,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACtF,CAAC;CACD;AAQD;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAS,sBAAsB,CAAC,QAA4B,EAAE,IAAwB,EAAE,SAAiB;IACxG,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1E,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAChD,MAAM,YAAY,GAAG,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACpD,MAAM,YAAY,GAAG,MAAM,GAAG,YAAY,CAAC;QAC3C,IAAI,YAAY,GAAG,SAAS,EAAE,CAAC;YAC9B,OAAO,KAAK,GAAG,0BAA0B,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC,CAAC;QAC/G,CAAC;QACD,KAAK,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,YAAY,CAAC;QACrD,MAAM,GAAG,YAAY,CAAC;IACvB,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,0BAA0B,CAClC,gBAAyD,EACzD,YAAqD,EACrD,SAAiB;IAEjB,IAAI,gBAAgB,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS;QAAE,OAAO,CAAC,CAAC;IAC3E,MAAM,UAAU,GAAG,IAAI,GAAG,EAAmB,CAAC;IAC9C,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;QACpC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAAE,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACpE,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IACxB,CAAC;IACD,MAAM,cAAc,GAAa,EAAE,CAAC;IACpC,IAAI,WAAW,GAAG,CAAC,CAAC,CAAC;IACrB,MAAM,GAAG,CAAC,CAAC;IACX,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,gBAAgB,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACjE,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5B,MAAM,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC;QAC7C,IAAI,WAAW,GAAG,CAAC,IAAI,MAAM,GAAG,SAAS;YAAE,WAAW,GAAG,KAAK,CAAC;IAChE,CAAC;IACD,IAAI,WAAW,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC;IAC9B,KAAK,IAAI,KAAK,GAAG,WAAW,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACtD,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9D,IAAI,SAAS,KAAK,SAAS;YAAE,OAAO,SAAS,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9E,CAAC;IACD,KAAK,IAAI,KAAK,GAAG,WAAW,GAAG,CAAC,EAAE,KAAK,GAAG,gBAAgB,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAC/E,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9D,IAAI,SAAS,KAAK,SAAS;YAAE,OAAO,SAAS,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,CAAC,CAAC;AACV,CAAC;AAED,SAAS,oBAAoB,CAAC,SAAoB;IACjD,MAAM,SAAS,GAAG,SAAwC,CAAC;IAC3D,OAAO,CACN,SAAS,CAAC,iBAAiB,KAAK,IAAI;QACpC,OAAO,SAAS,CAAC,QAAQ,KAAK,UAAU;QACxC,OAAO,SAAS,CAAC,UAAU,KAAK,UAAU,CAC1C,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,eAAe,CACvB,SAAoB;IAEpB,MAAM,SAAS,GAAG,SAAwC,CAAC;IAC3D,OAAO,OAAO,SAAS,CAAC,WAAW,KAAK,UAAU;QACjD,CAAC,CAAE,SAAyE;QAC5E,CAAC,CAAC,SAAS,CAAC;AACd,CAAC;AAED,MAAM,OAAO,iCAAiC;IAI7C,YAAY,OAA0B,EAAE,WAA2C;QAHlE,aAAQ,GAAG,IAAI,2BAA2B,EAAE,CAAC;QAI7D,IAAI,CAAC,UAAU,GAAG,IAAI,uBAAuB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QACpE,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,cAAc,CAAC,IAAY;QAC1B,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,WAAW,CAAC,IAAY;QACvB,OAAO,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,CAAC,KAAa;QACnB,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,UAAU;QACT,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;IAC5B,CAAC;IAED,mBAAmB;QAClB,OAAO,IAAI,CAAC,QAAQ,CAAC,mBAAmB,EAAE,CAAC;IAC5C,CAAC;IAED,YAAY;QACX,OAAO,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC;IACrC,CAAC;IAED,cAAc;QACb,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;IAChC,CAAC;CACD;AAED,SAAS,mBAAmB,CAAC,IAAY;IACxC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAClD,IAAI,GAAG;QAAE,OAAO,uBAAuB,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IACtE,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACnD,OAAO,uBAAuB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,CAAC,CAAC;AACV,CAAC;AAED,SAAS,uBAAuB,CAAC,IAAY;IAC5C,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAChC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC;IAC3B,IAAI,SAAS,KAAK,CAAC;QAAE,OAAO,CAAC,wBAAwB,CAAC;IACtD,IAAI,SAAS,KAAK,CAAC;QAAE,OAAO,wBAAwB,CAAC;IACrD,OAAO,CAAC,CAAC;AACV,CAAC;AAED,SAAS,eAAe,CAAC,IAAY;IACpC,OAAO,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AAC3E,CAAC","sourcesContent":["import { type Component, type Container, matchesKey, Spacer } from \"@earendil-works/pi-tui\";\n\n/**\n * Roles that participate in pi's chat spacing contract.\n *\n * Assistant turns own their leading whitespace internally, and tool rows attach\n * directly under the assistant/tool-call row they belong to. User-like rows get\n * one blank line when they are not the first row in the transcript.\n */\nexport type ChatTranscriptRole =\n\t| \"assistant\"\n\t| \"thinking\"\n\t| \"tool\"\n\t| \"user\"\n\t| \"custom\"\n\t| \"notice\"\n\t| \"system\"\n\t| \"summary\";\n\nexport interface ChatTranscriptEntryLike {\n\treadonly role: ChatTranscriptRole;\n}\n\nexport type ChatTranscriptRenderer<TEntry extends ChatTranscriptEntryLike> = (entry: TEntry) => Component;\n\nexport type ChatTranscriptCacheKey<TEntry extends ChatTranscriptEntryLike> = (entry: TEntry, index: number) => string;\n\ninterface CachedChatTranscriptBlock<TEntry extends ChatTranscriptEntryLike> {\n\treadonly entry: TEntry;\n\treadonly key: string;\n\treadonly width: number;\n\treadonly component: Component;\n\treadonly lines: readonly string[];\n}\n\ntype DisposableComponent = Component & { dispose?: () => void };\n\n/**\n * A run of rows inside a windowed component, tagged with the identity of the\n * thing that produced them.\n *\n * `id` is compared with `===` only, and is never rendered. Entry *objects* are\n * the natural id for a transcript: cache keys carry the entry's index and so\n * change for every survivor of a splice, while the entry objects themselves are\n * moved, not rebuilt.\n */\nexport interface RowWindowSegment {\n\treadonly id: unknown;\n\treadonly rows: number;\n}\n\ninterface RowWindowComponent extends Component {\n\treadonly supportsRowWindow: true;\n\trowCount(width: number): number;\n\trenderRows(width: number, startRow: number, endRow: number): string[];\n\t/**\n\t * Optional row map, letting the viewport keep a scroll anchor that sits\n\t * *inside* this component when its interior changes height.\n\t */\n\trowSegments?(width: number): readonly RowWindowSegment[];\n}\n\ninterface WindowedComponentRows {\n\treadonly kind: \"windowed\";\n\treadonly component: RowWindowComponent;\n\treadonly rowCount: number;\n\treadonly segments: readonly RowWindowSegment[] | undefined;\n}\n\ninterface StaticComponentRows {\n\treadonly kind: \"static\";\n\treadonly lines: readonly string[];\n\treadonly rowCount: number;\n\t/**\n\t * Present when a static component can still identify its own rows. A\n\t * transcript built without a cache key renders every row each frame rather\n\t * than windowing, but it knows just as well which entry produced which rows,\n\t * and the anchor needs that whenever it is the component spanning the anchor.\n\t */\n\treadonly segments?: readonly RowWindowSegment[] | undefined;\n}\n\ntype ComponentRows = WindowedComponentRows | StaticComponentRows;\n\nexport function addChatTranscriptEntry(container: Container, component: Component, role: ChatTranscriptRole): void {\n\tif (needsLeadingSpacer(role) && container.children.length > 0) {\n\t\tcontainer.addChild(new Spacer(1));\n\t}\n\tcontainer.addChild(component);\n}\n\nfunction needsLeadingSpacer(role: ChatTranscriptRole): boolean {\n\treturn role === \"user\" || role === \"custom\" || role === \"notice\" || role === \"system\" || role === \"summary\";\n}\n\n/**\n * Reusable pi chat transcript scaffold for extension surfaces.\n *\n * This intentionally mirrors InteractiveMode.addMessageToChat spacing without\n * coupling consumers to a full AgentSession. Extension UIs can bring their own\n * message model while still rendering inside the same Container/Spacer rhythm\n * as the main chat.\n */\nexport class ChatTranscriptComponent<TEntry extends ChatTranscriptEntryLike> implements Component {\n\tprivate readonly entries: readonly TEntry[];\n\tprivate readonly renderEntry: ChatTranscriptRenderer<TEntry>;\n\treadonly supportsRowWindow: boolean;\n\n\tprivate readonly cacheKey: ChatTranscriptCacheKey<TEntry> | undefined;\n\tprivate blockCache: Array<CachedChatTranscriptBlock<TEntry> | undefined> = [];\n\t/** Per-entry heights recorded by the most recent `renderAllRows`. */\n\tprivate staticSegments: readonly RowWindowSegment[] = [];\n\t/** Width those heights were measured at; they mean nothing at another width. */\n\tprivate staticSegmentsWidth: number | undefined;\n\n\tconstructor(\n\t\tentries: readonly TEntry[],\n\t\trenderEntry: ChatTranscriptRenderer<TEntry>,\n\t\tcacheKey?: ChatTranscriptCacheKey<TEntry>,\n\t) {\n\t\tthis.entries = entries;\n\t\tthis.renderEntry = renderEntry;\n\t\tthis.cacheKey = cacheKey;\n\t\tthis.supportsRowWindow = cacheKey !== undefined;\n\t}\n\n\trender(width: number): string[] {\n\t\tif (!this.supportsRowWindow) return this.renderAllRows(width);\n\t\treturn this.renderRows(width, 0, this.rowCount(width));\n\t}\n\n\trowCount(width: number): number {\n\t\tif (!this.supportsRowWindow) return this.renderAllRows(width).length;\n\t\tthis.ensureBlockCache(width);\n\t\tlet count = 0;\n\t\tfor (const block of this.blockCache) {\n\t\t\tif (block !== undefined) count += block.lines.length;\n\t\t}\n\t\treturn count;\n\t}\n\n\t/**\n\t * One segment per cached entry block, identified by the entry object itself.\n\t */\n\trowSegments(width: number): readonly RowWindowSegment[] {\n\t\tif (!this.supportsRowWindow) {\n\t\t\t// Recorded by the last renderAllRows. The viewport measures a static\n\t\t\t// component by rendering it and only then reads its segments, so this\n\t\t\t// is populated for the frame being measured. A width mismatch means the\n\t\t\t// heights describe a different layout, and reporting them would move the\n\t\t\t// anchor by a stale delta; the caller falls back to whole-component\n\t\t\t// accounting instead.\n\t\t\treturn this.staticSegmentsWidth === width ? this.staticSegments : [];\n\t\t}\n\t\tthis.ensureBlockCache(width);\n\t\tconst segments: RowWindowSegment[] = [];\n\t\tfor (const block of this.blockCache) {\n\t\t\tif (block !== undefined) segments.push({ id: block.entry, rows: block.lines.length });\n\t\t}\n\t\treturn segments;\n\t}\n\n\trenderRows(width: number, startRow: number, endRow: number): string[] {\n\t\tconst start = Math.max(0, Math.floor(startRow));\n\t\tconst end = Math.max(start, Math.floor(endRow));\n\t\tif (end <= start) return [];\n\t\tif (!this.supportsRowWindow) return this.renderAllRows(width).slice(start, end);\n\n\t\tthis.ensureBlockCache(width);\n\t\tconst lines: string[] = [];\n\t\tlet cursor = 0;\n\t\tfor (let index = 0; index < this.entries.length; index += 1) {\n\t\t\tconst block = this.blockCache[index];\n\t\t\tif (block === undefined) continue;\n\t\t\tconst blockStart = cursor;\n\t\t\tconst blockEnd = blockStart + block.lines.length;\n\t\t\tif (blockEnd > start && blockStart < end) {\n\t\t\t\tconst localStart = Math.max(0, start - blockStart);\n\t\t\t\tconst localEnd = Math.min(block.lines.length, end - blockStart);\n\t\t\t\tlines.push(...block.lines.slice(localStart, localEnd));\n\t\t\t}\n\t\t\tcursor = blockEnd;\n\t\t\tif (cursor >= end) break;\n\t\t}\n\t\treturn lines;\n\t}\n\n\tinvalidate(): void {\n\t\tfor (const block of this.blockCache) disposeComponent(block?.component);\n\t\tthis.blockCache = [];\n\t}\n\n\tprivate ensureBlockCache(width: number): void {\n\t\tif (this.blockCache.length > this.entries.length) {\n\t\t\tfor (let index = this.entries.length; index < this.blockCache.length; index += 1) {\n\t\t\t\tdisposeComponent(this.blockCache[index]?.component);\n\t\t\t}\n\t\t\tthis.blockCache.length = this.entries.length;\n\t\t}\n\t\tfor (let index = 0; index < this.entries.length; index += 1) {\n\t\t\tconst entry = this.entries[index];\n\t\t\tif (entry === undefined) continue;\n\t\t\tconst key = this.cacheKey?.(entry, index) ?? `${index}:${entry.role}`;\n\t\t\tconst cached = this.blockCache[index];\n\t\t\tif (cached !== undefined && cached.entry === entry && cached.key === key && cached.width === width) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tdisposeComponent(cached?.component);\n\t\t\tconst component = this.renderEntry(entry);\n\t\t\tthis.blockCache[index] = {\n\t\t\t\tentry,\n\t\t\t\tkey,\n\t\t\t\twidth,\n\t\t\t\tcomponent,\n\t\t\t\tlines: this.renderEntryBlock(component, entry, index, width),\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Render every entry, recording each one's height as it goes.\n\t *\n\t * The heights are what `rowSegments` reports on this path. They are a\n\t * by-product of work this method already does, so identifying rows costs\n\t * nothing extra and, unlike a cache key, cannot miss an entry mutated in\n\t * place -- which is the behaviour a transcript without a cache key exists to\n\t * provide.\n\t */\n\tprivate renderAllRows(width: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tconst segments: RowWindowSegment[] = [];\n\t\tfor (let index = 0; index < this.entries.length; index += 1) {\n\t\t\tconst entry = this.entries[index];\n\t\t\tif (entry === undefined) continue;\n\t\t\tconst block = this.renderEntryBlock(this.renderEntry(entry), entry, index, width);\n\t\t\tsegments.push({ id: entry, rows: block.length });\n\t\t\tlines.push(...block);\n\t\t}\n\t\tthis.staticSegments = segments;\n\t\tthis.staticSegmentsWidth = width;\n\t\treturn lines;\n\t}\n\n\tprivate renderEntryBlock(component: Component, entry: TEntry, index: number, width: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tif (index > 0 && needsLeadingSpacer(entry.role)) lines.push(\"\");\n\t\tlines.push(...component.render(width));\n\t\treturn lines;\n\t}\n}\n\nfunction disposeComponent(component: Component | undefined): void {\n\t(component as DisposableComponent | undefined)?.dispose?.();\n}\n\nconst DEFAULT_SCROLL_STEP_ROWS = 4;\n\n/**\n * Sticky-bottom, scrollable viewport for chat-like component stacks.\n *\n * Pi's main interactive chat gets terminal scrollback for free. Extension\n * overlays render into a fixed rectangle, so they need an explicit viewport\n * with the same sticky-bottom default plus keyboard and mouse history controls.\n */\nexport class ScrollableComponentViewport implements Component {\n\tprivate components: readonly Component[] = [];\n\tprivate visibleRows = 1;\n\tprivate scrollFromBottom = 0;\n\tprivate lastLineCount = 0;\n\tprivate lastComponentSegments: readonly (readonly RowWindowSegment[] | undefined)[] = [];\n\tprivate lastComponentRowCounts: readonly number[] = [];\n\tprivate lastWidth = 0;\n\tprivate maxScroll = 0;\n\t/**\n\t * Absolute row `scrollTo` asked for, still waiting for the render that can\n\t * honour it. See `scrollTo` for why the request has to outlive the call.\n\t */\n\tprivate pendingScrollRow: number | undefined;\n\n\tsetComponents(components: readonly Component[]): void {\n\t\tthis.components = components;\n\t}\n\n\tsetVisibleRows(rows: number): void {\n\t\tthis.visibleRows = Math.max(1, Math.floor(rows));\n\t\tthis.clampScroll();\n\t}\n\n\tgetScrollFromBottom(): number {\n\t\treturn this.scrollFromBottom;\n\t}\n\n\tgetMaxScroll(): number {\n\t\treturn this.maxScroll;\n\t}\n\n\tscrollToBottom(): void {\n\t\tthis.pendingScrollRow = undefined;\n\t\tthis.scrollFromBottom = 0;\n\t}\n\n\tscrollToTop(): void {\n\t\tthis.pendingScrollRow = undefined;\n\t\tthis.scrollFromBottom = this.maxScroll;\n\t}\n\n\tscrollBy(deltaRows: number): void {\n\t\t// Positive deltas move toward newer content; negative deltas move up\n\t\t// into older history. Store the offset from the sticky bottom so new\n\t\t// streaming output can keep following when the offset is zero.\n\t\tthis.pendingScrollRow = undefined;\n\t\tthis.scrollFromBottom -= deltaRows;\n\t\tthis.clampScroll();\n\t}\n\n\t/**\n\t * Park the viewport with `row` as its first visible row.\n\t *\n\t * The absolute counterpart of `scrollBy`, for a caller that already knows\n\t * which row it wants on screen.\n\t *\n\t * The request is *also* recorded for the next render, and that is the half\n\t * that matters. `scrollFromBottom` is a distance from the bottom, so the\n\t * row it names moves whenever the stack grows; and the render that follows\n\t * re-derives the offset from the previous frame's layout to hold a\n\t * scrolled-up reader's content still, which would drag this request back\n\t * with it. A caller who has just measured rows the last render never saw\n\t * would otherwise be answered with the old layout's clamp and the old\n\t * frame's anchor. The next render resolves the row against the layout it\n\t * actually paints; any other scroll before then withdraws the request.\n\t */\n\tscrollTo(row: number): void {\n\t\tconst requestedRow = Number.isNaN(row) ? 0 : Math.max(0, Math.floor(row));\n\t\tthis.pendingScrollRow = requestedRow;\n\t\tconst target = Math.min(this.maxScroll, requestedRow);\n\t\tthis.scrollFromBottom = this.maxScroll - target;\n\t\tthis.clampScroll();\n\t}\n\n\t/**\n\t * Total rows the component stack occupies at `width`, on and off screen.\n\t *\n\t * This measures rather than paints: it is what lets a search read the whole\n\t * transcript instead of the window the reader happens to be parked on.\n\t */\n\trowCount(width: number): number {\n\t\treturn this.measureComponentRows(width).reduce((sum, rows) => sum + rows.rowCount, 0);\n\t}\n\n\t/**\n\t * Rows `startRow` (inclusive) through `endRow` (exclusive) of the whole\n\t * stack, independent of the current scroll offset. Deliberately not paired\n\t * with `supportsRowWindow`: a viewport is a scroll container rather than a\n\t * windowed component, and an enclosing viewport must keep measuring it by\n\t * its visible height.\n\t */\n\trenderRows(width: number, startRow: number, endRow: number): string[] {\n\t\treturn this.renderVisibleRows(this.measureComponentRows(width), width, startRow, endRow);\n\t}\n\n\thandleInput(data: string): boolean {\n\t\tconst wheelDeltaRows = mouseWheelDeltaRows(data);\n\t\tif (wheelDeltaRows !== 0) {\n\t\t\tthis.scrollBy(wheelDeltaRows);\n\t\t\treturn true;\n\t\t}\n\t\tif (isMouseSequence(data)) return true;\n\t\tif (matchesKey(data, \"pageUp\")) {\n\t\t\tthis.scrollBy(-this.pageSize());\n\t\t\treturn true;\n\t\t}\n\t\tif (matchesKey(data, \"pageDown\")) {\n\t\t\tthis.scrollBy(this.pageSize());\n\t\t\treturn true;\n\t\t}\n\t\tif (matchesKey(data, \"home\")) {\n\t\t\tthis.scrollToTop();\n\t\t\treturn true;\n\t\t}\n\t\tif (matchesKey(data, \"end\")) {\n\t\t\tthis.scrollToBottom();\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\trender(width: number): string[] {\n\t\tconst componentRows = this.measureComponentRows(width);\n\t\tconst rowCounts = componentRows.map((rows) => rows.rowCount);\n\t\tconst lineCount = rowCounts.reduce((sum, count) => sum + count, 0);\n\t\tconst maxScroll = Math.max(0, lineCount - this.visibleRows);\n\t\t// The offset is a distance from the bottom, so the first visible row is\n\t\t// `maxScroll - scrollFromBottom`. Rows appearing or disappearing move the\n\t\t// content a scrolled-up viewer is reading unless the offset moves with\n\t\t// them -- a live subagent widget does exactly that every time it gains or\n\t\t// drops its current-tool row.\n\t\t//\n\t\t// Which way the offset must move depends on where the rows changed, so a\n\t\t// plain `scrollFromBottom += lineCount - lastLineCount` is wrong half the\n\t\t// time. Rows changing *below* the anchor need the offset adjusted by that\n\t\t// delta; rows changing *above* it need the offset left alone, because the\n\t\t// bottom-relative distance to the anchored content did not change. Anchor\n\t\t// on the row the viewer is actually reading and re-derive the offset from\n\t\t// it. A viewer already at the bottom keeps scrollFromBottom === 0 and is\n\t\t// skipped entirely, so sticky-bottom following is untouched.\n\t\t//\n\t\t// Per-component row counts alone cannot place a change that happens\n\t\t// inside the component holding the anchor -- and in the chat host the\n\t\t// whole transcript is one component, so that is the normal case. A\n\t\t// component that can hand over a row map turns the \"where\" question into\n\t\t// \"where did the anchored segment go\". Both kinds may supply one: a\n\t\t// transcript built without a cache key is not windowed, but it is still\n\t\t// one component spanning the anchor and still knows its own rows.\n\t\tconst segments = componentRows.map((rows) => rows.segments);\n\t\tconst pendingScrollRow = this.pendingScrollRow;\n\t\tthis.pendingScrollRow = undefined;\n\t\tif (pendingScrollRow !== undefined) {\n\t\t\t// An absolute request outranks the anchor: the caller measured this\n\t\t\t// frame's rows and named one of them. Re-deriving the anchor here\n\t\t\t// would answer with the previous frame's layout instead.\n\t\t\tthis.scrollFromBottom = maxScroll - Math.min(maxScroll, pendingScrollRow);\n\t\t} else if (this.scrollFromBottom > 0 && this.lastWidth === width) {\n\t\t\tconst previousMaxScroll = Math.max(0, this.lastLineCount - this.visibleRows);\n\t\t\tconst anchorRow = Math.max(0, previousMaxScroll - this.scrollFromBottom);\n\t\t\tconst shift = rowsShiftedAboveAnchor(\n\t\t\t\t{ rowCounts: this.lastComponentRowCounts, segments: this.lastComponentSegments },\n\t\t\t\t{ rowCounts, segments },\n\t\t\t\tanchorRow,\n\t\t\t);\n\t\t\tconst nextAnchorRow = Math.max(0, Math.min(maxScroll, anchorRow + shift));\n\t\t\tthis.scrollFromBottom = maxScroll - nextAnchorRow;\n\t\t}\n\t\tthis.lastLineCount = lineCount;\n\t\tthis.lastComponentRowCounts = rowCounts;\n\t\tthis.lastComponentSegments = segments;\n\t\tthis.lastWidth = width;\n\t\tthis.maxScroll = maxScroll;\n\t\tthis.clampScroll();\n\n\t\tconst start = Math.max(0, maxScroll - this.scrollFromBottom);\n\t\tconst visible = this.renderVisibleRows(componentRows, width, start, start + this.visibleRows);\n\t\twhile (visible.length < this.visibleRows) visible.push(\" \".repeat(width));\n\t\treturn visible;\n\t}\n\n\tinvalidate(): void {\n\t\tfor (const component of this.components) component.invalidate();\n\t}\n\n\tprivate measureComponentRows(width: number): ComponentRows[] {\n\t\treturn this.components.map((component) => {\n\t\t\tif (isRowWindowComponent(component)) {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"windowed\",\n\t\t\t\t\tcomponent,\n\t\t\t\t\trowCount: component.rowCount(width),\n\t\t\t\t\tsegments: component.rowSegments?.(width),\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst lines = component.render(width);\n\t\t\t// Read segments only after rendering: a static transcript records its\n\t\t\t// per-entry heights as a by-product of that render, so asking first\n\t\t\t// would return the previous frame's layout.\n\t\t\tconst segments = segmentReporter(component)?.rowSegments(width);\n\t\t\treturn {\n\t\t\t\tkind: \"static\",\n\t\t\t\tlines,\n\t\t\t\trowCount: lines.length,\n\t\t\t\tsegments: segments !== undefined && segments.length > 0 ? segments : undefined,\n\t\t\t};\n\t\t});\n\t}\n\n\tprivate renderVisibleRows(\n\t\tcomponentRows: readonly ComponentRows[],\n\t\twidth: number,\n\t\tstartRow: number,\n\t\tendRow: number,\n\t): string[] {\n\t\tconst lines: string[] = [];\n\t\tlet cursor = 0;\n\t\tfor (const rows of componentRows) {\n\t\t\tconst componentStart = cursor;\n\t\t\tconst componentEnd = componentStart + rows.rowCount;\n\t\t\tif (componentEnd > startRow && componentStart < endRow) {\n\t\t\t\tconst localStart = Math.max(0, startRow - componentStart);\n\t\t\t\tconst localEnd = Math.min(rows.rowCount, endRow - componentStart);\n\t\t\t\tif (rows.kind === \"windowed\") {\n\t\t\t\t\tlines.push(...rows.component.renderRows(width, localStart, localEnd));\n\t\t\t\t} else {\n\t\t\t\t\tlines.push(...rows.lines.slice(localStart, localEnd));\n\t\t\t\t}\n\t\t\t}\n\t\t\tcursor = componentEnd;\n\t\t\tif (cursor >= endRow) break;\n\t\t}\n\t\treturn lines;\n\t}\n\n\tprivate pageSize(): number {\n\t\treturn Math.max(4, this.visibleRows - 2);\n\t}\n\n\tprivate clampScroll(): void {\n\t\tthis.scrollFromBottom = Math.max(0, Math.min(this.maxScroll, this.scrollFromBottom));\n\t}\n}\n\n/** One rendered frame's row layout, as the viewport measured it. */\ninterface ComponentRowLayout {\n\treadonly rowCounts: readonly number[];\n\treadonly segments: readonly (readonly RowWindowSegment[] | undefined)[];\n}\n\n/**\n * Rows gained or lost above `anchorRow`, measured in the previous frame's rows.\n *\n * The anchored row moves down by exactly this many rows, so adding it to the\n * anchor keeps the same content under the viewer.\n *\n * Components entirely above the anchor contribute their whole height delta.\n * The component that *spans* the anchor contributes only what changed above the\n * anchored row, which needs its row map (`rowSegments`); without one it\n * contributes nothing, which is the old behaviour and is right for the\n * append-and-mutate-at-the-tail widgets that have no interior.\n *\n * Row counts are compared positionally over the shared prefix, which is what the\n * chat stacks this viewport drives actually do — they append and mutate at the\n * tail. A component inserted or removed *ahead* of the anchor would be\n * misattributed; the anchor then lands one component off rather than drifting on\n * every frame, and the next user scroll re-establishes it.\n */\nfunction rowsShiftedAboveAnchor(previous: ComponentRowLayout, next: ComponentRowLayout, anchorRow: number): number {\n\tlet cursor = 0;\n\tlet shift = 0;\n\tconst shared = Math.min(previous.rowCounts.length, next.rowCounts.length);\n\tfor (let index = 0; index < shared; index += 1) {\n\t\tconst previousRows = previous.rowCounts[index] ?? 0;\n\t\tconst componentEnd = cursor + previousRows;\n\t\tif (componentEnd > anchorRow) {\n\t\t\treturn shift + rowsShiftedInsideComponent(previous.segments[index], next.segments[index], anchorRow - cursor);\n\t\t}\n\t\tshift += (next.rowCounts[index] ?? 0) - previousRows;\n\t\tcursor = componentEnd;\n\t}\n\treturn shift;\n}\n\n/**\n * Rows gained or lost above `anchorRow` *within* one windowed component.\n *\n * Rather than diffing heights, this finds the segment the viewer is parked on\n * and reports how far that same segment moved. Segments are matched by `===` on\n * their id, so a transcript splice that renumbers every cache key still lines\n * up: the entry objects survive it. If the anchored segment itself is gone\n * (the viewer was reading rows that were compacted away) the nearest surviving\n * neighbour above it — then below it — stands in, so the viewer lands on the\n * closest content that still exists instead of drifting by the whole delta.\n */\nfunction rowsShiftedInsideComponent(\n\tpreviousSegments: readonly RowWindowSegment[] | undefined,\n\tnextSegments: readonly RowWindowSegment[] | undefined,\n\tanchorRow: number,\n): number {\n\tif (previousSegments === undefined || nextSegments === undefined) return 0;\n\tconst nextStarts = new Map<unknown, number>();\n\tlet cursor = 0;\n\tfor (const segment of nextSegments) {\n\t\tif (!nextStarts.has(segment.id)) nextStarts.set(segment.id, cursor);\n\t\tcursor += segment.rows;\n\t}\n\tconst previousStarts: number[] = [];\n\tlet anchorIndex = -1;\n\tcursor = 0;\n\tfor (let index = 0; index < previousSegments.length; index += 1) {\n\t\tpreviousStarts.push(cursor);\n\t\tcursor += previousSegments[index]?.rows ?? 0;\n\t\tif (anchorIndex < 0 && cursor > anchorRow) anchorIndex = index;\n\t}\n\tif (anchorIndex < 0) return 0;\n\tfor (let index = anchorIndex; index >= 0; index -= 1) {\n\t\tconst nextStart = nextStarts.get(previousSegments[index]?.id);\n\t\tif (nextStart !== undefined) return nextStart - (previousStarts[index] ?? 0);\n\t}\n\tfor (let index = anchorIndex + 1; index < previousSegments.length; index += 1) {\n\t\tconst nextStart = nextStarts.get(previousSegments[index]?.id);\n\t\tif (nextStart !== undefined) return nextStart - (previousStarts[index] ?? 0);\n\t}\n\treturn 0;\n}\n\nfunction isRowWindowComponent(component: Component): component is RowWindowComponent {\n\tconst candidate = component as Partial<RowWindowComponent>;\n\treturn (\n\t\tcandidate.supportsRowWindow === true &&\n\t\ttypeof candidate.rowCount === \"function\" &&\n\t\ttypeof candidate.renderRows === \"function\"\n\t);\n}\n\n/**\n * A component that can identify its own rows without being windowed.\n *\n * `ScrollableChatTranscriptComponent` builds its transcript without a cache key\n * — deliberately, because that is what lets it reflect entries mutated in place\n * — so it is not a `RowWindowComponent` and renders every row each frame. It\n * still knows which entry produced which rows, and it is still the component\n * spanning the anchor, so the anchor needs to ask.\n */\nfunction segmentReporter(\n\tcomponent: Component,\n): { rowSegments(width: number): readonly RowWindowSegment[] } | undefined {\n\tconst candidate = component as Partial<RowWindowComponent>;\n\treturn typeof candidate.rowSegments === \"function\"\n\t\t? (candidate as { rowSegments(width: number): readonly RowWindowSegment[] })\n\t\t: undefined;\n}\n\nexport class ScrollableChatTranscriptComponent<TEntry extends ChatTranscriptEntryLike> implements Component {\n\tprivate readonly viewport = new ScrollableComponentViewport();\n\tprivate readonly transcript: ChatTranscriptComponent<TEntry>;\n\n\tconstructor(entries: readonly TEntry[], renderEntry: ChatTranscriptRenderer<TEntry>) {\n\t\tthis.transcript = new ChatTranscriptComponent(entries, renderEntry);\n\t\tthis.viewport.setComponents([this.transcript]);\n\t}\n\n\tsetVisibleRows(rows: number): void {\n\t\tthis.viewport.setVisibleRows(rows);\n\t}\n\n\thandleInput(data: string): boolean {\n\t\treturn this.viewport.handleInput(data);\n\t}\n\n\trender(width: number): string[] {\n\t\treturn this.viewport.render(width);\n\t}\n\n\tinvalidate(): void {\n\t\tthis.viewport.invalidate();\n\t}\n\n\tgetScrollFromBottom(): number {\n\t\treturn this.viewport.getScrollFromBottom();\n\t}\n\n\tgetMaxScroll(): number {\n\t\treturn this.viewport.getMaxScroll();\n\t}\n\n\tscrollToBottom(): void {\n\t\tthis.viewport.scrollToBottom();\n\t}\n}\n\nfunction mouseWheelDeltaRows(data: string): number {\n\tconst sgr = data.match(/^\\x1b\\[<(\\d+);\\d+;\\d+M$/);\n\tif (sgr) return wheelDeltaForButtonCode(Number.parseInt(sgr[1]!, 10));\n\tif (data.startsWith(\"\\x1b[M\") && data.length >= 6) {\n\t\treturn wheelDeltaForButtonCode(data.charCodeAt(3) - 32);\n\t}\n\treturn 0;\n}\n\nfunction wheelDeltaForButtonCode(code: number): number {\n\tif ((code & 64) === 0) return 0;\n\tconst direction = code & 3;\n\tif (direction === 0) return -DEFAULT_SCROLL_STEP_ROWS;\n\tif (direction === 1) return DEFAULT_SCROLL_STEP_ROWS;\n\treturn 0;\n}\n\nfunction isMouseSequence(data: string): boolean {\n\treturn /^\\x1b\\[<\\d+;\\d+;\\d+[mM]$/.test(data) || data.startsWith(\"\\x1b[M\");\n}\n"]}
|
|
@@ -2,7 +2,7 @@ import { matchesKey, truncateToWidth, wrapTextWithAnsi } from "@earendil-works/p
|
|
|
2
2
|
import { theme } from "../theme/theme.js";
|
|
3
3
|
const ROWS = ["chat", "workflow"];
|
|
4
4
|
const LABEL_WIDTH = 16;
|
|
5
|
-
const DESCRIPTION = "Priority tier for supported
|
|
5
|
+
const DESCRIPTION = "Priority tier for supported OpenAI and shared ChatGPT Codex transports.";
|
|
6
6
|
const ROW_DETAILS = {
|
|
7
7
|
chat: {
|
|
8
8
|
label: "Chat",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fast-mode-selector.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/fast-mode-selector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACvF,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAc1C,MAAM,IAAI,GAA2B,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAC1D,MAAM,WAAW,GAAG,EAAE,CAAC;AACvB,MAAM,WAAW,GAAG,
|
|
1
|
+
{"version":3,"file":"fast-mode-selector.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/fast-mode-selector.ts"],"names":[],"mappings":"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","sourcesContent":["import { matchesKey, truncateToWidth, wrapTextWithAnsi } from \"@earendil-works/pi-tui\";\nimport { theme } from \"../theme/theme.ts\";\n\nexport interface FastModeSelectorConfig {\n\tchat: boolean;\n\tworkflow: boolean;\n}\n\nexport interface FastModeSelectorCallbacks {\n\tonChange: (settings: FastModeSelectorConfig, changedRow: FastModeRow) => void;\n\tonCancel: () => void | Promise<void>;\n}\n\nexport type FastModeRow = keyof FastModeSelectorConfig;\n\nconst ROWS: readonly FastModeRow[] = [\"chat\", \"workflow\"];\nconst LABEL_WIDTH = 16;\nconst DESCRIPTION = \"Priority tier for supported OpenAI and shared ChatGPT Codex transports.\";\nconst ROW_DETAILS: Record<FastModeRow, { label: string; scope: string }> = {\n\tchat: {\n\t\tlabel: \"Chat\",\n\t\tscope: \"this chat + subagents\",\n\t},\n\tworkflow: {\n\t\tlabel: \"Workflow stages\",\n\t\tscope: \"workflow stages\",\n\t},\n};\n\nexport class FastModeSelectorComponent {\n\tprivate selectedRowIndex = 0;\n\tprivate state: FastModeSelectorConfig;\n\tprivate readonly callbacks: FastModeSelectorCallbacks;\n\n\tconstructor(config: FastModeSelectorConfig, callbacks: FastModeSelectorCallbacks) {\n\t\tthis.state = { ...config };\n\t\tthis.callbacks = callbacks;\n\t}\n\n\tinvalidate(): void {}\n\n\trender(width: number): string[] {\n\t\tconst lines: string[] = [truncateToWidth(theme.bold(theme.fg(\"accent\", \"Codex fast mode\")), width)];\n\t\tfor (const line of wrapTextWithAnsi(DESCRIPTION, Math.max(20, width))) {\n\t\t\tlines.push(theme.fg(\"muted\", line));\n\t\t}\n\t\tlines.push(\"\");\n\t\tfor (const row of ROWS) {\n\t\t\tlines.push(this.renderRow(row, width));\n\t\t}\n\t\tlines.push(\"\");\n\t\tlines.push(truncateToWidth(this.renderHint(), width));\n\t\treturn lines.map((line) => truncateToWidth(line, width));\n\t}\n\n\thandleInput(data: string): boolean {\n\t\tif (matchesKey(data, \"tab\") || matchesKey(data, \"down\")) {\n\t\t\tthis.moveRow(1);\n\t\t\treturn true;\n\t\t}\n\t\tif (matchesKey(data, \"shift+tab\") || matchesKey(data, \"up\")) {\n\t\t\tthis.moveRow(-1);\n\t\t\treturn true;\n\t\t}\n\t\tif (matchesKey(data, \"enter\") || data === \" \") {\n\t\t\tthis.toggleCurrentRow();\n\t\t\treturn true;\n\t\t}\n\t\tif (matchesKey(data, \"left\")) {\n\t\t\tthis.setCurrentRow(false);\n\t\t\treturn true;\n\t\t}\n\t\tif (matchesKey(data, \"right\")) {\n\t\t\tthis.setCurrentRow(true);\n\t\t\treturn true;\n\t\t}\n\t\tif (matchesKey(data, \"escape\") || matchesKey(data, \"ctrl+c\")) {\n\t\t\tvoid this.callbacks.onCancel();\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tgetFocusedRow(): FastModeRow {\n\t\treturn ROWS[this.selectedRowIndex]!;\n\t}\n\n\tgetSettings(): FastModeSelectorConfig {\n\t\treturn { ...this.state };\n\t}\n\n\tprivate moveRow(delta: 1 | -1): void {\n\t\tthis.selectedRowIndex = (this.selectedRowIndex + delta + ROWS.length) % ROWS.length;\n\t}\n\n\tprivate setCurrentRow(enabled: boolean): void {\n\t\tconst row = this.getFocusedRow();\n\t\tif (this.state[row] === enabled) {\n\t\t\treturn;\n\t\t}\n\t\tthis.state = { ...this.state, [row]: enabled };\n\t\tthis.callbacks.onChange({ ...this.state }, row);\n\t}\n\n\tprivate toggleCurrentRow(): void {\n\t\tconst row = this.getFocusedRow();\n\t\tthis.setCurrentRow(!this.state[row]);\n\t}\n\n\tprivate renderHint(): string {\n\t\tconst sep = theme.fg(\"dim\", \" · \");\n\t\tconst hint = (key: string, label: string): string => theme.fg(\"dim\", key) + theme.fg(\"muted\", ` ${label}`);\n\t\treturn [hint(\"↑↓/tab\", \"row\"), hint(\"space/enter\", \"toggle\"), hint(\"esc\", \"close\")].join(sep);\n\t}\n\n\tprivate renderRow(row: FastModeRow, width: number): string {\n\t\tconst selected = this.getFocusedRow() === row;\n\t\tconst detail = ROW_DETAILS[row];\n\t\tconst prefix = selected ? theme.fg(\"accent\", \"› \") : \" \";\n\t\tconst label = detail.label.padEnd(LABEL_WIDTH, \" \");\n\t\tconst labelText = selected ? theme.bold(theme.fg(\"accent\", label)) : theme.fg(\"text\", label);\n\t\tconst scope = selected ? theme.fg(\"muted\", detail.scope) : theme.fg(\"dim\", detail.scope);\n\t\treturn truncateToWidth(`${prefix}${labelText} ${this.renderToggle(row)} ${scope}`, width);\n\t}\n\n\tprivate renderToggle(row: FastModeRow): string {\n\t\tconst enabled = this.state[row];\n\t\tconst text = enabled ? \"[● ON ]\" : \"[○ OFF]\";\n\t\tif (enabled) {\n\t\t\treturn theme.bold(theme.fg(\"success\", text));\n\t\t}\n\t\treturn this.getFocusedRow() === row ? theme.fg(\"muted\", text) : theme.fg(\"dim\", text);\n\t}\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Api, type Model } from "@earendil-works/pi-ai/compat";
|
|
2
2
|
import { Container, type Focusable, Input, type TUI } from "@earendil-works/pi-tui";
|
|
3
|
-
import type { ModelRuntime } from "../../../core/model-runtime.
|
|
3
|
+
import type { ModelRuntime } from "../../../core/model-runtime.js";
|
|
4
4
|
import type { SettingsManager } from "../../../core/settings-manager.ts";
|
|
5
5
|
interface ScopedModelItem {
|
|
6
6
|
model: Model<Api>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-selector.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/model-selector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,KAAK,EAAkB,MAAM,8BAA8B,CAAC;AACpF,OAAO,EACN,SAAS,EACT,KAAK,SAAS,EAGd,KAAK,EAGL,KAAK,GAAG,EACR,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"model-selector.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/model-selector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,KAAK,EAAkB,MAAM,8BAA8B,CAAC;AACpF,OAAO,EACN,SAAS,EACT,KAAK,SAAS,EAGd,KAAK,EAGL,KAAK,GAAG,EACR,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAazE,UAAU,eAAe;IACxB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAID;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,SAAU,YAAW,SAAS;IACzE,OAAO,CAAC,WAAW,CAAQ;IAG3B,OAAO,CAAC,QAAQ,CAAS;IACzB,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAGzB;IACD,OAAO,CAAC,aAAa,CAAY;IACjC,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,YAAY,CAAmB;IACvC,OAAO,CAAC,cAAc,CAAmB;IACzC,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,YAAY,CAAC,CAAa;IAClC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,gBAAgB,CAA8B;IACtD,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,oBAAoB,CAAgC;IAC5D,OAAO,CAAC,oBAAoB,CAAS;IACrC,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,SAAS,CAAC,CAAO;IACzB,OAAO,CAAC,aAAa,CAAC,CAAO;IAC7B,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAyB;IAChE,OAAO,CAAC,MAAM,CAAS;IAEvB,YACC,GAAG,EAAE,GAAG,EACR,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,EACpC,eAAe,EAAE,eAAe,EAChC,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,aAAa,CAAC,eAAe,CAAC,EAC5C,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,EACrC,QAAQ,EAAE,MAAM,IAAI,EACpB,kBAAkB,CAAC,EAAE,MAAM,EA2D3B;IAED,OAAO,CAAC,sBAAsB;YAuBhB,aAAa;IA4B3B,OAAO,IAAI,IAAI,CAId;IAED,OAAO,CAAC,UAAU;IAalB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,QAAQ;IAYhB,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,UAAU;IA+DlB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CA0CpC;IAED,OAAO,CAAC,YAAY;IAOpB,cAAc,IAAI,KAAK,CAEtB;CACD"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { modelsAreEqual } from "@earendil-works/pi-ai/compat";
|
|
2
2
|
import { Container, fuzzyFilter, getKeybindings, Input, Spacer, Text, } from "@earendil-works/pi-tui";
|
|
3
3
|
import { boundedInteractiveModelRefresh } from "../../../core/bounded-model-refresh.js";
|
|
4
|
+
import { refreshModelCatalogs } from "../model-catalog-refresh.js";
|
|
4
5
|
import { getModelSelectorSearchText } from "../model-search.js";
|
|
5
6
|
import { theme } from "../theme/theme.js";
|
|
6
7
|
import { DynamicBorder } from "./dynamic-border.js";
|
|
@@ -104,7 +105,7 @@ export class ModelSelectorComponent extends Container {
|
|
|
104
105
|
currentIndex >= 0 ? currentIndex : Math.min(this.selectedIndex, Math.max(0, this.filteredModels.length - 1));
|
|
105
106
|
}
|
|
106
107
|
async refreshModels() {
|
|
107
|
-
const outcome = await boundedInteractiveModelRefresh((options) => this.modelRuntime
|
|
108
|
+
const outcome = await boundedInteractiveModelRefresh((options) => refreshModelCatalogs(this.modelRuntime, options), {}, this.refreshAbortController.signal);
|
|
108
109
|
if (this.closed)
|
|
109
110
|
return;
|
|
110
111
|
this.refreshStatusMessage = "";
|