@caupulican/pi-adaptative 0.81.40 → 0.81.42
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 +41 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts.map +1 -1
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js +1 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js.map +1 -1
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.ts +1 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/commands/text.py +5 -1
- package/dist/bundled-resources/runtimes/pi-shell-engine/context.py +3 -3
- package/dist/bundled-resources/runtimes/pi-shell-engine/errors.py +8 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/exec.py +26 -3
- package/dist/bundled-resources/runtimes/pi-shell-engine/expand.py +3 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/main.py +4 -1
- package/dist/bundled-resources/runtimes/pi-shell-engine/state.py +2 -1
- package/dist/bundled-resources/runtimes/pi-shell-engine/tokens.py +2 -0
- package/dist/cli/args.d.ts +2 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +22 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-paths.d.ts +38 -0
- package/dist/core/agent-paths.d.ts.map +1 -1
- package/dist/core/agent-paths.js +77 -0
- package/dist/core/agent-paths.js.map +1 -1
- package/dist/core/agent-session-contracts.d.ts +311 -0
- package/dist/core/agent-session-contracts.d.ts.map +1 -0
- package/dist/core/agent-session-contracts.js +26 -0
- package/dist/core/agent-session-contracts.js.map +1 -0
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +3 -0
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session.d.ts +26 -405
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +90 -316
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +3 -1
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/autonomy/contracts.d.ts +2 -0
- package/dist/core/autonomy/contracts.d.ts.map +1 -1
- package/dist/core/autonomy/contracts.js.map +1 -1
- package/dist/core/autonomy/envelope-enforcement.d.ts.map +1 -1
- package/dist/core/autonomy/envelope-enforcement.js +4 -9
- package/dist/core/autonomy/envelope-enforcement.js.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.d.ts +3 -1
- package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.js +19 -5
- package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
- package/dist/core/autonomy/path-scope.d.ts +14 -0
- package/dist/core/autonomy/path-scope.d.ts.map +1 -1
- package/dist/core/autonomy/path-scope.js +37 -6
- package/dist/core/autonomy/path-scope.js.map +1 -1
- package/dist/core/background-lane-controller.d.ts +30 -2
- package/dist/core/background-lane-controller.d.ts.map +1 -1
- package/dist/core/background-lane-controller.js +33 -1
- package/dist/core/background-lane-controller.js.map +1 -1
- package/dist/core/bedrock-sso-login.d.ts +16 -0
- package/dist/core/bedrock-sso-login.d.ts.map +1 -0
- package/dist/core/bedrock-sso-login.js +98 -0
- package/dist/core/bedrock-sso-login.js.map +1 -0
- package/dist/core/compaction-controller.d.ts.map +1 -1
- package/dist/core/compaction-controller.js +1 -1
- package/dist/core/compaction-controller.js.map +1 -1
- package/dist/core/compaction-support.d.ts +3 -8
- package/dist/core/compaction-support.d.ts.map +1 -1
- package/dist/core/compaction-support.js +3 -3
- package/dist/core/compaction-support.js.map +1 -1
- package/dist/core/context-pipeline.d.ts +1 -1
- package/dist/core/context-pipeline.d.ts.map +1 -1
- package/dist/core/context-pipeline.js +7 -33
- package/dist/core/context-pipeline.js.map +1 -1
- package/dist/core/cost/cost-summary.d.ts.map +1 -1
- package/dist/core/cost/cost-summary.js +5 -3
- package/dist/core/cost/cost-summary.js.map +1 -1
- package/dist/core/cost/daily-usage.d.ts.map +1 -1
- package/dist/core/cost/daily-usage.js +4 -5
- package/dist/core/cost/daily-usage.js.map +1 -1
- package/dist/core/default-tool-surface.d.ts.map +1 -1
- package/dist/core/default-tool-surface.js +1 -0
- package/dist/core/default-tool-surface.js.map +1 -1
- package/dist/core/delegation/managed-lane-controller.d.ts +11 -1
- package/dist/core/delegation/managed-lane-controller.d.ts.map +1 -1
- package/dist/core/delegation/managed-lane-controller.js +84 -41
- package/dist/core/delegation/managed-lane-controller.js.map +1 -1
- package/dist/core/delegation/session-worker-claim.d.ts.map +1 -1
- package/dist/core/delegation/session-worker-claim.js +4 -3
- package/dist/core/delegation/session-worker-claim.js.map +1 -1
- package/dist/core/delegation/worker-action-journal.d.ts +73 -0
- package/dist/core/delegation/worker-action-journal.d.ts.map +1 -0
- package/dist/core/delegation/worker-action-journal.js +297 -0
- package/dist/core/delegation/worker-action-journal.js.map +1 -0
- package/dist/core/delegation/worker-actions.d.ts +36 -1
- package/dist/core/delegation/worker-actions.d.ts.map +1 -1
- package/dist/core/delegation/worker-actions.js +171 -46
- package/dist/core/delegation/worker-actions.js.map +1 -1
- package/dist/core/delegation/worker-agent-control-coordinator.d.ts +75 -0
- package/dist/core/delegation/worker-agent-control-coordinator.d.ts.map +1 -0
- package/dist/core/delegation/worker-agent-control-coordinator.js +218 -0
- package/dist/core/delegation/worker-agent-control-coordinator.js.map +1 -0
- package/dist/core/delegation/worker-agent-control.d.ts +66 -0
- package/dist/core/delegation/worker-agent-control.d.ts.map +1 -0
- package/dist/core/delegation/worker-agent-control.js +163 -0
- package/dist/core/delegation/worker-agent-control.js.map +1 -0
- package/dist/core/delegation/worker-attempt-executor.d.ts +80 -0
- package/dist/core/delegation/worker-attempt-executor.d.ts.map +1 -0
- package/dist/core/delegation/worker-attempt-executor.js +343 -0
- package/dist/core/delegation/worker-attempt-executor.js.map +1 -0
- package/dist/core/delegation/worker-claim.d.ts +30 -0
- package/dist/core/delegation/worker-claim.d.ts.map +1 -1
- package/dist/core/delegation/worker-claim.js +205 -53
- package/dist/core/delegation/worker-claim.js.map +1 -1
- package/dist/core/delegation/worker-conversation-store.d.ts +116 -0
- package/dist/core/delegation/worker-conversation-store.d.ts.map +1 -0
- package/dist/core/delegation/worker-conversation-store.js +442 -0
- package/dist/core/delegation/worker-conversation-store.js.map +1 -0
- package/dist/core/delegation/worker-delegation-controller.d.ts +21 -5
- package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.js +386 -251
- package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
- package/dist/core/delegation/worker-delegation-request.d.ts +14 -0
- package/dist/core/delegation/worker-delegation-request.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-request.js.map +1 -1
- package/dist/core/delegation/worker-dispatch-scheduler.d.ts +4 -2
- package/dist/core/delegation/worker-dispatch-scheduler.d.ts.map +1 -1
- package/dist/core/delegation/worker-dispatch-scheduler.js +16 -6
- package/dist/core/delegation/worker-dispatch-scheduler.js.map +1 -1
- package/dist/core/delegation/worker-execution-policy.d.ts +2 -1
- package/dist/core/delegation/worker-execution-policy.d.ts.map +1 -1
- package/dist/core/delegation/worker-execution-policy.js +5 -7
- package/dist/core/delegation/worker-execution-policy.js.map +1 -1
- package/dist/core/delegation/worker-lifecycle.d.ts +44 -1
- package/dist/core/delegation/worker-lifecycle.d.ts.map +1 -1
- package/dist/core/delegation/worker-lifecycle.js +120 -0
- package/dist/core/delegation/worker-lifecycle.js.map +1 -1
- package/dist/core/delegation/worker-process-owner.d.ts +18 -0
- package/dist/core/delegation/worker-process-owner.d.ts.map +1 -0
- package/dist/core/delegation/worker-process-owner.js +54 -0
- package/dist/core/delegation/worker-process-owner.js.map +1 -0
- package/dist/core/delegation/worker-profile-resolver.d.ts +5 -1
- package/dist/core/delegation/worker-profile-resolver.d.ts.map +1 -1
- package/dist/core/delegation/worker-profile-resolver.js +8 -0
- package/dist/core/delegation/worker-profile-resolver.js.map +1 -1
- package/dist/core/delegation/worker-recovery-coordinator.d.ts +54 -0
- package/dist/core/delegation/worker-recovery-coordinator.d.ts.map +1 -0
- package/dist/core/delegation/worker-recovery-coordinator.js +181 -0
- package/dist/core/delegation/worker-recovery-coordinator.js.map +1 -0
- package/dist/core/delegation/worker-resource-catalog.d.ts +32 -0
- package/dist/core/delegation/worker-resource-catalog.d.ts.map +1 -0
- package/dist/core/delegation/worker-resource-catalog.js +116 -0
- package/dist/core/delegation/worker-resource-catalog.js.map +1 -0
- package/dist/core/delegation/worker-resource-materializer.d.ts +47 -0
- package/dist/core/delegation/worker-resource-materializer.d.ts.map +1 -0
- package/dist/core/delegation/worker-resource-materializer.js +137 -0
- package/dist/core/delegation/worker-resource-materializer.js.map +1 -0
- package/dist/core/delegation/worker-runner.d.ts +3 -1
- package/dist/core/delegation/worker-runner.d.ts.map +1 -1
- package/dist/core/delegation/worker-runner.js +189 -54
- package/dist/core/delegation/worker-runner.js.map +1 -1
- package/dist/core/delegation/worker-terminal-finalizer.d.ts +23 -0
- package/dist/core/delegation/worker-terminal-finalizer.d.ts.map +1 -0
- package/dist/core/delegation/worker-terminal-finalizer.js +12 -0
- package/dist/core/delegation/worker-terminal-finalizer.js.map +1 -0
- package/dist/core/delegation/worker-write-reservation-coordinator.d.ts +38 -0
- package/dist/core/delegation/worker-write-reservation-coordinator.d.ts.map +1 -0
- package/dist/core/delegation/worker-write-reservation-coordinator.js +107 -0
- package/dist/core/delegation/worker-write-reservation-coordinator.js.map +1 -0
- package/dist/core/delegation/worker-write-reservation.d.ts +90 -0
- package/dist/core/delegation/worker-write-reservation.d.ts.map +1 -0
- package/dist/core/delegation/worker-write-reservation.js +348 -0
- package/dist/core/delegation/worker-write-reservation.js.map +1 -0
- package/dist/core/extension-import-authority.d.ts +6 -0
- package/dist/core/extension-import-authority.d.ts.map +1 -0
- package/dist/core/extension-import-authority.js +10 -0
- package/dist/core/extension-import-authority.js.map +1 -0
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +2 -3
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +3 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +14 -5
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/stale-context.d.ts +2 -0
- package/dist/core/extensions/stale-context.d.ts.map +1 -0
- package/dist/core/extensions/stale-context.js +2 -0
- package/dist/core/extensions/stale-context.js.map +1 -0
- package/dist/core/extensions/types.d.ts +8 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/foreground-recovery-controller.d.ts +1 -0
- package/dist/core/foreground-recovery-controller.d.ts.map +1 -1
- package/dist/core/foreground-recovery-controller.js +13 -13
- package/dist/core/foreground-recovery-controller.js.map +1 -1
- package/dist/core/goal-loop-controller.d.ts +14 -9
- package/dist/core/goal-loop-controller.d.ts.map +1 -1
- package/dist/core/goal-loop-controller.js +47 -75
- package/dist/core/goal-loop-controller.js.map +1 -1
- package/dist/core/goals/compact-goal-context.d.ts +11 -0
- package/dist/core/goals/compact-goal-context.d.ts.map +1 -0
- package/dist/core/goals/compact-goal-context.js +59 -0
- package/dist/core/goals/compact-goal-context.js.map +1 -0
- package/dist/core/goals/goal-acceptance.d.ts.map +1 -1
- package/dist/core/goals/goal-acceptance.js +2 -0
- package/dist/core/goals/goal-acceptance.js.map +1 -1
- package/dist/core/goals/goal-auto-continue-controller.d.ts +2 -1
- package/dist/core/goals/goal-auto-continue-controller.d.ts.map +1 -1
- package/dist/core/goals/goal-auto-continue-controller.js +5 -8
- package/dist/core/goals/goal-auto-continue-controller.js.map +1 -1
- package/dist/core/goals/goal-continuation-controller.d.ts +2 -2
- package/dist/core/goals/goal-continuation-controller.d.ts.map +1 -1
- package/dist/core/goals/goal-continuation-controller.js +42 -11
- package/dist/core/goals/goal-continuation-controller.js.map +1 -1
- package/dist/core/goals/goal-continuation-defaults.d.ts +4 -29
- package/dist/core/goals/goal-continuation-defaults.d.ts.map +1 -1
- package/dist/core/goals/goal-continuation-defaults.js +4 -32
- package/dist/core/goals/goal-continuation-defaults.js.map +1 -1
- package/dist/core/goals/goal-continuation-prompt.d.ts +8 -18
- package/dist/core/goals/goal-continuation-prompt.d.ts.map +1 -1
- package/dist/core/goals/goal-continuation-prompt.js +9 -179
- package/dist/core/goals/goal-continuation-prompt.js.map +1 -1
- package/dist/core/goals/goal-lifecycle.d.ts +35 -12
- package/dist/core/goals/goal-lifecycle.d.ts.map +1 -1
- package/dist/core/goals/goal-lifecycle.js +98 -13
- package/dist/core/goals/goal-lifecycle.js.map +1 -1
- package/dist/core/goals/goal-record.d.ts +17 -0
- package/dist/core/goals/goal-record.d.ts.map +1 -0
- package/dist/core/goals/goal-record.js +31 -0
- package/dist/core/goals/goal-record.js.map +1 -0
- package/dist/core/goals/goal-session-controller.d.ts +42 -0
- package/dist/core/goals/goal-session-controller.d.ts.map +1 -0
- package/dist/core/goals/goal-session-controller.js +128 -0
- package/dist/core/goals/goal-session-controller.js.map +1 -0
- package/dist/core/goals/goal-state.d.ts +45 -25
- package/dist/core/goals/goal-state.d.ts.map +1 -1
- package/dist/core/goals/goal-state.js +85 -15
- package/dist/core/goals/goal-state.js.map +1 -1
- package/dist/core/goals/goal-tool-core.d.ts +1 -4
- package/dist/core/goals/goal-tool-core.d.ts.map +1 -1
- package/dist/core/goals/goal-tool-core.js +49 -34
- package/dist/core/goals/goal-tool-core.js.map +1 -1
- package/dist/core/goals/session-goal-state.d.ts +18 -8
- package/dist/core/goals/session-goal-state.d.ts.map +1 -1
- package/dist/core/goals/session-goal-state.js +134 -11
- package/dist/core/goals/session-goal-state.js.map +1 -1
- package/dist/core/human-input-controller.d.ts +47 -0
- package/dist/core/human-input-controller.d.ts.map +1 -0
- package/dist/core/human-input-controller.js +181 -0
- package/dist/core/human-input-controller.js.map +1 -0
- package/dist/core/local-runtime-controller.d.ts +1 -1
- package/dist/core/local-runtime-controller.d.ts.map +1 -1
- package/dist/core/local-runtime-controller.js.map +1 -1
- package/dist/core/model-capability.d.ts +0 -19
- package/dist/core/model-capability.d.ts.map +1 -1
- package/dist/core/model-capability.js +0 -19
- package/dist/core/model-capability.js.map +1 -1
- package/dist/core/model-registry.d.ts +6 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +13 -5
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +16 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +32 -16
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-router-controller.d.ts +1 -1
- package/dist/core/model-router-controller.d.ts.map +1 -1
- package/dist/core/model-router-controller.js.map +1 -1
- package/dist/core/model-selection-controller.d.ts +1 -1
- package/dist/core/model-selection-controller.d.ts.map +1 -1
- package/dist/core/model-selection-controller.js.map +1 -1
- package/dist/core/models/model-endpoint.d.ts +3 -0
- package/dist/core/models/model-endpoint.d.ts.map +1 -0
- package/dist/core/models/model-endpoint.js +11 -0
- package/dist/core/models/model-endpoint.js.map +1 -0
- package/dist/core/orchestration/agent-resume.d.ts +2 -0
- package/dist/core/orchestration/agent-resume.d.ts.map +1 -1
- package/dist/core/orchestration/agent-resume.js +7 -0
- package/dist/core/orchestration/agent-resume.js.map +1 -1
- package/dist/core/orchestration/attempt-usage.d.ts +28 -0
- package/dist/core/orchestration/attempt-usage.d.ts.map +1 -0
- package/dist/core/orchestration/attempt-usage.js +168 -0
- package/dist/core/orchestration/attempt-usage.js.map +1 -0
- package/dist/core/orchestration/capability-gateway.d.ts +19 -1
- package/dist/core/orchestration/capability-gateway.d.ts.map +1 -1
- package/dist/core/orchestration/capability-gateway.js +128 -28
- package/dist/core/orchestration/capability-gateway.js.map +1 -1
- package/dist/core/orchestration/contracts.d.ts +35 -0
- package/dist/core/orchestration/contracts.d.ts.map +1 -1
- package/dist/core/orchestration/contracts.js +17 -0
- package/dist/core/orchestration/contracts.js.map +1 -1
- package/dist/core/orchestration/delegation-ledger.d.ts +17 -2
- package/dist/core/orchestration/delegation-ledger.d.ts.map +1 -1
- package/dist/core/orchestration/delegation-ledger.js +81 -3
- package/dist/core/orchestration/delegation-ledger.js.map +1 -1
- package/dist/core/orchestration/event-store.d.ts +1 -0
- package/dist/core/orchestration/event-store.d.ts.map +1 -1
- package/dist/core/orchestration/event-store.js +78 -38
- package/dist/core/orchestration/event-store.js.map +1 -1
- package/dist/core/orchestration/profile-registry.d.ts.map +1 -1
- package/dist/core/orchestration/profile-registry.js +81 -41
- package/dist/core/orchestration/profile-registry.js.map +1 -1
- package/dist/core/orchestration/profile-store.d.ts.map +1 -1
- package/dist/core/orchestration/profile-store.js +18 -4
- package/dist/core/orchestration/profile-store.js.map +1 -1
- package/dist/core/orchestration/risk-budget.d.ts +2 -0
- package/dist/core/orchestration/risk-budget.d.ts.map +1 -1
- package/dist/core/orchestration/risk-budget.js +26 -0
- package/dist/core/orchestration/risk-budget.js.map +1 -1
- package/dist/core/orchestration/task-runtime.d.ts +13 -1
- package/dist/core/orchestration/task-runtime.d.ts.map +1 -1
- package/dist/core/orchestration/task-runtime.js +127 -16
- package/dist/core/orchestration/task-runtime.js.map +1 -1
- package/dist/core/orchestration/work-state-projection.d.ts.map +1 -1
- package/dist/core/orchestration/work-state-projection.js +1 -1
- package/dist/core/orchestration/work-state-projection.js.map +1 -1
- package/dist/core/orchestration/worker-execution-contract.d.ts +3 -1
- package/dist/core/orchestration/worker-execution-contract.d.ts.map +1 -1
- package/dist/core/orchestration/worker-execution-contract.js +75 -23
- package/dist/core/orchestration/worker-execution-contract.js.map +1 -1
- package/dist/core/orchestration/worker-result-adapter.d.ts +9 -3
- package/dist/core/orchestration/worker-result-adapter.d.ts.map +1 -1
- package/dist/core/orchestration/worker-result-adapter.js +167 -14
- package/dist/core/orchestration/worker-result-adapter.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +20 -3
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/profile-filter-controller.d.ts +8 -1
- package/dist/core/profile-filter-controller.d.ts.map +1 -1
- package/dist/core/profile-filter-controller.js +23 -5
- package/dist/core/profile-filter-controller.js.map +1 -1
- package/dist/core/prompt-templates.d.ts +1 -0
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js +18 -29
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/reflection-controller.d.ts +2 -2
- package/dist/core/reflection-controller.d.ts.map +1 -1
- package/dist/core/reflection-controller.js +92 -54
- package/dist/core/reflection-controller.js.map +1 -1
- package/dist/core/request-auth.d.ts +7 -0
- package/dist/core/request-auth.d.ts.map +1 -0
- package/dist/core/request-auth.js +8 -0
- package/dist/core/request-auth.js.map +1 -0
- package/dist/core/research/evidence-bundle.d.ts +20 -0
- package/dist/core/research/evidence-bundle.d.ts.map +1 -1
- package/dist/core/research/evidence-bundle.js +173 -69
- package/dist/core/research/evidence-bundle.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +16 -6
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/risk-classifier.d.ts.map +1 -1
- package/dist/core/risk-classifier.js +8 -0
- package/dist/core/risk-classifier.js.map +1 -1
- package/dist/core/runtime-builder.d.ts +22 -3
- package/dist/core/runtime-builder.d.ts.map +1 -1
- package/dist/core/runtime-builder.js +147 -80
- package/dist/core/runtime-builder.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +7 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/secrets/credential-exposure-guard.d.ts +9 -0
- package/dist/core/secrets/credential-exposure-guard.d.ts.map +1 -0
- package/dist/core/secrets/credential-exposure-guard.js +241 -0
- package/dist/core/secrets/credential-exposure-guard.js.map +1 -0
- package/dist/core/secrets/secret-dotenv.d.ts +27 -0
- package/dist/core/secrets/secret-dotenv.d.ts.map +1 -0
- package/dist/core/secrets/secret-dotenv.js +183 -0
- package/dist/core/secrets/secret-dotenv.js.map +1 -0
- package/dist/core/secrets/secret-vault-format.d.ts +112 -0
- package/dist/core/secrets/secret-vault-format.d.ts.map +1 -0
- package/dist/core/secrets/secret-vault-format.js +397 -0
- package/dist/core/secrets/secret-vault-format.js.map +1 -0
- package/dist/core/secrets/secret-vault.d.ts +72 -0
- package/dist/core/secrets/secret-vault.d.ts.map +1 -0
- package/dist/core/secrets/secret-vault.js +671 -0
- package/dist/core/secrets/secret-vault.js.map +1 -0
- package/dist/core/session-analytics.d.ts +4 -23
- package/dist/core/session-analytics.d.ts.map +1 -1
- package/dist/core/session-analytics.js +39 -69
- package/dist/core/session-analytics.js.map +1 -1
- package/dist/core/session-artifact-bundle.d.ts +35 -0
- package/dist/core/session-artifact-bundle.d.ts.map +1 -0
- package/dist/core/session-artifact-bundle.js +61 -0
- package/dist/core/session-artifact-bundle.js.map +1 -0
- package/dist/core/session-role.d.ts +5 -0
- package/dist/core/session-role.d.ts.map +1 -1
- package/dist/core/session-role.js +14 -1
- package/dist/core/session-role.js.map +1 -1
- package/dist/core/session-tree-navigator.d.ts +4 -6
- package/dist/core/session-tree-navigator.d.ts.map +1 -1
- package/dist/core/session-tree-navigator.js +4 -1
- package/dist/core/session-tree-navigator.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 +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +2 -2
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/tool-capability-policy.d.ts.map +1 -1
- package/dist/core/tool-capability-policy.js +1 -0
- package/dist/core/tool-capability-policy.js.map +1 -1
- package/dist/core/tool-gate-controller.d.ts.map +1 -1
- package/dist/core/tool-gate-controller.js +8 -2
- package/dist/core/tool-gate-controller.js.map +1 -1
- package/dist/core/tool-protocol-controller.d.ts +2 -4
- package/dist/core/tool-protocol-controller.d.ts.map +1 -1
- package/dist/core/tool-protocol-controller.js.map +1 -1
- package/dist/core/tool-recovery-stats.d.ts +21 -1
- package/dist/core/tool-recovery-stats.d.ts.map +1 -1
- package/dist/core/tool-recovery-stats.js.map +1 -1
- package/dist/core/tools/bash.d.ts +5 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +59 -5
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/delegate-status.d.ts +6 -1
- package/dist/core/tools/delegate-status.d.ts.map +1 -1
- package/dist/core/tools/delegate-status.js +106 -25
- package/dist/core/tools/delegate-status.js.map +1 -1
- package/dist/core/tools/delegate.d.ts +9 -1
- package/dist/core/tools/delegate.d.ts.map +1 -1
- package/dist/core/tools/delegate.js +329 -69
- package/dist/core/tools/delegate.js.map +1 -1
- package/dist/core/tools/git-filter.d.ts +1 -8
- package/dist/core/tools/git-filter.d.ts.map +1 -1
- package/dist/core/tools/git-filter.js +2 -63
- package/dist/core/tools/git-filter.js.map +1 -1
- package/dist/core/tools/goal.d.ts +5 -3
- package/dist/core/tools/goal.d.ts.map +1 -1
- package/dist/core/tools/goal.js +97 -19
- package/dist/core/tools/goal.js.map +1 -1
- package/dist/core/tools/index.d.ts +1 -0
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +1 -0
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/orchestration-panel.d.ts +1 -4
- package/dist/core/tools/orchestration-panel.d.ts.map +1 -1
- package/dist/core/tools/orchestration-panel.js +0 -44
- package/dist/core/tools/orchestration-panel.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts +11 -0
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +36 -3
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/python.d.ts +2 -0
- package/dist/core/tools/python.d.ts.map +1 -1
- package/dist/core/tools/python.js +3 -1
- package/dist/core/tools/python.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/run-process.d.ts +1 -1
- package/dist/core/tools/run-process.d.ts.map +1 -1
- package/dist/core/tools/run-process.js +69 -9
- package/dist/core/tools/run-process.js.map +1 -1
- package/dist/core/tools/search-command-guard.d.ts +14 -0
- package/dist/core/tools/search-command-guard.d.ts.map +1 -0
- package/dist/core/tools/search-command-guard.js +333 -0
- package/dist/core/tools/search-command-guard.js.map +1 -0
- package/dist/core/tools/secret-store.d.ts +38 -0
- package/dist/core/tools/secret-store.d.ts.map +1 -0
- package/dist/core/tools/secret-store.js +412 -0
- package/dist/core/tools/secret-store.js.map +1 -0
- package/dist/core/tools/shell-command-parser.d.ts +16 -0
- package/dist/core/tools/shell-command-parser.d.ts.map +1 -0
- package/dist/core/tools/shell-command-parser.js +113 -0
- package/dist/core/tools/shell-command-parser.js.map +1 -0
- package/dist/core/tools/shell-contract-router.d.ts.map +1 -1
- package/dist/core/tools/shell-contract-router.js +12 -5
- package/dist/core/tools/shell-contract-router.js.map +1 -1
- package/dist/core/tools/task-steps.d.ts.map +1 -1
- package/dist/core/tools/task-steps.js +4 -7
- package/dist/core/tools/task-steps.js.map +1 -1
- package/dist/core/util/atomic-file.d.ts +6 -2
- package/dist/core/util/atomic-file.d.ts.map +1 -1
- package/dist/core/util/atomic-file.js +4 -4
- package/dist/core/util/atomic-file.js.map +1 -1
- package/dist/core/util/bounded-file.d.ts +15 -0
- package/dist/core/util/bounded-file.d.ts.map +1 -0
- package/dist/core/util/bounded-file.js +120 -0
- package/dist/core/util/bounded-file.js.map +1 -0
- package/dist/core/util/bounded-jsonl.d.ts.map +1 -1
- package/dist/core/util/bounded-jsonl.js +119 -9
- package/dist/core/util/bounded-jsonl.js.map +1 -1
- package/dist/core/util/bounded-value.d.ts +3 -0
- package/dist/core/util/bounded-value.d.ts.map +1 -0
- package/dist/core/util/bounded-value.js +12 -0
- package/dist/core/util/bounded-value.js.map +1 -0
- package/dist/core/util/value-guards.d.ts +2 -0
- package/dist/core/util/value-guards.d.ts.map +1 -1
- package/dist/core/util/value-guards.js +5 -0
- package/dist/core/util/value-guards.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +25 -11
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/auth-dialogs-controller.d.ts +4 -0
- package/dist/modes/interactive/auth-dialogs-controller.d.ts.map +1 -1
- package/dist/modes/interactive/auth-dialogs-controller.js +60 -1
- package/dist/modes/interactive/auth-dialogs-controller.js.map +1 -1
- package/dist/modes/interactive/components/activity-lane.d.ts +55 -0
- package/dist/modes/interactive/components/activity-lane.d.ts.map +1 -0
- package/dist/modes/interactive/components/activity-lane.js +304 -0
- package/dist/modes/interactive/components/activity-lane.js.map +1 -0
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +19 -10
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/expandable-text.d.ts +12 -0
- package/dist/modes/interactive/components/expandable-text.d.ts.map +1 -0
- package/dist/modes/interactive/components/expandable-text.js +17 -0
- package/dist/modes/interactive/components/expandable-text.js.map +1 -0
- package/dist/modes/interactive/components/extension-editor.d.ts +15 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +30 -21
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-input.d.ts +1 -0
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-input.js +6 -1
- package/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +2 -2
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +23 -14
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +27 -44
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +4 -4
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +19 -11
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +53 -20
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tool-group.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-group.js +3 -0
- package/dist/modes/interactive/components/tool-group.js.map +1 -1
- package/dist/modes/interactive/components/usage-action-selector.d.ts +16 -0
- package/dist/modes/interactive/components/usage-action-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/usage-action-selector.js +46 -0
- package/dist/modes/interactive/components/usage-action-selector.js.map +1 -0
- package/dist/modes/interactive/extension-ui-host.d.ts.map +1 -1
- package/dist/modes/interactive/extension-ui-host.js +1 -0
- package/dist/modes/interactive/extension-ui-host.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts +15 -0
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +27 -19
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/history-reload-math.d.ts +6 -2
- package/dist/modes/interactive/history-reload-math.d.ts.map +1 -1
- package/dist/modes/interactive/history-reload-math.js +10 -5
- package/dist/modes/interactive/history-reload-math.js.map +1 -1
- package/dist/modes/interactive/interactive-event-controller.d.ts +74 -0
- package/dist/modes/interactive/interactive-event-controller.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-event-controller.js +328 -0
- package/dist/modes/interactive/interactive-event-controller.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +20 -25
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +196 -608
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/loaded-resources-view.d.ts +20 -0
- package/dist/modes/interactive/loaded-resources-view.d.ts.map +1 -0
- package/dist/modes/interactive/loaded-resources-view.js +147 -0
- package/dist/modes/interactive/loaded-resources-view.js.map +1 -0
- package/dist/modes/interactive/resource-display.d.ts.map +1 -1
- package/dist/modes/interactive/resource-display.js +8 -2
- package/dist/modes/interactive/resource-display.js.map +1 -1
- package/dist/modes/interactive/resource-shell-commands.d.ts +1 -5
- package/dist/modes/interactive/resource-shell-commands.d.ts.map +1 -1
- package/dist/modes/interactive/resource-shell-commands.js +0 -5
- package/dist/modes/interactive/resource-shell-commands.js.map +1 -1
- package/dist/modes/interactive/session-flow-commands.d.ts +10 -6
- package/dist/modes/interactive/session-flow-commands.d.ts.map +1 -1
- package/dist/modes/interactive/session-flow-commands.js +123 -70
- package/dist/modes/interactive/session-flow-commands.js.map +1 -1
- package/dist/modes/interactive/usage-commands.d.ts +34 -0
- package/dist/modes/interactive/usage-commands.d.ts.map +1 -0
- package/dist/modes/interactive/usage-commands.js +225 -0
- package/dist/modes/interactive/usage-commands.js.map +1 -0
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +5 -3
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +3 -1
- package/dist/utils/version-check.js.map +1 -1
- package/docs/UI_POLISH_ORCHESTRATION.md +25 -31
- package/docs/UI_QUALITY_ORCHESTRATION.md +22 -24
- package/docs/providers.md +9 -1
- package/docs/tool-repair.md +3 -0
- package/docs/ui-reference/README.md +6 -6
- package/docs/ui-reference/orchestration-after.txt +14 -7
- package/docs/ui-reference/orchestration-before.txt +12 -6
- package/docs/ui-reference/orchestration-reference.txt +15 -5
- package/docs/usage.md +9 -1
- package/docs/windows.md +4 -2
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +13 -13
- package/package.json +4 -4
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Container, type SelectItem, SelectList } from "@caupulican/pi-tui";
|
|
2
|
+
export interface UsageActionSelectorOptions {
|
|
3
|
+
title: string;
|
|
4
|
+
subtitle?: string;
|
|
5
|
+
items: SelectItem[];
|
|
6
|
+
initialSelectedIndex?: number;
|
|
7
|
+
onSelect: (value: string) => void;
|
|
8
|
+
onCancel: () => void;
|
|
9
|
+
}
|
|
10
|
+
export declare class UsageActionSelectorComponent extends Container {
|
|
11
|
+
private readonly selectList;
|
|
12
|
+
constructor(options: UsageActionSelectorOptions);
|
|
13
|
+
handleInput(data: string): void;
|
|
14
|
+
getSelectList(): SelectList;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=usage-action-selector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage-action-selector.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/usage-action-selector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,UAAU,EAAE,UAAU,EAA8C,MAAM,oBAAoB,CAAC;AAUxH,MAAM,WAAW,0BAA0B;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,qBAAa,4BAA6B,SAAQ,SAAS;IAC1D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IAExC,YAAY,OAAO,EAAE,0BAA0B,EAuC9C;IAED,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAE9B;IAED,aAAa,IAAI,UAAU,CAE1B;CACD","sourcesContent":["import { Container, type SelectItem, SelectList, type SelectListLayoutOptions, Spacer, Text } from \"@caupulican/pi-tui\";\nimport { theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\nimport { keyHint, rawKeyHint } from \"./keybinding-hints.ts\";\n\nconst USAGE_ACTION_LAYOUT: SelectListLayoutOptions = {\n\tminPrimaryColumnWidth: 20,\n\tmaxPrimaryColumnWidth: 36,\n};\n\nexport interface UsageActionSelectorOptions {\n\ttitle: string;\n\tsubtitle?: string;\n\titems: SelectItem[];\n\tinitialSelectedIndex?: number;\n\tonSelect: (value: string) => void;\n\tonCancel: () => void;\n}\n\nexport class UsageActionSelectorComponent extends Container {\n\tprivate readonly selectList: SelectList;\n\n\tconstructor(options: UsageActionSelectorOptions) {\n\t\tsuper();\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new Text(theme.fg(\"accent\", theme.bold(options.title)), 1, 0));\n\t\tif (options.subtitle) this.addChild(new Text(theme.fg(\"muted\", options.subtitle), 1, 0));\n\t\tthis.addChild(new Spacer(1));\n\n\t\tthis.selectList = new SelectList(\n\t\t\toptions.items,\n\t\t\tMath.min(8, Math.max(2, options.items.length)),\n\t\t\t{\n\t\t\t\tselectedPrefix: (text) => theme.fg(\"accent\", text),\n\t\t\t\tselectedText: (text) => theme.fg(\"accent\", text),\n\t\t\t\tdescription: (text) => theme.fg(\"muted\", text),\n\t\t\t\tscrollInfo: (text) => theme.fg(\"dim\", text),\n\t\t\t\tnoMatch: (text) => theme.fg(\"muted\", text),\n\t\t\t},\n\t\t\tUSAGE_ACTION_LAYOUT,\n\t\t);\n\t\tthis.selectList.setSelectedIndex(options.initialSelectedIndex ?? 0);\n\t\tthis.selectList.onSelect = (item) => options.onSelect(item.value);\n\t\tthis.selectList.onCancel = options.onCancel;\n\t\tthis.addChild(this.selectList);\n\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(\n\t\t\tnew Text(\n\t\t\t\trawKeyHint(\"↑↓\", \"navigate\") +\n\t\t\t\t\t\" \" +\n\t\t\t\t\tkeyHint(\"tui.select.confirm\", \"select\") +\n\t\t\t\t\t\" \" +\n\t\t\t\t\tkeyHint(\"tui.select.cancel\", \"cancel\"),\n\t\t\t\t1,\n\t\t\t\t0,\n\t\t\t),\n\t\t);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t}\n\n\thandleInput(data: string): void {\n\t\tthis.selectList.handleInput(data);\n\t}\n\n\tgetSelectList(): SelectList {\n\t\treturn this.selectList;\n\t}\n}\n"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Container, SelectList, Spacer, Text } from "@caupulican/pi-tui";
|
|
2
|
+
import { theme } from "../theme/theme.js";
|
|
3
|
+
import { DynamicBorder } from "./dynamic-border.js";
|
|
4
|
+
import { keyHint, rawKeyHint } from "./keybinding-hints.js";
|
|
5
|
+
const USAGE_ACTION_LAYOUT = {
|
|
6
|
+
minPrimaryColumnWidth: 20,
|
|
7
|
+
maxPrimaryColumnWidth: 36,
|
|
8
|
+
};
|
|
9
|
+
export class UsageActionSelectorComponent extends Container {
|
|
10
|
+
selectList;
|
|
11
|
+
constructor(options) {
|
|
12
|
+
super();
|
|
13
|
+
this.addChild(new DynamicBorder());
|
|
14
|
+
this.addChild(new Spacer(1));
|
|
15
|
+
this.addChild(new Text(theme.fg("accent", theme.bold(options.title)), 1, 0));
|
|
16
|
+
if (options.subtitle)
|
|
17
|
+
this.addChild(new Text(theme.fg("muted", options.subtitle), 1, 0));
|
|
18
|
+
this.addChild(new Spacer(1));
|
|
19
|
+
this.selectList = new SelectList(options.items, Math.min(8, Math.max(2, options.items.length)), {
|
|
20
|
+
selectedPrefix: (text) => theme.fg("accent", text),
|
|
21
|
+
selectedText: (text) => theme.fg("accent", text),
|
|
22
|
+
description: (text) => theme.fg("muted", text),
|
|
23
|
+
scrollInfo: (text) => theme.fg("dim", text),
|
|
24
|
+
noMatch: (text) => theme.fg("muted", text),
|
|
25
|
+
}, USAGE_ACTION_LAYOUT);
|
|
26
|
+
this.selectList.setSelectedIndex(options.initialSelectedIndex ?? 0);
|
|
27
|
+
this.selectList.onSelect = (item) => options.onSelect(item.value);
|
|
28
|
+
this.selectList.onCancel = options.onCancel;
|
|
29
|
+
this.addChild(this.selectList);
|
|
30
|
+
this.addChild(new Spacer(1));
|
|
31
|
+
this.addChild(new Text(rawKeyHint("↑↓", "navigate") +
|
|
32
|
+
" " +
|
|
33
|
+
keyHint("tui.select.confirm", "select") +
|
|
34
|
+
" " +
|
|
35
|
+
keyHint("tui.select.cancel", "cancel"), 1, 0));
|
|
36
|
+
this.addChild(new Spacer(1));
|
|
37
|
+
this.addChild(new DynamicBorder());
|
|
38
|
+
}
|
|
39
|
+
handleInput(data) {
|
|
40
|
+
this.selectList.handleInput(data);
|
|
41
|
+
}
|
|
42
|
+
getSelectList() {
|
|
43
|
+
return this.selectList;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=usage-action-selector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage-action-selector.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/usage-action-selector.ts"],"names":[],"mappings":"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","sourcesContent":["import { Container, type SelectItem, SelectList, type SelectListLayoutOptions, Spacer, Text } from \"@caupulican/pi-tui\";\nimport { theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\nimport { keyHint, rawKeyHint } from \"./keybinding-hints.ts\";\n\nconst USAGE_ACTION_LAYOUT: SelectListLayoutOptions = {\n\tminPrimaryColumnWidth: 20,\n\tmaxPrimaryColumnWidth: 36,\n};\n\nexport interface UsageActionSelectorOptions {\n\ttitle: string;\n\tsubtitle?: string;\n\titems: SelectItem[];\n\tinitialSelectedIndex?: number;\n\tonSelect: (value: string) => void;\n\tonCancel: () => void;\n}\n\nexport class UsageActionSelectorComponent extends Container {\n\tprivate readonly selectList: SelectList;\n\n\tconstructor(options: UsageActionSelectorOptions) {\n\t\tsuper();\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new Text(theme.fg(\"accent\", theme.bold(options.title)), 1, 0));\n\t\tif (options.subtitle) this.addChild(new Text(theme.fg(\"muted\", options.subtitle), 1, 0));\n\t\tthis.addChild(new Spacer(1));\n\n\t\tthis.selectList = new SelectList(\n\t\t\toptions.items,\n\t\t\tMath.min(8, Math.max(2, options.items.length)),\n\t\t\t{\n\t\t\t\tselectedPrefix: (text) => theme.fg(\"accent\", text),\n\t\t\t\tselectedText: (text) => theme.fg(\"accent\", text),\n\t\t\t\tdescription: (text) => theme.fg(\"muted\", text),\n\t\t\t\tscrollInfo: (text) => theme.fg(\"dim\", text),\n\t\t\t\tnoMatch: (text) => theme.fg(\"muted\", text),\n\t\t\t},\n\t\t\tUSAGE_ACTION_LAYOUT,\n\t\t);\n\t\tthis.selectList.setSelectedIndex(options.initialSelectedIndex ?? 0);\n\t\tthis.selectList.onSelect = (item) => options.onSelect(item.value);\n\t\tthis.selectList.onCancel = options.onCancel;\n\t\tthis.addChild(this.selectList);\n\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(\n\t\t\tnew Text(\n\t\t\t\trawKeyHint(\"↑↓\", \"navigate\") +\n\t\t\t\t\t\" \" +\n\t\t\t\t\tkeyHint(\"tui.select.confirm\", \"select\") +\n\t\t\t\t\t\" \" +\n\t\t\t\t\tkeyHint(\"tui.select.cancel\", \"cancel\"),\n\t\t\t\t1,\n\t\t\t\t0,\n\t\t\t),\n\t\t);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t}\n\n\thandleInput(data: string): void {\n\t\tthis.selectList.handleInput(data);\n\t}\n\n\tgetSelectList(): SelectList {\n\t\treturn this.selectList;\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension-ui-host.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/extension-ui-host.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Extension UI host.\n *\n * Extracted verbatim from interactive-mode.ts (god-file decomposition). Owns the interactive-mode\n * surface of the extension UI API: extension-provided dialogs (selector / confirm / input / multi-line\n * editor / custom component), widget mounting above and below the editor, extension status text, custom\n * footer and header swaps, the custom editor-component swap, keyboard-shortcut wiring, terminal-input\n * listeners, and the `ExtensionUIContext` handed to extensions. It owns exactly the state this cluster\n * mutates (the live dialog components, the widget maps, the terminal-input unsubscribers, the custom\n * footer/header, and the current custom-editor factory) and reaches everything else — the mutable\n * `editor`, the render-core containers, the working-indicator, autocomplete wiring, theme/tools state —\n * through a narrow deps/ui surface rather than the whole InteractiveMode instance. Extensions must see\n * identical behavior, so the render-core operations (working indicator, hidden-thinking label,\n * autocomplete rebuild) stay host-side and are invoked here as delegations.\n */\n\nimport type {\n\tAutocompleteProvider,\n\tComponent,\n\tEditorComponent,\n\tKeyId,\n\tLoaderIndicatorOptions,\n\tOverlayHandle,\n\tOverlayOptions,\n} from \"@caupulican/pi-tui\";\nimport { Container, Editor, matchesKey, Spacer, Text, type TUI } from \"@caupulican/pi-tui\";\nimport type { AgentSession } from \"../../core/agent-session.ts\";\nimport type {\n\tAutocompleteProviderFactory,\n\tEditorFactory,\n\tExtensionContext,\n\tExtensionRunner,\n\tExtensionUIContext,\n\tExtensionUIDialogOptions,\n\tExtensionWidgetOptions,\n} from \"../../core/extensions/index.ts\";\nimport type { FooterDataProvider, ReadonlyFooterDataProvider } from \"../../core/footer-data-provider.ts\";\nimport type { HumanInputPresentationRequest, HumanInputPresentationResult } from \"../../core/human-input.ts\";\nimport type { KeybindingsManager } from \"../../core/keybindings.ts\";\nimport type { SessionImageStore } from \"../../core/session-image-store.ts\";\nimport { AskQuestionDialog } from \"../../core/tools/ask-question.ts\";\nimport { handleClipboardImagePaste } from \"./clipboard-input.ts\";\nimport type { CustomEditor } from \"./components/custom-editor.ts\";\nimport { ExtensionEditorComponent } from \"./components/extension-editor.ts\";\nimport { ExtensionInputComponent } from \"./components/extension-input.ts\";\nimport { ExtensionSelectorComponent } from \"./components/extension-selector.ts\";\nimport type { FooterComponent } from \"./components/footer.ts\";\nimport type { EditorOverlayHost } from \"./editor-overlay-host.ts\";\nimport {\n\tgetAvailableThemesWithPaths,\n\tgetEditorTheme,\n\tgetThemeByName,\n\tsetTheme,\n\tsetThemeInstance,\n\tTheme,\n\ttheme,\n} from \"./theme/theme.ts\";\n\n/** Components that can be expanded/collapsed (custom headers may opt in). */\ninterface Expandable {\n\tsetExpanded(expanded: boolean): void;\n}\n\nfunction isExpandable(obj: unknown): obj is Expandable {\n\treturn typeof obj === \"object\" && obj !== null && \"setExpanded\" in obj && typeof obj.setExpanded === \"function\";\n}\n\n/**\n * The narrow slice of InteractiveMode the extension UI host drives. Stable containers and the TUI are\n * passed directly; mutable render-core state (the active editor, built-in header, loading animation,\n * autocomplete wrappers, tools-expansion) is read/written through accessors so InteractiveMode keeps\n * ownership; and render-core / status operations stay host-side and are exposed here as callbacks.\n */\nexport interface ExtensionUiHostUi {\n\treadonly tui: TUI;\n\treadonly overlayHost: EditorOverlayHost;\n\treadonly keybindings: KeybindingsManager;\n\treadonly footer: FooterComponent;\n\treadonly footerDataProvider: FooterDataProvider;\n\treadonly headerContainer: Container;\n\treadonly chatContainer: Container;\n\treadonly defaultEditor: CustomEditor;\n\treadonly widgetContainerAbove: Container;\n\treadonly widgetContainerBelow: Container;\n\n\tgetEditor(): EditorComponent;\n\tsetEditor(editor: EditorComponent): void;\n\tgetBuiltInHeader(): Component | undefined;\n\tgetAutocompleteProvider(): AutocompleteProvider | undefined;\n\tgetClipboardImageStore(): Pick<SessionImageStore, \"write\"> | undefined;\n\tgetToolsExpanded(): boolean;\n\tpushAutocompleteProviderWrapper(factory: AutocompleteProviderFactory): void;\n\tresetAutocompleteProviderWrappers(): void;\n\n\tsetupAutocompleteProvider(): void;\n\tsetWorkingVisible(visible: boolean): void;\n\tsetWorkingIndicator(options?: LoaderIndicatorOptions): void;\n\tsetHiddenThinkingLabel(label?: string): void;\n\tsetWorkingMessage(message: string | undefined): void;\n\tresetWorkingIndicators(): void;\n\tsetToolsExpanded(expanded: boolean): void;\n\ttoggleToolsExpanded(): void;\n\tupdateTerminalTitle(): void;\n\tmarkShutdownRequested(): void;\n\tabort(): void;\n\treload(): Promise<void>;\n\tshowStatus(message: string): void;\n\tshowWarning(message: string): void;\n\tshowError(message: string): void;\n}\n\nexport interface ExtensionUiHostDeps {\n\tgetSession(): AgentSession;\n\tui: ExtensionUiHostUi;\n}\n\ntype DisposableComponent = Component & { dispose?(): void };\ntype WidgetPlacement = \"aboveEditor\" | \"belowEditor\";\n\nexport class ExtensionUiHost {\n\tprivate readonly deps: ExtensionUiHostDeps;\n\n\t// Extension UI state\n\tprivate extensionSelector: ExtensionSelectorComponent | undefined = undefined;\n\tprivate extensionInput: ExtensionInputComponent | undefined = undefined;\n\tprivate extensionEditor: ExtensionEditorComponent | undefined = undefined;\n\t/** Settles the mounted extension dialog before another dialog can replace its overlay. */\n\tprivate activeExtensionDialogCancel: (() => void) | undefined;\n\tprivate extensionTerminalInputUnsubscribers = new Set<() => void>();\n\n\t// Extension widgets (components rendered above/below the editor)\n\tprivate extensionWidgetsAbove = new Map<string, Component & { dispose?(): void }>();\n\tprivate extensionWidgetsBelow = new Map<string, Component & { dispose?(): void }>();\n\t// Host-owned widgets survive extension reloads and are cleared only by the owning interactive mode.\n\tprivate hostWidgetsAbove = new Map<string, DisposableComponent>();\n\tprivate hostWidgetsBelow = new Map<string, DisposableComponent>();\n\n\t// Custom footer from extension (undefined = use built-in footer)\n\tprivate customFooter: (Component & { dispose?(): void }) | undefined = undefined;\n\n\t// Custom header from extension (undefined = use built-in header)\n\tprivate customHeader: (Component & { dispose?(): void }) | undefined = undefined;\n\n\t// Current custom editor-component factory (undefined = default editor)\n\tprivate editorComponentFactory: EditorFactory | undefined;\n\n\tconstructor(deps: ExtensionUiHostDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\tprivate get session(): AgentSession {\n\t\treturn this.deps.getSession();\n\t}\n\tprivate get ui(): ExtensionUiHostUi {\n\t\treturn this.deps.ui;\n\t}\n\n\t/** The active custom header, if an extension has installed one. */\n\tgetCustomHeader(): (Component & { dispose?(): void }) | undefined {\n\t\treturn this.customHeader;\n\t}\n\n\t/**\n\t * Set up keyboard shortcuts registered by extensions.\n\t */\n\tsetupExtensionShortcuts(extensionRunner: ExtensionRunner): void {\n\t\tconst shortcuts = extensionRunner.getShortcuts(this.ui.keybindings.getEffectiveConfig());\n\t\tif (shortcuts.size === 0) return;\n\n\t\t// Create a context for shortcut handlers\n\t\tconst createContext = (): ExtensionContext => ({\n\t\t\tui: this.createExtensionUIContext(),\n\t\t\thasUI: true,\n\t\t\tmode: \"tui\",\n\t\t\tcwd: this.session.sessionManager.getCwd(),\n\t\t\tsessionManager: this.session.sessionManager,\n\t\t\tmodelRegistry: this.session.modelRegistry,\n\t\t\tmodel: this.session.model,\n\t\t\tisIdle: () => !this.session.isStreaming,\n\t\t\tsignal: this.session.agent.signal,\n\t\t\tabort: () => {\n\t\t\t\tthis.ui.abort();\n\t\t\t},\n\t\t\thasPendingMessages: () => this.session.pendingMessageCount > 0,\n\t\t\tshutdown: () => {\n\t\t\t\tthis.ui.markShutdownRequested();\n\t\t\t},\n\t\t\tgetContextUsage: () => this.session.getContextUsage(),\n\t\t\tcompact: (options) => {\n\t\t\t\tvoid (async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await this.session.compact(options?.customInstructions);\n\t\t\t\t\t\toptions?.onComplete?.(result);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tconst err = error instanceof Error ? error : new Error(String(error));\n\t\t\t\t\t\toptions?.onError?.(err);\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t},\n\t\t\treload: async () => {\n\t\t\t\tawait this.ui.reload();\n\t\t\t},\n\t\t\tgetSystemPrompt: () => this.session.systemPrompt,\n\t\t});\n\n\t\t// Set up the extension shortcut handler on the default editor\n\t\tthis.ui.defaultEditor.onExtensionShortcut = (data: string) => {\n\t\t\tfor (const [shortcutStr, shortcut] of shortcuts) {\n\t\t\t\t// Cast to KeyId - extension shortcuts use the same format\n\t\t\t\tif (matchesKey(data, shortcutStr as KeyId)) {\n\t\t\t\t\t// Run handler async, don't block input\n\t\t\t\t\tPromise.resolve(shortcut.handler(createContext())).catch((err) => {\n\t\t\t\t\t\tthis.ui.showError(`Shortcut handler error: ${err instanceof Error ? err.message : String(err)}`);\n\t\t\t\t\t});\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\t}\n\n\t/**\n\t * Set extension status text in the footer.\n\t */\n\tprivate setExtensionStatus(key: string, text: string | undefined): void {\n\t\tthis.ui.footerDataProvider.setExtensionStatus(key, text);\n\t\tthis.ui.tui.requestRender();\n\t}\n\n\t// Maximum total widget lines to prevent viewport overflow\n\tprivate static readonly MAX_WIDGET_LINES = 10;\n\n\tprivate removeWidget(map: Map<string, DisposableComponent>, key: string): void {\n\t\tconst existing = map.get(key);\n\t\texisting?.dispose?.();\n\t\tmap.delete(key);\n\t}\n\n\t/** Mount a native host widget without coupling it to extension reload lifecycle. */\n\tsetHostWidget(key: string, component: DisposableComponent | undefined, placement: WidgetPlacement): void {\n\t\tthis.removeWidget(this.hostWidgetsAbove, key);\n\t\tthis.removeWidget(this.hostWidgetsBelow, key);\n\t\tif (component) {\n\t\t\tconst target = placement === \"belowEditor\" ? this.hostWidgetsBelow : this.hostWidgetsAbove;\n\t\t\ttarget.set(key, component);\n\t\t}\n\t\tthis.renderWidgets();\n\t}\n\n\tclearHostWidgets(): void {\n\t\tfor (const widget of this.hostWidgetsAbove.values()) widget.dispose?.();\n\t\tfor (const widget of this.hostWidgetsBelow.values()) widget.dispose?.();\n\t\tthis.hostWidgetsAbove.clear();\n\t\tthis.hostWidgetsBelow.clear();\n\t\tthis.renderWidgets();\n\t}\n\n\t/**\n\t * Set an extension widget (string array or custom component).\n\t */\n\tprivate setExtensionWidget(\n\t\tkey: string,\n\t\tcontent: string[] | ((tui: TUI, thm: Theme) => Component & { dispose?(): void }) | undefined,\n\t\toptions?: ExtensionWidgetOptions,\n\t): void {\n\t\tconst placement = options?.placement ?? \"aboveEditor\";\n\t\tthis.removeWidget(this.extensionWidgetsAbove, key);\n\t\tthis.removeWidget(this.extensionWidgetsBelow, key);\n\n\t\tif (content === undefined) {\n\t\t\tthis.renderWidgets();\n\t\t\treturn;\n\t\t}\n\n\t\tlet component: Component & { dispose?(): void };\n\n\t\tif (Array.isArray(content)) {\n\t\t\t// Wrap string array in a Container with Text components\n\t\t\tconst container = new Container();\n\t\t\tfor (const line of content.slice(0, ExtensionUiHost.MAX_WIDGET_LINES)) {\n\t\t\t\tcontainer.addChild(new Text(line, 1, 0));\n\t\t\t}\n\t\t\tif (content.length > ExtensionUiHost.MAX_WIDGET_LINES) {\n\t\t\t\tcontainer.addChild(new Text(theme.fg(\"muted\", \"... (widget truncated)\"), 1, 0));\n\t\t\t}\n\t\t\tcomponent = container;\n\t\t} else {\n\t\t\t// Factory function - create component\n\t\t\tcomponent = content(this.ui.tui, theme);\n\t\t}\n\n\t\tconst targetMap = placement === \"belowEditor\" ? this.extensionWidgetsBelow : this.extensionWidgetsAbove;\n\t\ttargetMap.set(key, component);\n\t\tthis.renderWidgets();\n\t}\n\n\tprivate clearExtensionWidgets(): void {\n\t\tfor (const widget of this.extensionWidgetsAbove.values()) {\n\t\t\twidget.dispose?.();\n\t\t}\n\t\tfor (const widget of this.extensionWidgetsBelow.values()) {\n\t\t\twidget.dispose?.();\n\t\t}\n\t\tthis.extensionWidgetsAbove.clear();\n\t\tthis.extensionWidgetsBelow.clear();\n\t\tthis.renderWidgets();\n\t}\n\n\tresetExtensionUI(): void {\n\t\t// A reset/reload must settle the active dialog before disposing its component.\n\t\tthis.activeExtensionDialogCancel?.();\n\t\tthis.activeExtensionDialogCancel = undefined;\n\t\tif (this.extensionSelector) {\n\t\t\tthis.hideExtensionSelector();\n\t\t}\n\t\tif (this.extensionInput) {\n\t\t\tthis.hideExtensionInput();\n\t\t}\n\t\tif (this.extensionEditor) {\n\t\t\tthis.hideExtensionEditor();\n\t\t}\n\t\tthis.ui.tui.hideOverlay();\n\t\tthis.clearExtensionTerminalInputListeners();\n\t\tthis.setExtensionFooter(undefined);\n\t\tthis.setExtensionHeader(undefined);\n\t\tthis.clearExtensionWidgets();\n\t\tthis.ui.footerDataProvider.clearExtensionStatuses();\n\t\tthis.ui.footer.invalidate();\n\t\tthis.ui.resetAutocompleteProviderWrappers();\n\t\tthis.setCustomEditorComponent(undefined);\n\t\tthis.ui.setupAutocompleteProvider();\n\t\tthis.ui.defaultEditor.onExtensionShortcut = undefined;\n\t\tthis.ui.updateTerminalTitle();\n\t\tthis.ui.resetWorkingIndicators();\n\t}\n\n\t/**\n\t * Render all extension widgets to the widget container.\n\t */\n\trenderWidgets(): void {\n\t\tif (!this.ui.widgetContainerAbove || !this.ui.widgetContainerBelow) return;\n\t\tthis.renderWidgetContainer(\n\t\t\tthis.ui.widgetContainerAbove,\n\t\t\t[this.hostWidgetsAbove, this.extensionWidgetsAbove],\n\t\t\ttrue,\n\t\t\ttrue,\n\t\t);\n\t\tthis.renderWidgetContainer(\n\t\t\tthis.ui.widgetContainerBelow,\n\t\t\t[this.hostWidgetsBelow, this.extensionWidgetsBelow],\n\t\t\tfalse,\n\t\t\tfalse,\n\t\t);\n\t\tthis.ui.tui.requestRender();\n\t}\n\n\tprivate renderWidgetContainer(\n\t\tcontainer: Container,\n\t\twidgetGroups: readonly Map<string, DisposableComponent>[],\n\t\tspacerWhenEmpty: boolean,\n\t\tleadingSpacer: boolean,\n\t): void {\n\t\tcontainer.clear();\n\n\t\tif (widgetGroups.every((widgets) => widgets.size === 0)) {\n\t\t\tif (spacerWhenEmpty) {\n\t\t\t\tcontainer.addChild(new Spacer(1));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (leadingSpacer) {\n\t\t\tcontainer.addChild(new Spacer(1));\n\t\t}\n\t\tfor (const widgets of widgetGroups) {\n\t\t\tfor (const component of widgets.values()) {\n\t\t\t\tcontainer.addChild(component);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Set a custom footer component, or restore the built-in footer.\n\t */\n\tprivate setExtensionFooter(\n\t\tfactory:\n\t\t\t| ((tui: TUI, thm: Theme, footerData: ReadonlyFooterDataProvider) => Component & { dispose?(): void })\n\t\t\t| undefined,\n\t): void {\n\t\t// Dispose existing custom footer\n\t\tif (this.customFooter?.dispose) {\n\t\t\tthis.customFooter.dispose();\n\t\t}\n\n\t\t// Remove current footer from UI\n\t\tif (this.customFooter) {\n\t\t\tthis.ui.tui.removeChild(this.customFooter);\n\t\t} else {\n\t\t\tthis.ui.tui.removeChild(this.ui.footer);\n\t\t}\n\n\t\tif (factory) {\n\t\t\t// Create and add custom footer, passing the data provider\n\t\t\tthis.customFooter = factory(this.ui.tui, theme, this.ui.footerDataProvider);\n\t\t\tthis.ui.tui.addChild(this.customFooter);\n\t\t} else {\n\t\t\t// Restore built-in footer\n\t\t\tthis.customFooter = undefined;\n\t\t\tthis.ui.tui.addChild(this.ui.footer);\n\t\t}\n\n\t\tthis.ui.tui.requestRender();\n\t}\n\n\t/**\n\t * Set a custom header component, or restore the built-in header.\n\t */\n\tprivate setExtensionHeader(factory: ((tui: TUI, thm: Theme) => Component & { dispose?(): void }) | undefined): void {\n\t\t// Header may not be initialized yet if called during early initialization\n\t\tconst builtInHeader = this.ui.getBuiltInHeader();\n\t\tif (!builtInHeader) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Dispose existing custom header\n\t\tif (this.customHeader?.dispose) {\n\t\t\tthis.customHeader.dispose();\n\t\t}\n\n\t\t// Find the index of the current header in the header container\n\t\tconst currentHeader = this.customHeader || builtInHeader;\n\t\tconst index = this.ui.headerContainer.children.indexOf(currentHeader);\n\n\t\tif (factory) {\n\t\t\t// Create and add custom header\n\t\t\tthis.customHeader = factory(this.ui.tui, theme);\n\t\t\tif (isExpandable(this.customHeader)) {\n\t\t\t\tthis.customHeader.setExpanded(this.ui.getToolsExpanded());\n\t\t\t}\n\t\t\tif (index !== -1) {\n\t\t\t\tthis.ui.headerContainer.children[index] = this.customHeader;\n\t\t\t} else {\n\t\t\t\t// If not found (e.g. builtInHeader was never added), add at the top\n\t\t\t\tthis.ui.headerContainer.children.unshift(this.customHeader);\n\t\t\t}\n\t\t} else {\n\t\t\t// Restore built-in header\n\t\t\tthis.customHeader = undefined;\n\t\t\tif (isExpandable(builtInHeader)) {\n\t\t\t\tbuiltInHeader.setExpanded(this.ui.getToolsExpanded());\n\t\t\t}\n\t\t\tif (index !== -1) {\n\t\t\t\tthis.ui.headerContainer.children[index] = builtInHeader;\n\t\t\t}\n\t\t}\n\n\t\tthis.ui.tui.requestRender();\n\t}\n\n\tprivate addExtensionTerminalInputListener(\n\t\thandler: (data: string) => { consume?: boolean; data?: string } | undefined,\n\t): () => void {\n\t\tconst unsubscribe = this.ui.tui.addInputListener(handler);\n\t\tthis.extensionTerminalInputUnsubscribers.add(unsubscribe);\n\t\treturn () => {\n\t\t\tunsubscribe();\n\t\t\tthis.extensionTerminalInputUnsubscribers.delete(unsubscribe);\n\t\t};\n\t}\n\n\tclearExtensionTerminalInputListeners(): void {\n\t\tfor (const unsubscribe of this.extensionTerminalInputUnsubscribers) {\n\t\t\tunsubscribe();\n\t\t}\n\t\tthis.extensionTerminalInputUnsubscribers.clear();\n\t}\n\n\t/**\n\t * Create the ExtensionUIContext for extensions.\n\t */\n\tcreateExtensionUIContext(): ExtensionUIContext {\n\t\treturn {\n\t\t\taskQuestions: (request, opts) => this.showHumanInput(request, opts),\n\t\t\tselect: (title, options, opts) => this.showExtensionSelector(title, options, opts),\n\t\t\tconfirm: (title, message, opts) => this.showExtensionConfirm(title, message, opts),\n\t\t\tinput: (title, placeholder, opts) => this.showExtensionInput(title, placeholder, opts),\n\t\t\tnotify: (message, type) => this.showExtensionNotify(message, type),\n\t\t\tonTerminalInput: (handler) => this.addExtensionTerminalInputListener(handler),\n\t\t\tsetStatus: (key, text) => this.setExtensionStatus(key, text),\n\t\t\tsetWorkingMessage: (message) => this.ui.setWorkingMessage(message),\n\t\t\tsetWorkingVisible: (visible) => this.ui.setWorkingVisible(visible),\n\t\t\tsetWorkingIndicator: (options) => this.ui.setWorkingIndicator(options),\n\t\t\tsetHiddenThinkingLabel: (label) => this.ui.setHiddenThinkingLabel(label),\n\t\t\tsetWidget: (key, content, options) => this.setExtensionWidget(key, content, options),\n\t\t\tsetFooter: (factory) => this.setExtensionFooter(factory),\n\t\t\tsetHeader: (factory) => this.setExtensionHeader(factory),\n\t\t\tsetTitle: (title) => this.ui.tui.terminal.setTitle(title),\n\t\t\tcustom: (factory, options) => this.showExtensionCustom(factory, options),\n\t\t\tpasteToEditor: (text) => this.ui.getEditor().handleInput(`\\x1b[200~${text}\\x1b[201~`),\n\t\t\tsetEditorText: (text) => this.ui.getEditor().setText(text),\n\t\t\tgetEditorText: () => this.ui.getEditor().getExpandedText?.() ?? this.ui.getEditor().getText(),\n\t\t\teditor: (title, prefill) => this.showExtensionEditor(title, prefill),\n\t\t\taddAutocompleteProvider: (factory) => {\n\t\t\t\tthis.ui.pushAutocompleteProviderWrapper(factory);\n\t\t\t\tthis.ui.setupAutocompleteProvider();\n\t\t\t},\n\t\t\tsetEditorComponent: (factory) => this.setCustomEditorComponent(factory),\n\t\t\tgetEditorComponent: () => this.editorComponentFactory,\n\t\t\tget theme() {\n\t\t\t\treturn theme;\n\t\t\t},\n\t\t\tgetAllThemes: () => getAvailableThemesWithPaths(),\n\t\t\tgetTheme: (name) => getThemeByName(name),\n\t\t\tsetTheme: (themeOrName) => {\n\t\t\t\tif (themeOrName instanceof Theme) {\n\t\t\t\t\tsetThemeInstance(themeOrName);\n\t\t\t\t\tthis.ui.tui.requestRender();\n\t\t\t\t\treturn { success: true };\n\t\t\t\t}\n\t\t\t\tconst result = setTheme(themeOrName, true);\n\t\t\t\tif (result.success) {\n\t\t\t\t\tif (this.session.settingsManager.getTheme() !== themeOrName) {\n\t\t\t\t\t\tthis.session.settingsManager.setTheme(themeOrName);\n\t\t\t\t\t}\n\t\t\t\t\tthis.ui.tui.requestRender();\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t},\n\t\t\tgetToolsExpanded: () => this.ui.getToolsExpanded(),\n\t\t\tsetToolsExpanded: (expanded) => this.ui.setToolsExpanded(expanded),\n\t\t};\n\t}\n\n\tprivate showHumanInput(\n\t\trequest: HumanInputPresentationRequest,\n\t\topts?: Pick<ExtensionUIDialogOptions, \"signal\">,\n\t): Promise<HumanInputPresentationResult> {\n\t\tif (opts?.signal?.aborted) {\n\t\t\treturn Promise.resolve({ answers: [], cancelled: true, reason: \"interrupted\", imageContents: [] });\n\t\t}\n\t\treturn this.showExtensionCustom<HumanInputPresentationResult>((tui, currentTheme, keybindings, done) => {\n\t\t\tlet onAbort: (() => void) | undefined;\n\t\t\tconst finish = (result: HumanInputPresentationResult) => {\n\t\t\t\tif (onAbort) opts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\tdone(result);\n\t\t\t};\n\t\t\tconst settings = this.session.settingsManager;\n\t\t\tconst modelCannotSeeImages = !request.acceptsImages;\n\t\t\tconst dialog = new AskQuestionDialog({\n\t\t\t\tquestions: request.questions,\n\t\t\t\ttheme: currentTheme,\n\t\t\t\tkeybindings,\n\t\t\t\trequestRender: () => tui.requestRender(),\n\t\t\t\tfinish,\n\t\t\t\tcreateAnswerEditor: () => new Editor(tui, getEditorTheme()),\n\t\t\t\tclipboard: {\n\t\t\t\t\tautoResizeImages: settings.getImageAutoResize(),\n\t\t\t\t\tblockImages: settings.getBlockImages() || modelCannotSeeImages,\n\t\t\t\t\tblockImagesReason: modelCannotSeeImages\n\t\t\t\t\t\t? \"The selected model does not accept image input. Switch to an image-capable model or route this inspection to a vision worker.\"\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\timageStore: this.ui.getClipboardImageStore(),\n\t\t\t\t},\n\t\t\t\tpasteClipboardImage: handleClipboardImagePaste,\n\t\t\t});\n\t\t\tonAbort = () => dialog.cancel(\"interrupted\");\n\t\t\topts?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\treturn dialog;\n\t\t}).catch(() => ({ answers: [], cancelled: true, reason: \"interrupted\", imageContents: [] }));\n\t}\n\n\t/**\n\t * Show a selector for extensions.\n\t */\n\tshowExtensionSelector(\n\t\ttitle: string,\n\t\toptions: string[],\n\t\topts?: ExtensionUIDialogOptions,\n\t): Promise<string | undefined> {\n\t\tif (opts?.signal?.aborted) return Promise.resolve(undefined);\n\t\t// Replacing an overlay without settling its promise strands the extension handler forever.\n\t\tthis.activeExtensionDialogCancel?.();\n\t\treturn new Promise((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tlet selector: ExtensionSelectorComponent;\n\t\t\tconst finish = (value: string | undefined, restoreEditor = true) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\topts?.signal?.removeEventListener(\"abort\", cancel);\n\t\t\t\tif (this.activeExtensionDialogCancel === cancel) {\n\t\t\t\t\tthis.activeExtensionDialogCancel = undefined;\n\t\t\t\t}\n\t\t\t\tthis.hideExtensionSelector(selector, restoreEditor);\n\t\t\t\tresolve(value);\n\t\t\t};\n\t\t\tconst cancel = () => finish(undefined);\n\n\t\t\tselector = new ExtensionSelectorComponent(title, options, (option) => finish(option), cancel, {\n\t\t\t\ttui: this.ui.tui,\n\t\t\t\ttimeout: opts?.timeout,\n\t\t\t\tonToggleToolsExpanded: () => this.ui.toggleToolsExpanded(),\n\t\t\t});\n\t\t\tthis.extensionSelector = selector;\n\t\t\tthis.activeExtensionDialogCancel = cancel;\n\t\t\tthis.ui.overlayHost.swap(selector, { onUnmount: () => finish(undefined, false) });\n\t\t\topts?.signal?.addEventListener(\"abort\", cancel, { once: true });\n\t\t});\n\t}\n\n\t/**\n\t * Hide the extension selector.\n\t */\n\tprivate hideExtensionSelector(selector = this.extensionSelector, restoreEditor = true): void {\n\t\tif (!selector) return;\n\t\tselector.dispose();\n\t\tif (this.extensionSelector !== selector) return;\n\t\tthis.extensionSelector = undefined;\n\t\tif (restoreEditor) this.ui.overlayHost.swap(this.ui.getEditor());\n\t}\n\n\t/**\n\t * Show a confirmation dialog for extensions.\n\t */\n\tasync showExtensionConfirm(title: string, message: string, opts?: ExtensionUIDialogOptions): Promise<boolean> {\n\t\tconst result = await this.showExtensionSelector(`${title}\\n${message}`, [\"Yes\", \"No\"], opts);\n\t\treturn result === \"Yes\";\n\t}\n\n\t/**\n\t * Show a text input for extensions.\n\t */\n\tprivate showExtensionInput(\n\t\ttitle: string,\n\t\tplaceholder?: string,\n\t\topts?: ExtensionUIDialogOptions,\n\t): Promise<string | undefined> {\n\t\tif (opts?.signal?.aborted) return Promise.resolve(undefined);\n\t\tthis.activeExtensionDialogCancel?.();\n\t\treturn new Promise((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tlet input: ExtensionInputComponent;\n\t\t\tconst finish = (value: string | undefined, restoreEditor = true) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\topts?.signal?.removeEventListener(\"abort\", cancel);\n\t\t\t\tif (this.activeExtensionDialogCancel === cancel) {\n\t\t\t\t\tthis.activeExtensionDialogCancel = undefined;\n\t\t\t\t}\n\t\t\t\tthis.hideExtensionInput(input, restoreEditor);\n\t\t\t\tresolve(value);\n\t\t\t};\n\t\t\tconst cancel = () => finish(undefined);\n\n\t\t\tinput = new ExtensionInputComponent(title, placeholder, (value) => finish(value), cancel, {\n\t\t\t\ttui: this.ui.tui,\n\t\t\t\ttimeout: opts?.timeout,\n\t\t\t});\n\t\t\tthis.extensionInput = input;\n\t\t\tthis.activeExtensionDialogCancel = cancel;\n\t\t\tthis.ui.overlayHost.swap(input, { onUnmount: () => finish(undefined, false) });\n\t\t\topts?.signal?.addEventListener(\"abort\", cancel, { once: true });\n\t\t});\n\t}\n\n\t/**\n\t * Hide the extension input.\n\t */\n\tprivate hideExtensionInput(input = this.extensionInput, restoreEditor = true): void {\n\t\tif (!input) return;\n\t\tinput.dispose();\n\t\tif (this.extensionInput !== input) return;\n\t\tthis.extensionInput = undefined;\n\t\tif (restoreEditor) this.ui.overlayHost.swap(this.ui.getEditor());\n\t}\n\n\t/**\n\t * Show a multi-line editor for extensions (with Ctrl+G support).\n\t */\n\tshowExtensionEditor(title: string, prefill?: string): Promise<string | undefined> {\n\t\tthis.activeExtensionDialogCancel?.();\n\t\treturn new Promise((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tlet editor: ExtensionEditorComponent;\n\t\t\tconst finish = (value: string | undefined, restoreEditor = true) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tif (this.activeExtensionDialogCancel === cancel) {\n\t\t\t\t\tthis.activeExtensionDialogCancel = undefined;\n\t\t\t\t}\n\t\t\t\tthis.hideExtensionEditor(editor, restoreEditor);\n\t\t\t\tresolve(value);\n\t\t\t};\n\t\t\tconst cancel = () => finish(undefined);\n\n\t\t\teditor = new ExtensionEditorComponent(\n\t\t\t\tthis.ui.tui,\n\t\t\t\tthis.ui.keybindings,\n\t\t\t\ttitle,\n\t\t\t\tprefill,\n\t\t\t\t(value) => finish(value),\n\t\t\t\tcancel,\n\t\t\t);\n\t\t\tthis.extensionEditor = editor;\n\t\t\tthis.activeExtensionDialogCancel = cancel;\n\t\t\tthis.ui.overlayHost.swap(editor, { onUnmount: () => finish(undefined, false) });\n\t\t});\n\t}\n\n\t/**\n\t * Hide the extension editor.\n\t */\n\tprivate hideExtensionEditor(editor = this.extensionEditor, restoreEditor = true): void {\n\t\tif (!editor || this.extensionEditor !== editor) return;\n\t\tthis.extensionEditor = undefined;\n\t\tif (restoreEditor) this.ui.overlayHost.swap(this.ui.getEditor());\n\t}\n\n\t/**\n\t * Set a custom editor component from an extension.\n\t * Pass undefined to restore the default editor.\n\t */\n\tprivate setCustomEditorComponent(factory: EditorFactory | undefined): void {\n\t\tthis.editorComponentFactory = factory;\n\n\t\t// Save text from current editor before switching\n\t\tconst currentText = this.ui.getEditor().getText();\n\n\t\tif (factory) {\n\t\t\t// Create the custom editor with tui, theme, and keybindings\n\t\t\tconst newEditor = factory(this.ui.tui, getEditorTheme(), this.ui.keybindings);\n\n\t\t\t// Wire up callbacks from the default editor\n\t\t\tnewEditor.onSubmit = this.ui.defaultEditor.onSubmit;\n\t\t\tnewEditor.onChange = this.ui.defaultEditor.onChange;\n\n\t\t\t// Copy text from previous editor\n\t\t\tnewEditor.setText(currentText);\n\n\t\t\t// Copy appearance settings if supported\n\t\t\tif (newEditor.borderColor !== undefined) {\n\t\t\t\tnewEditor.borderColor = this.ui.defaultEditor.borderColor;\n\t\t\t}\n\t\t\tif (newEditor.setPaddingX !== undefined) {\n\t\t\t\tnewEditor.setPaddingX(this.ui.defaultEditor.getPaddingX());\n\t\t\t}\n\n\t\t\t// Set autocomplete if supported\n\t\t\tconst autocompleteProvider = this.ui.getAutocompleteProvider();\n\t\t\tif (newEditor.setAutocompleteProvider && autocompleteProvider) {\n\t\t\t\tnewEditor.setAutocompleteProvider(autocompleteProvider);\n\t\t\t}\n\n\t\t\t// If extending CustomEditor, copy app-level handlers\n\t\t\t// Use duck typing since instanceof fails across jiti module boundaries\n\t\t\tconst customEditor = newEditor as unknown as Record<string, unknown>;\n\t\t\tif (\"actionHandlers\" in customEditor && customEditor.actionHandlers instanceof Map) {\n\t\t\t\tif (!customEditor.onEscape) {\n\t\t\t\t\tcustomEditor.onEscape = () => this.ui.defaultEditor.onEscape?.();\n\t\t\t\t}\n\t\t\t\tif (!customEditor.onCtrlD) {\n\t\t\t\t\tcustomEditor.onCtrlD = () => this.ui.defaultEditor.onCtrlD?.();\n\t\t\t\t}\n\t\t\t\tif (!customEditor.onPasteImage) {\n\t\t\t\t\tcustomEditor.onPasteImage = () => this.ui.defaultEditor.onPasteImage?.();\n\t\t\t\t}\n\t\t\t\tif (!customEditor.onExtensionShortcut) {\n\t\t\t\t\tcustomEditor.onExtensionShortcut = (data: string) => this.ui.defaultEditor.onExtensionShortcut?.(data);\n\t\t\t\t}\n\t\t\t\t// Copy action handlers (clear, suspend, model switching, etc.)\n\t\t\t\tfor (const [action, handler] of this.ui.defaultEditor.actionHandlers) {\n\t\t\t\t\t(customEditor.actionHandlers as Map<string, () => void>).set(action, handler);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.ui.setEditor(newEditor);\n\t\t} else {\n\t\t\t// Restore default editor with text from custom editor\n\t\t\tthis.ui.defaultEditor.setText(currentText);\n\t\t\tthis.ui.setEditor(this.ui.defaultEditor);\n\t\t}\n\n\t\tthis.ui.overlayHost.swap(this.ui.getEditor() as Component);\n\t}\n\n\t/**\n\t * Show a notification for extensions.\n\t */\n\tprivate showExtensionNotify(message: string, type?: \"info\" | \"warning\" | \"error\"): void {\n\t\tif (type === \"error\") {\n\t\t\tthis.ui.showError(message);\n\t\t} else if (type === \"warning\") {\n\t\t\tthis.ui.showWarning(message);\n\t\t} else {\n\t\t\tthis.ui.showStatus(message);\n\t\t}\n\t}\n\n\t/** Show a custom component with keyboard focus. Overlay mode renders on top of existing content. */\n\tprivate async showExtensionCustom<T>(\n\t\tfactory: (\n\t\t\ttui: TUI,\n\t\t\ttheme: Theme,\n\t\t\tkeybindings: KeybindingsManager,\n\t\t\tdone: (result: T) => void,\n\t\t) => (Component & { dispose?(): void }) | Promise<Component & { dispose?(): void }>,\n\t\toptions?: {\n\t\t\toverlay?: boolean;\n\t\t\toverlayOptions?: OverlayOptions | (() => OverlayOptions);\n\t\t\tonHandle?: (handle: OverlayHandle) => void;\n\t\t},\n\t): Promise<T> {\n\t\tthis.activeExtensionDialogCancel?.();\n\t\tconst savedText = this.ui.getEditor().getText();\n\t\tconst isOverlay = options?.overlay ?? false;\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tlet component: (Component & { dispose?(): void }) | undefined;\n\t\t\tlet overlayHandle: OverlayHandle | undefined;\n\t\t\tlet closed = false;\n\t\t\tlet cancel: () => void;\n\t\t\tconst dispose = (candidate: (Component & { dispose?(): void }) | undefined) => {\n\t\t\t\ttry {\n\t\t\t\t\tcandidate?.dispose?.();\n\t\t\t\t} catch {\n\t\t\t\t\t/* ignore dispose errors */\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst restore = (restoreEditor = true) => {\n\t\t\t\tif (this.activeExtensionDialogCancel !== cancel) return;\n\t\t\t\tthis.activeExtensionDialogCancel = undefined;\n\t\t\t\tif (isOverlay) {\n\t\t\t\t\toverlayHandle?.hide();\n\t\t\t\t} else if (restoreEditor) {\n\t\t\t\t\tthis.ui.getEditor().setText(savedText);\n\t\t\t\t\tthis.ui.overlayHost.swap(this.ui.getEditor(), { focusMode: \"restore\" });\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst close = (result: T) => {\n\t\t\t\tif (closed) return;\n\t\t\t\tclosed = true;\n\t\t\t\tdispose(component);\n\t\t\t\trestore();\n\t\t\t\tresolve(result);\n\t\t\t};\n\t\t\tconst fail = (error: unknown, restoreEditor = true) => {\n\t\t\t\tif (closed) return;\n\t\t\t\tclosed = true;\n\t\t\t\tdispose(component);\n\t\t\t\trestore(restoreEditor);\n\t\t\t\treject(error);\n\t\t\t};\n\t\t\tcancel = () => fail(new Error(\"Extension UI request was superseded or reset\"));\n\t\t\tthis.activeExtensionDialogCancel = cancel;\n\t\t\tlet mountingComponent = false;\n\t\t\tconst onUnmount = () => {\n\t\t\t\tif (!mountingComponent) fail(new Error(\"Extension UI request was superseded or reset\"), false);\n\t\t\t};\n\t\t\tif (!isOverlay) {\n\t\t\t\tthis.ui.overlayHost.swap(this.ui.getEditor(), {\n\t\t\t\t\tfocusMode: \"restore\",\n\t\t\t\t\trender: \"none\",\n\t\t\t\t\tonUnmount,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tPromise.resolve()\n\t\t\t\t.then(() => (closed ? undefined : factory(this.ui.tui, theme, this.ui.keybindings, close)))\n\t\t\t\t.then((createdComponent) => {\n\t\t\t\t\tif (!createdComponent) return;\n\t\t\t\t\tcomponent = createdComponent;\n\t\t\t\t\tif (closed) {\n\t\t\t\t\t\tdispose(component);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (isOverlay) {\n\t\t\t\t\t\tconst resolvedOptions =\n\t\t\t\t\t\t\ttypeof options?.overlayOptions === \"function\" ? options.overlayOptions() : options?.overlayOptions;\n\t\t\t\t\t\tconst width = (component as { width?: number }).width;\n\t\t\t\t\t\toverlayHandle = this.ui.tui.showOverlay(\n\t\t\t\t\t\t\tcomponent,\n\t\t\t\t\t\t\tresolvedOptions ?? (width ? { width } : undefined),\n\t\t\t\t\t\t);\n\t\t\t\t\t\toptions?.onHandle?.(overlayHandle);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tmountingComponent = true;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tthis.ui.overlayHost.swap(component, { onUnmount });\n\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\tmountingComponent = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(fail);\n\t\t});\n\t}\n\n\t/**\n\t * Show an extension error in the UI.\n\t */\n\tshowExtensionError(extensionPath: string, error: string, stack?: string): void {\n\t\tconst errorMsg = `Extension \"${extensionPath}\" error: ${error}`;\n\t\tconst errorText = new Text(theme.fg(\"error\", errorMsg), 1, 0);\n\t\tthis.ui.chatContainer.addChild(errorText);\n\t\tif (stack) {\n\t\t\t// Show stack trace in dim color, indented\n\t\t\tconst stackLines = stack\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.slice(1) // Skip first line (duplicates error message)\n\t\t\t\t.map((line) => theme.fg(\"dim\", ` ${line.trim()}`))\n\t\t\t\t.join(\"\\n\");\n\t\t\tif (stackLines) {\n\t\t\t\tthis.ui.chatContainer.addChild(new Text(stackLines, 1, 0));\n\t\t\t}\n\t\t}\n\t\tthis.ui.tui.requestRender();\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"extension-ui-host.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/extension-ui-host.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EACX,oBAAoB,EACpB,SAAS,EACT,eAAe,EAEf,sBAAsB,EAGtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAoC,KAAK,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAC3F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EACX,2BAA2B,EAG3B,eAAe,EACf,kBAAkB,EAClB,wBAAwB,EAExB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,kBAAkB,EAA8B,MAAM,oCAAoC,CAAC;AAEzG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAG3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAIlE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAoBlE;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;IAClB,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;IACxC,QAAQ,CAAC,WAAW,EAAE,kBAAkB,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;IAChD,QAAQ,CAAC,eAAe,EAAE,SAAS,CAAC;IACpC,QAAQ,CAAC,aAAa,EAAE,SAAS,CAAC;IAClC,QAAQ,CAAC,aAAa,EAAE,YAAY,CAAC;IACrC,QAAQ,CAAC,oBAAoB,EAAE,SAAS,CAAC;IACzC,QAAQ,CAAC,oBAAoB,EAAE,SAAS,CAAC;IAEzC,SAAS,IAAI,eAAe,CAAC;IAC7B,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IACzC,gBAAgB,IAAI,SAAS,GAAG,SAAS,CAAC;IAC1C,uBAAuB,IAAI,oBAAoB,GAAG,SAAS,CAAC;IAC5D,sBAAsB,IAAI,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACvE,gBAAgB,IAAI,OAAO,CAAC;IAC5B,+BAA+B,CAAC,OAAO,EAAE,2BAA2B,GAAG,IAAI,CAAC;IAC5E,iCAAiC,IAAI,IAAI,CAAC;IAE1C,yBAAyB,IAAI,IAAI,CAAC;IAClC,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1C,mBAAmB,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC5D,sBAAsB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IACrD,sBAAsB,IAAI,IAAI,CAAC;IAC/B,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1C,mBAAmB,IAAI,IAAI,CAAC;IAC5B,mBAAmB,IAAI,IAAI,CAAC;IAC5B,qBAAqB,IAAI,IAAI,CAAC;IAC9B,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,mBAAmB;IACnC,UAAU,IAAI,YAAY,CAAC;IAC3B,EAAE,EAAE,iBAAiB,CAAC;CACtB;AAED,KAAK,mBAAmB,GAAG,SAAS,GAAG;IAAE,OAAO,CAAC,IAAI,IAAI,CAAA;CAAE,CAAC;AAC5D,KAAK,eAAe,GAAG,aAAa,GAAG,aAAa,CAAC;AAErD,qBAAa,eAAe;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAsB;IAG3C,OAAO,CAAC,iBAAiB,CAAqD;IAC9E,OAAO,CAAC,cAAc,CAAkD;IACxE,OAAO,CAAC,eAAe,CAAmD;IAC1E,0FAA0F;IAC1F,OAAO,CAAC,2BAA2B,CAA2B;IAC9D,OAAO,CAAC,mCAAmC,CAAyB;IAGpE,OAAO,CAAC,qBAAqB,CAAuD;IACpF,OAAO,CAAC,qBAAqB,CAAuD;IAEpF,OAAO,CAAC,gBAAgB,CAA0C;IAClE,OAAO,CAAC,gBAAgB,CAA0C;IAGlE,OAAO,CAAC,YAAY,CAA6D;IAGjF,OAAO,CAAC,YAAY,CAA6D;IAGjF,OAAO,CAAC,sBAAsB,CAA4B;IAE1D,YAAY,IAAI,EAAE,mBAAmB,EAEpC;IAED,OAAO,KAAK,OAAO,GAElB;IACD,OAAO,KAAK,EAAE,GAEb;IAED,mEAAmE;IACnE,eAAe,IAAI,CAAC,SAAS,GAAG;QAAE,OAAO,CAAC,IAAI,IAAI,CAAA;KAAE,CAAC,GAAG,SAAS,CAEhE;IAED;;OAEG;IACH,uBAAuB,CAAC,eAAe,EAAE,eAAe,GAAG,IAAI,CAsD9D;IAED;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAM;IAE9C,OAAO,CAAC,YAAY;IAMpB,oFAAoF;IACpF,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,mBAAmB,GAAG,SAAS,EAAE,SAAS,EAAE,eAAe,GAAG,IAAI,CAQvG;IAED,gBAAgB,IAAI,IAAI,CAMvB;IAED;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAoC1B,OAAO,CAAC,qBAAqB;IAY7B,gBAAgB,IAAI,IAAI,CA0BvB;IAED;;OAEG;IACH,aAAa,IAAI,IAAI,CAepB;IAED,OAAO,CAAC,qBAAqB;IAyB7B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA8B1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA0C1B,OAAO,CAAC,iCAAiC;IAWzC,oCAAoC,IAAI,IAAI,CAK3C;IAED;;OAEG;IACH,wBAAwB,IAAI,kBAAkB,CAmD7C;IAED,OAAO,CAAC,cAAc;IAsCtB;;OAEG;IACH,qBAAqB,CACpB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EAAE,EACjB,IAAI,CAAC,EAAE,wBAAwB,GAC7B,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA6B7B;IAED;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAQ7B;;OAEG;IACG,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC,OAAO,CAAC,CAG5G;IAED;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAkC1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAQ1B;;OAEG;IACH,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA4BhF;IAED;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAM3B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IA+DhC;;OAEG;IACH,OAAO,CAAC,mBAAmB;YAWb,mBAAmB;IAkGjC;;OAEG;IACH,kBAAkB,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAgB7E;CACD","sourcesContent":["/**\n * Extension UI host.\n *\n * Extracted verbatim from interactive-mode.ts (god-file decomposition). Owns the interactive-mode\n * surface of the extension UI API: extension-provided dialogs (selector / confirm / input / multi-line\n * editor / custom component), widget mounting above and below the editor, extension status text, custom\n * footer and header swaps, the custom editor-component swap, keyboard-shortcut wiring, terminal-input\n * listeners, and the `ExtensionUIContext` handed to extensions. It owns exactly the state this cluster\n * mutates (the live dialog components, the widget maps, the terminal-input unsubscribers, the custom\n * footer/header, and the current custom-editor factory) and reaches everything else — the mutable\n * `editor`, the render-core containers, the working-indicator, autocomplete wiring, theme/tools state —\n * through a narrow deps/ui surface rather than the whole InteractiveMode instance. Extensions must see\n * identical behavior, so the render-core operations (working indicator, hidden-thinking label,\n * autocomplete rebuild) stay host-side and are invoked here as delegations.\n */\n\nimport type {\n\tAutocompleteProvider,\n\tComponent,\n\tEditorComponent,\n\tKeyId,\n\tLoaderIndicatorOptions,\n\tOverlayHandle,\n\tOverlayOptions,\n} from \"@caupulican/pi-tui\";\nimport { Container, Editor, matchesKey, Spacer, Text, type TUI } from \"@caupulican/pi-tui\";\nimport type { AgentSession } from \"../../core/agent-session.ts\";\nimport type {\n\tAutocompleteProviderFactory,\n\tEditorFactory,\n\tExtensionContext,\n\tExtensionRunner,\n\tExtensionUIContext,\n\tExtensionUIDialogOptions,\n\tExtensionWidgetOptions,\n} from \"../../core/extensions/index.ts\";\nimport type { FooterDataProvider, ReadonlyFooterDataProvider } from \"../../core/footer-data-provider.ts\";\nimport type { HumanInputPresentationRequest, HumanInputPresentationResult } from \"../../core/human-input.ts\";\nimport type { KeybindingsManager } from \"../../core/keybindings.ts\";\nimport type { SessionImageStore } from \"../../core/session-image-store.ts\";\nimport { AskQuestionDialog } from \"../../core/tools/ask-question.ts\";\nimport { handleClipboardImagePaste } from \"./clipboard-input.ts\";\nimport type { CustomEditor } from \"./components/custom-editor.ts\";\nimport { ExtensionEditorComponent } from \"./components/extension-editor.ts\";\nimport { ExtensionInputComponent } from \"./components/extension-input.ts\";\nimport { ExtensionSelectorComponent } from \"./components/extension-selector.ts\";\nimport type { FooterComponent } from \"./components/footer.ts\";\nimport type { EditorOverlayHost } from \"./editor-overlay-host.ts\";\nimport {\n\tgetAvailableThemesWithPaths,\n\tgetEditorTheme,\n\tgetThemeByName,\n\tsetTheme,\n\tsetThemeInstance,\n\tTheme,\n\ttheme,\n} from \"./theme/theme.ts\";\n\n/** Components that can be expanded/collapsed (custom headers may opt in). */\ninterface Expandable {\n\tsetExpanded(expanded: boolean): void;\n}\n\nfunction isExpandable(obj: unknown): obj is Expandable {\n\treturn typeof obj === \"object\" && obj !== null && \"setExpanded\" in obj && typeof obj.setExpanded === \"function\";\n}\n\n/**\n * The narrow slice of InteractiveMode the extension UI host drives. Stable containers and the TUI are\n * passed directly; mutable render-core state (the active editor, built-in header, loading animation,\n * autocomplete wrappers, tools-expansion) is read/written through accessors so InteractiveMode keeps\n * ownership; and render-core / status operations stay host-side and are exposed here as callbacks.\n */\nexport interface ExtensionUiHostUi {\n\treadonly tui: TUI;\n\treadonly overlayHost: EditorOverlayHost;\n\treadonly keybindings: KeybindingsManager;\n\treadonly footer: FooterComponent;\n\treadonly footerDataProvider: FooterDataProvider;\n\treadonly headerContainer: Container;\n\treadonly chatContainer: Container;\n\treadonly defaultEditor: CustomEditor;\n\treadonly widgetContainerAbove: Container;\n\treadonly widgetContainerBelow: Container;\n\n\tgetEditor(): EditorComponent;\n\tsetEditor(editor: EditorComponent): void;\n\tgetBuiltInHeader(): Component | undefined;\n\tgetAutocompleteProvider(): AutocompleteProvider | undefined;\n\tgetClipboardImageStore(): Pick<SessionImageStore, \"write\"> | undefined;\n\tgetToolsExpanded(): boolean;\n\tpushAutocompleteProviderWrapper(factory: AutocompleteProviderFactory): void;\n\tresetAutocompleteProviderWrappers(): void;\n\n\tsetupAutocompleteProvider(): void;\n\tsetWorkingVisible(visible: boolean): void;\n\tsetWorkingIndicator(options?: LoaderIndicatorOptions): void;\n\tsetHiddenThinkingLabel(label?: string): void;\n\tsetWorkingMessage(message: string | undefined): void;\n\tresetWorkingIndicators(): void;\n\tsetToolsExpanded(expanded: boolean): void;\n\ttoggleToolsExpanded(): void;\n\tupdateTerminalTitle(): void;\n\tmarkShutdownRequested(): void;\n\tabort(): void;\n\treload(): Promise<void>;\n\tshowStatus(message: string): void;\n\tshowWarning(message: string): void;\n\tshowError(message: string): void;\n}\n\nexport interface ExtensionUiHostDeps {\n\tgetSession(): AgentSession;\n\tui: ExtensionUiHostUi;\n}\n\ntype DisposableComponent = Component & { dispose?(): void };\ntype WidgetPlacement = \"aboveEditor\" | \"belowEditor\";\n\nexport class ExtensionUiHost {\n\tprivate readonly deps: ExtensionUiHostDeps;\n\n\t// Extension UI state\n\tprivate extensionSelector: ExtensionSelectorComponent | undefined = undefined;\n\tprivate extensionInput: ExtensionInputComponent | undefined = undefined;\n\tprivate extensionEditor: ExtensionEditorComponent | undefined = undefined;\n\t/** Settles the mounted extension dialog before another dialog can replace its overlay. */\n\tprivate activeExtensionDialogCancel: (() => void) | undefined;\n\tprivate extensionTerminalInputUnsubscribers = new Set<() => void>();\n\n\t// Extension widgets (components rendered above/below the editor)\n\tprivate extensionWidgetsAbove = new Map<string, Component & { dispose?(): void }>();\n\tprivate extensionWidgetsBelow = new Map<string, Component & { dispose?(): void }>();\n\t// Host-owned widgets survive extension reloads and are cleared only by the owning interactive mode.\n\tprivate hostWidgetsAbove = new Map<string, DisposableComponent>();\n\tprivate hostWidgetsBelow = new Map<string, DisposableComponent>();\n\n\t// Custom footer from extension (undefined = use built-in footer)\n\tprivate customFooter: (Component & { dispose?(): void }) | undefined = undefined;\n\n\t// Custom header from extension (undefined = use built-in header)\n\tprivate customHeader: (Component & { dispose?(): void }) | undefined = undefined;\n\n\t// Current custom editor-component factory (undefined = default editor)\n\tprivate editorComponentFactory: EditorFactory | undefined;\n\n\tconstructor(deps: ExtensionUiHostDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\tprivate get session(): AgentSession {\n\t\treturn this.deps.getSession();\n\t}\n\tprivate get ui(): ExtensionUiHostUi {\n\t\treturn this.deps.ui;\n\t}\n\n\t/** The active custom header, if an extension has installed one. */\n\tgetCustomHeader(): (Component & { dispose?(): void }) | undefined {\n\t\treturn this.customHeader;\n\t}\n\n\t/**\n\t * Set up keyboard shortcuts registered by extensions.\n\t */\n\tsetupExtensionShortcuts(extensionRunner: ExtensionRunner): void {\n\t\tconst shortcuts = extensionRunner.getShortcuts(this.ui.keybindings.getEffectiveConfig());\n\t\tif (shortcuts.size === 0) return;\n\n\t\t// Create a context for shortcut handlers\n\t\tconst createContext = (): ExtensionContext => ({\n\t\t\tui: this.createExtensionUIContext(),\n\t\t\thasUI: true,\n\t\t\tmode: \"tui\",\n\t\t\tcwd: this.session.sessionManager.getCwd(),\n\t\t\tsessionManager: this.session.sessionManager,\n\t\t\tmodelRegistry: this.session.modelRegistry,\n\t\t\tmodel: this.session.model,\n\t\t\tisIdle: () => !this.session.isStreaming,\n\t\t\tsignal: this.session.agent.signal,\n\t\t\tabort: () => {\n\t\t\t\tthis.ui.abort();\n\t\t\t},\n\t\t\thasPendingMessages: () => this.session.pendingMessageCount > 0,\n\t\t\tshutdown: () => {\n\t\t\t\tthis.ui.markShutdownRequested();\n\t\t\t},\n\t\t\tgetContextUsage: () => this.session.getContextUsage(),\n\t\t\tcompact: (options) => {\n\t\t\t\tvoid (async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await this.session.compact(options?.customInstructions);\n\t\t\t\t\t\toptions?.onComplete?.(result);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tconst err = error instanceof Error ? error : new Error(String(error));\n\t\t\t\t\t\toptions?.onError?.(err);\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t},\n\t\t\treload: async () => {\n\t\t\t\tawait this.ui.reload();\n\t\t\t},\n\t\t\tgetSystemPrompt: () => this.session.systemPrompt,\n\t\t});\n\n\t\t// Set up the extension shortcut handler on the default editor\n\t\tthis.ui.defaultEditor.onExtensionShortcut = (data: string) => {\n\t\t\tfor (const [shortcutStr, shortcut] of shortcuts) {\n\t\t\t\t// Cast to KeyId - extension shortcuts use the same format\n\t\t\t\tif (matchesKey(data, shortcutStr as KeyId)) {\n\t\t\t\t\t// Run handler async, don't block input\n\t\t\t\t\tPromise.resolve(shortcut.handler(createContext())).catch((err) => {\n\t\t\t\t\t\tthis.ui.showError(`Shortcut handler error: ${err instanceof Error ? err.message : String(err)}`);\n\t\t\t\t\t});\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\t}\n\n\t/**\n\t * Set extension status text in the footer.\n\t */\n\tprivate setExtensionStatus(key: string, text: string | undefined): void {\n\t\tthis.ui.footerDataProvider.setExtensionStatus(key, text);\n\t\tthis.ui.tui.requestRender();\n\t}\n\n\t// Maximum total widget lines to prevent viewport overflow\n\tprivate static readonly MAX_WIDGET_LINES = 10;\n\n\tprivate removeWidget(map: Map<string, DisposableComponent>, key: string): void {\n\t\tconst existing = map.get(key);\n\t\texisting?.dispose?.();\n\t\tmap.delete(key);\n\t}\n\n\t/** Mount a native host widget without coupling it to extension reload lifecycle. */\n\tsetHostWidget(key: string, component: DisposableComponent | undefined, placement: WidgetPlacement): void {\n\t\tthis.removeWidget(this.hostWidgetsAbove, key);\n\t\tthis.removeWidget(this.hostWidgetsBelow, key);\n\t\tif (component) {\n\t\t\tconst target = placement === \"belowEditor\" ? this.hostWidgetsBelow : this.hostWidgetsAbove;\n\t\t\ttarget.set(key, component);\n\t\t}\n\t\tthis.renderWidgets();\n\t}\n\n\tclearHostWidgets(): void {\n\t\tfor (const widget of this.hostWidgetsAbove.values()) widget.dispose?.();\n\t\tfor (const widget of this.hostWidgetsBelow.values()) widget.dispose?.();\n\t\tthis.hostWidgetsAbove.clear();\n\t\tthis.hostWidgetsBelow.clear();\n\t\tthis.renderWidgets();\n\t}\n\n\t/**\n\t * Set an extension widget (string array or custom component).\n\t */\n\tprivate setExtensionWidget(\n\t\tkey: string,\n\t\tcontent: string[] | ((tui: TUI, thm: Theme) => Component & { dispose?(): void }) | undefined,\n\t\toptions?: ExtensionWidgetOptions,\n\t): void {\n\t\tconst placement = options?.placement ?? \"aboveEditor\";\n\t\tthis.removeWidget(this.extensionWidgetsAbove, key);\n\t\tthis.removeWidget(this.extensionWidgetsBelow, key);\n\n\t\tif (content === undefined) {\n\t\t\tthis.renderWidgets();\n\t\t\treturn;\n\t\t}\n\n\t\tlet component: Component & { dispose?(): void };\n\n\t\tif (Array.isArray(content)) {\n\t\t\t// Wrap string array in a Container with Text components\n\t\t\tconst container = new Container();\n\t\t\tfor (const line of content.slice(0, ExtensionUiHost.MAX_WIDGET_LINES)) {\n\t\t\t\tcontainer.addChild(new Text(line, 1, 0));\n\t\t\t}\n\t\t\tif (content.length > ExtensionUiHost.MAX_WIDGET_LINES) {\n\t\t\t\tcontainer.addChild(new Text(theme.fg(\"muted\", \"... (widget truncated)\"), 1, 0));\n\t\t\t}\n\t\t\tcomponent = container;\n\t\t} else {\n\t\t\t// Factory function - create component\n\t\t\tcomponent = content(this.ui.tui, theme);\n\t\t}\n\n\t\tconst targetMap = placement === \"belowEditor\" ? this.extensionWidgetsBelow : this.extensionWidgetsAbove;\n\t\ttargetMap.set(key, component);\n\t\tthis.renderWidgets();\n\t}\n\n\tprivate clearExtensionWidgets(): void {\n\t\tfor (const widget of this.extensionWidgetsAbove.values()) {\n\t\t\twidget.dispose?.();\n\t\t}\n\t\tfor (const widget of this.extensionWidgetsBelow.values()) {\n\t\t\twidget.dispose?.();\n\t\t}\n\t\tthis.extensionWidgetsAbove.clear();\n\t\tthis.extensionWidgetsBelow.clear();\n\t\tthis.renderWidgets();\n\t}\n\n\tresetExtensionUI(): void {\n\t\t// A reset/reload must settle the active dialog before disposing its component.\n\t\tthis.activeExtensionDialogCancel?.();\n\t\tthis.activeExtensionDialogCancel = undefined;\n\t\tif (this.extensionSelector) {\n\t\t\tthis.hideExtensionSelector();\n\t\t}\n\t\tif (this.extensionInput) {\n\t\t\tthis.hideExtensionInput();\n\t\t}\n\t\tif (this.extensionEditor) {\n\t\t\tthis.hideExtensionEditor();\n\t\t}\n\t\tthis.ui.tui.hideOverlay();\n\t\tthis.clearExtensionTerminalInputListeners();\n\t\tthis.setExtensionFooter(undefined);\n\t\tthis.setExtensionHeader(undefined);\n\t\tthis.clearExtensionWidgets();\n\t\tthis.ui.footerDataProvider.clearExtensionStatuses();\n\t\tthis.ui.footer.invalidate();\n\t\tthis.ui.resetAutocompleteProviderWrappers();\n\t\tthis.setCustomEditorComponent(undefined);\n\t\tthis.ui.setupAutocompleteProvider();\n\t\tthis.ui.defaultEditor.onExtensionShortcut = undefined;\n\t\tthis.ui.updateTerminalTitle();\n\t\tthis.ui.resetWorkingIndicators();\n\t}\n\n\t/**\n\t * Render all extension widgets to the widget container.\n\t */\n\trenderWidgets(): void {\n\t\tif (!this.ui.widgetContainerAbove || !this.ui.widgetContainerBelow) return;\n\t\tthis.renderWidgetContainer(\n\t\t\tthis.ui.widgetContainerAbove,\n\t\t\t[this.hostWidgetsAbove, this.extensionWidgetsAbove],\n\t\t\ttrue,\n\t\t\ttrue,\n\t\t);\n\t\tthis.renderWidgetContainer(\n\t\t\tthis.ui.widgetContainerBelow,\n\t\t\t[this.hostWidgetsBelow, this.extensionWidgetsBelow],\n\t\t\tfalse,\n\t\t\tfalse,\n\t\t);\n\t\tthis.ui.tui.requestRender();\n\t}\n\n\tprivate renderWidgetContainer(\n\t\tcontainer: Container,\n\t\twidgetGroups: readonly Map<string, DisposableComponent>[],\n\t\tspacerWhenEmpty: boolean,\n\t\tleadingSpacer: boolean,\n\t): void {\n\t\tcontainer.clear();\n\n\t\tif (widgetGroups.every((widgets) => widgets.size === 0)) {\n\t\t\tif (spacerWhenEmpty) {\n\t\t\t\tcontainer.addChild(new Spacer(1));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (leadingSpacer) {\n\t\t\tcontainer.addChild(new Spacer(1));\n\t\t}\n\t\tfor (const widgets of widgetGroups) {\n\t\t\tfor (const component of widgets.values()) {\n\t\t\t\tcontainer.addChild(component);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Set a custom footer component, or restore the built-in footer.\n\t */\n\tprivate setExtensionFooter(\n\t\tfactory:\n\t\t\t| ((tui: TUI, thm: Theme, footerData: ReadonlyFooterDataProvider) => Component & { dispose?(): void })\n\t\t\t| undefined,\n\t): void {\n\t\t// Dispose existing custom footer\n\t\tif (this.customFooter?.dispose) {\n\t\t\tthis.customFooter.dispose();\n\t\t}\n\n\t\t// Remove current footer from UI\n\t\tif (this.customFooter) {\n\t\t\tthis.ui.tui.removeChild(this.customFooter);\n\t\t} else {\n\t\t\tthis.ui.tui.removeChild(this.ui.footer);\n\t\t}\n\n\t\tif (factory) {\n\t\t\t// Create and add custom footer, passing the data provider\n\t\t\tthis.customFooter = factory(this.ui.tui, theme, this.ui.footerDataProvider);\n\t\t\tthis.ui.tui.addChild(this.customFooter);\n\t\t} else {\n\t\t\t// Restore built-in footer\n\t\t\tthis.customFooter = undefined;\n\t\t\tthis.ui.tui.addChild(this.ui.footer);\n\t\t}\n\n\t\tthis.ui.tui.requestRender();\n\t}\n\n\t/**\n\t * Set a custom header component, or restore the built-in header.\n\t */\n\tprivate setExtensionHeader(factory: ((tui: TUI, thm: Theme) => Component & { dispose?(): void }) | undefined): void {\n\t\t// Header may not be initialized yet if called during early initialization\n\t\tconst builtInHeader = this.ui.getBuiltInHeader();\n\t\tif (!builtInHeader) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Dispose existing custom header\n\t\tif (this.customHeader?.dispose) {\n\t\t\tthis.customHeader.dispose();\n\t\t}\n\n\t\t// Find the index of the current header in the header container\n\t\tconst currentHeader = this.customHeader || builtInHeader;\n\t\tconst index = this.ui.headerContainer.children.indexOf(currentHeader);\n\n\t\tif (factory) {\n\t\t\t// Create and add custom header\n\t\t\tthis.customHeader = factory(this.ui.tui, theme);\n\t\t\tif (isExpandable(this.customHeader)) {\n\t\t\t\tthis.customHeader.setExpanded(this.ui.getToolsExpanded());\n\t\t\t}\n\t\t\tif (index !== -1) {\n\t\t\t\tthis.ui.headerContainer.children[index] = this.customHeader;\n\t\t\t} else {\n\t\t\t\t// If not found (e.g. builtInHeader was never added), add at the top\n\t\t\t\tthis.ui.headerContainer.children.unshift(this.customHeader);\n\t\t\t}\n\t\t} else {\n\t\t\t// Restore built-in header\n\t\t\tthis.customHeader = undefined;\n\t\t\tif (isExpandable(builtInHeader)) {\n\t\t\t\tbuiltInHeader.setExpanded(this.ui.getToolsExpanded());\n\t\t\t}\n\t\t\tif (index !== -1) {\n\t\t\t\tthis.ui.headerContainer.children[index] = builtInHeader;\n\t\t\t}\n\t\t}\n\n\t\tthis.ui.tui.requestRender();\n\t}\n\n\tprivate addExtensionTerminalInputListener(\n\t\thandler: (data: string) => { consume?: boolean; data?: string } | undefined,\n\t): () => void {\n\t\tconst unsubscribe = this.ui.tui.addInputListener(handler);\n\t\tthis.extensionTerminalInputUnsubscribers.add(unsubscribe);\n\t\treturn () => {\n\t\t\tunsubscribe();\n\t\t\tthis.extensionTerminalInputUnsubscribers.delete(unsubscribe);\n\t\t};\n\t}\n\n\tclearExtensionTerminalInputListeners(): void {\n\t\tfor (const unsubscribe of this.extensionTerminalInputUnsubscribers) {\n\t\t\tunsubscribe();\n\t\t}\n\t\tthis.extensionTerminalInputUnsubscribers.clear();\n\t}\n\n\t/**\n\t * Create the ExtensionUIContext for extensions.\n\t */\n\tcreateExtensionUIContext(): ExtensionUIContext {\n\t\treturn {\n\t\t\taskQuestions: (request, opts) => this.showHumanInput(request, opts),\n\t\t\tselect: (title, options, opts) => this.showExtensionSelector(title, options, opts),\n\t\t\tconfirm: (title, message, opts) => this.showExtensionConfirm(title, message, opts),\n\t\t\tinput: (title, placeholder, opts) => this.showExtensionInput(title, placeholder, opts),\n\t\t\tnotify: (message, type) => this.showExtensionNotify(message, type),\n\t\t\tonTerminalInput: (handler) => this.addExtensionTerminalInputListener(handler),\n\t\t\tsetStatus: (key, text) => this.setExtensionStatus(key, text),\n\t\t\tsetWorkingMessage: (message) => this.ui.setWorkingMessage(message),\n\t\t\tsetWorkingVisible: (visible) => this.ui.setWorkingVisible(visible),\n\t\t\tsetWorkingIndicator: (options) => this.ui.setWorkingIndicator(options),\n\t\t\tsetHiddenThinkingLabel: (label) => this.ui.setHiddenThinkingLabel(label),\n\t\t\tsetWidget: (key, content, options) => this.setExtensionWidget(key, content, options),\n\t\t\tsetFooter: (factory) => this.setExtensionFooter(factory),\n\t\t\tsetHeader: (factory) => this.setExtensionHeader(factory),\n\t\t\tsetTitle: (title) => this.ui.tui.terminal.setTitle(title),\n\t\t\tcustom: (factory, options) => this.showExtensionCustom(factory, options),\n\t\t\tpasteToEditor: (text) => this.ui.getEditor().handleInput(`\\x1b[200~${text}\\x1b[201~`),\n\t\t\tsetEditorText: (text) => this.ui.getEditor().setText(text),\n\t\t\tgetEditorText: () => this.ui.getEditor().getExpandedText?.() ?? this.ui.getEditor().getText(),\n\t\t\teditor: (title, prefill) => this.showExtensionEditor(title, prefill),\n\t\t\taddAutocompleteProvider: (factory) => {\n\t\t\t\tthis.ui.pushAutocompleteProviderWrapper(factory);\n\t\t\t\tthis.ui.setupAutocompleteProvider();\n\t\t\t},\n\t\t\tsetEditorComponent: (factory) => this.setCustomEditorComponent(factory),\n\t\t\tgetEditorComponent: () => this.editorComponentFactory,\n\t\t\tget theme() {\n\t\t\t\treturn theme;\n\t\t\t},\n\t\t\tgetAllThemes: () => getAvailableThemesWithPaths(),\n\t\t\tgetTheme: (name) => getThemeByName(name),\n\t\t\tsetTheme: (themeOrName) => {\n\t\t\t\tif (themeOrName instanceof Theme) {\n\t\t\t\t\tsetThemeInstance(themeOrName);\n\t\t\t\t\tthis.ui.tui.requestRender();\n\t\t\t\t\treturn { success: true };\n\t\t\t\t}\n\t\t\t\tconst result = setTheme(themeOrName, true);\n\t\t\t\tif (result.success) {\n\t\t\t\t\tif (this.session.settingsManager.getTheme() !== themeOrName) {\n\t\t\t\t\t\tthis.session.settingsManager.setTheme(themeOrName);\n\t\t\t\t\t}\n\t\t\t\t\tthis.ui.tui.requestRender();\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t},\n\t\t\tgetToolsExpanded: () => this.ui.getToolsExpanded(),\n\t\t\tsetToolsExpanded: (expanded) => this.ui.setToolsExpanded(expanded),\n\t\t};\n\t}\n\n\tprivate showHumanInput(\n\t\trequest: HumanInputPresentationRequest,\n\t\topts?: Pick<ExtensionUIDialogOptions, \"signal\">,\n\t): Promise<HumanInputPresentationResult> {\n\t\tif (opts?.signal?.aborted) {\n\t\t\treturn Promise.resolve({ answers: [], cancelled: true, reason: \"interrupted\", imageContents: [] });\n\t\t}\n\t\treturn this.showExtensionCustom<HumanInputPresentationResult>((tui, currentTheme, keybindings, done) => {\n\t\t\tlet onAbort: (() => void) | undefined;\n\t\t\tconst finish = (result: HumanInputPresentationResult) => {\n\t\t\t\tif (onAbort) opts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\tdone(result);\n\t\t\t};\n\t\t\tconst settings = this.session.settingsManager;\n\t\t\tconst modelCannotSeeImages = !request.acceptsImages;\n\t\t\tconst dialog = new AskQuestionDialog({\n\t\t\t\tquestions: request.questions,\n\t\t\t\ttheme: currentTheme,\n\t\t\t\tkeybindings,\n\t\t\t\trequestRender: () => tui.requestRender(),\n\t\t\t\tfinish,\n\t\t\t\tcreateAnswerEditor: () => new Editor(tui, getEditorTheme()),\n\t\t\t\tclipboard: {\n\t\t\t\t\tautoResizeImages: settings.getImageAutoResize(),\n\t\t\t\t\tblockImages: settings.getBlockImages() || modelCannotSeeImages,\n\t\t\t\t\tblockImagesReason: modelCannotSeeImages\n\t\t\t\t\t\t? \"The selected model does not accept image input. Switch to an image-capable model or route this inspection to a vision worker.\"\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\timageStore: this.ui.getClipboardImageStore(),\n\t\t\t\t},\n\t\t\t\tpasteClipboardImage: handleClipboardImagePaste,\n\t\t\t});\n\t\t\tonAbort = () => dialog.cancel(\"interrupted\");\n\t\t\topts?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\treturn dialog;\n\t\t}).catch(() => ({ answers: [], cancelled: true, reason: \"interrupted\", imageContents: [] }));\n\t}\n\n\t/**\n\t * Show a selector for extensions.\n\t */\n\tshowExtensionSelector(\n\t\ttitle: string,\n\t\toptions: string[],\n\t\topts?: ExtensionUIDialogOptions,\n\t): Promise<string | undefined> {\n\t\tif (opts?.signal?.aborted) return Promise.resolve(undefined);\n\t\t// Replacing an overlay without settling its promise strands the extension handler forever.\n\t\tthis.activeExtensionDialogCancel?.();\n\t\treturn new Promise((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tlet selector: ExtensionSelectorComponent;\n\t\t\tconst finish = (value: string | undefined, restoreEditor = true) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\topts?.signal?.removeEventListener(\"abort\", cancel);\n\t\t\t\tif (this.activeExtensionDialogCancel === cancel) {\n\t\t\t\t\tthis.activeExtensionDialogCancel = undefined;\n\t\t\t\t}\n\t\t\t\tthis.hideExtensionSelector(selector, restoreEditor);\n\t\t\t\tresolve(value);\n\t\t\t};\n\t\t\tconst cancel = () => finish(undefined);\n\n\t\t\tselector = new ExtensionSelectorComponent(title, options, (option) => finish(option), cancel, {\n\t\t\t\ttui: this.ui.tui,\n\t\t\t\ttimeout: opts?.timeout,\n\t\t\t\tonToggleToolsExpanded: () => this.ui.toggleToolsExpanded(),\n\t\t\t});\n\t\t\tthis.extensionSelector = selector;\n\t\t\tthis.activeExtensionDialogCancel = cancel;\n\t\t\tthis.ui.overlayHost.swap(selector, { onUnmount: () => finish(undefined, false) });\n\t\t\topts?.signal?.addEventListener(\"abort\", cancel, { once: true });\n\t\t});\n\t}\n\n\t/**\n\t * Hide the extension selector.\n\t */\n\tprivate hideExtensionSelector(selector = this.extensionSelector, restoreEditor = true): void {\n\t\tif (!selector) return;\n\t\tselector.dispose();\n\t\tif (this.extensionSelector !== selector) return;\n\t\tthis.extensionSelector = undefined;\n\t\tif (restoreEditor) this.ui.overlayHost.swap(this.ui.getEditor());\n\t}\n\n\t/**\n\t * Show a confirmation dialog for extensions.\n\t */\n\tasync showExtensionConfirm(title: string, message: string, opts?: ExtensionUIDialogOptions): Promise<boolean> {\n\t\tconst result = await this.showExtensionSelector(`${title}\\n${message}`, [\"Yes\", \"No\"], opts);\n\t\treturn result === \"Yes\";\n\t}\n\n\t/**\n\t * Show a text input for extensions.\n\t */\n\tprivate showExtensionInput(\n\t\ttitle: string,\n\t\tplaceholder?: string,\n\t\topts?: ExtensionUIDialogOptions,\n\t): Promise<string | undefined> {\n\t\tif (opts?.signal?.aborted) return Promise.resolve(undefined);\n\t\tthis.activeExtensionDialogCancel?.();\n\t\treturn new Promise((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tlet input: ExtensionInputComponent;\n\t\t\tconst finish = (value: string | undefined, restoreEditor = true) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\topts?.signal?.removeEventListener(\"abort\", cancel);\n\t\t\t\tif (this.activeExtensionDialogCancel === cancel) {\n\t\t\t\t\tthis.activeExtensionDialogCancel = undefined;\n\t\t\t\t}\n\t\t\t\tthis.hideExtensionInput(input, restoreEditor);\n\t\t\t\tresolve(value);\n\t\t\t};\n\t\t\tconst cancel = () => finish(undefined);\n\n\t\t\tinput = new ExtensionInputComponent(title, placeholder, (value) => finish(value), cancel, {\n\t\t\t\ttui: this.ui.tui,\n\t\t\t\ttimeout: opts?.timeout,\n\t\t\t\tsensitive: opts?.sensitive,\n\t\t\t});\n\t\t\tthis.extensionInput = input;\n\t\t\tthis.activeExtensionDialogCancel = cancel;\n\t\t\tthis.ui.overlayHost.swap(input, { onUnmount: () => finish(undefined, false) });\n\t\t\topts?.signal?.addEventListener(\"abort\", cancel, { once: true });\n\t\t});\n\t}\n\n\t/**\n\t * Hide the extension input.\n\t */\n\tprivate hideExtensionInput(input = this.extensionInput, restoreEditor = true): void {\n\t\tif (!input) return;\n\t\tinput.dispose();\n\t\tif (this.extensionInput !== input) return;\n\t\tthis.extensionInput = undefined;\n\t\tif (restoreEditor) this.ui.overlayHost.swap(this.ui.getEditor());\n\t}\n\n\t/**\n\t * Show a multi-line editor for extensions (with Ctrl+G support).\n\t */\n\tshowExtensionEditor(title: string, prefill?: string): Promise<string | undefined> {\n\t\tthis.activeExtensionDialogCancel?.();\n\t\treturn new Promise((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tlet editor: ExtensionEditorComponent;\n\t\t\tconst finish = (value: string | undefined, restoreEditor = true) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tif (this.activeExtensionDialogCancel === cancel) {\n\t\t\t\t\tthis.activeExtensionDialogCancel = undefined;\n\t\t\t\t}\n\t\t\t\tthis.hideExtensionEditor(editor, restoreEditor);\n\t\t\t\tresolve(value);\n\t\t\t};\n\t\t\tconst cancel = () => finish(undefined);\n\n\t\t\teditor = new ExtensionEditorComponent(\n\t\t\t\tthis.ui.tui,\n\t\t\t\tthis.ui.keybindings,\n\t\t\t\ttitle,\n\t\t\t\tprefill,\n\t\t\t\t(value) => finish(value),\n\t\t\t\tcancel,\n\t\t\t);\n\t\t\tthis.extensionEditor = editor;\n\t\t\tthis.activeExtensionDialogCancel = cancel;\n\t\t\tthis.ui.overlayHost.swap(editor, { onUnmount: () => finish(undefined, false) });\n\t\t});\n\t}\n\n\t/**\n\t * Hide the extension editor.\n\t */\n\tprivate hideExtensionEditor(editor = this.extensionEditor, restoreEditor = true): void {\n\t\tif (!editor || this.extensionEditor !== editor) return;\n\t\tthis.extensionEditor = undefined;\n\t\tif (restoreEditor) this.ui.overlayHost.swap(this.ui.getEditor());\n\t}\n\n\t/**\n\t * Set a custom editor component from an extension.\n\t * Pass undefined to restore the default editor.\n\t */\n\tprivate setCustomEditorComponent(factory: EditorFactory | undefined): void {\n\t\tthis.editorComponentFactory = factory;\n\n\t\t// Save text from current editor before switching\n\t\tconst currentText = this.ui.getEditor().getText();\n\n\t\tif (factory) {\n\t\t\t// Create the custom editor with tui, theme, and keybindings\n\t\t\tconst newEditor = factory(this.ui.tui, getEditorTheme(), this.ui.keybindings);\n\n\t\t\t// Wire up callbacks from the default editor\n\t\t\tnewEditor.onSubmit = this.ui.defaultEditor.onSubmit;\n\t\t\tnewEditor.onChange = this.ui.defaultEditor.onChange;\n\n\t\t\t// Copy text from previous editor\n\t\t\tnewEditor.setText(currentText);\n\n\t\t\t// Copy appearance settings if supported\n\t\t\tif (newEditor.borderColor !== undefined) {\n\t\t\t\tnewEditor.borderColor = this.ui.defaultEditor.borderColor;\n\t\t\t}\n\t\t\tif (newEditor.setPaddingX !== undefined) {\n\t\t\t\tnewEditor.setPaddingX(this.ui.defaultEditor.getPaddingX());\n\t\t\t}\n\n\t\t\t// Set autocomplete if supported\n\t\t\tconst autocompleteProvider = this.ui.getAutocompleteProvider();\n\t\t\tif (newEditor.setAutocompleteProvider && autocompleteProvider) {\n\t\t\t\tnewEditor.setAutocompleteProvider(autocompleteProvider);\n\t\t\t}\n\n\t\t\t// If extending CustomEditor, copy app-level handlers\n\t\t\t// Use duck typing since instanceof fails across jiti module boundaries\n\t\t\tconst customEditor = newEditor as unknown as Record<string, unknown>;\n\t\t\tif (\"actionHandlers\" in customEditor && customEditor.actionHandlers instanceof Map) {\n\t\t\t\tif (!customEditor.onEscape) {\n\t\t\t\t\tcustomEditor.onEscape = () => this.ui.defaultEditor.onEscape?.();\n\t\t\t\t}\n\t\t\t\tif (!customEditor.onCtrlD) {\n\t\t\t\t\tcustomEditor.onCtrlD = () => this.ui.defaultEditor.onCtrlD?.();\n\t\t\t\t}\n\t\t\t\tif (!customEditor.onPasteImage) {\n\t\t\t\t\tcustomEditor.onPasteImage = () => this.ui.defaultEditor.onPasteImage?.();\n\t\t\t\t}\n\t\t\t\tif (!customEditor.onExtensionShortcut) {\n\t\t\t\t\tcustomEditor.onExtensionShortcut = (data: string) => this.ui.defaultEditor.onExtensionShortcut?.(data);\n\t\t\t\t}\n\t\t\t\t// Copy action handlers (clear, suspend, model switching, etc.)\n\t\t\t\tfor (const [action, handler] of this.ui.defaultEditor.actionHandlers) {\n\t\t\t\t\t(customEditor.actionHandlers as Map<string, () => void>).set(action, handler);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.ui.setEditor(newEditor);\n\t\t} else {\n\t\t\t// Restore default editor with text from custom editor\n\t\t\tthis.ui.defaultEditor.setText(currentText);\n\t\t\tthis.ui.setEditor(this.ui.defaultEditor);\n\t\t}\n\n\t\tthis.ui.overlayHost.swap(this.ui.getEditor() as Component);\n\t}\n\n\t/**\n\t * Show a notification for extensions.\n\t */\n\tprivate showExtensionNotify(message: string, type?: \"info\" | \"warning\" | \"error\"): void {\n\t\tif (type === \"error\") {\n\t\t\tthis.ui.showError(message);\n\t\t} else if (type === \"warning\") {\n\t\t\tthis.ui.showWarning(message);\n\t\t} else {\n\t\t\tthis.ui.showStatus(message);\n\t\t}\n\t}\n\n\t/** Show a custom component with keyboard focus. Overlay mode renders on top of existing content. */\n\tprivate async showExtensionCustom<T>(\n\t\tfactory: (\n\t\t\ttui: TUI,\n\t\t\ttheme: Theme,\n\t\t\tkeybindings: KeybindingsManager,\n\t\t\tdone: (result: T) => void,\n\t\t) => (Component & { dispose?(): void }) | Promise<Component & { dispose?(): void }>,\n\t\toptions?: {\n\t\t\toverlay?: boolean;\n\t\t\toverlayOptions?: OverlayOptions | (() => OverlayOptions);\n\t\t\tonHandle?: (handle: OverlayHandle) => void;\n\t\t},\n\t): Promise<T> {\n\t\tthis.activeExtensionDialogCancel?.();\n\t\tconst savedText = this.ui.getEditor().getText();\n\t\tconst isOverlay = options?.overlay ?? false;\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tlet component: (Component & { dispose?(): void }) | undefined;\n\t\t\tlet overlayHandle: OverlayHandle | undefined;\n\t\t\tlet closed = false;\n\t\t\tlet cancel: () => void;\n\t\t\tconst dispose = (candidate: (Component & { dispose?(): void }) | undefined) => {\n\t\t\t\ttry {\n\t\t\t\t\tcandidate?.dispose?.();\n\t\t\t\t} catch {\n\t\t\t\t\t/* ignore dispose errors */\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst restore = (restoreEditor = true) => {\n\t\t\t\tif (this.activeExtensionDialogCancel !== cancel) return;\n\t\t\t\tthis.activeExtensionDialogCancel = undefined;\n\t\t\t\tif (isOverlay) {\n\t\t\t\t\toverlayHandle?.hide();\n\t\t\t\t} else if (restoreEditor) {\n\t\t\t\t\tthis.ui.getEditor().setText(savedText);\n\t\t\t\t\tthis.ui.overlayHost.swap(this.ui.getEditor(), { focusMode: \"restore\" });\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst close = (result: T) => {\n\t\t\t\tif (closed) return;\n\t\t\t\tclosed = true;\n\t\t\t\tdispose(component);\n\t\t\t\trestore();\n\t\t\t\tresolve(result);\n\t\t\t};\n\t\t\tconst fail = (error: unknown, restoreEditor = true) => {\n\t\t\t\tif (closed) return;\n\t\t\t\tclosed = true;\n\t\t\t\tdispose(component);\n\t\t\t\trestore(restoreEditor);\n\t\t\t\treject(error);\n\t\t\t};\n\t\t\tcancel = () => fail(new Error(\"Extension UI request was superseded or reset\"));\n\t\t\tthis.activeExtensionDialogCancel = cancel;\n\t\t\tlet mountingComponent = false;\n\t\t\tconst onUnmount = () => {\n\t\t\t\tif (!mountingComponent) fail(new Error(\"Extension UI request was superseded or reset\"), false);\n\t\t\t};\n\t\t\tif (!isOverlay) {\n\t\t\t\tthis.ui.overlayHost.swap(this.ui.getEditor(), {\n\t\t\t\t\tfocusMode: \"restore\",\n\t\t\t\t\trender: \"none\",\n\t\t\t\t\tonUnmount,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tPromise.resolve()\n\t\t\t\t.then(() => (closed ? undefined : factory(this.ui.tui, theme, this.ui.keybindings, close)))\n\t\t\t\t.then((createdComponent) => {\n\t\t\t\t\tif (!createdComponent) return;\n\t\t\t\t\tcomponent = createdComponent;\n\t\t\t\t\tif (closed) {\n\t\t\t\t\t\tdispose(component);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (isOverlay) {\n\t\t\t\t\t\tconst resolvedOptions =\n\t\t\t\t\t\t\ttypeof options?.overlayOptions === \"function\" ? options.overlayOptions() : options?.overlayOptions;\n\t\t\t\t\t\tconst width = (component as { width?: number }).width;\n\t\t\t\t\t\toverlayHandle = this.ui.tui.showOverlay(\n\t\t\t\t\t\t\tcomponent,\n\t\t\t\t\t\t\tresolvedOptions ?? (width ? { width } : undefined),\n\t\t\t\t\t\t);\n\t\t\t\t\t\toptions?.onHandle?.(overlayHandle);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tmountingComponent = true;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tthis.ui.overlayHost.swap(component, { onUnmount });\n\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\tmountingComponent = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(fail);\n\t\t});\n\t}\n\n\t/**\n\t * Show an extension error in the UI.\n\t */\n\tshowExtensionError(extensionPath: string, error: string, stack?: string): void {\n\t\tconst errorMsg = `Extension \"${extensionPath}\" error: ${error}`;\n\t\tconst errorText = new Text(theme.fg(\"error\", errorMsg), 1, 0);\n\t\tthis.ui.chatContainer.addChild(errorText);\n\t\tif (stack) {\n\t\t\t// Show stack trace in dim color, indented\n\t\t\tconst stackLines = stack\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.slice(1) // Skip first line (duplicates error message)\n\t\t\t\t.map((line) => theme.fg(\"dim\", ` ${line.trim()}`))\n\t\t\t\t.join(\"\\n\");\n\t\t\tif (stackLines) {\n\t\t\t\tthis.ui.chatContainer.addChild(new Text(stackLines, 1, 0));\n\t\t\t}\n\t\t}\n\t\tthis.ui.tui.requestRender();\n\t}\n}\n"]}
|
|
@@ -496,6 +496,7 @@ export class ExtensionUiHost {
|
|
|
496
496
|
input = new ExtensionInputComponent(title, placeholder, (value) => finish(value), cancel, {
|
|
497
497
|
tui: this.ui.tui,
|
|
498
498
|
timeout: opts?.timeout,
|
|
499
|
+
sensitive: opts?.sensitive,
|
|
499
500
|
});
|
|
500
501
|
this.extensionInput = input;
|
|
501
502
|
this.activeExtensionDialogCancel = cancel;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension-ui-host.js","sourceRoot":"","sources":["../../../src/modes/interactive/extension-ui-host.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Extension UI host.\n *\n * Extracted verbatim from interactive-mode.ts (god-file decomposition). Owns the interactive-mode\n * surface of the extension UI API: extension-provided dialogs (selector / confirm / input / multi-line\n * editor / custom component), widget mounting above and below the editor, extension status text, custom\n * footer and header swaps, the custom editor-component swap, keyboard-shortcut wiring, terminal-input\n * listeners, and the `ExtensionUIContext` handed to extensions. It owns exactly the state this cluster\n * mutates (the live dialog components, the widget maps, the terminal-input unsubscribers, the custom\n * footer/header, and the current custom-editor factory) and reaches everything else — the mutable\n * `editor`, the render-core containers, the working-indicator, autocomplete wiring, theme/tools state —\n * through a narrow deps/ui surface rather than the whole InteractiveMode instance. Extensions must see\n * identical behavior, so the render-core operations (working indicator, hidden-thinking label,\n * autocomplete rebuild) stay host-side and are invoked here as delegations.\n */\n\nimport type {\n\tAutocompleteProvider,\n\tComponent,\n\tEditorComponent,\n\tKeyId,\n\tLoaderIndicatorOptions,\n\tOverlayHandle,\n\tOverlayOptions,\n} from \"@caupulican/pi-tui\";\nimport { Container, Editor, matchesKey, Spacer, Text, type TUI } from \"@caupulican/pi-tui\";\nimport type { AgentSession } from \"../../core/agent-session.ts\";\nimport type {\n\tAutocompleteProviderFactory,\n\tEditorFactory,\n\tExtensionContext,\n\tExtensionRunner,\n\tExtensionUIContext,\n\tExtensionUIDialogOptions,\n\tExtensionWidgetOptions,\n} from \"../../core/extensions/index.ts\";\nimport type { FooterDataProvider, ReadonlyFooterDataProvider } from \"../../core/footer-data-provider.ts\";\nimport type { HumanInputPresentationRequest, HumanInputPresentationResult } from \"../../core/human-input.ts\";\nimport type { KeybindingsManager } from \"../../core/keybindings.ts\";\nimport type { SessionImageStore } from \"../../core/session-image-store.ts\";\nimport { AskQuestionDialog } from \"../../core/tools/ask-question.ts\";\nimport { handleClipboardImagePaste } from \"./clipboard-input.ts\";\nimport type { CustomEditor } from \"./components/custom-editor.ts\";\nimport { ExtensionEditorComponent } from \"./components/extension-editor.ts\";\nimport { ExtensionInputComponent } from \"./components/extension-input.ts\";\nimport { ExtensionSelectorComponent } from \"./components/extension-selector.ts\";\nimport type { FooterComponent } from \"./components/footer.ts\";\nimport type { EditorOverlayHost } from \"./editor-overlay-host.ts\";\nimport {\n\tgetAvailableThemesWithPaths,\n\tgetEditorTheme,\n\tgetThemeByName,\n\tsetTheme,\n\tsetThemeInstance,\n\tTheme,\n\ttheme,\n} from \"./theme/theme.ts\";\n\n/** Components that can be expanded/collapsed (custom headers may opt in). */\ninterface Expandable {\n\tsetExpanded(expanded: boolean): void;\n}\n\nfunction isExpandable(obj: unknown): obj is Expandable {\n\treturn typeof obj === \"object\" && obj !== null && \"setExpanded\" in obj && typeof obj.setExpanded === \"function\";\n}\n\n/**\n * The narrow slice of InteractiveMode the extension UI host drives. Stable containers and the TUI are\n * passed directly; mutable render-core state (the active editor, built-in header, loading animation,\n * autocomplete wrappers, tools-expansion) is read/written through accessors so InteractiveMode keeps\n * ownership; and render-core / status operations stay host-side and are exposed here as callbacks.\n */\nexport interface ExtensionUiHostUi {\n\treadonly tui: TUI;\n\treadonly overlayHost: EditorOverlayHost;\n\treadonly keybindings: KeybindingsManager;\n\treadonly footer: FooterComponent;\n\treadonly footerDataProvider: FooterDataProvider;\n\treadonly headerContainer: Container;\n\treadonly chatContainer: Container;\n\treadonly defaultEditor: CustomEditor;\n\treadonly widgetContainerAbove: Container;\n\treadonly widgetContainerBelow: Container;\n\n\tgetEditor(): EditorComponent;\n\tsetEditor(editor: EditorComponent): void;\n\tgetBuiltInHeader(): Component | undefined;\n\tgetAutocompleteProvider(): AutocompleteProvider | undefined;\n\tgetClipboardImageStore(): Pick<SessionImageStore, \"write\"> | undefined;\n\tgetToolsExpanded(): boolean;\n\tpushAutocompleteProviderWrapper(factory: AutocompleteProviderFactory): void;\n\tresetAutocompleteProviderWrappers(): void;\n\n\tsetupAutocompleteProvider(): void;\n\tsetWorkingVisible(visible: boolean): void;\n\tsetWorkingIndicator(options?: LoaderIndicatorOptions): void;\n\tsetHiddenThinkingLabel(label?: string): void;\n\tsetWorkingMessage(message: string | undefined): void;\n\tresetWorkingIndicators(): void;\n\tsetToolsExpanded(expanded: boolean): void;\n\ttoggleToolsExpanded(): void;\n\tupdateTerminalTitle(): void;\n\tmarkShutdownRequested(): void;\n\tabort(): void;\n\treload(): Promise<void>;\n\tshowStatus(message: string): void;\n\tshowWarning(message: string): void;\n\tshowError(message: string): void;\n}\n\nexport interface ExtensionUiHostDeps {\n\tgetSession(): AgentSession;\n\tui: ExtensionUiHostUi;\n}\n\ntype DisposableComponent = Component & { dispose?(): void };\ntype WidgetPlacement = \"aboveEditor\" | \"belowEditor\";\n\nexport class ExtensionUiHost {\n\tprivate readonly deps: ExtensionUiHostDeps;\n\n\t// Extension UI state\n\tprivate extensionSelector: ExtensionSelectorComponent | undefined = undefined;\n\tprivate extensionInput: ExtensionInputComponent | undefined = undefined;\n\tprivate extensionEditor: ExtensionEditorComponent | undefined = undefined;\n\t/** Settles the mounted extension dialog before another dialog can replace its overlay. */\n\tprivate activeExtensionDialogCancel: (() => void) | undefined;\n\tprivate extensionTerminalInputUnsubscribers = new Set<() => void>();\n\n\t// Extension widgets (components rendered above/below the editor)\n\tprivate extensionWidgetsAbove = new Map<string, Component & { dispose?(): void }>();\n\tprivate extensionWidgetsBelow = new Map<string, Component & { dispose?(): void }>();\n\t// Host-owned widgets survive extension reloads and are cleared only by the owning interactive mode.\n\tprivate hostWidgetsAbove = new Map<string, DisposableComponent>();\n\tprivate hostWidgetsBelow = new Map<string, DisposableComponent>();\n\n\t// Custom footer from extension (undefined = use built-in footer)\n\tprivate customFooter: (Component & { dispose?(): void }) | undefined = undefined;\n\n\t// Custom header from extension (undefined = use built-in header)\n\tprivate customHeader: (Component & { dispose?(): void }) | undefined = undefined;\n\n\t// Current custom editor-component factory (undefined = default editor)\n\tprivate editorComponentFactory: EditorFactory | undefined;\n\n\tconstructor(deps: ExtensionUiHostDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\tprivate get session(): AgentSession {\n\t\treturn this.deps.getSession();\n\t}\n\tprivate get ui(): ExtensionUiHostUi {\n\t\treturn this.deps.ui;\n\t}\n\n\t/** The active custom header, if an extension has installed one. */\n\tgetCustomHeader(): (Component & { dispose?(): void }) | undefined {\n\t\treturn this.customHeader;\n\t}\n\n\t/**\n\t * Set up keyboard shortcuts registered by extensions.\n\t */\n\tsetupExtensionShortcuts(extensionRunner: ExtensionRunner): void {\n\t\tconst shortcuts = extensionRunner.getShortcuts(this.ui.keybindings.getEffectiveConfig());\n\t\tif (shortcuts.size === 0) return;\n\n\t\t// Create a context for shortcut handlers\n\t\tconst createContext = (): ExtensionContext => ({\n\t\t\tui: this.createExtensionUIContext(),\n\t\t\thasUI: true,\n\t\t\tmode: \"tui\",\n\t\t\tcwd: this.session.sessionManager.getCwd(),\n\t\t\tsessionManager: this.session.sessionManager,\n\t\t\tmodelRegistry: this.session.modelRegistry,\n\t\t\tmodel: this.session.model,\n\t\t\tisIdle: () => !this.session.isStreaming,\n\t\t\tsignal: this.session.agent.signal,\n\t\t\tabort: () => {\n\t\t\t\tthis.ui.abort();\n\t\t\t},\n\t\t\thasPendingMessages: () => this.session.pendingMessageCount > 0,\n\t\t\tshutdown: () => {\n\t\t\t\tthis.ui.markShutdownRequested();\n\t\t\t},\n\t\t\tgetContextUsage: () => this.session.getContextUsage(),\n\t\t\tcompact: (options) => {\n\t\t\t\tvoid (async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await this.session.compact(options?.customInstructions);\n\t\t\t\t\t\toptions?.onComplete?.(result);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tconst err = error instanceof Error ? error : new Error(String(error));\n\t\t\t\t\t\toptions?.onError?.(err);\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t},\n\t\t\treload: async () => {\n\t\t\t\tawait this.ui.reload();\n\t\t\t},\n\t\t\tgetSystemPrompt: () => this.session.systemPrompt,\n\t\t});\n\n\t\t// Set up the extension shortcut handler on the default editor\n\t\tthis.ui.defaultEditor.onExtensionShortcut = (data: string) => {\n\t\t\tfor (const [shortcutStr, shortcut] of shortcuts) {\n\t\t\t\t// Cast to KeyId - extension shortcuts use the same format\n\t\t\t\tif (matchesKey(data, shortcutStr as KeyId)) {\n\t\t\t\t\t// Run handler async, don't block input\n\t\t\t\t\tPromise.resolve(shortcut.handler(createContext())).catch((err) => {\n\t\t\t\t\t\tthis.ui.showError(`Shortcut handler error: ${err instanceof Error ? err.message : String(err)}`);\n\t\t\t\t\t});\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\t}\n\n\t/**\n\t * Set extension status text in the footer.\n\t */\n\tprivate setExtensionStatus(key: string, text: string | undefined): void {\n\t\tthis.ui.footerDataProvider.setExtensionStatus(key, text);\n\t\tthis.ui.tui.requestRender();\n\t}\n\n\t// Maximum total widget lines to prevent viewport overflow\n\tprivate static readonly MAX_WIDGET_LINES = 10;\n\n\tprivate removeWidget(map: Map<string, DisposableComponent>, key: string): void {\n\t\tconst existing = map.get(key);\n\t\texisting?.dispose?.();\n\t\tmap.delete(key);\n\t}\n\n\t/** Mount a native host widget without coupling it to extension reload lifecycle. */\n\tsetHostWidget(key: string, component: DisposableComponent | undefined, placement: WidgetPlacement): void {\n\t\tthis.removeWidget(this.hostWidgetsAbove, key);\n\t\tthis.removeWidget(this.hostWidgetsBelow, key);\n\t\tif (component) {\n\t\t\tconst target = placement === \"belowEditor\" ? this.hostWidgetsBelow : this.hostWidgetsAbove;\n\t\t\ttarget.set(key, component);\n\t\t}\n\t\tthis.renderWidgets();\n\t}\n\n\tclearHostWidgets(): void {\n\t\tfor (const widget of this.hostWidgetsAbove.values()) widget.dispose?.();\n\t\tfor (const widget of this.hostWidgetsBelow.values()) widget.dispose?.();\n\t\tthis.hostWidgetsAbove.clear();\n\t\tthis.hostWidgetsBelow.clear();\n\t\tthis.renderWidgets();\n\t}\n\n\t/**\n\t * Set an extension widget (string array or custom component).\n\t */\n\tprivate setExtensionWidget(\n\t\tkey: string,\n\t\tcontent: string[] | ((tui: TUI, thm: Theme) => Component & { dispose?(): void }) | undefined,\n\t\toptions?: ExtensionWidgetOptions,\n\t): void {\n\t\tconst placement = options?.placement ?? \"aboveEditor\";\n\t\tthis.removeWidget(this.extensionWidgetsAbove, key);\n\t\tthis.removeWidget(this.extensionWidgetsBelow, key);\n\n\t\tif (content === undefined) {\n\t\t\tthis.renderWidgets();\n\t\t\treturn;\n\t\t}\n\n\t\tlet component: Component & { dispose?(): void };\n\n\t\tif (Array.isArray(content)) {\n\t\t\t// Wrap string array in a Container with Text components\n\t\t\tconst container = new Container();\n\t\t\tfor (const line of content.slice(0, ExtensionUiHost.MAX_WIDGET_LINES)) {\n\t\t\t\tcontainer.addChild(new Text(line, 1, 0));\n\t\t\t}\n\t\t\tif (content.length > ExtensionUiHost.MAX_WIDGET_LINES) {\n\t\t\t\tcontainer.addChild(new Text(theme.fg(\"muted\", \"... (widget truncated)\"), 1, 0));\n\t\t\t}\n\t\t\tcomponent = container;\n\t\t} else {\n\t\t\t// Factory function - create component\n\t\t\tcomponent = content(this.ui.tui, theme);\n\t\t}\n\n\t\tconst targetMap = placement === \"belowEditor\" ? this.extensionWidgetsBelow : this.extensionWidgetsAbove;\n\t\ttargetMap.set(key, component);\n\t\tthis.renderWidgets();\n\t}\n\n\tprivate clearExtensionWidgets(): void {\n\t\tfor (const widget of this.extensionWidgetsAbove.values()) {\n\t\t\twidget.dispose?.();\n\t\t}\n\t\tfor (const widget of this.extensionWidgetsBelow.values()) {\n\t\t\twidget.dispose?.();\n\t\t}\n\t\tthis.extensionWidgetsAbove.clear();\n\t\tthis.extensionWidgetsBelow.clear();\n\t\tthis.renderWidgets();\n\t}\n\n\tresetExtensionUI(): void {\n\t\t// A reset/reload must settle the active dialog before disposing its component.\n\t\tthis.activeExtensionDialogCancel?.();\n\t\tthis.activeExtensionDialogCancel = undefined;\n\t\tif (this.extensionSelector) {\n\t\t\tthis.hideExtensionSelector();\n\t\t}\n\t\tif (this.extensionInput) {\n\t\t\tthis.hideExtensionInput();\n\t\t}\n\t\tif (this.extensionEditor) {\n\t\t\tthis.hideExtensionEditor();\n\t\t}\n\t\tthis.ui.tui.hideOverlay();\n\t\tthis.clearExtensionTerminalInputListeners();\n\t\tthis.setExtensionFooter(undefined);\n\t\tthis.setExtensionHeader(undefined);\n\t\tthis.clearExtensionWidgets();\n\t\tthis.ui.footerDataProvider.clearExtensionStatuses();\n\t\tthis.ui.footer.invalidate();\n\t\tthis.ui.resetAutocompleteProviderWrappers();\n\t\tthis.setCustomEditorComponent(undefined);\n\t\tthis.ui.setupAutocompleteProvider();\n\t\tthis.ui.defaultEditor.onExtensionShortcut = undefined;\n\t\tthis.ui.updateTerminalTitle();\n\t\tthis.ui.resetWorkingIndicators();\n\t}\n\n\t/**\n\t * Render all extension widgets to the widget container.\n\t */\n\trenderWidgets(): void {\n\t\tif (!this.ui.widgetContainerAbove || !this.ui.widgetContainerBelow) return;\n\t\tthis.renderWidgetContainer(\n\t\t\tthis.ui.widgetContainerAbove,\n\t\t\t[this.hostWidgetsAbove, this.extensionWidgetsAbove],\n\t\t\ttrue,\n\t\t\ttrue,\n\t\t);\n\t\tthis.renderWidgetContainer(\n\t\t\tthis.ui.widgetContainerBelow,\n\t\t\t[this.hostWidgetsBelow, this.extensionWidgetsBelow],\n\t\t\tfalse,\n\t\t\tfalse,\n\t\t);\n\t\tthis.ui.tui.requestRender();\n\t}\n\n\tprivate renderWidgetContainer(\n\t\tcontainer: Container,\n\t\twidgetGroups: readonly Map<string, DisposableComponent>[],\n\t\tspacerWhenEmpty: boolean,\n\t\tleadingSpacer: boolean,\n\t): void {\n\t\tcontainer.clear();\n\n\t\tif (widgetGroups.every((widgets) => widgets.size === 0)) {\n\t\t\tif (spacerWhenEmpty) {\n\t\t\t\tcontainer.addChild(new Spacer(1));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (leadingSpacer) {\n\t\t\tcontainer.addChild(new Spacer(1));\n\t\t}\n\t\tfor (const widgets of widgetGroups) {\n\t\t\tfor (const component of widgets.values()) {\n\t\t\t\tcontainer.addChild(component);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Set a custom footer component, or restore the built-in footer.\n\t */\n\tprivate setExtensionFooter(\n\t\tfactory:\n\t\t\t| ((tui: TUI, thm: Theme, footerData: ReadonlyFooterDataProvider) => Component & { dispose?(): void })\n\t\t\t| undefined,\n\t): void {\n\t\t// Dispose existing custom footer\n\t\tif (this.customFooter?.dispose) {\n\t\t\tthis.customFooter.dispose();\n\t\t}\n\n\t\t// Remove current footer from UI\n\t\tif (this.customFooter) {\n\t\t\tthis.ui.tui.removeChild(this.customFooter);\n\t\t} else {\n\t\t\tthis.ui.tui.removeChild(this.ui.footer);\n\t\t}\n\n\t\tif (factory) {\n\t\t\t// Create and add custom footer, passing the data provider\n\t\t\tthis.customFooter = factory(this.ui.tui, theme, this.ui.footerDataProvider);\n\t\t\tthis.ui.tui.addChild(this.customFooter);\n\t\t} else {\n\t\t\t// Restore built-in footer\n\t\t\tthis.customFooter = undefined;\n\t\t\tthis.ui.tui.addChild(this.ui.footer);\n\t\t}\n\n\t\tthis.ui.tui.requestRender();\n\t}\n\n\t/**\n\t * Set a custom header component, or restore the built-in header.\n\t */\n\tprivate setExtensionHeader(factory: ((tui: TUI, thm: Theme) => Component & { dispose?(): void }) | undefined): void {\n\t\t// Header may not be initialized yet if called during early initialization\n\t\tconst builtInHeader = this.ui.getBuiltInHeader();\n\t\tif (!builtInHeader) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Dispose existing custom header\n\t\tif (this.customHeader?.dispose) {\n\t\t\tthis.customHeader.dispose();\n\t\t}\n\n\t\t// Find the index of the current header in the header container\n\t\tconst currentHeader = this.customHeader || builtInHeader;\n\t\tconst index = this.ui.headerContainer.children.indexOf(currentHeader);\n\n\t\tif (factory) {\n\t\t\t// Create and add custom header\n\t\t\tthis.customHeader = factory(this.ui.tui, theme);\n\t\t\tif (isExpandable(this.customHeader)) {\n\t\t\t\tthis.customHeader.setExpanded(this.ui.getToolsExpanded());\n\t\t\t}\n\t\t\tif (index !== -1) {\n\t\t\t\tthis.ui.headerContainer.children[index] = this.customHeader;\n\t\t\t} else {\n\t\t\t\t// If not found (e.g. builtInHeader was never added), add at the top\n\t\t\t\tthis.ui.headerContainer.children.unshift(this.customHeader);\n\t\t\t}\n\t\t} else {\n\t\t\t// Restore built-in header\n\t\t\tthis.customHeader = undefined;\n\t\t\tif (isExpandable(builtInHeader)) {\n\t\t\t\tbuiltInHeader.setExpanded(this.ui.getToolsExpanded());\n\t\t\t}\n\t\t\tif (index !== -1) {\n\t\t\t\tthis.ui.headerContainer.children[index] = builtInHeader;\n\t\t\t}\n\t\t}\n\n\t\tthis.ui.tui.requestRender();\n\t}\n\n\tprivate addExtensionTerminalInputListener(\n\t\thandler: (data: string) => { consume?: boolean; data?: string } | undefined,\n\t): () => void {\n\t\tconst unsubscribe = this.ui.tui.addInputListener(handler);\n\t\tthis.extensionTerminalInputUnsubscribers.add(unsubscribe);\n\t\treturn () => {\n\t\t\tunsubscribe();\n\t\t\tthis.extensionTerminalInputUnsubscribers.delete(unsubscribe);\n\t\t};\n\t}\n\n\tclearExtensionTerminalInputListeners(): void {\n\t\tfor (const unsubscribe of this.extensionTerminalInputUnsubscribers) {\n\t\t\tunsubscribe();\n\t\t}\n\t\tthis.extensionTerminalInputUnsubscribers.clear();\n\t}\n\n\t/**\n\t * Create the ExtensionUIContext for extensions.\n\t */\n\tcreateExtensionUIContext(): ExtensionUIContext {\n\t\treturn {\n\t\t\taskQuestions: (request, opts) => this.showHumanInput(request, opts),\n\t\t\tselect: (title, options, opts) => this.showExtensionSelector(title, options, opts),\n\t\t\tconfirm: (title, message, opts) => this.showExtensionConfirm(title, message, opts),\n\t\t\tinput: (title, placeholder, opts) => this.showExtensionInput(title, placeholder, opts),\n\t\t\tnotify: (message, type) => this.showExtensionNotify(message, type),\n\t\t\tonTerminalInput: (handler) => this.addExtensionTerminalInputListener(handler),\n\t\t\tsetStatus: (key, text) => this.setExtensionStatus(key, text),\n\t\t\tsetWorkingMessage: (message) => this.ui.setWorkingMessage(message),\n\t\t\tsetWorkingVisible: (visible) => this.ui.setWorkingVisible(visible),\n\t\t\tsetWorkingIndicator: (options) => this.ui.setWorkingIndicator(options),\n\t\t\tsetHiddenThinkingLabel: (label) => this.ui.setHiddenThinkingLabel(label),\n\t\t\tsetWidget: (key, content, options) => this.setExtensionWidget(key, content, options),\n\t\t\tsetFooter: (factory) => this.setExtensionFooter(factory),\n\t\t\tsetHeader: (factory) => this.setExtensionHeader(factory),\n\t\t\tsetTitle: (title) => this.ui.tui.terminal.setTitle(title),\n\t\t\tcustom: (factory, options) => this.showExtensionCustom(factory, options),\n\t\t\tpasteToEditor: (text) => this.ui.getEditor().handleInput(`\\x1b[200~${text}\\x1b[201~`),\n\t\t\tsetEditorText: (text) => this.ui.getEditor().setText(text),\n\t\t\tgetEditorText: () => this.ui.getEditor().getExpandedText?.() ?? this.ui.getEditor().getText(),\n\t\t\teditor: (title, prefill) => this.showExtensionEditor(title, prefill),\n\t\t\taddAutocompleteProvider: (factory) => {\n\t\t\t\tthis.ui.pushAutocompleteProviderWrapper(factory);\n\t\t\t\tthis.ui.setupAutocompleteProvider();\n\t\t\t},\n\t\t\tsetEditorComponent: (factory) => this.setCustomEditorComponent(factory),\n\t\t\tgetEditorComponent: () => this.editorComponentFactory,\n\t\t\tget theme() {\n\t\t\t\treturn theme;\n\t\t\t},\n\t\t\tgetAllThemes: () => getAvailableThemesWithPaths(),\n\t\t\tgetTheme: (name) => getThemeByName(name),\n\t\t\tsetTheme: (themeOrName) => {\n\t\t\t\tif (themeOrName instanceof Theme) {\n\t\t\t\t\tsetThemeInstance(themeOrName);\n\t\t\t\t\tthis.ui.tui.requestRender();\n\t\t\t\t\treturn { success: true };\n\t\t\t\t}\n\t\t\t\tconst result = setTheme(themeOrName, true);\n\t\t\t\tif (result.success) {\n\t\t\t\t\tif (this.session.settingsManager.getTheme() !== themeOrName) {\n\t\t\t\t\t\tthis.session.settingsManager.setTheme(themeOrName);\n\t\t\t\t\t}\n\t\t\t\t\tthis.ui.tui.requestRender();\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t},\n\t\t\tgetToolsExpanded: () => this.ui.getToolsExpanded(),\n\t\t\tsetToolsExpanded: (expanded) => this.ui.setToolsExpanded(expanded),\n\t\t};\n\t}\n\n\tprivate showHumanInput(\n\t\trequest: HumanInputPresentationRequest,\n\t\topts?: Pick<ExtensionUIDialogOptions, \"signal\">,\n\t): Promise<HumanInputPresentationResult> {\n\t\tif (opts?.signal?.aborted) {\n\t\t\treturn Promise.resolve({ answers: [], cancelled: true, reason: \"interrupted\", imageContents: [] });\n\t\t}\n\t\treturn this.showExtensionCustom<HumanInputPresentationResult>((tui, currentTheme, keybindings, done) => {\n\t\t\tlet onAbort: (() => void) | undefined;\n\t\t\tconst finish = (result: HumanInputPresentationResult) => {\n\t\t\t\tif (onAbort) opts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\tdone(result);\n\t\t\t};\n\t\t\tconst settings = this.session.settingsManager;\n\t\t\tconst modelCannotSeeImages = !request.acceptsImages;\n\t\t\tconst dialog = new AskQuestionDialog({\n\t\t\t\tquestions: request.questions,\n\t\t\t\ttheme: currentTheme,\n\t\t\t\tkeybindings,\n\t\t\t\trequestRender: () => tui.requestRender(),\n\t\t\t\tfinish,\n\t\t\t\tcreateAnswerEditor: () => new Editor(tui, getEditorTheme()),\n\t\t\t\tclipboard: {\n\t\t\t\t\tautoResizeImages: settings.getImageAutoResize(),\n\t\t\t\t\tblockImages: settings.getBlockImages() || modelCannotSeeImages,\n\t\t\t\t\tblockImagesReason: modelCannotSeeImages\n\t\t\t\t\t\t? \"The selected model does not accept image input. Switch to an image-capable model or route this inspection to a vision worker.\"\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\timageStore: this.ui.getClipboardImageStore(),\n\t\t\t\t},\n\t\t\t\tpasteClipboardImage: handleClipboardImagePaste,\n\t\t\t});\n\t\t\tonAbort = () => dialog.cancel(\"interrupted\");\n\t\t\topts?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\treturn dialog;\n\t\t}).catch(() => ({ answers: [], cancelled: true, reason: \"interrupted\", imageContents: [] }));\n\t}\n\n\t/**\n\t * Show a selector for extensions.\n\t */\n\tshowExtensionSelector(\n\t\ttitle: string,\n\t\toptions: string[],\n\t\topts?: ExtensionUIDialogOptions,\n\t): Promise<string | undefined> {\n\t\tif (opts?.signal?.aborted) return Promise.resolve(undefined);\n\t\t// Replacing an overlay without settling its promise strands the extension handler forever.\n\t\tthis.activeExtensionDialogCancel?.();\n\t\treturn new Promise((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tlet selector: ExtensionSelectorComponent;\n\t\t\tconst finish = (value: string | undefined, restoreEditor = true) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\topts?.signal?.removeEventListener(\"abort\", cancel);\n\t\t\t\tif (this.activeExtensionDialogCancel === cancel) {\n\t\t\t\t\tthis.activeExtensionDialogCancel = undefined;\n\t\t\t\t}\n\t\t\t\tthis.hideExtensionSelector(selector, restoreEditor);\n\t\t\t\tresolve(value);\n\t\t\t};\n\t\t\tconst cancel = () => finish(undefined);\n\n\t\t\tselector = new ExtensionSelectorComponent(title, options, (option) => finish(option), cancel, {\n\t\t\t\ttui: this.ui.tui,\n\t\t\t\ttimeout: opts?.timeout,\n\t\t\t\tonToggleToolsExpanded: () => this.ui.toggleToolsExpanded(),\n\t\t\t});\n\t\t\tthis.extensionSelector = selector;\n\t\t\tthis.activeExtensionDialogCancel = cancel;\n\t\t\tthis.ui.overlayHost.swap(selector, { onUnmount: () => finish(undefined, false) });\n\t\t\topts?.signal?.addEventListener(\"abort\", cancel, { once: true });\n\t\t});\n\t}\n\n\t/**\n\t * Hide the extension selector.\n\t */\n\tprivate hideExtensionSelector(selector = this.extensionSelector, restoreEditor = true): void {\n\t\tif (!selector) return;\n\t\tselector.dispose();\n\t\tif (this.extensionSelector !== selector) return;\n\t\tthis.extensionSelector = undefined;\n\t\tif (restoreEditor) this.ui.overlayHost.swap(this.ui.getEditor());\n\t}\n\n\t/**\n\t * Show a confirmation dialog for extensions.\n\t */\n\tasync showExtensionConfirm(title: string, message: string, opts?: ExtensionUIDialogOptions): Promise<boolean> {\n\t\tconst result = await this.showExtensionSelector(`${title}\\n${message}`, [\"Yes\", \"No\"], opts);\n\t\treturn result === \"Yes\";\n\t}\n\n\t/**\n\t * Show a text input for extensions.\n\t */\n\tprivate showExtensionInput(\n\t\ttitle: string,\n\t\tplaceholder?: string,\n\t\topts?: ExtensionUIDialogOptions,\n\t): Promise<string | undefined> {\n\t\tif (opts?.signal?.aborted) return Promise.resolve(undefined);\n\t\tthis.activeExtensionDialogCancel?.();\n\t\treturn new Promise((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tlet input: ExtensionInputComponent;\n\t\t\tconst finish = (value: string | undefined, restoreEditor = true) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\topts?.signal?.removeEventListener(\"abort\", cancel);\n\t\t\t\tif (this.activeExtensionDialogCancel === cancel) {\n\t\t\t\t\tthis.activeExtensionDialogCancel = undefined;\n\t\t\t\t}\n\t\t\t\tthis.hideExtensionInput(input, restoreEditor);\n\t\t\t\tresolve(value);\n\t\t\t};\n\t\t\tconst cancel = () => finish(undefined);\n\n\t\t\tinput = new ExtensionInputComponent(title, placeholder, (value) => finish(value), cancel, {\n\t\t\t\ttui: this.ui.tui,\n\t\t\t\ttimeout: opts?.timeout,\n\t\t\t});\n\t\t\tthis.extensionInput = input;\n\t\t\tthis.activeExtensionDialogCancel = cancel;\n\t\t\tthis.ui.overlayHost.swap(input, { onUnmount: () => finish(undefined, false) });\n\t\t\topts?.signal?.addEventListener(\"abort\", cancel, { once: true });\n\t\t});\n\t}\n\n\t/**\n\t * Hide the extension input.\n\t */\n\tprivate hideExtensionInput(input = this.extensionInput, restoreEditor = true): void {\n\t\tif (!input) return;\n\t\tinput.dispose();\n\t\tif (this.extensionInput !== input) return;\n\t\tthis.extensionInput = undefined;\n\t\tif (restoreEditor) this.ui.overlayHost.swap(this.ui.getEditor());\n\t}\n\n\t/**\n\t * Show a multi-line editor for extensions (with Ctrl+G support).\n\t */\n\tshowExtensionEditor(title: string, prefill?: string): Promise<string | undefined> {\n\t\tthis.activeExtensionDialogCancel?.();\n\t\treturn new Promise((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tlet editor: ExtensionEditorComponent;\n\t\t\tconst finish = (value: string | undefined, restoreEditor = true) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tif (this.activeExtensionDialogCancel === cancel) {\n\t\t\t\t\tthis.activeExtensionDialogCancel = undefined;\n\t\t\t\t}\n\t\t\t\tthis.hideExtensionEditor(editor, restoreEditor);\n\t\t\t\tresolve(value);\n\t\t\t};\n\t\t\tconst cancel = () => finish(undefined);\n\n\t\t\teditor = new ExtensionEditorComponent(\n\t\t\t\tthis.ui.tui,\n\t\t\t\tthis.ui.keybindings,\n\t\t\t\ttitle,\n\t\t\t\tprefill,\n\t\t\t\t(value) => finish(value),\n\t\t\t\tcancel,\n\t\t\t);\n\t\t\tthis.extensionEditor = editor;\n\t\t\tthis.activeExtensionDialogCancel = cancel;\n\t\t\tthis.ui.overlayHost.swap(editor, { onUnmount: () => finish(undefined, false) });\n\t\t});\n\t}\n\n\t/**\n\t * Hide the extension editor.\n\t */\n\tprivate hideExtensionEditor(editor = this.extensionEditor, restoreEditor = true): void {\n\t\tif (!editor || this.extensionEditor !== editor) return;\n\t\tthis.extensionEditor = undefined;\n\t\tif (restoreEditor) this.ui.overlayHost.swap(this.ui.getEditor());\n\t}\n\n\t/**\n\t * Set a custom editor component from an extension.\n\t * Pass undefined to restore the default editor.\n\t */\n\tprivate setCustomEditorComponent(factory: EditorFactory | undefined): void {\n\t\tthis.editorComponentFactory = factory;\n\n\t\t// Save text from current editor before switching\n\t\tconst currentText = this.ui.getEditor().getText();\n\n\t\tif (factory) {\n\t\t\t// Create the custom editor with tui, theme, and keybindings\n\t\t\tconst newEditor = factory(this.ui.tui, getEditorTheme(), this.ui.keybindings);\n\n\t\t\t// Wire up callbacks from the default editor\n\t\t\tnewEditor.onSubmit = this.ui.defaultEditor.onSubmit;\n\t\t\tnewEditor.onChange = this.ui.defaultEditor.onChange;\n\n\t\t\t// Copy text from previous editor\n\t\t\tnewEditor.setText(currentText);\n\n\t\t\t// Copy appearance settings if supported\n\t\t\tif (newEditor.borderColor !== undefined) {\n\t\t\t\tnewEditor.borderColor = this.ui.defaultEditor.borderColor;\n\t\t\t}\n\t\t\tif (newEditor.setPaddingX !== undefined) {\n\t\t\t\tnewEditor.setPaddingX(this.ui.defaultEditor.getPaddingX());\n\t\t\t}\n\n\t\t\t// Set autocomplete if supported\n\t\t\tconst autocompleteProvider = this.ui.getAutocompleteProvider();\n\t\t\tif (newEditor.setAutocompleteProvider && autocompleteProvider) {\n\t\t\t\tnewEditor.setAutocompleteProvider(autocompleteProvider);\n\t\t\t}\n\n\t\t\t// If extending CustomEditor, copy app-level handlers\n\t\t\t// Use duck typing since instanceof fails across jiti module boundaries\n\t\t\tconst customEditor = newEditor as unknown as Record<string, unknown>;\n\t\t\tif (\"actionHandlers\" in customEditor && customEditor.actionHandlers instanceof Map) {\n\t\t\t\tif (!customEditor.onEscape) {\n\t\t\t\t\tcustomEditor.onEscape = () => this.ui.defaultEditor.onEscape?.();\n\t\t\t\t}\n\t\t\t\tif (!customEditor.onCtrlD) {\n\t\t\t\t\tcustomEditor.onCtrlD = () => this.ui.defaultEditor.onCtrlD?.();\n\t\t\t\t}\n\t\t\t\tif (!customEditor.onPasteImage) {\n\t\t\t\t\tcustomEditor.onPasteImage = () => this.ui.defaultEditor.onPasteImage?.();\n\t\t\t\t}\n\t\t\t\tif (!customEditor.onExtensionShortcut) {\n\t\t\t\t\tcustomEditor.onExtensionShortcut = (data: string) => this.ui.defaultEditor.onExtensionShortcut?.(data);\n\t\t\t\t}\n\t\t\t\t// Copy action handlers (clear, suspend, model switching, etc.)\n\t\t\t\tfor (const [action, handler] of this.ui.defaultEditor.actionHandlers) {\n\t\t\t\t\t(customEditor.actionHandlers as Map<string, () => void>).set(action, handler);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.ui.setEditor(newEditor);\n\t\t} else {\n\t\t\t// Restore default editor with text from custom editor\n\t\t\tthis.ui.defaultEditor.setText(currentText);\n\t\t\tthis.ui.setEditor(this.ui.defaultEditor);\n\t\t}\n\n\t\tthis.ui.overlayHost.swap(this.ui.getEditor() as Component);\n\t}\n\n\t/**\n\t * Show a notification for extensions.\n\t */\n\tprivate showExtensionNotify(message: string, type?: \"info\" | \"warning\" | \"error\"): void {\n\t\tif (type === \"error\") {\n\t\t\tthis.ui.showError(message);\n\t\t} else if (type === \"warning\") {\n\t\t\tthis.ui.showWarning(message);\n\t\t} else {\n\t\t\tthis.ui.showStatus(message);\n\t\t}\n\t}\n\n\t/** Show a custom component with keyboard focus. Overlay mode renders on top of existing content. */\n\tprivate async showExtensionCustom<T>(\n\t\tfactory: (\n\t\t\ttui: TUI,\n\t\t\ttheme: Theme,\n\t\t\tkeybindings: KeybindingsManager,\n\t\t\tdone: (result: T) => void,\n\t\t) => (Component & { dispose?(): void }) | Promise<Component & { dispose?(): void }>,\n\t\toptions?: {\n\t\t\toverlay?: boolean;\n\t\t\toverlayOptions?: OverlayOptions | (() => OverlayOptions);\n\t\t\tonHandle?: (handle: OverlayHandle) => void;\n\t\t},\n\t): Promise<T> {\n\t\tthis.activeExtensionDialogCancel?.();\n\t\tconst savedText = this.ui.getEditor().getText();\n\t\tconst isOverlay = options?.overlay ?? false;\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tlet component: (Component & { dispose?(): void }) | undefined;\n\t\t\tlet overlayHandle: OverlayHandle | undefined;\n\t\t\tlet closed = false;\n\t\t\tlet cancel: () => void;\n\t\t\tconst dispose = (candidate: (Component & { dispose?(): void }) | undefined) => {\n\t\t\t\ttry {\n\t\t\t\t\tcandidate?.dispose?.();\n\t\t\t\t} catch {\n\t\t\t\t\t/* ignore dispose errors */\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst restore = (restoreEditor = true) => {\n\t\t\t\tif (this.activeExtensionDialogCancel !== cancel) return;\n\t\t\t\tthis.activeExtensionDialogCancel = undefined;\n\t\t\t\tif (isOverlay) {\n\t\t\t\t\toverlayHandle?.hide();\n\t\t\t\t} else if (restoreEditor) {\n\t\t\t\t\tthis.ui.getEditor().setText(savedText);\n\t\t\t\t\tthis.ui.overlayHost.swap(this.ui.getEditor(), { focusMode: \"restore\" });\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst close = (result: T) => {\n\t\t\t\tif (closed) return;\n\t\t\t\tclosed = true;\n\t\t\t\tdispose(component);\n\t\t\t\trestore();\n\t\t\t\tresolve(result);\n\t\t\t};\n\t\t\tconst fail = (error: unknown, restoreEditor = true) => {\n\t\t\t\tif (closed) return;\n\t\t\t\tclosed = true;\n\t\t\t\tdispose(component);\n\t\t\t\trestore(restoreEditor);\n\t\t\t\treject(error);\n\t\t\t};\n\t\t\tcancel = () => fail(new Error(\"Extension UI request was superseded or reset\"));\n\t\t\tthis.activeExtensionDialogCancel = cancel;\n\t\t\tlet mountingComponent = false;\n\t\t\tconst onUnmount = () => {\n\t\t\t\tif (!mountingComponent) fail(new Error(\"Extension UI request was superseded or reset\"), false);\n\t\t\t};\n\t\t\tif (!isOverlay) {\n\t\t\t\tthis.ui.overlayHost.swap(this.ui.getEditor(), {\n\t\t\t\t\tfocusMode: \"restore\",\n\t\t\t\t\trender: \"none\",\n\t\t\t\t\tonUnmount,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tPromise.resolve()\n\t\t\t\t.then(() => (closed ? undefined : factory(this.ui.tui, theme, this.ui.keybindings, close)))\n\t\t\t\t.then((createdComponent) => {\n\t\t\t\t\tif (!createdComponent) return;\n\t\t\t\t\tcomponent = createdComponent;\n\t\t\t\t\tif (closed) {\n\t\t\t\t\t\tdispose(component);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (isOverlay) {\n\t\t\t\t\t\tconst resolvedOptions =\n\t\t\t\t\t\t\ttypeof options?.overlayOptions === \"function\" ? options.overlayOptions() : options?.overlayOptions;\n\t\t\t\t\t\tconst width = (component as { width?: number }).width;\n\t\t\t\t\t\toverlayHandle = this.ui.tui.showOverlay(\n\t\t\t\t\t\t\tcomponent,\n\t\t\t\t\t\t\tresolvedOptions ?? (width ? { width } : undefined),\n\t\t\t\t\t\t);\n\t\t\t\t\t\toptions?.onHandle?.(overlayHandle);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tmountingComponent = true;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tthis.ui.overlayHost.swap(component, { onUnmount });\n\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\tmountingComponent = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(fail);\n\t\t});\n\t}\n\n\t/**\n\t * Show an extension error in the UI.\n\t */\n\tshowExtensionError(extensionPath: string, error: string, stack?: string): void {\n\t\tconst errorMsg = `Extension \"${extensionPath}\" error: ${error}`;\n\t\tconst errorText = new Text(theme.fg(\"error\", errorMsg), 1, 0);\n\t\tthis.ui.chatContainer.addChild(errorText);\n\t\tif (stack) {\n\t\t\t// Show stack trace in dim color, indented\n\t\t\tconst stackLines = stack\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.slice(1) // Skip first line (duplicates error message)\n\t\t\t\t.map((line) => theme.fg(\"dim\", ` ${line.trim()}`))\n\t\t\t\t.join(\"\\n\");\n\t\t\tif (stackLines) {\n\t\t\t\tthis.ui.chatContainer.addChild(new Text(stackLines, 1, 0));\n\t\t\t}\n\t\t}\n\t\tthis.ui.tui.requestRender();\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"extension-ui-host.js","sourceRoot":"","sources":["../../../src/modes/interactive/extension-ui-host.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Extension UI host.\n *\n * Extracted verbatim from interactive-mode.ts (god-file decomposition). Owns the interactive-mode\n * surface of the extension UI API: extension-provided dialogs (selector / confirm / input / multi-line\n * editor / custom component), widget mounting above and below the editor, extension status text, custom\n * footer and header swaps, the custom editor-component swap, keyboard-shortcut wiring, terminal-input\n * listeners, and the `ExtensionUIContext` handed to extensions. It owns exactly the state this cluster\n * mutates (the live dialog components, the widget maps, the terminal-input unsubscribers, the custom\n * footer/header, and the current custom-editor factory) and reaches everything else — the mutable\n * `editor`, the render-core containers, the working-indicator, autocomplete wiring, theme/tools state —\n * through a narrow deps/ui surface rather than the whole InteractiveMode instance. Extensions must see\n * identical behavior, so the render-core operations (working indicator, hidden-thinking label,\n * autocomplete rebuild) stay host-side and are invoked here as delegations.\n */\n\nimport type {\n\tAutocompleteProvider,\n\tComponent,\n\tEditorComponent,\n\tKeyId,\n\tLoaderIndicatorOptions,\n\tOverlayHandle,\n\tOverlayOptions,\n} from \"@caupulican/pi-tui\";\nimport { Container, Editor, matchesKey, Spacer, Text, type TUI } from \"@caupulican/pi-tui\";\nimport type { AgentSession } from \"../../core/agent-session.ts\";\nimport type {\n\tAutocompleteProviderFactory,\n\tEditorFactory,\n\tExtensionContext,\n\tExtensionRunner,\n\tExtensionUIContext,\n\tExtensionUIDialogOptions,\n\tExtensionWidgetOptions,\n} from \"../../core/extensions/index.ts\";\nimport type { FooterDataProvider, ReadonlyFooterDataProvider } from \"../../core/footer-data-provider.ts\";\nimport type { HumanInputPresentationRequest, HumanInputPresentationResult } from \"../../core/human-input.ts\";\nimport type { KeybindingsManager } from \"../../core/keybindings.ts\";\nimport type { SessionImageStore } from \"../../core/session-image-store.ts\";\nimport { AskQuestionDialog } from \"../../core/tools/ask-question.ts\";\nimport { handleClipboardImagePaste } from \"./clipboard-input.ts\";\nimport type { CustomEditor } from \"./components/custom-editor.ts\";\nimport { ExtensionEditorComponent } from \"./components/extension-editor.ts\";\nimport { ExtensionInputComponent } from \"./components/extension-input.ts\";\nimport { ExtensionSelectorComponent } from \"./components/extension-selector.ts\";\nimport type { FooterComponent } from \"./components/footer.ts\";\nimport type { EditorOverlayHost } from \"./editor-overlay-host.ts\";\nimport {\n\tgetAvailableThemesWithPaths,\n\tgetEditorTheme,\n\tgetThemeByName,\n\tsetTheme,\n\tsetThemeInstance,\n\tTheme,\n\ttheme,\n} from \"./theme/theme.ts\";\n\n/** Components that can be expanded/collapsed (custom headers may opt in). */\ninterface Expandable {\n\tsetExpanded(expanded: boolean): void;\n}\n\nfunction isExpandable(obj: unknown): obj is Expandable {\n\treturn typeof obj === \"object\" && obj !== null && \"setExpanded\" in obj && typeof obj.setExpanded === \"function\";\n}\n\n/**\n * The narrow slice of InteractiveMode the extension UI host drives. Stable containers and the TUI are\n * passed directly; mutable render-core state (the active editor, built-in header, loading animation,\n * autocomplete wrappers, tools-expansion) is read/written through accessors so InteractiveMode keeps\n * ownership; and render-core / status operations stay host-side and are exposed here as callbacks.\n */\nexport interface ExtensionUiHostUi {\n\treadonly tui: TUI;\n\treadonly overlayHost: EditorOverlayHost;\n\treadonly keybindings: KeybindingsManager;\n\treadonly footer: FooterComponent;\n\treadonly footerDataProvider: FooterDataProvider;\n\treadonly headerContainer: Container;\n\treadonly chatContainer: Container;\n\treadonly defaultEditor: CustomEditor;\n\treadonly widgetContainerAbove: Container;\n\treadonly widgetContainerBelow: Container;\n\n\tgetEditor(): EditorComponent;\n\tsetEditor(editor: EditorComponent): void;\n\tgetBuiltInHeader(): Component | undefined;\n\tgetAutocompleteProvider(): AutocompleteProvider | undefined;\n\tgetClipboardImageStore(): Pick<SessionImageStore, \"write\"> | undefined;\n\tgetToolsExpanded(): boolean;\n\tpushAutocompleteProviderWrapper(factory: AutocompleteProviderFactory): void;\n\tresetAutocompleteProviderWrappers(): void;\n\n\tsetupAutocompleteProvider(): void;\n\tsetWorkingVisible(visible: boolean): void;\n\tsetWorkingIndicator(options?: LoaderIndicatorOptions): void;\n\tsetHiddenThinkingLabel(label?: string): void;\n\tsetWorkingMessage(message: string | undefined): void;\n\tresetWorkingIndicators(): void;\n\tsetToolsExpanded(expanded: boolean): void;\n\ttoggleToolsExpanded(): void;\n\tupdateTerminalTitle(): void;\n\tmarkShutdownRequested(): void;\n\tabort(): void;\n\treload(): Promise<void>;\n\tshowStatus(message: string): void;\n\tshowWarning(message: string): void;\n\tshowError(message: string): void;\n}\n\nexport interface ExtensionUiHostDeps {\n\tgetSession(): AgentSession;\n\tui: ExtensionUiHostUi;\n}\n\ntype DisposableComponent = Component & { dispose?(): void };\ntype WidgetPlacement = \"aboveEditor\" | \"belowEditor\";\n\nexport class ExtensionUiHost {\n\tprivate readonly deps: ExtensionUiHostDeps;\n\n\t// Extension UI state\n\tprivate extensionSelector: ExtensionSelectorComponent | undefined = undefined;\n\tprivate extensionInput: ExtensionInputComponent | undefined = undefined;\n\tprivate extensionEditor: ExtensionEditorComponent | undefined = undefined;\n\t/** Settles the mounted extension dialog before another dialog can replace its overlay. */\n\tprivate activeExtensionDialogCancel: (() => void) | undefined;\n\tprivate extensionTerminalInputUnsubscribers = new Set<() => void>();\n\n\t// Extension widgets (components rendered above/below the editor)\n\tprivate extensionWidgetsAbove = new Map<string, Component & { dispose?(): void }>();\n\tprivate extensionWidgetsBelow = new Map<string, Component & { dispose?(): void }>();\n\t// Host-owned widgets survive extension reloads and are cleared only by the owning interactive mode.\n\tprivate hostWidgetsAbove = new Map<string, DisposableComponent>();\n\tprivate hostWidgetsBelow = new Map<string, DisposableComponent>();\n\n\t// Custom footer from extension (undefined = use built-in footer)\n\tprivate customFooter: (Component & { dispose?(): void }) | undefined = undefined;\n\n\t// Custom header from extension (undefined = use built-in header)\n\tprivate customHeader: (Component & { dispose?(): void }) | undefined = undefined;\n\n\t// Current custom editor-component factory (undefined = default editor)\n\tprivate editorComponentFactory: EditorFactory | undefined;\n\n\tconstructor(deps: ExtensionUiHostDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\tprivate get session(): AgentSession {\n\t\treturn this.deps.getSession();\n\t}\n\tprivate get ui(): ExtensionUiHostUi {\n\t\treturn this.deps.ui;\n\t}\n\n\t/** The active custom header, if an extension has installed one. */\n\tgetCustomHeader(): (Component & { dispose?(): void }) | undefined {\n\t\treturn this.customHeader;\n\t}\n\n\t/**\n\t * Set up keyboard shortcuts registered by extensions.\n\t */\n\tsetupExtensionShortcuts(extensionRunner: ExtensionRunner): void {\n\t\tconst shortcuts = extensionRunner.getShortcuts(this.ui.keybindings.getEffectiveConfig());\n\t\tif (shortcuts.size === 0) return;\n\n\t\t// Create a context for shortcut handlers\n\t\tconst createContext = (): ExtensionContext => ({\n\t\t\tui: this.createExtensionUIContext(),\n\t\t\thasUI: true,\n\t\t\tmode: \"tui\",\n\t\t\tcwd: this.session.sessionManager.getCwd(),\n\t\t\tsessionManager: this.session.sessionManager,\n\t\t\tmodelRegistry: this.session.modelRegistry,\n\t\t\tmodel: this.session.model,\n\t\t\tisIdle: () => !this.session.isStreaming,\n\t\t\tsignal: this.session.agent.signal,\n\t\t\tabort: () => {\n\t\t\t\tthis.ui.abort();\n\t\t\t},\n\t\t\thasPendingMessages: () => this.session.pendingMessageCount > 0,\n\t\t\tshutdown: () => {\n\t\t\t\tthis.ui.markShutdownRequested();\n\t\t\t},\n\t\t\tgetContextUsage: () => this.session.getContextUsage(),\n\t\t\tcompact: (options) => {\n\t\t\t\tvoid (async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await this.session.compact(options?.customInstructions);\n\t\t\t\t\t\toptions?.onComplete?.(result);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tconst err = error instanceof Error ? error : new Error(String(error));\n\t\t\t\t\t\toptions?.onError?.(err);\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t},\n\t\t\treload: async () => {\n\t\t\t\tawait this.ui.reload();\n\t\t\t},\n\t\t\tgetSystemPrompt: () => this.session.systemPrompt,\n\t\t});\n\n\t\t// Set up the extension shortcut handler on the default editor\n\t\tthis.ui.defaultEditor.onExtensionShortcut = (data: string) => {\n\t\t\tfor (const [shortcutStr, shortcut] of shortcuts) {\n\t\t\t\t// Cast to KeyId - extension shortcuts use the same format\n\t\t\t\tif (matchesKey(data, shortcutStr as KeyId)) {\n\t\t\t\t\t// Run handler async, don't block input\n\t\t\t\t\tPromise.resolve(shortcut.handler(createContext())).catch((err) => {\n\t\t\t\t\t\tthis.ui.showError(`Shortcut handler error: ${err instanceof Error ? err.message : String(err)}`);\n\t\t\t\t\t});\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\t}\n\n\t/**\n\t * Set extension status text in the footer.\n\t */\n\tprivate setExtensionStatus(key: string, text: string | undefined): void {\n\t\tthis.ui.footerDataProvider.setExtensionStatus(key, text);\n\t\tthis.ui.tui.requestRender();\n\t}\n\n\t// Maximum total widget lines to prevent viewport overflow\n\tprivate static readonly MAX_WIDGET_LINES = 10;\n\n\tprivate removeWidget(map: Map<string, DisposableComponent>, key: string): void {\n\t\tconst existing = map.get(key);\n\t\texisting?.dispose?.();\n\t\tmap.delete(key);\n\t}\n\n\t/** Mount a native host widget without coupling it to extension reload lifecycle. */\n\tsetHostWidget(key: string, component: DisposableComponent | undefined, placement: WidgetPlacement): void {\n\t\tthis.removeWidget(this.hostWidgetsAbove, key);\n\t\tthis.removeWidget(this.hostWidgetsBelow, key);\n\t\tif (component) {\n\t\t\tconst target = placement === \"belowEditor\" ? this.hostWidgetsBelow : this.hostWidgetsAbove;\n\t\t\ttarget.set(key, component);\n\t\t}\n\t\tthis.renderWidgets();\n\t}\n\n\tclearHostWidgets(): void {\n\t\tfor (const widget of this.hostWidgetsAbove.values()) widget.dispose?.();\n\t\tfor (const widget of this.hostWidgetsBelow.values()) widget.dispose?.();\n\t\tthis.hostWidgetsAbove.clear();\n\t\tthis.hostWidgetsBelow.clear();\n\t\tthis.renderWidgets();\n\t}\n\n\t/**\n\t * Set an extension widget (string array or custom component).\n\t */\n\tprivate setExtensionWidget(\n\t\tkey: string,\n\t\tcontent: string[] | ((tui: TUI, thm: Theme) => Component & { dispose?(): void }) | undefined,\n\t\toptions?: ExtensionWidgetOptions,\n\t): void {\n\t\tconst placement = options?.placement ?? \"aboveEditor\";\n\t\tthis.removeWidget(this.extensionWidgetsAbove, key);\n\t\tthis.removeWidget(this.extensionWidgetsBelow, key);\n\n\t\tif (content === undefined) {\n\t\t\tthis.renderWidgets();\n\t\t\treturn;\n\t\t}\n\n\t\tlet component: Component & { dispose?(): void };\n\n\t\tif (Array.isArray(content)) {\n\t\t\t// Wrap string array in a Container with Text components\n\t\t\tconst container = new Container();\n\t\t\tfor (const line of content.slice(0, ExtensionUiHost.MAX_WIDGET_LINES)) {\n\t\t\t\tcontainer.addChild(new Text(line, 1, 0));\n\t\t\t}\n\t\t\tif (content.length > ExtensionUiHost.MAX_WIDGET_LINES) {\n\t\t\t\tcontainer.addChild(new Text(theme.fg(\"muted\", \"... (widget truncated)\"), 1, 0));\n\t\t\t}\n\t\t\tcomponent = container;\n\t\t} else {\n\t\t\t// Factory function - create component\n\t\t\tcomponent = content(this.ui.tui, theme);\n\t\t}\n\n\t\tconst targetMap = placement === \"belowEditor\" ? this.extensionWidgetsBelow : this.extensionWidgetsAbove;\n\t\ttargetMap.set(key, component);\n\t\tthis.renderWidgets();\n\t}\n\n\tprivate clearExtensionWidgets(): void {\n\t\tfor (const widget of this.extensionWidgetsAbove.values()) {\n\t\t\twidget.dispose?.();\n\t\t}\n\t\tfor (const widget of this.extensionWidgetsBelow.values()) {\n\t\t\twidget.dispose?.();\n\t\t}\n\t\tthis.extensionWidgetsAbove.clear();\n\t\tthis.extensionWidgetsBelow.clear();\n\t\tthis.renderWidgets();\n\t}\n\n\tresetExtensionUI(): void {\n\t\t// A reset/reload must settle the active dialog before disposing its component.\n\t\tthis.activeExtensionDialogCancel?.();\n\t\tthis.activeExtensionDialogCancel = undefined;\n\t\tif (this.extensionSelector) {\n\t\t\tthis.hideExtensionSelector();\n\t\t}\n\t\tif (this.extensionInput) {\n\t\t\tthis.hideExtensionInput();\n\t\t}\n\t\tif (this.extensionEditor) {\n\t\t\tthis.hideExtensionEditor();\n\t\t}\n\t\tthis.ui.tui.hideOverlay();\n\t\tthis.clearExtensionTerminalInputListeners();\n\t\tthis.setExtensionFooter(undefined);\n\t\tthis.setExtensionHeader(undefined);\n\t\tthis.clearExtensionWidgets();\n\t\tthis.ui.footerDataProvider.clearExtensionStatuses();\n\t\tthis.ui.footer.invalidate();\n\t\tthis.ui.resetAutocompleteProviderWrappers();\n\t\tthis.setCustomEditorComponent(undefined);\n\t\tthis.ui.setupAutocompleteProvider();\n\t\tthis.ui.defaultEditor.onExtensionShortcut = undefined;\n\t\tthis.ui.updateTerminalTitle();\n\t\tthis.ui.resetWorkingIndicators();\n\t}\n\n\t/**\n\t * Render all extension widgets to the widget container.\n\t */\n\trenderWidgets(): void {\n\t\tif (!this.ui.widgetContainerAbove || !this.ui.widgetContainerBelow) return;\n\t\tthis.renderWidgetContainer(\n\t\t\tthis.ui.widgetContainerAbove,\n\t\t\t[this.hostWidgetsAbove, this.extensionWidgetsAbove],\n\t\t\ttrue,\n\t\t\ttrue,\n\t\t);\n\t\tthis.renderWidgetContainer(\n\t\t\tthis.ui.widgetContainerBelow,\n\t\t\t[this.hostWidgetsBelow, this.extensionWidgetsBelow],\n\t\t\tfalse,\n\t\t\tfalse,\n\t\t);\n\t\tthis.ui.tui.requestRender();\n\t}\n\n\tprivate renderWidgetContainer(\n\t\tcontainer: Container,\n\t\twidgetGroups: readonly Map<string, DisposableComponent>[],\n\t\tspacerWhenEmpty: boolean,\n\t\tleadingSpacer: boolean,\n\t): void {\n\t\tcontainer.clear();\n\n\t\tif (widgetGroups.every((widgets) => widgets.size === 0)) {\n\t\t\tif (spacerWhenEmpty) {\n\t\t\t\tcontainer.addChild(new Spacer(1));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (leadingSpacer) {\n\t\t\tcontainer.addChild(new Spacer(1));\n\t\t}\n\t\tfor (const widgets of widgetGroups) {\n\t\t\tfor (const component of widgets.values()) {\n\t\t\t\tcontainer.addChild(component);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Set a custom footer component, or restore the built-in footer.\n\t */\n\tprivate setExtensionFooter(\n\t\tfactory:\n\t\t\t| ((tui: TUI, thm: Theme, footerData: ReadonlyFooterDataProvider) => Component & { dispose?(): void })\n\t\t\t| undefined,\n\t): void {\n\t\t// Dispose existing custom footer\n\t\tif (this.customFooter?.dispose) {\n\t\t\tthis.customFooter.dispose();\n\t\t}\n\n\t\t// Remove current footer from UI\n\t\tif (this.customFooter) {\n\t\t\tthis.ui.tui.removeChild(this.customFooter);\n\t\t} else {\n\t\t\tthis.ui.tui.removeChild(this.ui.footer);\n\t\t}\n\n\t\tif (factory) {\n\t\t\t// Create and add custom footer, passing the data provider\n\t\t\tthis.customFooter = factory(this.ui.tui, theme, this.ui.footerDataProvider);\n\t\t\tthis.ui.tui.addChild(this.customFooter);\n\t\t} else {\n\t\t\t// Restore built-in footer\n\t\t\tthis.customFooter = undefined;\n\t\t\tthis.ui.tui.addChild(this.ui.footer);\n\t\t}\n\n\t\tthis.ui.tui.requestRender();\n\t}\n\n\t/**\n\t * Set a custom header component, or restore the built-in header.\n\t */\n\tprivate setExtensionHeader(factory: ((tui: TUI, thm: Theme) => Component & { dispose?(): void }) | undefined): void {\n\t\t// Header may not be initialized yet if called during early initialization\n\t\tconst builtInHeader = this.ui.getBuiltInHeader();\n\t\tif (!builtInHeader) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Dispose existing custom header\n\t\tif (this.customHeader?.dispose) {\n\t\t\tthis.customHeader.dispose();\n\t\t}\n\n\t\t// Find the index of the current header in the header container\n\t\tconst currentHeader = this.customHeader || builtInHeader;\n\t\tconst index = this.ui.headerContainer.children.indexOf(currentHeader);\n\n\t\tif (factory) {\n\t\t\t// Create and add custom header\n\t\t\tthis.customHeader = factory(this.ui.tui, theme);\n\t\t\tif (isExpandable(this.customHeader)) {\n\t\t\t\tthis.customHeader.setExpanded(this.ui.getToolsExpanded());\n\t\t\t}\n\t\t\tif (index !== -1) {\n\t\t\t\tthis.ui.headerContainer.children[index] = this.customHeader;\n\t\t\t} else {\n\t\t\t\t// If not found (e.g. builtInHeader was never added), add at the top\n\t\t\t\tthis.ui.headerContainer.children.unshift(this.customHeader);\n\t\t\t}\n\t\t} else {\n\t\t\t// Restore built-in header\n\t\t\tthis.customHeader = undefined;\n\t\t\tif (isExpandable(builtInHeader)) {\n\t\t\t\tbuiltInHeader.setExpanded(this.ui.getToolsExpanded());\n\t\t\t}\n\t\t\tif (index !== -1) {\n\t\t\t\tthis.ui.headerContainer.children[index] = builtInHeader;\n\t\t\t}\n\t\t}\n\n\t\tthis.ui.tui.requestRender();\n\t}\n\n\tprivate addExtensionTerminalInputListener(\n\t\thandler: (data: string) => { consume?: boolean; data?: string } | undefined,\n\t): () => void {\n\t\tconst unsubscribe = this.ui.tui.addInputListener(handler);\n\t\tthis.extensionTerminalInputUnsubscribers.add(unsubscribe);\n\t\treturn () => {\n\t\t\tunsubscribe();\n\t\t\tthis.extensionTerminalInputUnsubscribers.delete(unsubscribe);\n\t\t};\n\t}\n\n\tclearExtensionTerminalInputListeners(): void {\n\t\tfor (const unsubscribe of this.extensionTerminalInputUnsubscribers) {\n\t\t\tunsubscribe();\n\t\t}\n\t\tthis.extensionTerminalInputUnsubscribers.clear();\n\t}\n\n\t/**\n\t * Create the ExtensionUIContext for extensions.\n\t */\n\tcreateExtensionUIContext(): ExtensionUIContext {\n\t\treturn {\n\t\t\taskQuestions: (request, opts) => this.showHumanInput(request, opts),\n\t\t\tselect: (title, options, opts) => this.showExtensionSelector(title, options, opts),\n\t\t\tconfirm: (title, message, opts) => this.showExtensionConfirm(title, message, opts),\n\t\t\tinput: (title, placeholder, opts) => this.showExtensionInput(title, placeholder, opts),\n\t\t\tnotify: (message, type) => this.showExtensionNotify(message, type),\n\t\t\tonTerminalInput: (handler) => this.addExtensionTerminalInputListener(handler),\n\t\t\tsetStatus: (key, text) => this.setExtensionStatus(key, text),\n\t\t\tsetWorkingMessage: (message) => this.ui.setWorkingMessage(message),\n\t\t\tsetWorkingVisible: (visible) => this.ui.setWorkingVisible(visible),\n\t\t\tsetWorkingIndicator: (options) => this.ui.setWorkingIndicator(options),\n\t\t\tsetHiddenThinkingLabel: (label) => this.ui.setHiddenThinkingLabel(label),\n\t\t\tsetWidget: (key, content, options) => this.setExtensionWidget(key, content, options),\n\t\t\tsetFooter: (factory) => this.setExtensionFooter(factory),\n\t\t\tsetHeader: (factory) => this.setExtensionHeader(factory),\n\t\t\tsetTitle: (title) => this.ui.tui.terminal.setTitle(title),\n\t\t\tcustom: (factory, options) => this.showExtensionCustom(factory, options),\n\t\t\tpasteToEditor: (text) => this.ui.getEditor().handleInput(`\\x1b[200~${text}\\x1b[201~`),\n\t\t\tsetEditorText: (text) => this.ui.getEditor().setText(text),\n\t\t\tgetEditorText: () => this.ui.getEditor().getExpandedText?.() ?? this.ui.getEditor().getText(),\n\t\t\teditor: (title, prefill) => this.showExtensionEditor(title, prefill),\n\t\t\taddAutocompleteProvider: (factory) => {\n\t\t\t\tthis.ui.pushAutocompleteProviderWrapper(factory);\n\t\t\t\tthis.ui.setupAutocompleteProvider();\n\t\t\t},\n\t\t\tsetEditorComponent: (factory) => this.setCustomEditorComponent(factory),\n\t\t\tgetEditorComponent: () => this.editorComponentFactory,\n\t\t\tget theme() {\n\t\t\t\treturn theme;\n\t\t\t},\n\t\t\tgetAllThemes: () => getAvailableThemesWithPaths(),\n\t\t\tgetTheme: (name) => getThemeByName(name),\n\t\t\tsetTheme: (themeOrName) => {\n\t\t\t\tif (themeOrName instanceof Theme) {\n\t\t\t\t\tsetThemeInstance(themeOrName);\n\t\t\t\t\tthis.ui.tui.requestRender();\n\t\t\t\t\treturn { success: true };\n\t\t\t\t}\n\t\t\t\tconst result = setTheme(themeOrName, true);\n\t\t\t\tif (result.success) {\n\t\t\t\t\tif (this.session.settingsManager.getTheme() !== themeOrName) {\n\t\t\t\t\t\tthis.session.settingsManager.setTheme(themeOrName);\n\t\t\t\t\t}\n\t\t\t\t\tthis.ui.tui.requestRender();\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t},\n\t\t\tgetToolsExpanded: () => this.ui.getToolsExpanded(),\n\t\t\tsetToolsExpanded: (expanded) => this.ui.setToolsExpanded(expanded),\n\t\t};\n\t}\n\n\tprivate showHumanInput(\n\t\trequest: HumanInputPresentationRequest,\n\t\topts?: Pick<ExtensionUIDialogOptions, \"signal\">,\n\t): Promise<HumanInputPresentationResult> {\n\t\tif (opts?.signal?.aborted) {\n\t\t\treturn Promise.resolve({ answers: [], cancelled: true, reason: \"interrupted\", imageContents: [] });\n\t\t}\n\t\treturn this.showExtensionCustom<HumanInputPresentationResult>((tui, currentTheme, keybindings, done) => {\n\t\t\tlet onAbort: (() => void) | undefined;\n\t\t\tconst finish = (result: HumanInputPresentationResult) => {\n\t\t\t\tif (onAbort) opts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\tdone(result);\n\t\t\t};\n\t\t\tconst settings = this.session.settingsManager;\n\t\t\tconst modelCannotSeeImages = !request.acceptsImages;\n\t\t\tconst dialog = new AskQuestionDialog({\n\t\t\t\tquestions: request.questions,\n\t\t\t\ttheme: currentTheme,\n\t\t\t\tkeybindings,\n\t\t\t\trequestRender: () => tui.requestRender(),\n\t\t\t\tfinish,\n\t\t\t\tcreateAnswerEditor: () => new Editor(tui, getEditorTheme()),\n\t\t\t\tclipboard: {\n\t\t\t\t\tautoResizeImages: settings.getImageAutoResize(),\n\t\t\t\t\tblockImages: settings.getBlockImages() || modelCannotSeeImages,\n\t\t\t\t\tblockImagesReason: modelCannotSeeImages\n\t\t\t\t\t\t? \"The selected model does not accept image input. Switch to an image-capable model or route this inspection to a vision worker.\"\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\timageStore: this.ui.getClipboardImageStore(),\n\t\t\t\t},\n\t\t\t\tpasteClipboardImage: handleClipboardImagePaste,\n\t\t\t});\n\t\t\tonAbort = () => dialog.cancel(\"interrupted\");\n\t\t\topts?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\treturn dialog;\n\t\t}).catch(() => ({ answers: [], cancelled: true, reason: \"interrupted\", imageContents: [] }));\n\t}\n\n\t/**\n\t * Show a selector for extensions.\n\t */\n\tshowExtensionSelector(\n\t\ttitle: string,\n\t\toptions: string[],\n\t\topts?: ExtensionUIDialogOptions,\n\t): Promise<string | undefined> {\n\t\tif (opts?.signal?.aborted) return Promise.resolve(undefined);\n\t\t// Replacing an overlay without settling its promise strands the extension handler forever.\n\t\tthis.activeExtensionDialogCancel?.();\n\t\treturn new Promise((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tlet selector: ExtensionSelectorComponent;\n\t\t\tconst finish = (value: string | undefined, restoreEditor = true) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\topts?.signal?.removeEventListener(\"abort\", cancel);\n\t\t\t\tif (this.activeExtensionDialogCancel === cancel) {\n\t\t\t\t\tthis.activeExtensionDialogCancel = undefined;\n\t\t\t\t}\n\t\t\t\tthis.hideExtensionSelector(selector, restoreEditor);\n\t\t\t\tresolve(value);\n\t\t\t};\n\t\t\tconst cancel = () => finish(undefined);\n\n\t\t\tselector = new ExtensionSelectorComponent(title, options, (option) => finish(option), cancel, {\n\t\t\t\ttui: this.ui.tui,\n\t\t\t\ttimeout: opts?.timeout,\n\t\t\t\tonToggleToolsExpanded: () => this.ui.toggleToolsExpanded(),\n\t\t\t});\n\t\t\tthis.extensionSelector = selector;\n\t\t\tthis.activeExtensionDialogCancel = cancel;\n\t\t\tthis.ui.overlayHost.swap(selector, { onUnmount: () => finish(undefined, false) });\n\t\t\topts?.signal?.addEventListener(\"abort\", cancel, { once: true });\n\t\t});\n\t}\n\n\t/**\n\t * Hide the extension selector.\n\t */\n\tprivate hideExtensionSelector(selector = this.extensionSelector, restoreEditor = true): void {\n\t\tif (!selector) return;\n\t\tselector.dispose();\n\t\tif (this.extensionSelector !== selector) return;\n\t\tthis.extensionSelector = undefined;\n\t\tif (restoreEditor) this.ui.overlayHost.swap(this.ui.getEditor());\n\t}\n\n\t/**\n\t * Show a confirmation dialog for extensions.\n\t */\n\tasync showExtensionConfirm(title: string, message: string, opts?: ExtensionUIDialogOptions): Promise<boolean> {\n\t\tconst result = await this.showExtensionSelector(`${title}\\n${message}`, [\"Yes\", \"No\"], opts);\n\t\treturn result === \"Yes\";\n\t}\n\n\t/**\n\t * Show a text input for extensions.\n\t */\n\tprivate showExtensionInput(\n\t\ttitle: string,\n\t\tplaceholder?: string,\n\t\topts?: ExtensionUIDialogOptions,\n\t): Promise<string | undefined> {\n\t\tif (opts?.signal?.aborted) return Promise.resolve(undefined);\n\t\tthis.activeExtensionDialogCancel?.();\n\t\treturn new Promise((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tlet input: ExtensionInputComponent;\n\t\t\tconst finish = (value: string | undefined, restoreEditor = true) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\topts?.signal?.removeEventListener(\"abort\", cancel);\n\t\t\t\tif (this.activeExtensionDialogCancel === cancel) {\n\t\t\t\t\tthis.activeExtensionDialogCancel = undefined;\n\t\t\t\t}\n\t\t\t\tthis.hideExtensionInput(input, restoreEditor);\n\t\t\t\tresolve(value);\n\t\t\t};\n\t\t\tconst cancel = () => finish(undefined);\n\n\t\t\tinput = new ExtensionInputComponent(title, placeholder, (value) => finish(value), cancel, {\n\t\t\t\ttui: this.ui.tui,\n\t\t\t\ttimeout: opts?.timeout,\n\t\t\t\tsensitive: opts?.sensitive,\n\t\t\t});\n\t\t\tthis.extensionInput = input;\n\t\t\tthis.activeExtensionDialogCancel = cancel;\n\t\t\tthis.ui.overlayHost.swap(input, { onUnmount: () => finish(undefined, false) });\n\t\t\topts?.signal?.addEventListener(\"abort\", cancel, { once: true });\n\t\t});\n\t}\n\n\t/**\n\t * Hide the extension input.\n\t */\n\tprivate hideExtensionInput(input = this.extensionInput, restoreEditor = true): void {\n\t\tif (!input) return;\n\t\tinput.dispose();\n\t\tif (this.extensionInput !== input) return;\n\t\tthis.extensionInput = undefined;\n\t\tif (restoreEditor) this.ui.overlayHost.swap(this.ui.getEditor());\n\t}\n\n\t/**\n\t * Show a multi-line editor for extensions (with Ctrl+G support).\n\t */\n\tshowExtensionEditor(title: string, prefill?: string): Promise<string | undefined> {\n\t\tthis.activeExtensionDialogCancel?.();\n\t\treturn new Promise((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tlet editor: ExtensionEditorComponent;\n\t\t\tconst finish = (value: string | undefined, restoreEditor = true) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tif (this.activeExtensionDialogCancel === cancel) {\n\t\t\t\t\tthis.activeExtensionDialogCancel = undefined;\n\t\t\t\t}\n\t\t\t\tthis.hideExtensionEditor(editor, restoreEditor);\n\t\t\t\tresolve(value);\n\t\t\t};\n\t\t\tconst cancel = () => finish(undefined);\n\n\t\t\teditor = new ExtensionEditorComponent(\n\t\t\t\tthis.ui.tui,\n\t\t\t\tthis.ui.keybindings,\n\t\t\t\ttitle,\n\t\t\t\tprefill,\n\t\t\t\t(value) => finish(value),\n\t\t\t\tcancel,\n\t\t\t);\n\t\t\tthis.extensionEditor = editor;\n\t\t\tthis.activeExtensionDialogCancel = cancel;\n\t\t\tthis.ui.overlayHost.swap(editor, { onUnmount: () => finish(undefined, false) });\n\t\t});\n\t}\n\n\t/**\n\t * Hide the extension editor.\n\t */\n\tprivate hideExtensionEditor(editor = this.extensionEditor, restoreEditor = true): void {\n\t\tif (!editor || this.extensionEditor !== editor) return;\n\t\tthis.extensionEditor = undefined;\n\t\tif (restoreEditor) this.ui.overlayHost.swap(this.ui.getEditor());\n\t}\n\n\t/**\n\t * Set a custom editor component from an extension.\n\t * Pass undefined to restore the default editor.\n\t */\n\tprivate setCustomEditorComponent(factory: EditorFactory | undefined): void {\n\t\tthis.editorComponentFactory = factory;\n\n\t\t// Save text from current editor before switching\n\t\tconst currentText = this.ui.getEditor().getText();\n\n\t\tif (factory) {\n\t\t\t// Create the custom editor with tui, theme, and keybindings\n\t\t\tconst newEditor = factory(this.ui.tui, getEditorTheme(), this.ui.keybindings);\n\n\t\t\t// Wire up callbacks from the default editor\n\t\t\tnewEditor.onSubmit = this.ui.defaultEditor.onSubmit;\n\t\t\tnewEditor.onChange = this.ui.defaultEditor.onChange;\n\n\t\t\t// Copy text from previous editor\n\t\t\tnewEditor.setText(currentText);\n\n\t\t\t// Copy appearance settings if supported\n\t\t\tif (newEditor.borderColor !== undefined) {\n\t\t\t\tnewEditor.borderColor = this.ui.defaultEditor.borderColor;\n\t\t\t}\n\t\t\tif (newEditor.setPaddingX !== undefined) {\n\t\t\t\tnewEditor.setPaddingX(this.ui.defaultEditor.getPaddingX());\n\t\t\t}\n\n\t\t\t// Set autocomplete if supported\n\t\t\tconst autocompleteProvider = this.ui.getAutocompleteProvider();\n\t\t\tif (newEditor.setAutocompleteProvider && autocompleteProvider) {\n\t\t\t\tnewEditor.setAutocompleteProvider(autocompleteProvider);\n\t\t\t}\n\n\t\t\t// If extending CustomEditor, copy app-level handlers\n\t\t\t// Use duck typing since instanceof fails across jiti module boundaries\n\t\t\tconst customEditor = newEditor as unknown as Record<string, unknown>;\n\t\t\tif (\"actionHandlers\" in customEditor && customEditor.actionHandlers instanceof Map) {\n\t\t\t\tif (!customEditor.onEscape) {\n\t\t\t\t\tcustomEditor.onEscape = () => this.ui.defaultEditor.onEscape?.();\n\t\t\t\t}\n\t\t\t\tif (!customEditor.onCtrlD) {\n\t\t\t\t\tcustomEditor.onCtrlD = () => this.ui.defaultEditor.onCtrlD?.();\n\t\t\t\t}\n\t\t\t\tif (!customEditor.onPasteImage) {\n\t\t\t\t\tcustomEditor.onPasteImage = () => this.ui.defaultEditor.onPasteImage?.();\n\t\t\t\t}\n\t\t\t\tif (!customEditor.onExtensionShortcut) {\n\t\t\t\t\tcustomEditor.onExtensionShortcut = (data: string) => this.ui.defaultEditor.onExtensionShortcut?.(data);\n\t\t\t\t}\n\t\t\t\t// Copy action handlers (clear, suspend, model switching, etc.)\n\t\t\t\tfor (const [action, handler] of this.ui.defaultEditor.actionHandlers) {\n\t\t\t\t\t(customEditor.actionHandlers as Map<string, () => void>).set(action, handler);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.ui.setEditor(newEditor);\n\t\t} else {\n\t\t\t// Restore default editor with text from custom editor\n\t\t\tthis.ui.defaultEditor.setText(currentText);\n\t\t\tthis.ui.setEditor(this.ui.defaultEditor);\n\t\t}\n\n\t\tthis.ui.overlayHost.swap(this.ui.getEditor() as Component);\n\t}\n\n\t/**\n\t * Show a notification for extensions.\n\t */\n\tprivate showExtensionNotify(message: string, type?: \"info\" | \"warning\" | \"error\"): void {\n\t\tif (type === \"error\") {\n\t\t\tthis.ui.showError(message);\n\t\t} else if (type === \"warning\") {\n\t\t\tthis.ui.showWarning(message);\n\t\t} else {\n\t\t\tthis.ui.showStatus(message);\n\t\t}\n\t}\n\n\t/** Show a custom component with keyboard focus. Overlay mode renders on top of existing content. */\n\tprivate async showExtensionCustom<T>(\n\t\tfactory: (\n\t\t\ttui: TUI,\n\t\t\ttheme: Theme,\n\t\t\tkeybindings: KeybindingsManager,\n\t\t\tdone: (result: T) => void,\n\t\t) => (Component & { dispose?(): void }) | Promise<Component & { dispose?(): void }>,\n\t\toptions?: {\n\t\t\toverlay?: boolean;\n\t\t\toverlayOptions?: OverlayOptions | (() => OverlayOptions);\n\t\t\tonHandle?: (handle: OverlayHandle) => void;\n\t\t},\n\t): Promise<T> {\n\t\tthis.activeExtensionDialogCancel?.();\n\t\tconst savedText = this.ui.getEditor().getText();\n\t\tconst isOverlay = options?.overlay ?? false;\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tlet component: (Component & { dispose?(): void }) | undefined;\n\t\t\tlet overlayHandle: OverlayHandle | undefined;\n\t\t\tlet closed = false;\n\t\t\tlet cancel: () => void;\n\t\t\tconst dispose = (candidate: (Component & { dispose?(): void }) | undefined) => {\n\t\t\t\ttry {\n\t\t\t\t\tcandidate?.dispose?.();\n\t\t\t\t} catch {\n\t\t\t\t\t/* ignore dispose errors */\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst restore = (restoreEditor = true) => {\n\t\t\t\tif (this.activeExtensionDialogCancel !== cancel) return;\n\t\t\t\tthis.activeExtensionDialogCancel = undefined;\n\t\t\t\tif (isOverlay) {\n\t\t\t\t\toverlayHandle?.hide();\n\t\t\t\t} else if (restoreEditor) {\n\t\t\t\t\tthis.ui.getEditor().setText(savedText);\n\t\t\t\t\tthis.ui.overlayHost.swap(this.ui.getEditor(), { focusMode: \"restore\" });\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst close = (result: T) => {\n\t\t\t\tif (closed) return;\n\t\t\t\tclosed = true;\n\t\t\t\tdispose(component);\n\t\t\t\trestore();\n\t\t\t\tresolve(result);\n\t\t\t};\n\t\t\tconst fail = (error: unknown, restoreEditor = true) => {\n\t\t\t\tif (closed) return;\n\t\t\t\tclosed = true;\n\t\t\t\tdispose(component);\n\t\t\t\trestore(restoreEditor);\n\t\t\t\treject(error);\n\t\t\t};\n\t\t\tcancel = () => fail(new Error(\"Extension UI request was superseded or reset\"));\n\t\t\tthis.activeExtensionDialogCancel = cancel;\n\t\t\tlet mountingComponent = false;\n\t\t\tconst onUnmount = () => {\n\t\t\t\tif (!mountingComponent) fail(new Error(\"Extension UI request was superseded or reset\"), false);\n\t\t\t};\n\t\t\tif (!isOverlay) {\n\t\t\t\tthis.ui.overlayHost.swap(this.ui.getEditor(), {\n\t\t\t\t\tfocusMode: \"restore\",\n\t\t\t\t\trender: \"none\",\n\t\t\t\t\tonUnmount,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tPromise.resolve()\n\t\t\t\t.then(() => (closed ? undefined : factory(this.ui.tui, theme, this.ui.keybindings, close)))\n\t\t\t\t.then((createdComponent) => {\n\t\t\t\t\tif (!createdComponent) return;\n\t\t\t\t\tcomponent = createdComponent;\n\t\t\t\t\tif (closed) {\n\t\t\t\t\t\tdispose(component);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (isOverlay) {\n\t\t\t\t\t\tconst resolvedOptions =\n\t\t\t\t\t\t\ttypeof options?.overlayOptions === \"function\" ? options.overlayOptions() : options?.overlayOptions;\n\t\t\t\t\t\tconst width = (component as { width?: number }).width;\n\t\t\t\t\t\toverlayHandle = this.ui.tui.showOverlay(\n\t\t\t\t\t\t\tcomponent,\n\t\t\t\t\t\t\tresolvedOptions ?? (width ? { width } : undefined),\n\t\t\t\t\t\t);\n\t\t\t\t\t\toptions?.onHandle?.(overlayHandle);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tmountingComponent = true;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tthis.ui.overlayHost.swap(component, { onUnmount });\n\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\tmountingComponent = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(fail);\n\t\t});\n\t}\n\n\t/**\n\t * Show an extension error in the UI.\n\t */\n\tshowExtensionError(extensionPath: string, error: string, stack?: string): void {\n\t\tconst errorMsg = `Extension \"${extensionPath}\" error: ${error}`;\n\t\tconst errorText = new Text(theme.fg(\"error\", errorMsg), 1, 0);\n\t\tthis.ui.chatContainer.addChild(errorText);\n\t\tif (stack) {\n\t\t\t// Show stack trace in dim color, indented\n\t\t\tconst stackLines = stack\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.slice(1) // Skip first line (duplicates error message)\n\t\t\t\t.map((line) => theme.fg(\"dim\", ` ${line.trim()}`))\n\t\t\t\t.join(\"\\n\");\n\t\t\tif (stackLines) {\n\t\t\t\tthis.ui.chatContainer.addChild(new Text(stackLines, 1, 0));\n\t\t\t}\n\t\t}\n\t\tthis.ui.tui.requestRender();\n\t}\n}\n"]}
|