@ashx-j/lunr 0.2.20 → 0.2.22
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 +14 -2
- package/README.md +20 -4
- package/dist/builtin-extensions/index.d.ts.map +1 -1
- package/dist/builtin-extensions/index.js +1 -0
- package/dist/builtin-extensions/index.js.map +1 -1
- package/dist/builtin-extensions/lunr-browser.d.ts +3 -0
- package/dist/builtin-extensions/lunr-browser.d.ts.map +1 -0
- package/dist/builtin-extensions/lunr-browser.js +56 -0
- package/dist/builtin-extensions/lunr-browser.js.map +1 -0
- package/dist/builtin-extensions/lunr-todos.d.ts +6 -5
- package/dist/builtin-extensions/lunr-todos.d.ts.map +1 -1
- package/dist/builtin-extensions/lunr-todos.js +24 -7
- package/dist/builtin-extensions/lunr-todos.js.map +1 -1
- package/dist/builtin-extensions/pi-intercom/broker/spawn.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-intercom/broker/spawn.js +30 -21
- package/dist/builtin-extensions/pi-intercom/broker/spawn.js.map +1 -1
- package/dist/builtin-extensions/pi-intercom/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-intercom/index.js +15 -3
- package/dist/builtin-extensions/pi-intercom/index.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/control-notices.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/control-notices.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/control-notices.js +5 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/control-notices.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/fanout-child.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/fanout-child.js +2 -2
- package/dist/builtin-extensions/pi-subagents/src/extension/fanout-child.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts +8 -7
- package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js +78 -31
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +2 -2
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +4 -3
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +6 -2
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/communication.d.ts +17 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/communication.d.ts.map +1 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/communication.js +45 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/communication.js.map +1 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/intercom-bridge.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/intercom-bridge.js +4 -11
- package/dist/builtin-extensions/pi-subagents/src/intercom/intercom-bridge.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.d.ts +5 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.js +186 -58
- package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/result-intercom.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/result-intercom.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/result-intercom.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/result-intercom.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.js +5 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.d.ts +2 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.js +3 -2
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts +2 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js +4 -3
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.js +2 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/auto-drain.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/auto-drain.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/auto-drain.js +2 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/auto-drain.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts +6 -2
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js +23 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts +100 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +46 -31
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js +2 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/top-level-async.d.ts +15 -2
- package/dist/builtin-extensions/pi-subagents/src/runs/background/top-level-async.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/top-level-async.js +14 -4
- package/dist/builtin-extensions/pi-subagents/src/runs/background/top-level-async.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts +0 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +9 -9
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/completion-guard.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/completion-guard.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/completion-guard.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/completion-guard.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.d.ts +3 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js +5 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-control.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-control.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-control.js +3 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-control.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/task-intent.d.ts +2 -2
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/task-intent.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/task-intent.js +5 -10
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/task-intent.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/async-guidance.d.ts +2 -0
- package/dist/builtin-extensions/pi-subagents/src/shared/async-guidance.d.ts.map +1 -0
- package/dist/builtin-extensions/pi-subagents/src/shared/async-guidance.js +3 -0
- package/dist/builtin-extensions/pi-subagents/src/shared/async-guidance.js.map +1 -0
- package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts +6 -0
- package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/types.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/delegation-adapters.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/delegation-adapters.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts +7 -0
- package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js +11 -7
- package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts +4 -0
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js +22 -23
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/communication.d.ts +18 -0
- package/dist/builtin-extensions/pi-subagents/src/tui/communication.d.ts.map +1 -0
- package/dist/builtin-extensions/pi-subagents/src/tui/communication.js +47 -0
- package/dist/builtin-extensions/pi-subagents/src/tui/communication.js.map +1 -0
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +2 -0
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js +237 -374
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/index.js +11 -7
- package/dist/builtin-extensions/pi-web-access/index.js.map +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +2 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/install-cli.d.ts.map +1 -1
- package/dist/cli/install-cli.js +15 -45
- package/dist/cli/install-cli.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts +9 -0
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +126 -29
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session.d.ts +3 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +20 -2
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/browser/network.d.ts +9 -0
- package/dist/core/browser/network.d.ts.map +1 -0
- package/dist/core/browser/network.js +146 -0
- package/dist/core/browser/network.js.map +1 -0
- package/dist/core/browser/runtime.d.ts +24 -0
- package/dist/core/browser/runtime.d.ts.map +1 -0
- package/dist/core/browser/runtime.js +289 -0
- package/dist/core/browser/runtime.js.map +1 -0
- package/dist/core/browser/schema.d.ts +16 -0
- package/dist/core/browser/schema.d.ts.map +1 -0
- package/dist/core/browser/schema.js +36 -0
- package/dist/core/browser/schema.js.map +1 -0
- package/dist/core/browser/settings.d.ts +8 -0
- package/dist/core/browser/settings.d.ts.map +1 -0
- package/dist/core/browser/settings.js +30 -0
- package/dist/core/browser/settings.js.map +1 -0
- package/dist/core/browser/setup.d.ts +2 -0
- package/dist/core/browser/setup.d.ts.map +1 -0
- package/dist/core/browser/setup.js +16 -0
- package/dist/core/browser/setup.js.map +1 -0
- package/dist/core/customize.d.ts +2 -0
- package/dist/core/customize.d.ts.map +1 -1
- package/dist/core/customize.js +17 -13
- package/dist/core/customize.js.map +1 -1
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js +1 -1
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +1 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +1 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +1 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/install-features.d.ts.map +1 -1
- package/dist/core/install-features.js +10 -8
- package/dist/core/install-features.js.map +1 -1
- package/dist/core/memory-cap.d.ts.map +1 -1
- package/dist/core/memory-cap.js +5 -3
- package/dist/core/memory-cap.js.map +1 -1
- package/dist/core/model-tiers.d.ts.map +1 -1
- package/dist/core/model-tiers.js +9 -6
- package/dist/core/model-tiers.js.map +1 -1
- package/dist/core/permissions.d.ts.map +1 -1
- package/dist/core/permissions.js +9 -0
- package/dist/core/permissions.js.map +1 -1
- package/dist/core/plan-mode.d.ts.map +1 -1
- package/dist/core/plan-mode.js +3 -0
- package/dist/core/plan-mode.js.map +1 -1
- package/dist/core/process-registry.d.ts.map +1 -1
- package/dist/core/process-registry.js +6 -4
- package/dist/core/process-registry.js.map +1 -1
- package/dist/core/runtime-scope.d.ts +11 -0
- package/dist/core/runtime-scope.d.ts.map +1 -0
- package/dist/core/runtime-scope.js +3 -0
- package/dist/core/runtime-scope.js.map +1 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +13 -0
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-handoff.d.ts +35 -0
- package/dist/core/session-handoff.d.ts.map +1 -0
- package/dist/core/session-handoff.js +214 -0
- package/dist/core/session-handoff.js.map +1 -0
- package/dist/core/session-manager.d.ts +20 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +184 -22
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-ownership.d.ts +28 -0
- package/dist/core/session-ownership.d.ts.map +1 -0
- package/dist/core/session-ownership.js +138 -0
- package/dist/core/session-ownership.js.map +1 -0
- package/dist/core/session-retention.d.ts.map +1 -1
- package/dist/core/session-retention.js +11 -2
- package/dist/core/session-retention.js.map +1 -1
- package/dist/core/settings-manager.d.ts +11 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +29 -0
- 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 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/subagent-spinner-setting.d.ts +6 -0
- package/dist/core/subagent-spinner-setting.d.ts.map +1 -0
- package/dist/core/subagent-spinner-setting.js +12 -0
- package/dist/core/subagent-spinner-setting.js.map +1 -0
- package/dist/core/subagent-spinner.d.ts +4 -0
- package/dist/core/subagent-spinner.d.ts.map +1 -0
- package/dist/core/subagent-spinner.js +6 -0
- package/dist/core/subagent-spinner.js.map +1 -0
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +5 -2
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/todo-settings.d.ts +5 -0
- package/dist/core/todo-settings.d.ts.map +1 -0
- package/dist/core/todo-settings.js +7 -0
- package/dist/core/todo-settings.js.map +1 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +4 -4
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +5 -3
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +4 -4
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +4 -4
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +4 -4
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +4 -4
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +11 -2
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +31 -4
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +4 -4
- package/dist/core/tools/write.js.map +1 -1
- package/dist/core/usage-service.d.ts.map +1 -1
- package/dist/core/usage-service.js +5 -3
- package/dist/core/usage-service.js.map +1 -1
- package/dist/gateway/adapters/discord.d.ts +12 -1
- package/dist/gateway/adapters/discord.d.ts.map +1 -1
- package/dist/gateway/adapters/discord.js +112 -17
- package/dist/gateway/adapters/discord.js.map +1 -1
- package/dist/gateway/adapters/telegram.d.ts +4 -2
- package/dist/gateway/adapters/telegram.d.ts.map +1 -1
- package/dist/gateway/adapters/telegram.js +34 -11
- package/dist/gateway/adapters/telegram.js.map +1 -1
- package/dist/gateway/agent-bridge.d.ts +14 -3
- package/dist/gateway/agent-bridge.d.ts.map +1 -1
- package/dist/gateway/agent-bridge.js +252 -60
- package/dist/gateway/agent-bridge.js.map +1 -1
- package/dist/gateway/approval.d.ts +1 -0
- package/dist/gateway/approval.d.ts.map +1 -1
- package/dist/gateway/approval.js +60 -18
- package/dist/gateway/approval.js.map +1 -1
- package/dist/gateway/authz.d.ts +2 -0
- package/dist/gateway/authz.d.ts.map +1 -1
- package/dist/gateway/authz.js +13 -0
- package/dist/gateway/authz.js.map +1 -1
- package/dist/gateway/buttons.d.ts +3 -1
- package/dist/gateway/buttons.d.ts.map +1 -1
- package/dist/gateway/buttons.js +18 -3
- package/dist/gateway/buttons.js.map +1 -1
- package/dist/gateway/command.d.ts.map +1 -1
- package/dist/gateway/command.js +49 -4
- package/dist/gateway/command.js.map +1 -1
- package/dist/gateway/commands.d.ts.map +1 -1
- package/dist/gateway/commands.js +18 -3
- package/dist/gateway/commands.js.map +1 -1
- package/dist/gateway/config.d.ts +5 -0
- package/dist/gateway/config.d.ts.map +1 -1
- package/dist/gateway/config.js +5 -0
- package/dist/gateway/config.js.map +1 -1
- package/dist/gateway/conversations.d.ts +14 -0
- package/dist/gateway/conversations.d.ts.map +1 -0
- package/dist/gateway/conversations.js +30 -0
- package/dist/gateway/conversations.js.map +1 -0
- package/dist/gateway/download.d.ts +2 -0
- package/dist/gateway/download.d.ts.map +1 -0
- package/dist/gateway/download.js +36 -0
- package/dist/gateway/download.js.map +1 -0
- package/dist/gateway/index.d.ts.map +1 -1
- package/dist/gateway/index.js +85 -26
- package/dist/gateway/index.js.map +1 -1
- package/dist/gateway/mobile-commands.d.ts +24 -0
- package/dist/gateway/mobile-commands.d.ts.map +1 -0
- package/dist/gateway/mobile-commands.js +422 -0
- package/dist/gateway/mobile-commands.js.map +1 -0
- package/dist/gateway/presenter.d.ts +16 -0
- package/dist/gateway/presenter.d.ts.map +1 -0
- package/dist/gateway/presenter.js +210 -0
- package/dist/gateway/presenter.js.map +1 -0
- package/dist/gateway/router.d.ts +1 -0
- package/dist/gateway/router.d.ts.map +1 -1
- package/dist/gateway/router.js +32 -3
- package/dist/gateway/router.js.map +1 -1
- package/dist/gateway/service.d.ts +46 -0
- package/dist/gateway/service.d.ts.map +1 -0
- package/dist/gateway/service.js +395 -0
- package/dist/gateway/service.js.map +1 -0
- package/dist/gateway/setup.d.ts +4 -0
- package/dist/gateway/setup.d.ts.map +1 -0
- package/dist/gateway/setup.js +146 -0
- package/dist/gateway/setup.js.map +1 -0
- package/dist/gateway/types.d.ts +4 -2
- package/dist/gateway/types.d.ts.map +1 -1
- package/dist/gateway/types.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +2 -1
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +11 -2
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +53 -16
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/copyable-text.d.ts +31 -0
- package/dist/modes/interactive/components/copyable-text.d.ts.map +1 -0
- package/dist/modes/interactive/components/copyable-text.js +165 -0
- package/dist/modes/interactive/components/copyable-text.js.map +1 -0
- package/dist/modes/interactive/components/custom-entry.d.ts +1 -0
- package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-entry.js +8 -0
- package/dist/modes/interactive/components/custom-entry.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts +1 -0
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +8 -0
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +16 -0
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +9 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +111 -1
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/extension-widget-order.d.ts +8 -0
- package/dist/modes/interactive/extension-widget-order.d.ts.map +1 -0
- package/dist/modes/interactive/extension-widget-order.js +37 -0
- package/dist/modes/interactive/extension-widget-order.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +3 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +166 -29
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/node-runtime/agent-session-services-NQ6GKOIK.js +49 -0
- package/dist/node-runtime/{builtin-extensions-X4JMM4ZS.js → builtin-extensions-GVC6IFDU.js} +6 -4
- package/dist/node-runtime/{chunk-LTYWTR3V.js → chunk-2MI5OPMN.js} +17 -2
- package/dist/node-runtime/{chunk-W3CVH5RX.js → chunk-2TKODGBZ.js} +11 -6
- package/dist/node-runtime/chunk-4EULYYR4.js +62 -0
- package/dist/node-runtime/chunk-5BNJ4JUH.js +672 -0
- package/dist/node-runtime/{chunk-6N22HULO.js → chunk-5D7LC2ZQ.js} +7 -2
- package/dist/node-runtime/chunk-5ZH3ZFIZ.js +308 -0
- package/dist/node-runtime/{chunk-KBKMCJDU.js → chunk-5ZQXRPMC.js} +19 -4
- package/dist/node-runtime/{chunk-6KDIOJL3.js → chunk-6427XAWG.js} +3 -3
- package/dist/node-runtime/{chunk-BOHIDQT4.js → chunk-6B2POMK7.js} +1 -1
- package/dist/node-runtime/{chunk-RNBHABBA.js → chunk-7QWNYZDI.js} +7 -0
- package/dist/node-runtime/chunk-AZJHNQKQ.js +205 -0
- package/dist/node-runtime/chunk-BFNXONG3.js +521 -0
- package/dist/node-runtime/{chunk-IRPJXI6U.js → chunk-BX2RB477.js} +1 -1
- package/dist/node-runtime/chunk-CCCN2UCX.js +14 -0
- package/dist/node-runtime/{chunk-25I2BHAA.js → chunk-CSUZVNYE.js} +1 -1
- package/dist/node-runtime/{chunk-QZMODZQ2.js → chunk-E24EO34J.js} +2 -1
- package/dist/node-runtime/{chunk-QKFMBRAL.js → chunk-EQ63ANHL.js} +508 -140
- package/dist/node-runtime/{chunk-ELWEXVO5.js → chunk-GJSAD4AB.js} +216 -201
- package/dist/node-runtime/{chunk-AOFXZQKA.js → chunk-GMHJCCEN.js} +8 -8
- package/dist/node-runtime/{chunk-DDWHZ633.js → chunk-GNN7H3B7.js} +1 -1
- package/dist/node-runtime/chunk-GS66LV4M.js +2830 -0
- package/dist/node-runtime/{chunk-6BEIBLQ3.js → chunk-H3XF4UVQ.js} +1 -1
- package/dist/node-runtime/chunk-H4K3JDRB.js +47 -0
- package/dist/node-runtime/{chunk-AROOY4BB.js → chunk-HTFRRDSF.js} +2 -7
- package/dist/node-runtime/chunk-IMLCWLPI.js +9 -0
- package/dist/node-runtime/{chunk-4CSFRBCN.js → chunk-IQIEU7SB.js} +9 -674
- package/dist/node-runtime/{chunk-OPEK5RRY.js → chunk-IVXYUAJE.js} +1 -1
- package/dist/node-runtime/{chunk-AL2FMKKM.js → chunk-IWOWXRWU.js} +58 -48
- package/dist/node-runtime/chunk-KKUTQQV7.js +144 -0
- package/dist/node-runtime/chunk-LISUTZS3.js +19 -0
- package/dist/node-runtime/{chunk-K3646JTM.js → chunk-LMBNLFXQ.js} +25 -314
- package/dist/node-runtime/{chunk-7NBZ5P7I.js → chunk-NAY6UUQZ.js} +1 -1
- package/dist/node-runtime/chunk-OAR4TYZE.js +146 -0
- package/dist/node-runtime/{chunk-STERBGUB.js → chunk-OFKSVRV7.js} +2 -2
- package/dist/node-runtime/{chunk-JZQ7F36T.js → chunk-ORH324EP.js} +19 -3
- package/dist/node-runtime/{chunk-2SJB2AWP.js → chunk-PC2Z5TKZ.js} +3 -3
- package/dist/node-runtime/{chunk-46ECNOLF.js → chunk-QDGKKKUM.js} +97 -162
- package/dist/node-runtime/chunk-R3K2F5GI.js +122 -0
- package/dist/node-runtime/chunk-RMQZU2YU.js +117 -0
- package/dist/node-runtime/{chunk-JYNNB7DU.js → chunk-TDL7UWJ7.js} +283 -2999
- package/dist/node-runtime/{chunk-G6LRAP36.js → chunk-TQGPP4SC.js} +1 -1
- package/dist/node-runtime/chunk-UAEOTO52.js +119 -0
- package/dist/node-runtime/{chunk-4DJ6HEGH.js → chunk-UAFLNHSH.js} +18 -14
- package/dist/node-runtime/{chunk-AY6CAJSL.js → chunk-UJOCPOMX.js} +6 -3
- package/dist/node-runtime/chunk-UP2XBVH5.js +40 -0
- package/dist/node-runtime/{chunk-WJVFOIB5.js → chunk-UQUCFAJ3.js} +1 -1
- package/dist/node-runtime/chunk-URD2SLIT.js +1019 -0
- package/dist/node-runtime/chunk-US544NN6.js +13 -0
- package/dist/node-runtime/chunk-UWPJL22I.js +341 -0
- package/dist/node-runtime/chunk-V2A7CEXK.js +355 -0
- package/dist/node-runtime/chunk-VJPTNWAP.js +708 -0
- package/dist/node-runtime/{chunk-WKDK4C5P.js → chunk-VSSXXL36.js} +38 -164
- package/dist/node-runtime/{chunk-4I23VTC4.js → chunk-VWCE2HSZ.js} +21 -124
- package/dist/node-runtime/{chunk-CBGB57XT.js → chunk-WADV2VDS.js} +32 -1014
- package/dist/node-runtime/{chunk-GKLEQ3I4.js → chunk-XLTL257W.js} +126 -27
- package/dist/node-runtime/chunk-YPHAIRZT.js +10 -0
- package/dist/node-runtime/cli-runtime.js +2 -2
- package/dist/node-runtime/command-3JHHXOPX.js +45 -0
- package/dist/node-runtime/commands-2JVNFGMQ.js +36 -0
- package/dist/node-runtime/{commands-MV5KOZ64.js → commands-KAMO2T6P.js} +10 -10
- package/dist/node-runtime/config-RORQUQFG.js +20 -0
- package/dist/node-runtime/{customize-XEXL2DGQ.js → customize-VFJV3U6A.js} +2 -1
- package/dist/node-runtime/{direct-tool-executor-BK7CLEBX.js → direct-tool-executor-YAVOLDFY.js} +8 -8
- package/dist/node-runtime/{export-html-TEXVV5RP.js → export-html-KBFVV63J.js} +4 -3
- package/dist/node-runtime/{extension-input-O4HSAEM4.js → extension-input-K24TVKVW.js} +4 -4
- package/dist/node-runtime/{extension-selector-X5FCX43D.js → extension-selector-SPNF7EDR.js} +4 -4
- package/dist/node-runtime/{extract-XLQSJN4V.js → extract-EQJE7FZZ.js} +2 -2
- package/dist/node-runtime/{gateway-L4ANRTVE.js → gateway-VFO6SFKK.js} +275 -994
- package/dist/node-runtime/{gemini-search-U7SUMPQA.js → gemini-search-35OCRFLN.js} +1 -1
- package/dist/node-runtime/{gemini-url-context-PXWCBQHK.js → gemini-url-context-UQY3PHHW.js} +2 -2
- package/dist/node-runtime/index.js +105 -64
- package/dist/node-runtime/{init-3C7Z24OI.js → init-X2LIUB2H.js} +3 -3
- package/dist/node-runtime/{install-cli-EXMJQESX.js → install-cli-C3CF7O7N.js} +21 -82
- package/dist/node-runtime/interactive-mode-LOM6AIF6.js +72 -0
- package/dist/node-runtime/{interactive-view-ILS6TAN5.js → interactive-view-IDSCPPK7.js} +8 -8
- package/dist/node-runtime/lunr-browser-YNW7FTYX.js +87 -0
- package/dist/node-runtime/{lunr-cron-NNYTWTGF.js → lunr-cron-BKHGNBKT.js} +19 -5
- package/dist/node-runtime/main.js +45 -30
- package/dist/node-runtime/{memory-cap-3S4XRLNP.js → memory-cap-EL3KL4JJ.js} +2 -1
- package/dist/node-runtime/mobile-commands-HMP25WBC.js +32 -0
- package/dist/node-runtime/model-runtime-PLQKAG4B.js +16 -0
- package/dist/node-runtime/{model-tiers-NJLHUEGK.js → model-tiers-OU3U5CZG.js} +2 -1
- package/dist/node-runtime/{package-manager-cli-7RKSZGEN.js → package-manager-cli-VCK4E2RC.js} +23 -15
- package/dist/node-runtime/{pi-intercom-DDQMRNPJ.js → pi-intercom-HBPK5HSJ.js} +38 -34
- package/dist/node-runtime/{pi-mcp-adapter-GUFZWW54.js → pi-mcp-adapter-E6WULBKF.js} +4 -4
- package/dist/node-runtime/{pi-subagents-T5WMMLBB.js → pi-subagents-FEUDLJOE.js} +476 -412
- package/dist/node-runtime/{pi-web-access-2CQGFLT2.js → pi-web-access-WTGMNZ32.js} +15 -15
- package/dist/node-runtime/process-registry-4FAKZQOL.js +31 -0
- package/dist/node-runtime/{proxy-modes-V6YVFH3C.js → proxy-modes-OSQCWRBI.js} +9 -9
- package/dist/node-runtime/rpc-entry.js +46 -31
- package/dist/node-runtime/{rpc-mode-W5ZTLTMZ.js → rpc-mode-P5ODXPEG.js} +2 -2
- package/dist/node-runtime/runtime-4VA6JKNF.js +373 -0
- package/dist/node-runtime/{runtime-bridges-NJQERQ72.js → runtime-bridges-3XUQ46XW.js} +6 -5
- package/dist/node-runtime/service-ISSP6VHE.js +36 -0
- package/dist/node-runtime/session-handoff-HC7R5E24.js +33 -0
- package/dist/node-runtime/{session-manager-E7AREDTV.js → session-manager-CFN4UFM2.js} +2 -1
- package/dist/node-runtime/{session-selector-FJ7M2AIX.js → session-selector-LHRMJOKT.js} +5 -4
- package/dist/node-runtime/{settings-manager-GHPTUN7R.js → settings-manager-UUZ6NUXI.js} +8 -2
- package/dist/node-runtime/setup-JBKOLJ6F.js +18 -0
- package/dist/node-runtime/setup-NRXVZBLJ.js +155 -0
- package/dist/node-runtime/{subagent-executor-SRFC26SJ.js → subagent-executor-MLUMBWCP.js} +35 -63
- package/dist/node-runtime/theme-U7IGOA7O.js +68 -0
- package/dist/node-runtime/trust-manager-MMISNCYO.js +17 -0
- package/dist/node-runtime/{update-cli-L3JIBH2U.js → update-cli-4TP25CNW.js} +8 -2
- package/dist/node-runtime/usage-service-LFB2SWYV.js +37 -0
- package/dist/node-runtime/{video-extract-OYT5WKS5.js → video-extract-OOZHR7SU.js} +2 -2
- package/dist/node-runtime/{youtube-extract-TQYKGFGS.js → youtube-extract-FNPAUNHU.js} +6 -6
- package/docs/browser.md +86 -0
- package/docs/extensions.md +2 -0
- package/docs/features.md +99 -17
- package/docs/interactive-startup.md +2 -1
- package/docs/sessions.md +10 -0
- package/docs/settings.md +3 -1
- package/docs/tui.md +2 -0
- package/docs/usage.md +16 -0
- 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/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/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/package.json +7 -4
- package/scripts/install-browser.mjs +20 -0
- package/dist/node-runtime/agent-session-services-75JKASCW.js +0 -36
- package/dist/node-runtime/chunk-HQCKFM2O.js +0 -56
- package/dist/node-runtime/command-RBTRL55A.js +0 -13
- package/dist/node-runtime/interactive-mode-HPUNH7SV.js +0 -57
- package/dist/node-runtime/{chunk-UWQYRSYQ.js → chunk-YJMMG7C6.js} +25 -25
- package/dist/node-runtime/{mcp-panel-IIGMXQGP.js → mcp-panel-KTTFXJZ4.js} +3 -3
- package/dist/node-runtime/{src-BPQFJR76.js → src-IVPNZ2BX.js} +9 -9
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { AssistantMessage } from "@ashx-j/lunr-ai";
|
|
2
2
|
import { Container, type MarkdownTheme } from "@ashx-j/lunr-tui";
|
|
3
3
|
import { type ThinkingRunTiming } from "./thinking-summary.ts";
|
|
4
|
+
export interface AssistantMessageCopyOptions {
|
|
5
|
+
copyText?: (text: string) => Promise<void>;
|
|
6
|
+
requestRender?: () => void;
|
|
7
|
+
}
|
|
4
8
|
/**
|
|
5
9
|
* Component that renders a complete assistant message
|
|
6
10
|
*/
|
|
@@ -18,14 +22,17 @@ export declare class AssistantMessageComponent extends Container {
|
|
|
18
22
|
private lastMessage?;
|
|
19
23
|
private thinkingSource?;
|
|
20
24
|
private hasToolCalls;
|
|
21
|
-
|
|
25
|
+
private readonly copyText;
|
|
26
|
+
private readonly requestRender;
|
|
27
|
+
private readonly copyStates;
|
|
28
|
+
constructor(message?: AssistantMessage, hideThinkingBlock?: boolean, markdownTheme?: MarkdownTheme, hiddenThinkingLabel?: string, outputPad?: number, thinkingCollapse?: boolean, copyOptions?: AssistantMessageCopyOptions);
|
|
22
29
|
invalidate(): void;
|
|
23
30
|
setHideThinkingBlock(hide: boolean): void;
|
|
24
31
|
setThinkingCollapse(collapse: boolean): void;
|
|
25
32
|
setExpanded(expanded: boolean): void;
|
|
26
33
|
private isRunExpanded;
|
|
27
34
|
toggleThinkingRun(runIndex: number): void;
|
|
28
|
-
handleClick(localY: number, width: number): boolean;
|
|
35
|
+
handleClick(localY: number, width: number, localX?: number): boolean;
|
|
29
36
|
setThinkingTimings(timings: ThinkingRunTiming[] | undefined): void;
|
|
30
37
|
setHiddenThinkingLabel(label: string): void;
|
|
31
38
|
setOutputPad(padding: number): void;
|
|
@@ -34,6 +41,8 @@ export declare class AssistantMessageComponent extends Container {
|
|
|
34
41
|
updateContent(message: AssistantMessage, options?: {
|
|
35
42
|
thinkingSource?: AssistantMessage;
|
|
36
43
|
}): void;
|
|
44
|
+
private copyPayload;
|
|
45
|
+
private refreshCopyStatus;
|
|
37
46
|
private renderThinkingRun;
|
|
38
47
|
}
|
|
39
48
|
//# sourceMappingURL=assistant-message.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assistant-message.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/assistant-message.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAkB,SAAS,EAAY,KAAK,aAAa,EAAgB,MAAM,wBAAwB,CAAC;AAE/G,OAAO,EAGN,KAAK,iBAAiB,EAEtB,MAAM,uBAAuB,CAAC;AAO/B;;GAEG;AACH,qBAAa,yBAA0B,SAAQ,SAAS;IACvD,UAAU,UAAQ;IAClB,OAAO,CAAC,gBAAgB,CAAY;IACpC,OAAO,CAAC,iBAAiB,CAAU;IAGnC,OAAO,CAAC,gBAAgB,CAAU;IAElC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,YAAY,CAAqB;IAGzC,OAAO,CAAC,eAAe,CAAC,CAAsB;IAC9C,OAAO,CAAC,aAAa,CAAgB;IAGrC,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAC,CAAmB;IACvC,OAAO,CAAC,cAAc,CAAC,CAAmB;IAC1C,OAAO,CAAC,YAAY,CAAS;IAE7B,YACC,OAAO,CAAC,EAAE,gBAAgB,EAC1B,iBAAiB,UAAQ,EACzB,aAAa,GAAE,aAAkC,EACjD,mBAAmB,SAAgB,EACnC,SAAS,SAAI,EACb,gBAAgB,UAAQ,EAiBxB;IAEQ,UAAU,IAAI,IAAI,CAK1B;IAED,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAKxC;IAGD,mBAAmB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAK3C;IAGD,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAMnC;IAED,OAAO,CAAC,aAAa;IAIrB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAgBxC;IAED,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAclD;IAED,kBAAkB,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,SAAS,GAAG,IAAI,CAEjE;IAED,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAK1C;IAED,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAKlC;IAEQ,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAQvC;IAED,OAAO,CAAC,qBAAqB;IAI7B,aAAa,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,gBAAgB,CAAA;KAAE,GAAG,IAAI,CAiG9F;IAED,OAAO,CAAC,iBAAiB;CA6DzB","sourcesContent":["import type { AssistantMessage } from \"@ashx-j/lunr-ai\";\nimport { type Component, Container, Markdown, type MarkdownTheme, Spacer, Text } from \"@ashx-j/lunr-tui\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\nimport {\n\tformatThoughtDuration,\n\tisThinkingRunComplete,\n\ttype ThinkingRunTiming,\n\tthinkingSnippet,\n} from \"./thinking-summary.ts\";\nimport { ThinkingTailComponent } from \"./thinking-tail.ts\";\n\nconst OSC133_ZONE_START = \"\\x1b]133;A\\x07\";\nconst OSC133_ZONE_END = \"\\x1b]133;B\\x07\";\nconst OSC133_ZONE_FINAL = \"\\x1b]133;C\\x07\";\n\n/**\n * Component that renders a complete assistant message\n */\nexport class AssistantMessageComponent extends Container {\n\tselectable = true;\n\tprivate contentContainer: Container;\n\tprivate hideThinkingBlock: boolean;\n\t// lunr: collapsible reasoning — when true, a completed thinking run renders as\n\t// \"✻ Thought for Xs\" + its first sentence instead of the full block.\n\tprivate thinkingCollapse: boolean;\n\t// lunr: per-run expand. `expanded` still means \"all runs\" for setExpanded().\n\tprivate expanded = false;\n\tprivate expandedRuns = new Set<number>();\n\t// lunr: live per-run timings from interactive-mode; undefined = history message\n\t// (always treated as final, rendered without durations).\n\tprivate thinkingTimings?: ThinkingRunTiming[];\n\tprivate markdownTheme: MarkdownTheme;\n\t// lunr: kept for the deferred alternative hidden-thinking indicator (Phase 8 removed the label render).\n\t// biome-ignore lint/correctness/noUnusedPrivateClassMembers: retained for future use\n\tprivate hiddenThinkingLabel: string;\n\tprivate outputPad: number;\n\tprivate lastMessage?: AssistantMessage;\n\tprivate thinkingSource?: AssistantMessage;\n\tprivate hasToolCalls = false;\n\n\tconstructor(\n\t\tmessage?: AssistantMessage,\n\t\thideThinkingBlock = false,\n\t\tmarkdownTheme: MarkdownTheme = getMarkdownTheme(),\n\t\thiddenThinkingLabel = \"Thinking...\",\n\t\toutputPad = 1,\n\t\tthinkingCollapse = false,\n\t) {\n\t\tsuper();\n\n\t\tthis.hideThinkingBlock = hideThinkingBlock;\n\t\tthis.thinkingCollapse = thinkingCollapse;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.hiddenThinkingLabel = hiddenThinkingLabel;\n\t\tthis.outputPad = outputPad;\n\n\t\t// Container for text/thinking content\n\t\tthis.contentContainer = new Container();\n\t\tthis.addChild(this.contentContainer);\n\n\t\tif (message) {\n\t\t\tthis.updateContent(message);\n\t\t}\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\tsetHideThinkingBlock(hide: boolean): void {\n\t\tthis.hideThinkingBlock = hide;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\t// lunr: collapsible reasoning toggles (live; re-render like setHideThinkingBlock).\n\tsetThinkingCollapse(collapse: boolean): void {\n\t\tthis.thinkingCollapse = collapse;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\t// lunr: Expandable hook; true expands every thinking run, false collapses all.\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tif (!expanded) this.expandedRuns.clear();\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\tprivate isRunExpanded(runIndex: number): boolean {\n\t\treturn this.expanded || this.expandedRuns.has(runIndex);\n\t}\n\n\ttoggleThinkingRun(runIndex: number): void {\n\t\tif (this.expanded) {\n\t\t\tthis.expanded = false;\n\t\t\tthis.expandedRuns.clear();\n\t\t\tconst count = this.lastMessage ? collectThinkingRuns(this.lastMessage.content).length : 0;\n\t\t\tfor (let i = 0; i < count; i++) {\n\t\t\t\tif (i !== runIndex) this.expandedRuns.add(i);\n\t\t\t}\n\t\t} else if (this.expandedRuns.has(runIndex)) {\n\t\t\tthis.expandedRuns.delete(runIndex);\n\t\t} else {\n\t\t\tthis.expandedRuns.add(runIndex);\n\t\t}\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\thandleClick(localY: number, width: number): boolean {\n\t\tconst contentWidth = width;\n\t\tlet y = 0;\n\t\tfor (const child of this.contentContainer.children) {\n\t\t\tconst h = child.render(contentWidth).length;\n\t\t\tif (localY >= y && localY < y + h) {\n\t\t\t\tif (typeof child.handleClick === \"function\") {\n\t\t\t\t\treturn child.handleClick(localY - y, contentWidth);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\ty += h;\n\t\t}\n\t\treturn false;\n\t}\n\n\tsetThinkingTimings(timings: ThinkingRunTiming[] | undefined): void {\n\t\tthis.thinkingTimings = timings;\n\t}\n\n\tsetHiddenThinkingLabel(label: string): void {\n\t\tthis.hiddenThinkingLabel = label;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\tsetOutputPad(padding: number): void {\n\t\tthis.outputPad = padding;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst lines = super.render(width);\n\t\tif (this.hasToolCalls || lines.length === 0) return lines;\n\n\t\tlines[0] = OSC133_ZONE_START + lines[0];\n\t\tlines[lines.length - 1] = OSC133_ZONE_END + OSC133_ZONE_FINAL + lines[lines.length - 1];\n\n\t\treturn lines;\n\t}\n\n\tprivate thinkingSourceOptions(): { thinkingSource?: AssistantMessage } | undefined {\n\t\treturn this.thinkingSource ? { thinkingSource: this.thinkingSource } : undefined;\n\t}\n\n\tupdateContent(message: AssistantMessage, options?: { thinkingSource?: AssistantMessage }): void {\n\t\tthis.lastMessage = message;\n\t\tthis.thinkingSource = options?.thinkingSource;\n\n\t\t// Clear content container\n\t\tthis.contentContainer.clear();\n\n\t\tconst sourceMessage = this.thinkingSource ?? message;\n\t\tconst sourceThinkingRuns = collectThinkingRuns(sourceMessage.content);\n\t\tconst hasVisibleContent = message.content.some(\n\t\t\t(c) =>\n\t\t\t\t(c.type === \"text\" && c.text.trim()) ||\n\t\t\t\t(!this.hideThinkingBlock && c.type === \"thinking\" && c.thinking.trim()),\n\t\t);\n\n\t\tif (hasVisibleContent) {\n\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t}\n\n\t\t// Render content in order\n\t\tlet isFirstTextBlock = true;\n\t\tlet thinkingRunIndex = -1;\n\t\tfor (let i = 0; i < message.content.length; i++) {\n\t\t\tconst content = message.content[i];\n\t\t\tif (content.type === \"text\" && content.text.trim()) {\n\t\t\t\t// Assistant text messages with no background - trim the text\n\t\t\t\t// Set paddingY=0 to avoid extra spacing before tool executions\n\t\t\t\t// lunr: leading ● marks the first text block (never thinking blocks). It rides\n\t\t\t\t// the defaultTextStyle below, so it renders bright white like the body.\n\t\t\t\tconst trimmed = content.text.trim();\n\t\t\t\tconst text = isFirstTextBlock ? `● ${trimmed}` : trimmed;\n\t\t\t\tisFirstTextBlock = false;\n\t\t\t\t// lunr: theme-polish — assistant message body renders bright white via the\n\t\t\t\t// shared userMessageText token (same knob as user messages).\n\t\t\t\tthis.contentContainer.addChild(\n\t\t\t\t\tnew Markdown(text, this.outputPad, 0, this.markdownTheme, {\n\t\t\t\t\t\tcolor: (body: string) => theme.fg(\"userMessageText\", body),\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t} else if (content.type === \"thinking\") {\n\t\t\t\tthinkingRunIndex++;\n\t\t\t\tconst displayBlocks: string[] = [];\n\t\t\t\tfor (; i < message.content.length; i++) {\n\t\t\t\t\tconst thinkingContent = message.content[i];\n\t\t\t\t\tif (thinkingContent.type !== \"thinking\") {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tconst thinking = thinkingContent.thinking.trim();\n\t\t\t\t\tif (thinking) {\n\t\t\t\t\t\tdisplayBlocks.push(thinking);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ti--;\n\n\t\t\t\tif (displayBlocks.length === 0 || this.hideThinkingBlock) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst sourceBlocks = sourceThinkingRuns[thinkingRunIndex] ?? [];\n\t\t\t\tconst fullyRevealed =\n\t\t\t\t\tdisplayBlocks.length === sourceBlocks.length &&\n\t\t\t\t\tdisplayBlocks.every((block, index) => block === sourceBlocks[index]);\n\t\t\t\tthis.renderThinkingRun(thinkingRunIndex, displayBlocks, message, i, fullyRevealed);\n\t\t\t}\n\t\t}\n\n\t\t// Check if incomplete/failed - show after partial content.\n\t\t// For aborted/error tool calls, tool execution components show the error.\n\t\t// Length stops can happen before a tool call is complete, so surface them here too.\n\t\tconst hasToolCalls = message.content.some((c) => c.type === \"toolCall\");\n\t\tthis.hasToolCalls = hasToolCalls;\n\t\tif (message.stopReason === \"length\") {\n\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\tthis.contentContainer.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\t\"Error: Model stopped because it reached the maximum output token limit. The response may be incomplete.\",\n\t\t\t\t\t),\n\t\t\t\t\tthis.outputPad,\n\t\t\t\t\t0,\n\t\t\t\t),\n\t\t\t);\n\t\t} else if (!hasToolCalls) {\n\t\t\tif (message.stopReason === \"aborted\") {\n\t\t\t\tconst abortMessage =\n\t\t\t\t\tmessage.errorMessage && message.errorMessage !== \"Request was aborted\"\n\t\t\t\t\t\t? message.errorMessage\n\t\t\t\t\t\t: \"Operation aborted\";\n\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t\tthis.contentContainer.addChild(new Text(theme.fg(\"error\", abortMessage), this.outputPad, 0));\n\t\t\t} else if (message.stopReason === \"error\") {\n\t\t\t\tconst errorMsg = message.errorMessage || \"Unknown error\";\n\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t\tthis.contentContainer.addChild(new Text(theme.fg(\"error\", `Error: ${errorMsg}`), this.outputPad, 0));\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate renderThinkingRun(\n\t\tthinkingRunIndex: number,\n\t\tthinkingBlocks: string[],\n\t\tdisplayMessage: AssistantMessage,\n\t\tdisplayIndex: number,\n\t\tfullyRevealed: boolean,\n\t): void {\n\t\tconst hasVisibleContentAfter =\n\t\t\tdisplayIndex >= 0\n\t\t\t\t? displayMessage.content\n\t\t\t\t\t\t.slice(displayIndex + 1)\n\t\t\t\t\t\t.some((c) => (c.type === \"text\" && c.text.trim()) || (c.type === \"thinking\" && c.thinking.trim()))\n\t\t\t\t: displayMessage.content.some((c) => c.type === \"text\" && c.text.trim());\n\n\t\t// Provider completion can precede the reveal cursor; keep animating until it catches up.\n\t\tconst runComplete =\n\t\t\tfullyRevealed &&\n\t\t\tisThinkingRunComplete(false, this.thinkingTimings?.[thinkingRunIndex], this.thinkingTimings !== undefined);\n\t\tconst wrap = (inner: Component): void => {\n\t\t\tthis.contentContainer.addChild(new ThinkingRunBlock(this, thinkingRunIndex, inner));\n\t\t};\n\t\tif (this.thinkingCollapse && !this.isRunExpanded(thinkingRunIndex) && runComplete) {\n\t\t\tconst timing = this.thinkingTimings?.[thinkingRunIndex];\n\t\t\tconst label =\n\t\t\t\ttiming?.end !== undefined\n\t\t\t\t\t? `✻ Thought for ${formatThoughtDuration(timing.end - timing.start)}`\n\t\t\t\t\t: \"✻ Thought\";\n\t\t\tconst block = new Container();\n\t\t\tblock.addChild(new Text(theme.fg(\"thinkingText\", theme.italic(label)), this.outputPad, 0));\n\t\t\tconst snippet = thinkingSnippet(thinkingBlocks.join(\"\\n\\n\"));\n\t\t\tif (snippet) {\n\t\t\t\tblock.addChild(new Text(theme.fg(\"thinkingText\", theme.italic(snippet)), this.outputPad + 2, 0));\n\t\t\t}\n\t\t\twrap(block);\n\t\t\tif (hasVisibleContentAfter) {\n\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (!runComplete && !this.isRunExpanded(thinkingRunIndex)) {\n\t\t\twrap(\n\t\t\t\tnew ThinkingTailComponent(thinkingBlocks.join(\"\\n\\n\"), this.outputPad, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"thinkingText\", text),\n\t\t\t\t\titalic: true,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tif (hasVisibleContentAfter) {\n\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\twrap(\n\t\t\tnew Markdown(thinkingBlocks.join(\"\\n\\n\"), this.outputPad, 0, this.markdownTheme, {\n\t\t\t\tcolor: (text: string) => theme.fg(\"thinkingText\", text),\n\t\t\t\titalic: true,\n\t\t\t}),\n\t\t);\n\t\tif (hasVisibleContentAfter) {\n\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t}\n\t}\n}\n\nclass ThinkingRunBlock extends Container {\n\tprivate readonly owner: AssistantMessageComponent;\n\tprivate readonly runIndex: number;\n\n\tconstructor(owner: AssistantMessageComponent, runIndex: number, inner: Component) {\n\t\tsuper();\n\t\tthis.owner = owner;\n\t\tthis.runIndex = runIndex;\n\t\tthis.addChild(inner);\n\t}\n\n\thandleClick(_localY: number, _width: number): boolean {\n\t\tthis.owner.toggleThinkingRun(this.runIndex);\n\t\treturn true;\n\t}\n}\n\nfunction collectThinkingRuns(content: AssistantMessage[\"content\"]): string[][] {\n\tconst runs: string[][] = [];\n\tfor (let i = 0; i < content.length; i++) {\n\t\tconst block = content[i];\n\t\tif (block.type !== \"thinking\") continue;\n\t\tconst blocks: string[] = [];\n\t\tfor (; i < content.length; i++) {\n\t\t\tconst thinkingContent = content[i];\n\t\t\tif (thinkingContent.type !== \"thinking\") {\n\t\t\t\ti--;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tconst thinking = thinkingContent.thinking.trim();\n\t\t\tif (thinking) blocks.push(thinking);\n\t\t}\n\t\truns.push(blocks);\n\t}\n\treturn runs;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"assistant-message.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/assistant-message.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAkB,SAAS,EAAY,KAAK,aAAa,EAAgB,MAAM,wBAAwB,CAAC;AAI/G,OAAO,EAGN,KAAK,iBAAiB,EAEtB,MAAM,uBAAuB,CAAC;AAO/B,MAAM,WAAW,2BAA2B;IAC3C,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAOD;;GAEG;AACH,qBAAa,yBAA0B,SAAQ,SAAS;IACvD,UAAU,UAAQ;IAClB,OAAO,CAAC,gBAAgB,CAAY;IACpC,OAAO,CAAC,iBAAiB,CAAU;IAGnC,OAAO,CAAC,gBAAgB,CAAU;IAElC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,YAAY,CAAqB;IAGzC,OAAO,CAAC,eAAe,CAAC,CAAsB;IAC9C,OAAO,CAAC,aAAa,CAAgB;IAGrC,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAC,CAAmB;IACvC,OAAO,CAAC,cAAc,CAAC,CAAmB;IAC1C,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;IAC3D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAa;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgC;IAE3D,YACC,OAAO,CAAC,EAAE,gBAAgB,EAC1B,iBAAiB,UAAQ,EACzB,aAAa,GAAE,aAAkC,EACjD,mBAAmB,SAAgB,EACnC,SAAS,SAAI,EACb,gBAAgB,UAAQ,EACxB,WAAW,GAAE,2BAAgC,EAmB7C;IAEQ,UAAU,IAAI,IAAI,CAK1B;IAED,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAKxC;IAGD,mBAAmB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAK3C;IAGD,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAMnC;IAED,OAAO,CAAC,aAAa;IAIrB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAgBxC;IAED,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAcnE;IAED,kBAAkB,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,SAAS,GAAG,IAAI,CAEjE;IAED,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAK1C;IAED,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAKlC;IAEQ,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAQvC;IAED,OAAO,CAAC,qBAAqB;IAI7B,aAAa,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,gBAAgB,CAAA;KAAE,GAAG,IAAI,CAgH9F;IAED,OAAO,CAAC,WAAW;IAkBnB,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,iBAAiB;CAgEzB","sourcesContent":["import type { AssistantMessage } from \"@ashx-j/lunr-ai\";\nimport { type Component, Container, Markdown, type MarkdownTheme, Spacer, Text } from \"@ashx-j/lunr-tui\";\nimport { copyToClipboard } from \"../../../utils/clipboard.ts\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\nimport { CopyableTextBlockComponent, type CopyableTextStatus, parseCopyableTextSegments } from \"./copyable-text.ts\";\nimport {\n\tformatThoughtDuration,\n\tisThinkingRunComplete,\n\ttype ThinkingRunTiming,\n\tthinkingSnippet,\n} from \"./thinking-summary.ts\";\nimport { ThinkingTailComponent } from \"./thinking-tail.ts\";\n\nconst OSC133_ZONE_START = \"\\x1b]133;A\\x07\";\nconst OSC133_ZONE_END = \"\\x1b]133;B\\x07\";\nconst OSC133_ZONE_FINAL = \"\\x1b]133;C\\x07\";\n\nexport interface AssistantMessageCopyOptions {\n\tcopyText?: (text: string) => Promise<void>;\n\trequestRender?: () => void;\n}\n\ninterface CopyState {\n\tpayload: string;\n\tstatus: CopyableTextStatus;\n}\n\n/**\n * Component that renders a complete assistant message\n */\nexport class AssistantMessageComponent extends Container {\n\tselectable = true;\n\tprivate contentContainer: Container;\n\tprivate hideThinkingBlock: boolean;\n\t// lunr: collapsible reasoning — when true, a completed thinking run renders as\n\t// \"✻ Thought for Xs\" + its first sentence instead of the full block.\n\tprivate thinkingCollapse: boolean;\n\t// lunr: per-run expand. `expanded` still means \"all runs\" for setExpanded().\n\tprivate expanded = false;\n\tprivate expandedRuns = new Set<number>();\n\t// lunr: live per-run timings from interactive-mode; undefined = history message\n\t// (always treated as final, rendered without durations).\n\tprivate thinkingTimings?: ThinkingRunTiming[];\n\tprivate markdownTheme: MarkdownTheme;\n\t// lunr: kept for the deferred alternative hidden-thinking indicator (Phase 8 removed the label render).\n\t// biome-ignore lint/correctness/noUnusedPrivateClassMembers: retained for future use\n\tprivate hiddenThinkingLabel: string;\n\tprivate outputPad: number;\n\tprivate lastMessage?: AssistantMessage;\n\tprivate thinkingSource?: AssistantMessage;\n\tprivate hasToolCalls = false;\n\tprivate readonly copyText: (text: string) => Promise<void>;\n\tprivate readonly requestRender: () => void;\n\tprivate readonly copyStates = new Map<string, CopyState>();\n\n\tconstructor(\n\t\tmessage?: AssistantMessage,\n\t\thideThinkingBlock = false,\n\t\tmarkdownTheme: MarkdownTheme = getMarkdownTheme(),\n\t\thiddenThinkingLabel = \"Thinking...\",\n\t\toutputPad = 1,\n\t\tthinkingCollapse = false,\n\t\tcopyOptions: AssistantMessageCopyOptions = {},\n\t) {\n\t\tsuper();\n\n\t\tthis.hideThinkingBlock = hideThinkingBlock;\n\t\tthis.thinkingCollapse = thinkingCollapse;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.hiddenThinkingLabel = hiddenThinkingLabel;\n\t\tthis.outputPad = outputPad;\n\t\tthis.copyText = copyOptions.copyText ?? copyToClipboard;\n\t\tthis.requestRender = copyOptions.requestRender ?? (() => {});\n\n\t\t// Container for text/thinking content\n\t\tthis.contentContainer = new Container();\n\t\tthis.addChild(this.contentContainer);\n\n\t\tif (message) {\n\t\t\tthis.updateContent(message);\n\t\t}\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\tsetHideThinkingBlock(hide: boolean): void {\n\t\tthis.hideThinkingBlock = hide;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\t// lunr: collapsible reasoning toggles (live; re-render like setHideThinkingBlock).\n\tsetThinkingCollapse(collapse: boolean): void {\n\t\tthis.thinkingCollapse = collapse;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\t// lunr: Expandable hook; true expands every thinking run, false collapses all.\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tif (!expanded) this.expandedRuns.clear();\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\tprivate isRunExpanded(runIndex: number): boolean {\n\t\treturn this.expanded || this.expandedRuns.has(runIndex);\n\t}\n\n\ttoggleThinkingRun(runIndex: number): void {\n\t\tif (this.expanded) {\n\t\t\tthis.expanded = false;\n\t\t\tthis.expandedRuns.clear();\n\t\t\tconst count = this.lastMessage ? collectThinkingRuns(this.lastMessage.content).length : 0;\n\t\t\tfor (let i = 0; i < count; i++) {\n\t\t\t\tif (i !== runIndex) this.expandedRuns.add(i);\n\t\t\t}\n\t\t} else if (this.expandedRuns.has(runIndex)) {\n\t\t\tthis.expandedRuns.delete(runIndex);\n\t\t} else {\n\t\t\tthis.expandedRuns.add(runIndex);\n\t\t}\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\thandleClick(localY: number, width: number, localX?: number): boolean {\n\t\tconst contentWidth = width;\n\t\tlet y = 0;\n\t\tfor (const child of this.contentContainer.children) {\n\t\t\tconst h = child.render(contentWidth).length;\n\t\t\tif (localY >= y && localY < y + h) {\n\t\t\t\tif (typeof child.handleClick === \"function\") {\n\t\t\t\t\treturn child.handleClick(localY - y, contentWidth, localX);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\ty += h;\n\t\t}\n\t\treturn false;\n\t}\n\n\tsetThinkingTimings(timings: ThinkingRunTiming[] | undefined): void {\n\t\tthis.thinkingTimings = timings;\n\t}\n\n\tsetHiddenThinkingLabel(label: string): void {\n\t\tthis.hiddenThinkingLabel = label;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\tsetOutputPad(padding: number): void {\n\t\tthis.outputPad = padding;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst lines = super.render(width);\n\t\tif (this.hasToolCalls || lines.length === 0) return lines;\n\n\t\tlines[0] = OSC133_ZONE_START + lines[0];\n\t\tlines[lines.length - 1] = OSC133_ZONE_END + OSC133_ZONE_FINAL + lines[lines.length - 1];\n\n\t\treturn lines;\n\t}\n\n\tprivate thinkingSourceOptions(): { thinkingSource?: AssistantMessage } | undefined {\n\t\treturn this.thinkingSource ? { thinkingSource: this.thinkingSource } : undefined;\n\t}\n\n\tupdateContent(message: AssistantMessage, options?: { thinkingSource?: AssistantMessage }): void {\n\t\tthis.lastMessage = message;\n\t\tthis.thinkingSource = options?.thinkingSource;\n\n\t\t// Clear content container\n\t\tthis.contentContainer.clear();\n\n\t\tconst sourceMessage = this.thinkingSource ?? message;\n\t\tconst sourceThinkingRuns = collectThinkingRuns(sourceMessage.content);\n\t\tconst hasVisibleContent = message.content.some(\n\t\t\t(c) =>\n\t\t\t\t(c.type === \"text\" && c.text.trim()) ||\n\t\t\t\t(!this.hideThinkingBlock && c.type === \"thinking\" && c.thinking.trim()),\n\t\t);\n\n\t\tif (hasVisibleContent) {\n\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t}\n\n\t\t// Render content in order\n\t\tlet isFirstTextBlock = true;\n\t\tlet thinkingRunIndex = -1;\n\t\tfor (let i = 0; i < message.content.length; i++) {\n\t\t\tconst content = message.content[i];\n\t\t\tif (content.type === \"text\" && content.text.trim()) {\n\t\t\t\tfor (const segment of parseCopyableTextSegments(content.text)) {\n\t\t\t\t\tif (segment.type === \"markdown\") {\n\t\t\t\t\t\tconst trimmed = segment.text.trim();\n\t\t\t\t\t\tif (!trimmed) continue;\n\t\t\t\t\t\tconst text = isFirstTextBlock ? `● ${trimmed}` : trimmed;\n\t\t\t\t\t\tisFirstTextBlock = false;\n\t\t\t\t\t\tthis.contentContainer.addChild(\n\t\t\t\t\t\t\tnew Markdown(text, this.outputPad, 0, this.markdownTheme, {\n\t\t\t\t\t\t\t\tcolor: (body: string) => theme.fg(\"userMessageText\", body),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst key = `${i}:${segment.start}`;\n\t\t\t\t\tconst copyState = this.copyStates.get(key);\n\t\t\t\t\tconst status = copyState?.payload === segment.payload ? copyState.status : \"idle\";\n\t\t\t\t\tif (copyState && copyState.payload !== segment.payload) this.copyStates.delete(key);\n\t\t\t\t\tthis.contentContainer.addChild(\n\t\t\t\t\t\tnew CopyableTextBlockComponent(\n\t\t\t\t\t\t\tsegment.payload,\n\t\t\t\t\t\t\tsegment.complete,\n\t\t\t\t\t\t\tthis.outputPad,\n\t\t\t\t\t\t\tthis.markdownTheme,\n\t\t\t\t\t\t\tstatus,\n\t\t\t\t\t\t\t() => this.copyPayload(key, segment.payload),\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else if (content.type === \"thinking\") {\n\t\t\t\tthinkingRunIndex++;\n\t\t\t\tconst displayBlocks: string[] = [];\n\t\t\t\tfor (; i < message.content.length; i++) {\n\t\t\t\t\tconst thinkingContent = message.content[i];\n\t\t\t\t\tif (thinkingContent.type !== \"thinking\") {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tconst thinking = thinkingContent.thinking.trim();\n\t\t\t\t\tif (thinking) {\n\t\t\t\t\t\tdisplayBlocks.push(thinking);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ti--;\n\n\t\t\t\tif (displayBlocks.length === 0 || this.hideThinkingBlock) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst sourceBlocks = sourceThinkingRuns[thinkingRunIndex] ?? [];\n\t\t\t\tconst fullyRevealed =\n\t\t\t\t\tdisplayBlocks.length === sourceBlocks.length &&\n\t\t\t\t\tdisplayBlocks.every((block, index) => block === sourceBlocks[index]);\n\t\t\t\tthis.renderThinkingRun(thinkingRunIndex, displayBlocks, message, i, fullyRevealed);\n\t\t\t}\n\t\t}\n\n\t\t// Check if incomplete/failed - show after partial content.\n\t\t// For aborted/error tool calls, tool execution components show the error.\n\t\t// Length stops can happen before a tool call is complete, so surface them here too.\n\t\tconst hasToolCalls = message.content.some((c) => c.type === \"toolCall\");\n\t\tthis.hasToolCalls = hasToolCalls;\n\t\tif (message.stopReason === \"length\") {\n\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\tthis.contentContainer.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\t\"Error: Model stopped because it reached the maximum output token limit. The response may be incomplete.\",\n\t\t\t\t\t),\n\t\t\t\t\tthis.outputPad,\n\t\t\t\t\t0,\n\t\t\t\t),\n\t\t\t);\n\t\t} else if (!hasToolCalls) {\n\t\t\tif (message.stopReason === \"aborted\") {\n\t\t\t\tconst abortMessage =\n\t\t\t\t\tmessage.errorMessage && message.errorMessage !== \"Request was aborted\"\n\t\t\t\t\t\t? message.errorMessage\n\t\t\t\t\t\t: \"Operation aborted\";\n\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t\tthis.contentContainer.addChild(new Text(theme.fg(\"error\", abortMessage), this.outputPad, 0));\n\t\t\t} else if (message.stopReason === \"error\") {\n\t\t\t\tconst errorMsg = message.errorMessage || \"Unknown error\";\n\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t\tthis.contentContainer.addChild(new Text(theme.fg(\"error\", `Error: ${errorMsg}`), this.outputPad, 0));\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate copyPayload(key: string, payload: string): void {\n\t\tif (this.copyStates.get(key)?.status === \"copying\") return;\n\t\tthis.copyStates.set(key, { payload, status: \"copying\" });\n\t\tthis.refreshCopyStatus();\n\n\t\tPromise.resolve()\n\t\t\t.then(() => this.copyText(payload))\n\t\t\t.then(() => {\n\t\t\t\tthis.copyStates.set(key, { payload, status: \"copied\" });\n\t\t\t\tthis.refreshCopyStatus();\n\t\t\t})\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tconst message = (error instanceof Error ? error.message : String(error)).replace(/\\s+/g, \" \").trim();\n\t\t\t\tthis.copyStates.set(key, { payload, status: { error: message || \"Unknown error\" } });\n\t\t\t\tthis.refreshCopyStatus();\n\t\t\t});\n\t}\n\n\tprivate refreshCopyStatus(): void {\n\t\tif (this.lastMessage) this.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\tthis.requestRender();\n\t}\n\n\tprivate renderThinkingRun(\n\t\tthinkingRunIndex: number,\n\t\tthinkingBlocks: string[],\n\t\tdisplayMessage: AssistantMessage,\n\t\tdisplayIndex: number,\n\t\tfullyRevealed: boolean,\n\t): void {\n\t\tconst hasVisibleContentAfter =\n\t\t\tdisplayIndex >= 0\n\t\t\t\t? displayMessage.content\n\t\t\t\t\t\t.slice(displayIndex + 1)\n\t\t\t\t\t\t.some((c) => (c.type === \"text\" && c.text.trim()) || (c.type === \"thinking\" && c.thinking.trim()))\n\t\t\t\t: displayMessage.content.some((c) => c.type === \"text\" && c.text.trim());\n\n\t\t// Provider completion can precede the reveal cursor; keep animating until it catches up.\n\t\tconst runComplete =\n\t\t\tfullyRevealed &&\n\t\t\tisThinkingRunComplete(false, this.thinkingTimings?.[thinkingRunIndex], this.thinkingTimings !== undefined);\n\t\tconst wrap = (inner: Component): void => {\n\t\t\tthis.contentContainer.addChild(new ThinkingRunBlock(this, thinkingRunIndex, inner));\n\t\t};\n\t\tif (this.thinkingCollapse && !this.isRunExpanded(thinkingRunIndex) && runComplete) {\n\t\t\tconst timing = this.thinkingTimings?.[thinkingRunIndex];\n\t\t\tconst label =\n\t\t\t\ttiming?.end !== undefined\n\t\t\t\t\t? `✻ Thought for ${formatThoughtDuration(timing.end - timing.start)}`\n\t\t\t\t\t: \"✻ Thought\";\n\t\t\tconst block = new Container();\n\t\t\tblock.addChild(new Text(theme.fg(\"thinkingText\", theme.italic(label)), this.outputPad, 0));\n\t\t\tconst joinedThinking = thinkingBlocks.join(\"\\n\\n\");\n\t\t\tconst snippet = thinkingSnippet(\n\t\t\t\tdisplayMessage.provider === \"openai-codex\" ? joinedThinking.replaceAll(\"**\", \"\") : joinedThinking,\n\t\t\t);\n\t\t\tif (snippet) {\n\t\t\t\tblock.addChild(new Text(theme.fg(\"thinkingText\", theme.italic(snippet)), this.outputPad + 2, 0));\n\t\t\t}\n\t\t\twrap(block);\n\t\t\tif (hasVisibleContentAfter) {\n\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (!runComplete && !this.isRunExpanded(thinkingRunIndex)) {\n\t\t\twrap(\n\t\t\t\tnew ThinkingTailComponent(thinkingBlocks.join(\"\\n\\n\"), this.outputPad, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"thinkingText\", text),\n\t\t\t\t\titalic: true,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tif (hasVisibleContentAfter) {\n\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\twrap(\n\t\t\tnew Markdown(thinkingBlocks.join(\"\\n\\n\"), this.outputPad, 0, this.markdownTheme, {\n\t\t\t\tcolor: (text: string) => theme.fg(\"thinkingText\", text),\n\t\t\t\titalic: true,\n\t\t\t}),\n\t\t);\n\t\tif (hasVisibleContentAfter) {\n\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t}\n\t}\n}\n\nclass ThinkingRunBlock extends Container {\n\tprivate readonly owner: AssistantMessageComponent;\n\tprivate readonly runIndex: number;\n\n\tconstructor(owner: AssistantMessageComponent, runIndex: number, inner: Component) {\n\t\tsuper();\n\t\tthis.owner = owner;\n\t\tthis.runIndex = runIndex;\n\t\tthis.addChild(inner);\n\t}\n\n\thandleClick(_localY: number, _width: number): boolean {\n\t\tthis.owner.toggleThinkingRun(this.runIndex);\n\t\treturn true;\n\t}\n}\n\nfunction collectThinkingRuns(content: AssistantMessage[\"content\"]): string[][] {\n\tconst runs: string[][] = [];\n\tfor (let i = 0; i < content.length; i++) {\n\t\tconst block = content[i];\n\t\tif (block.type !== \"thinking\") continue;\n\t\tconst blocks: string[] = [];\n\t\tfor (; i < content.length; i++) {\n\t\t\tconst thinkingContent = content[i];\n\t\t\tif (thinkingContent.type !== \"thinking\") {\n\t\t\t\ti--;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tconst thinking = thinkingContent.thinking.trim();\n\t\t\tif (thinking) blocks.push(thinking);\n\t\t}\n\t\truns.push(blocks);\n\t}\n\treturn runs;\n}\n"]}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Container, Markdown, Spacer, Text } from "@ashx-j/lunr-tui";
|
|
2
|
+
import { copyToClipboard } from "../../../utils/clipboard.js";
|
|
2
3
|
import { getMarkdownTheme, theme } from "../theme/theme.js";
|
|
4
|
+
import { CopyableTextBlockComponent, parseCopyableTextSegments } from "./copyable-text.js";
|
|
3
5
|
import { formatThoughtDuration, isThinkingRunComplete, thinkingSnippet, } from "./thinking-summary.js";
|
|
4
6
|
import { ThinkingTailComponent } from "./thinking-tail.js";
|
|
5
7
|
const OSC133_ZONE_START = "\x1b]133;A\x07";
|
|
@@ -29,13 +31,18 @@ export class AssistantMessageComponent extends Container {
|
|
|
29
31
|
lastMessage;
|
|
30
32
|
thinkingSource;
|
|
31
33
|
hasToolCalls = false;
|
|
32
|
-
|
|
34
|
+
copyText;
|
|
35
|
+
requestRender;
|
|
36
|
+
copyStates = new Map();
|
|
37
|
+
constructor(message, hideThinkingBlock = false, markdownTheme = getMarkdownTheme(), hiddenThinkingLabel = "Thinking...", outputPad = 1, thinkingCollapse = false, copyOptions = {}) {
|
|
33
38
|
super();
|
|
34
39
|
this.hideThinkingBlock = hideThinkingBlock;
|
|
35
40
|
this.thinkingCollapse = thinkingCollapse;
|
|
36
41
|
this.markdownTheme = markdownTheme;
|
|
37
42
|
this.hiddenThinkingLabel = hiddenThinkingLabel;
|
|
38
43
|
this.outputPad = outputPad;
|
|
44
|
+
this.copyText = copyOptions.copyText ?? copyToClipboard;
|
|
45
|
+
this.requestRender = copyOptions.requestRender ?? (() => { });
|
|
39
46
|
// Container for text/thinking content
|
|
40
47
|
this.contentContainer = new Container();
|
|
41
48
|
this.addChild(this.contentContainer);
|
|
@@ -94,14 +101,14 @@ export class AssistantMessageComponent extends Container {
|
|
|
94
101
|
this.updateContent(this.lastMessage, this.thinkingSourceOptions());
|
|
95
102
|
}
|
|
96
103
|
}
|
|
97
|
-
handleClick(localY, width) {
|
|
104
|
+
handleClick(localY, width, localX) {
|
|
98
105
|
const contentWidth = width;
|
|
99
106
|
let y = 0;
|
|
100
107
|
for (const child of this.contentContainer.children) {
|
|
101
108
|
const h = child.render(contentWidth).length;
|
|
102
109
|
if (localY >= y && localY < y + h) {
|
|
103
110
|
if (typeof child.handleClick === "function") {
|
|
104
|
-
return child.handleClick(localY - y, contentWidth);
|
|
111
|
+
return child.handleClick(localY - y, contentWidth, localX);
|
|
105
112
|
}
|
|
106
113
|
return false;
|
|
107
114
|
}
|
|
@@ -153,18 +160,25 @@ export class AssistantMessageComponent extends Container {
|
|
|
153
160
|
for (let i = 0; i < message.content.length; i++) {
|
|
154
161
|
const content = message.content[i];
|
|
155
162
|
if (content.type === "text" && content.text.trim()) {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
163
|
+
for (const segment of parseCopyableTextSegments(content.text)) {
|
|
164
|
+
if (segment.type === "markdown") {
|
|
165
|
+
const trimmed = segment.text.trim();
|
|
166
|
+
if (!trimmed)
|
|
167
|
+
continue;
|
|
168
|
+
const text = isFirstTextBlock ? `● ${trimmed}` : trimmed;
|
|
169
|
+
isFirstTextBlock = false;
|
|
170
|
+
this.contentContainer.addChild(new Markdown(text, this.outputPad, 0, this.markdownTheme, {
|
|
171
|
+
color: (body) => theme.fg("userMessageText", body),
|
|
172
|
+
}));
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
const key = `${i}:${segment.start}`;
|
|
176
|
+
const copyState = this.copyStates.get(key);
|
|
177
|
+
const status = copyState?.payload === segment.payload ? copyState.status : "idle";
|
|
178
|
+
if (copyState && copyState.payload !== segment.payload)
|
|
179
|
+
this.copyStates.delete(key);
|
|
180
|
+
this.contentContainer.addChild(new CopyableTextBlockComponent(segment.payload, segment.complete, this.outputPad, this.markdownTheme, status, () => this.copyPayload(key, segment.payload)));
|
|
181
|
+
}
|
|
168
182
|
}
|
|
169
183
|
else if (content.type === "thinking") {
|
|
170
184
|
thinkingRunIndex++;
|
|
@@ -213,6 +227,28 @@ export class AssistantMessageComponent extends Container {
|
|
|
213
227
|
}
|
|
214
228
|
}
|
|
215
229
|
}
|
|
230
|
+
copyPayload(key, payload) {
|
|
231
|
+
if (this.copyStates.get(key)?.status === "copying")
|
|
232
|
+
return;
|
|
233
|
+
this.copyStates.set(key, { payload, status: "copying" });
|
|
234
|
+
this.refreshCopyStatus();
|
|
235
|
+
Promise.resolve()
|
|
236
|
+
.then(() => this.copyText(payload))
|
|
237
|
+
.then(() => {
|
|
238
|
+
this.copyStates.set(key, { payload, status: "copied" });
|
|
239
|
+
this.refreshCopyStatus();
|
|
240
|
+
})
|
|
241
|
+
.catch((error) => {
|
|
242
|
+
const message = (error instanceof Error ? error.message : String(error)).replace(/\s+/g, " ").trim();
|
|
243
|
+
this.copyStates.set(key, { payload, status: { error: message || "Unknown error" } });
|
|
244
|
+
this.refreshCopyStatus();
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
refreshCopyStatus() {
|
|
248
|
+
if (this.lastMessage)
|
|
249
|
+
this.updateContent(this.lastMessage, this.thinkingSourceOptions());
|
|
250
|
+
this.requestRender();
|
|
251
|
+
}
|
|
216
252
|
renderThinkingRun(thinkingRunIndex, thinkingBlocks, displayMessage, displayIndex, fullyRevealed) {
|
|
217
253
|
const hasVisibleContentAfter = displayIndex >= 0
|
|
218
254
|
? displayMessage.content
|
|
@@ -232,7 +268,8 @@ export class AssistantMessageComponent extends Container {
|
|
|
232
268
|
: "✻ Thought";
|
|
233
269
|
const block = new Container();
|
|
234
270
|
block.addChild(new Text(theme.fg("thinkingText", theme.italic(label)), this.outputPad, 0));
|
|
235
|
-
const
|
|
271
|
+
const joinedThinking = thinkingBlocks.join("\n\n");
|
|
272
|
+
const snippet = thinkingSnippet(displayMessage.provider === "openai-codex" ? joinedThinking.replaceAll("**", "") : joinedThinking);
|
|
236
273
|
if (snippet) {
|
|
237
274
|
block.addChild(new Text(theme.fg("thinkingText", theme.italic(snippet)), this.outputPad + 2, 0));
|
|
238
275
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assistant-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/assistant-message.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AssistantMessage } from \"@ashx-j/lunr-ai\";\nimport { type Component, Container, Markdown, type MarkdownTheme, Spacer, Text } from \"@ashx-j/lunr-tui\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\nimport {\n\tformatThoughtDuration,\n\tisThinkingRunComplete,\n\ttype ThinkingRunTiming,\n\tthinkingSnippet,\n} from \"./thinking-summary.ts\";\nimport { ThinkingTailComponent } from \"./thinking-tail.ts\";\n\nconst OSC133_ZONE_START = \"\\x1b]133;A\\x07\";\nconst OSC133_ZONE_END = \"\\x1b]133;B\\x07\";\nconst OSC133_ZONE_FINAL = \"\\x1b]133;C\\x07\";\n\n/**\n * Component that renders a complete assistant message\n */\nexport class AssistantMessageComponent extends Container {\n\tselectable = true;\n\tprivate contentContainer: Container;\n\tprivate hideThinkingBlock: boolean;\n\t// lunr: collapsible reasoning — when true, a completed thinking run renders as\n\t// \"✻ Thought for Xs\" + its first sentence instead of the full block.\n\tprivate thinkingCollapse: boolean;\n\t// lunr: per-run expand. `expanded` still means \"all runs\" for setExpanded().\n\tprivate expanded = false;\n\tprivate expandedRuns = new Set<number>();\n\t// lunr: live per-run timings from interactive-mode; undefined = history message\n\t// (always treated as final, rendered without durations).\n\tprivate thinkingTimings?: ThinkingRunTiming[];\n\tprivate markdownTheme: MarkdownTheme;\n\t// lunr: kept for the deferred alternative hidden-thinking indicator (Phase 8 removed the label render).\n\t// biome-ignore lint/correctness/noUnusedPrivateClassMembers: retained for future use\n\tprivate hiddenThinkingLabel: string;\n\tprivate outputPad: number;\n\tprivate lastMessage?: AssistantMessage;\n\tprivate thinkingSource?: AssistantMessage;\n\tprivate hasToolCalls = false;\n\n\tconstructor(\n\t\tmessage?: AssistantMessage,\n\t\thideThinkingBlock = false,\n\t\tmarkdownTheme: MarkdownTheme = getMarkdownTheme(),\n\t\thiddenThinkingLabel = \"Thinking...\",\n\t\toutputPad = 1,\n\t\tthinkingCollapse = false,\n\t) {\n\t\tsuper();\n\n\t\tthis.hideThinkingBlock = hideThinkingBlock;\n\t\tthis.thinkingCollapse = thinkingCollapse;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.hiddenThinkingLabel = hiddenThinkingLabel;\n\t\tthis.outputPad = outputPad;\n\n\t\t// Container for text/thinking content\n\t\tthis.contentContainer = new Container();\n\t\tthis.addChild(this.contentContainer);\n\n\t\tif (message) {\n\t\t\tthis.updateContent(message);\n\t\t}\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\tsetHideThinkingBlock(hide: boolean): void {\n\t\tthis.hideThinkingBlock = hide;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\t// lunr: collapsible reasoning toggles (live; re-render like setHideThinkingBlock).\n\tsetThinkingCollapse(collapse: boolean): void {\n\t\tthis.thinkingCollapse = collapse;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\t// lunr: Expandable hook; true expands every thinking run, false collapses all.\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tif (!expanded) this.expandedRuns.clear();\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\tprivate isRunExpanded(runIndex: number): boolean {\n\t\treturn this.expanded || this.expandedRuns.has(runIndex);\n\t}\n\n\ttoggleThinkingRun(runIndex: number): void {\n\t\tif (this.expanded) {\n\t\t\tthis.expanded = false;\n\t\t\tthis.expandedRuns.clear();\n\t\t\tconst count = this.lastMessage ? collectThinkingRuns(this.lastMessage.content).length : 0;\n\t\t\tfor (let i = 0; i < count; i++) {\n\t\t\t\tif (i !== runIndex) this.expandedRuns.add(i);\n\t\t\t}\n\t\t} else if (this.expandedRuns.has(runIndex)) {\n\t\t\tthis.expandedRuns.delete(runIndex);\n\t\t} else {\n\t\t\tthis.expandedRuns.add(runIndex);\n\t\t}\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\thandleClick(localY: number, width: number): boolean {\n\t\tconst contentWidth = width;\n\t\tlet y = 0;\n\t\tfor (const child of this.contentContainer.children) {\n\t\t\tconst h = child.render(contentWidth).length;\n\t\t\tif (localY >= y && localY < y + h) {\n\t\t\t\tif (typeof child.handleClick === \"function\") {\n\t\t\t\t\treturn child.handleClick(localY - y, contentWidth);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\ty += h;\n\t\t}\n\t\treturn false;\n\t}\n\n\tsetThinkingTimings(timings: ThinkingRunTiming[] | undefined): void {\n\t\tthis.thinkingTimings = timings;\n\t}\n\n\tsetHiddenThinkingLabel(label: string): void {\n\t\tthis.hiddenThinkingLabel = label;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\tsetOutputPad(padding: number): void {\n\t\tthis.outputPad = padding;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst lines = super.render(width);\n\t\tif (this.hasToolCalls || lines.length === 0) return lines;\n\n\t\tlines[0] = OSC133_ZONE_START + lines[0];\n\t\tlines[lines.length - 1] = OSC133_ZONE_END + OSC133_ZONE_FINAL + lines[lines.length - 1];\n\n\t\treturn lines;\n\t}\n\n\tprivate thinkingSourceOptions(): { thinkingSource?: AssistantMessage } | undefined {\n\t\treturn this.thinkingSource ? { thinkingSource: this.thinkingSource } : undefined;\n\t}\n\n\tupdateContent(message: AssistantMessage, options?: { thinkingSource?: AssistantMessage }): void {\n\t\tthis.lastMessage = message;\n\t\tthis.thinkingSource = options?.thinkingSource;\n\n\t\t// Clear content container\n\t\tthis.contentContainer.clear();\n\n\t\tconst sourceMessage = this.thinkingSource ?? message;\n\t\tconst sourceThinkingRuns = collectThinkingRuns(sourceMessage.content);\n\t\tconst hasVisibleContent = message.content.some(\n\t\t\t(c) =>\n\t\t\t\t(c.type === \"text\" && c.text.trim()) ||\n\t\t\t\t(!this.hideThinkingBlock && c.type === \"thinking\" && c.thinking.trim()),\n\t\t);\n\n\t\tif (hasVisibleContent) {\n\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t}\n\n\t\t// Render content in order\n\t\tlet isFirstTextBlock = true;\n\t\tlet thinkingRunIndex = -1;\n\t\tfor (let i = 0; i < message.content.length; i++) {\n\t\t\tconst content = message.content[i];\n\t\t\tif (content.type === \"text\" && content.text.trim()) {\n\t\t\t\t// Assistant text messages with no background - trim the text\n\t\t\t\t// Set paddingY=0 to avoid extra spacing before tool executions\n\t\t\t\t// lunr: leading ● marks the first text block (never thinking blocks). It rides\n\t\t\t\t// the defaultTextStyle below, so it renders bright white like the body.\n\t\t\t\tconst trimmed = content.text.trim();\n\t\t\t\tconst text = isFirstTextBlock ? `● ${trimmed}` : trimmed;\n\t\t\t\tisFirstTextBlock = false;\n\t\t\t\t// lunr: theme-polish — assistant message body renders bright white via the\n\t\t\t\t// shared userMessageText token (same knob as user messages).\n\t\t\t\tthis.contentContainer.addChild(\n\t\t\t\t\tnew Markdown(text, this.outputPad, 0, this.markdownTheme, {\n\t\t\t\t\t\tcolor: (body: string) => theme.fg(\"userMessageText\", body),\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t} else if (content.type === \"thinking\") {\n\t\t\t\tthinkingRunIndex++;\n\t\t\t\tconst displayBlocks: string[] = [];\n\t\t\t\tfor (; i < message.content.length; i++) {\n\t\t\t\t\tconst thinkingContent = message.content[i];\n\t\t\t\t\tif (thinkingContent.type !== \"thinking\") {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tconst thinking = thinkingContent.thinking.trim();\n\t\t\t\t\tif (thinking) {\n\t\t\t\t\t\tdisplayBlocks.push(thinking);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ti--;\n\n\t\t\t\tif (displayBlocks.length === 0 || this.hideThinkingBlock) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst sourceBlocks = sourceThinkingRuns[thinkingRunIndex] ?? [];\n\t\t\t\tconst fullyRevealed =\n\t\t\t\t\tdisplayBlocks.length === sourceBlocks.length &&\n\t\t\t\t\tdisplayBlocks.every((block, index) => block === sourceBlocks[index]);\n\t\t\t\tthis.renderThinkingRun(thinkingRunIndex, displayBlocks, message, i, fullyRevealed);\n\t\t\t}\n\t\t}\n\n\t\t// Check if incomplete/failed - show after partial content.\n\t\t// For aborted/error tool calls, tool execution components show the error.\n\t\t// Length stops can happen before a tool call is complete, so surface them here too.\n\t\tconst hasToolCalls = message.content.some((c) => c.type === \"toolCall\");\n\t\tthis.hasToolCalls = hasToolCalls;\n\t\tif (message.stopReason === \"length\") {\n\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\tthis.contentContainer.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\t\"Error: Model stopped because it reached the maximum output token limit. The response may be incomplete.\",\n\t\t\t\t\t),\n\t\t\t\t\tthis.outputPad,\n\t\t\t\t\t0,\n\t\t\t\t),\n\t\t\t);\n\t\t} else if (!hasToolCalls) {\n\t\t\tif (message.stopReason === \"aborted\") {\n\t\t\t\tconst abortMessage =\n\t\t\t\t\tmessage.errorMessage && message.errorMessage !== \"Request was aborted\"\n\t\t\t\t\t\t? message.errorMessage\n\t\t\t\t\t\t: \"Operation aborted\";\n\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t\tthis.contentContainer.addChild(new Text(theme.fg(\"error\", abortMessage), this.outputPad, 0));\n\t\t\t} else if (message.stopReason === \"error\") {\n\t\t\t\tconst errorMsg = message.errorMessage || \"Unknown error\";\n\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t\tthis.contentContainer.addChild(new Text(theme.fg(\"error\", `Error: ${errorMsg}`), this.outputPad, 0));\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate renderThinkingRun(\n\t\tthinkingRunIndex: number,\n\t\tthinkingBlocks: string[],\n\t\tdisplayMessage: AssistantMessage,\n\t\tdisplayIndex: number,\n\t\tfullyRevealed: boolean,\n\t): void {\n\t\tconst hasVisibleContentAfter =\n\t\t\tdisplayIndex >= 0\n\t\t\t\t? displayMessage.content\n\t\t\t\t\t\t.slice(displayIndex + 1)\n\t\t\t\t\t\t.some((c) => (c.type === \"text\" && c.text.trim()) || (c.type === \"thinking\" && c.thinking.trim()))\n\t\t\t\t: displayMessage.content.some((c) => c.type === \"text\" && c.text.trim());\n\n\t\t// Provider completion can precede the reveal cursor; keep animating until it catches up.\n\t\tconst runComplete =\n\t\t\tfullyRevealed &&\n\t\t\tisThinkingRunComplete(false, this.thinkingTimings?.[thinkingRunIndex], this.thinkingTimings !== undefined);\n\t\tconst wrap = (inner: Component): void => {\n\t\t\tthis.contentContainer.addChild(new ThinkingRunBlock(this, thinkingRunIndex, inner));\n\t\t};\n\t\tif (this.thinkingCollapse && !this.isRunExpanded(thinkingRunIndex) && runComplete) {\n\t\t\tconst timing = this.thinkingTimings?.[thinkingRunIndex];\n\t\t\tconst label =\n\t\t\t\ttiming?.end !== undefined\n\t\t\t\t\t? `✻ Thought for ${formatThoughtDuration(timing.end - timing.start)}`\n\t\t\t\t\t: \"✻ Thought\";\n\t\t\tconst block = new Container();\n\t\t\tblock.addChild(new Text(theme.fg(\"thinkingText\", theme.italic(label)), this.outputPad, 0));\n\t\t\tconst snippet = thinkingSnippet(thinkingBlocks.join(\"\\n\\n\"));\n\t\t\tif (snippet) {\n\t\t\t\tblock.addChild(new Text(theme.fg(\"thinkingText\", theme.italic(snippet)), this.outputPad + 2, 0));\n\t\t\t}\n\t\t\twrap(block);\n\t\t\tif (hasVisibleContentAfter) {\n\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (!runComplete && !this.isRunExpanded(thinkingRunIndex)) {\n\t\t\twrap(\n\t\t\t\tnew ThinkingTailComponent(thinkingBlocks.join(\"\\n\\n\"), this.outputPad, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"thinkingText\", text),\n\t\t\t\t\titalic: true,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tif (hasVisibleContentAfter) {\n\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\twrap(\n\t\t\tnew Markdown(thinkingBlocks.join(\"\\n\\n\"), this.outputPad, 0, this.markdownTheme, {\n\t\t\t\tcolor: (text: string) => theme.fg(\"thinkingText\", text),\n\t\t\t\titalic: true,\n\t\t\t}),\n\t\t);\n\t\tif (hasVisibleContentAfter) {\n\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t}\n\t}\n}\n\nclass ThinkingRunBlock extends Container {\n\tprivate readonly owner: AssistantMessageComponent;\n\tprivate readonly runIndex: number;\n\n\tconstructor(owner: AssistantMessageComponent, runIndex: number, inner: Component) {\n\t\tsuper();\n\t\tthis.owner = owner;\n\t\tthis.runIndex = runIndex;\n\t\tthis.addChild(inner);\n\t}\n\n\thandleClick(_localY: number, _width: number): boolean {\n\t\tthis.owner.toggleThinkingRun(this.runIndex);\n\t\treturn true;\n\t}\n}\n\nfunction collectThinkingRuns(content: AssistantMessage[\"content\"]): string[][] {\n\tconst runs: string[][] = [];\n\tfor (let i = 0; i < content.length; i++) {\n\t\tconst block = content[i];\n\t\tif (block.type !== \"thinking\") continue;\n\t\tconst blocks: string[] = [];\n\t\tfor (; i < content.length; i++) {\n\t\t\tconst thinkingContent = content[i];\n\t\t\tif (thinkingContent.type !== \"thinking\") {\n\t\t\t\ti--;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tconst thinking = thinkingContent.thinking.trim();\n\t\t\tif (thinking) blocks.push(thinking);\n\t\t}\n\t\truns.push(blocks);\n\t}\n\treturn runs;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"assistant-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/assistant-message.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AssistantMessage } from \"@ashx-j/lunr-ai\";\nimport { type Component, Container, Markdown, type MarkdownTheme, Spacer, Text } from \"@ashx-j/lunr-tui\";\nimport { copyToClipboard } from \"../../../utils/clipboard.ts\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\nimport { CopyableTextBlockComponent, type CopyableTextStatus, parseCopyableTextSegments } from \"./copyable-text.ts\";\nimport {\n\tformatThoughtDuration,\n\tisThinkingRunComplete,\n\ttype ThinkingRunTiming,\n\tthinkingSnippet,\n} from \"./thinking-summary.ts\";\nimport { ThinkingTailComponent } from \"./thinking-tail.ts\";\n\nconst OSC133_ZONE_START = \"\\x1b]133;A\\x07\";\nconst OSC133_ZONE_END = \"\\x1b]133;B\\x07\";\nconst OSC133_ZONE_FINAL = \"\\x1b]133;C\\x07\";\n\nexport interface AssistantMessageCopyOptions {\n\tcopyText?: (text: string) => Promise<void>;\n\trequestRender?: () => void;\n}\n\ninterface CopyState {\n\tpayload: string;\n\tstatus: CopyableTextStatus;\n}\n\n/**\n * Component that renders a complete assistant message\n */\nexport class AssistantMessageComponent extends Container {\n\tselectable = true;\n\tprivate contentContainer: Container;\n\tprivate hideThinkingBlock: boolean;\n\t// lunr: collapsible reasoning — when true, a completed thinking run renders as\n\t// \"✻ Thought for Xs\" + its first sentence instead of the full block.\n\tprivate thinkingCollapse: boolean;\n\t// lunr: per-run expand. `expanded` still means \"all runs\" for setExpanded().\n\tprivate expanded = false;\n\tprivate expandedRuns = new Set<number>();\n\t// lunr: live per-run timings from interactive-mode; undefined = history message\n\t// (always treated as final, rendered without durations).\n\tprivate thinkingTimings?: ThinkingRunTiming[];\n\tprivate markdownTheme: MarkdownTheme;\n\t// lunr: kept for the deferred alternative hidden-thinking indicator (Phase 8 removed the label render).\n\t// biome-ignore lint/correctness/noUnusedPrivateClassMembers: retained for future use\n\tprivate hiddenThinkingLabel: string;\n\tprivate outputPad: number;\n\tprivate lastMessage?: AssistantMessage;\n\tprivate thinkingSource?: AssistantMessage;\n\tprivate hasToolCalls = false;\n\tprivate readonly copyText: (text: string) => Promise<void>;\n\tprivate readonly requestRender: () => void;\n\tprivate readonly copyStates = new Map<string, CopyState>();\n\n\tconstructor(\n\t\tmessage?: AssistantMessage,\n\t\thideThinkingBlock = false,\n\t\tmarkdownTheme: MarkdownTheme = getMarkdownTheme(),\n\t\thiddenThinkingLabel = \"Thinking...\",\n\t\toutputPad = 1,\n\t\tthinkingCollapse = false,\n\t\tcopyOptions: AssistantMessageCopyOptions = {},\n\t) {\n\t\tsuper();\n\n\t\tthis.hideThinkingBlock = hideThinkingBlock;\n\t\tthis.thinkingCollapse = thinkingCollapse;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.hiddenThinkingLabel = hiddenThinkingLabel;\n\t\tthis.outputPad = outputPad;\n\t\tthis.copyText = copyOptions.copyText ?? copyToClipboard;\n\t\tthis.requestRender = copyOptions.requestRender ?? (() => {});\n\n\t\t// Container for text/thinking content\n\t\tthis.contentContainer = new Container();\n\t\tthis.addChild(this.contentContainer);\n\n\t\tif (message) {\n\t\t\tthis.updateContent(message);\n\t\t}\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\tsetHideThinkingBlock(hide: boolean): void {\n\t\tthis.hideThinkingBlock = hide;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\t// lunr: collapsible reasoning toggles (live; re-render like setHideThinkingBlock).\n\tsetThinkingCollapse(collapse: boolean): void {\n\t\tthis.thinkingCollapse = collapse;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\t// lunr: Expandable hook; true expands every thinking run, false collapses all.\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tif (!expanded) this.expandedRuns.clear();\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\tprivate isRunExpanded(runIndex: number): boolean {\n\t\treturn this.expanded || this.expandedRuns.has(runIndex);\n\t}\n\n\ttoggleThinkingRun(runIndex: number): void {\n\t\tif (this.expanded) {\n\t\t\tthis.expanded = false;\n\t\t\tthis.expandedRuns.clear();\n\t\t\tconst count = this.lastMessage ? collectThinkingRuns(this.lastMessage.content).length : 0;\n\t\t\tfor (let i = 0; i < count; i++) {\n\t\t\t\tif (i !== runIndex) this.expandedRuns.add(i);\n\t\t\t}\n\t\t} else if (this.expandedRuns.has(runIndex)) {\n\t\t\tthis.expandedRuns.delete(runIndex);\n\t\t} else {\n\t\t\tthis.expandedRuns.add(runIndex);\n\t\t}\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\thandleClick(localY: number, width: number, localX?: number): boolean {\n\t\tconst contentWidth = width;\n\t\tlet y = 0;\n\t\tfor (const child of this.contentContainer.children) {\n\t\t\tconst h = child.render(contentWidth).length;\n\t\t\tif (localY >= y && localY < y + h) {\n\t\t\t\tif (typeof child.handleClick === \"function\") {\n\t\t\t\t\treturn child.handleClick(localY - y, contentWidth, localX);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\ty += h;\n\t\t}\n\t\treturn false;\n\t}\n\n\tsetThinkingTimings(timings: ThinkingRunTiming[] | undefined): void {\n\t\tthis.thinkingTimings = timings;\n\t}\n\n\tsetHiddenThinkingLabel(label: string): void {\n\t\tthis.hiddenThinkingLabel = label;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\tsetOutputPad(padding: number): void {\n\t\tthis.outputPad = padding;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\t}\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst lines = super.render(width);\n\t\tif (this.hasToolCalls || lines.length === 0) return lines;\n\n\t\tlines[0] = OSC133_ZONE_START + lines[0];\n\t\tlines[lines.length - 1] = OSC133_ZONE_END + OSC133_ZONE_FINAL + lines[lines.length - 1];\n\n\t\treturn lines;\n\t}\n\n\tprivate thinkingSourceOptions(): { thinkingSource?: AssistantMessage } | undefined {\n\t\treturn this.thinkingSource ? { thinkingSource: this.thinkingSource } : undefined;\n\t}\n\n\tupdateContent(message: AssistantMessage, options?: { thinkingSource?: AssistantMessage }): void {\n\t\tthis.lastMessage = message;\n\t\tthis.thinkingSource = options?.thinkingSource;\n\n\t\t// Clear content container\n\t\tthis.contentContainer.clear();\n\n\t\tconst sourceMessage = this.thinkingSource ?? message;\n\t\tconst sourceThinkingRuns = collectThinkingRuns(sourceMessage.content);\n\t\tconst hasVisibleContent = message.content.some(\n\t\t\t(c) =>\n\t\t\t\t(c.type === \"text\" && c.text.trim()) ||\n\t\t\t\t(!this.hideThinkingBlock && c.type === \"thinking\" && c.thinking.trim()),\n\t\t);\n\n\t\tif (hasVisibleContent) {\n\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t}\n\n\t\t// Render content in order\n\t\tlet isFirstTextBlock = true;\n\t\tlet thinkingRunIndex = -1;\n\t\tfor (let i = 0; i < message.content.length; i++) {\n\t\t\tconst content = message.content[i];\n\t\t\tif (content.type === \"text\" && content.text.trim()) {\n\t\t\t\tfor (const segment of parseCopyableTextSegments(content.text)) {\n\t\t\t\t\tif (segment.type === \"markdown\") {\n\t\t\t\t\t\tconst trimmed = segment.text.trim();\n\t\t\t\t\t\tif (!trimmed) continue;\n\t\t\t\t\t\tconst text = isFirstTextBlock ? `● ${trimmed}` : trimmed;\n\t\t\t\t\t\tisFirstTextBlock = false;\n\t\t\t\t\t\tthis.contentContainer.addChild(\n\t\t\t\t\t\t\tnew Markdown(text, this.outputPad, 0, this.markdownTheme, {\n\t\t\t\t\t\t\t\tcolor: (body: string) => theme.fg(\"userMessageText\", body),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst key = `${i}:${segment.start}`;\n\t\t\t\t\tconst copyState = this.copyStates.get(key);\n\t\t\t\t\tconst status = copyState?.payload === segment.payload ? copyState.status : \"idle\";\n\t\t\t\t\tif (copyState && copyState.payload !== segment.payload) this.copyStates.delete(key);\n\t\t\t\t\tthis.contentContainer.addChild(\n\t\t\t\t\t\tnew CopyableTextBlockComponent(\n\t\t\t\t\t\t\tsegment.payload,\n\t\t\t\t\t\t\tsegment.complete,\n\t\t\t\t\t\t\tthis.outputPad,\n\t\t\t\t\t\t\tthis.markdownTheme,\n\t\t\t\t\t\t\tstatus,\n\t\t\t\t\t\t\t() => this.copyPayload(key, segment.payload),\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else if (content.type === \"thinking\") {\n\t\t\t\tthinkingRunIndex++;\n\t\t\t\tconst displayBlocks: string[] = [];\n\t\t\t\tfor (; i < message.content.length; i++) {\n\t\t\t\t\tconst thinkingContent = message.content[i];\n\t\t\t\t\tif (thinkingContent.type !== \"thinking\") {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tconst thinking = thinkingContent.thinking.trim();\n\t\t\t\t\tif (thinking) {\n\t\t\t\t\t\tdisplayBlocks.push(thinking);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ti--;\n\n\t\t\t\tif (displayBlocks.length === 0 || this.hideThinkingBlock) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst sourceBlocks = sourceThinkingRuns[thinkingRunIndex] ?? [];\n\t\t\t\tconst fullyRevealed =\n\t\t\t\t\tdisplayBlocks.length === sourceBlocks.length &&\n\t\t\t\t\tdisplayBlocks.every((block, index) => block === sourceBlocks[index]);\n\t\t\t\tthis.renderThinkingRun(thinkingRunIndex, displayBlocks, message, i, fullyRevealed);\n\t\t\t}\n\t\t}\n\n\t\t// Check if incomplete/failed - show after partial content.\n\t\t// For aborted/error tool calls, tool execution components show the error.\n\t\t// Length stops can happen before a tool call is complete, so surface them here too.\n\t\tconst hasToolCalls = message.content.some((c) => c.type === \"toolCall\");\n\t\tthis.hasToolCalls = hasToolCalls;\n\t\tif (message.stopReason === \"length\") {\n\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\tthis.contentContainer.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\t\"Error: Model stopped because it reached the maximum output token limit. The response may be incomplete.\",\n\t\t\t\t\t),\n\t\t\t\t\tthis.outputPad,\n\t\t\t\t\t0,\n\t\t\t\t),\n\t\t\t);\n\t\t} else if (!hasToolCalls) {\n\t\t\tif (message.stopReason === \"aborted\") {\n\t\t\t\tconst abortMessage =\n\t\t\t\t\tmessage.errorMessage && message.errorMessage !== \"Request was aborted\"\n\t\t\t\t\t\t? message.errorMessage\n\t\t\t\t\t\t: \"Operation aborted\";\n\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t\tthis.contentContainer.addChild(new Text(theme.fg(\"error\", abortMessage), this.outputPad, 0));\n\t\t\t} else if (message.stopReason === \"error\") {\n\t\t\t\tconst errorMsg = message.errorMessage || \"Unknown error\";\n\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t\tthis.contentContainer.addChild(new Text(theme.fg(\"error\", `Error: ${errorMsg}`), this.outputPad, 0));\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate copyPayload(key: string, payload: string): void {\n\t\tif (this.copyStates.get(key)?.status === \"copying\") return;\n\t\tthis.copyStates.set(key, { payload, status: \"copying\" });\n\t\tthis.refreshCopyStatus();\n\n\t\tPromise.resolve()\n\t\t\t.then(() => this.copyText(payload))\n\t\t\t.then(() => {\n\t\t\t\tthis.copyStates.set(key, { payload, status: \"copied\" });\n\t\t\t\tthis.refreshCopyStatus();\n\t\t\t})\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tconst message = (error instanceof Error ? error.message : String(error)).replace(/\\s+/g, \" \").trim();\n\t\t\t\tthis.copyStates.set(key, { payload, status: { error: message || \"Unknown error\" } });\n\t\t\t\tthis.refreshCopyStatus();\n\t\t\t});\n\t}\n\n\tprivate refreshCopyStatus(): void {\n\t\tif (this.lastMessage) this.updateContent(this.lastMessage, this.thinkingSourceOptions());\n\t\tthis.requestRender();\n\t}\n\n\tprivate renderThinkingRun(\n\t\tthinkingRunIndex: number,\n\t\tthinkingBlocks: string[],\n\t\tdisplayMessage: AssistantMessage,\n\t\tdisplayIndex: number,\n\t\tfullyRevealed: boolean,\n\t): void {\n\t\tconst hasVisibleContentAfter =\n\t\t\tdisplayIndex >= 0\n\t\t\t\t? displayMessage.content\n\t\t\t\t\t\t.slice(displayIndex + 1)\n\t\t\t\t\t\t.some((c) => (c.type === \"text\" && c.text.trim()) || (c.type === \"thinking\" && c.thinking.trim()))\n\t\t\t\t: displayMessage.content.some((c) => c.type === \"text\" && c.text.trim());\n\n\t\t// Provider completion can precede the reveal cursor; keep animating until it catches up.\n\t\tconst runComplete =\n\t\t\tfullyRevealed &&\n\t\t\tisThinkingRunComplete(false, this.thinkingTimings?.[thinkingRunIndex], this.thinkingTimings !== undefined);\n\t\tconst wrap = (inner: Component): void => {\n\t\t\tthis.contentContainer.addChild(new ThinkingRunBlock(this, thinkingRunIndex, inner));\n\t\t};\n\t\tif (this.thinkingCollapse && !this.isRunExpanded(thinkingRunIndex) && runComplete) {\n\t\t\tconst timing = this.thinkingTimings?.[thinkingRunIndex];\n\t\t\tconst label =\n\t\t\t\ttiming?.end !== undefined\n\t\t\t\t\t? `✻ Thought for ${formatThoughtDuration(timing.end - timing.start)}`\n\t\t\t\t\t: \"✻ Thought\";\n\t\t\tconst block = new Container();\n\t\t\tblock.addChild(new Text(theme.fg(\"thinkingText\", theme.italic(label)), this.outputPad, 0));\n\t\t\tconst joinedThinking = thinkingBlocks.join(\"\\n\\n\");\n\t\t\tconst snippet = thinkingSnippet(\n\t\t\t\tdisplayMessage.provider === \"openai-codex\" ? joinedThinking.replaceAll(\"**\", \"\") : joinedThinking,\n\t\t\t);\n\t\t\tif (snippet) {\n\t\t\t\tblock.addChild(new Text(theme.fg(\"thinkingText\", theme.italic(snippet)), this.outputPad + 2, 0));\n\t\t\t}\n\t\t\twrap(block);\n\t\t\tif (hasVisibleContentAfter) {\n\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (!runComplete && !this.isRunExpanded(thinkingRunIndex)) {\n\t\t\twrap(\n\t\t\t\tnew ThinkingTailComponent(thinkingBlocks.join(\"\\n\\n\"), this.outputPad, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"thinkingText\", text),\n\t\t\t\t\titalic: true,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tif (hasVisibleContentAfter) {\n\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\twrap(\n\t\t\tnew Markdown(thinkingBlocks.join(\"\\n\\n\"), this.outputPad, 0, this.markdownTheme, {\n\t\t\t\tcolor: (text: string) => theme.fg(\"thinkingText\", text),\n\t\t\t\titalic: true,\n\t\t\t}),\n\t\t);\n\t\tif (hasVisibleContentAfter) {\n\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t}\n\t}\n}\n\nclass ThinkingRunBlock extends Container {\n\tprivate readonly owner: AssistantMessageComponent;\n\tprivate readonly runIndex: number;\n\n\tconstructor(owner: AssistantMessageComponent, runIndex: number, inner: Component) {\n\t\tsuper();\n\t\tthis.owner = owner;\n\t\tthis.runIndex = runIndex;\n\t\tthis.addChild(inner);\n\t}\n\n\thandleClick(_localY: number, _width: number): boolean {\n\t\tthis.owner.toggleThinkingRun(this.runIndex);\n\t\treturn true;\n\t}\n}\n\nfunction collectThinkingRuns(content: AssistantMessage[\"content\"]): string[][] {\n\tconst runs: string[][] = [];\n\tfor (let i = 0; i < content.length; i++) {\n\t\tconst block = content[i];\n\t\tif (block.type !== \"thinking\") continue;\n\t\tconst blocks: string[] = [];\n\t\tfor (; i < content.length; i++) {\n\t\t\tconst thinkingContent = content[i];\n\t\t\tif (thinkingContent.type !== \"thinking\") {\n\t\t\t\ti--;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tconst thinking = thinkingContent.thinking.trim();\n\t\t\tif (thinking) blocks.push(thinking);\n\t\t}\n\t\truns.push(blocks);\n\t}\n\treturn runs;\n}\n"]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { MarkdownTheme } from "@ashx-j/lunr-tui";
|
|
2
|
+
import { type Component } from "@ashx-j/lunr-tui";
|
|
3
|
+
export type CopyableTextSegment = {
|
|
4
|
+
type: "markdown";
|
|
5
|
+
text: string;
|
|
6
|
+
} | {
|
|
7
|
+
type: "copyable";
|
|
8
|
+
payload: string;
|
|
9
|
+
complete: boolean;
|
|
10
|
+
start: number;
|
|
11
|
+
};
|
|
12
|
+
export declare function parseCopyableTextSegments(source: string): CopyableTextSegment[];
|
|
13
|
+
export type CopyableTextStatus = "idle" | "copying" | "copied" | {
|
|
14
|
+
error: string;
|
|
15
|
+
};
|
|
16
|
+
export declare class CopyableTextBlockComponent implements Component {
|
|
17
|
+
private buttonRow;
|
|
18
|
+
private buttonStart;
|
|
19
|
+
private buttonEnd;
|
|
20
|
+
private readonly payload;
|
|
21
|
+
private readonly complete;
|
|
22
|
+
private readonly outputPad;
|
|
23
|
+
private readonly markdownTheme;
|
|
24
|
+
private readonly status;
|
|
25
|
+
private readonly onCopy;
|
|
26
|
+
constructor(payload: string, complete: boolean, outputPad: number, markdownTheme: MarkdownTheme, status: CopyableTextStatus, onCopy: () => void);
|
|
27
|
+
invalidate(): void;
|
|
28
|
+
render(width: number): string[];
|
|
29
|
+
handleClick(localY: number, width: number, localX?: number): boolean;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=copyable-text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copyable-text.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/copyable-text.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,KAAK,SAAS,EAAqC,MAAM,wBAAwB,CAAC;AAG3F,MAAM,MAAM,mBAAmB,GAC5B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAuD3E,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB,EAAE,CA0D/E;AAED,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnF,qBAAa,0BAA2B,YAAW,SAAS;IAC3D,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,WAAW,CAAM;IACzB,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IAEpC,YACC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,OAAO,EACjB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,kBAAkB,EAC1B,MAAM,EAAE,MAAM,IAAI,EAQlB;IAED,UAAU,IAAI,IAAI,CAIjB;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CA0C9B;IAED,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAcnE;CACD","sourcesContent":["import type { MarkdownTheme } from \"@ashx-j/lunr-tui\";\nimport { type Component, truncateToWidth, wrapTextWithAnsi } from \"@ashx-j/lunr-tui\";\nimport { theme } from \"../theme/theme.ts\";\n\nexport type CopyableTextSegment =\n\t| { type: \"markdown\"; text: string }\n\t| { type: \"copyable\"; payload: string; complete: boolean; start: number };\n\ninterface SourceLine {\n\tstart: number;\n\tend: number;\n\ttext: string;\n}\n\ninterface FenceOpening {\n\tmarker: \"`\" | \"~\";\n\tlength: number;\n\tcopyable: boolean;\n}\n\nfunction sourceLines(source: string): SourceLine[] {\n\tconst lines: SourceLine[] = [];\n\tconst pattern = /([^\\r\\n]*)(\\r\\n|\\r|\\n|$)/g;\n\tfor (const match of source.matchAll(pattern)) {\n\t\tconst start = match.index;\n\t\tconst text = match[1];\n\t\tconst newline = match[2];\n\t\tlines.push({ start, end: start + text.length + newline.length, text });\n\t\tif (!newline) break;\n\t}\n\treturn lines;\n}\n\nfunction parseFenceOpening(line: string): FenceOpening | undefined {\n\tconst match = /^( {0,3})(`{3,}|~{3,})(.*)$/.exec(line);\n\tif (!match) return undefined;\n\tconst fence = match[2];\n\tconst info = match[3];\n\tif (fence[0] === \"`\" && info.includes(\"`\")) return undefined;\n\treturn {\n\t\tmarker: fence[0] as \"`\" | \"~\",\n\t\tlength: fence.length,\n\t\tcopyable: info.trim() === \"lunr-copy\",\n\t};\n}\n\nfunction isFenceClosing(line: string, opening: FenceOpening): boolean {\n\tconst match = /^( {0,3})(`+|~+)[ \\t]*$/.exec(line);\n\tif (!match) return false;\n\tconst fence = match[2];\n\treturn fence[0] === opening.marker && fence.length >= opening.length;\n}\n\nfunction payloadEndBeforeClosing(source: string, closingStart: number): number {\n\tif (closingStart >= 2 && source.slice(closingStart - 2, closingStart) === \"\\r\\n\") return closingStart - 2;\n\tif (closingStart >= 1 && (source[closingStart - 1] === \"\\n\" || source[closingStart - 1] === \"\\r\")) {\n\t\treturn closingStart - 1;\n\t}\n\treturn closingStart;\n}\n\nexport function parseCopyableTextSegments(source: string): CopyableTextSegment[] {\n\tconst lines = sourceLines(source);\n\tconst segments: CopyableTextSegment[] = [];\n\tlet emittedThrough = 0;\n\tlet lineIndex = 0;\n\n\twhile (lineIndex < lines.length) {\n\t\tconst openingLine = lines[lineIndex];\n\t\tconst opening = parseFenceOpening(openingLine.text);\n\t\tif (!opening) {\n\t\t\tlineIndex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tlet closingIndex = -1;\n\t\tfor (let i = lineIndex + 1; i < lines.length; i++) {\n\t\t\tif (isFenceClosing(lines[i].text, opening)) {\n\t\t\t\tclosingIndex = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (!opening.copyable) {\n\t\t\tif (closingIndex < 0) break;\n\t\t\tlineIndex = closingIndex + 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (openingLine.start > emittedThrough) {\n\t\t\tsegments.push({ type: \"markdown\", text: source.slice(emittedThrough, openingLine.start) });\n\t\t}\n\n\t\tconst payloadStart = openingLine.end;\n\t\tif (closingIndex < 0) {\n\t\t\tsegments.push({\n\t\t\t\ttype: \"copyable\",\n\t\t\t\tpayload: source.slice(payloadStart),\n\t\t\t\tcomplete: false,\n\t\t\t\tstart: openingLine.start,\n\t\t\t});\n\t\t\treturn segments;\n\t\t}\n\n\t\tconst closingLine = lines[closingIndex];\n\t\tsegments.push({\n\t\t\ttype: \"copyable\",\n\t\t\tpayload: source.slice(payloadStart, payloadEndBeforeClosing(source, closingLine.start)),\n\t\t\tcomplete: true,\n\t\t\tstart: openingLine.start,\n\t\t});\n\t\temittedThrough = closingLine.end;\n\t\tlineIndex = closingIndex + 1;\n\t}\n\n\tif (emittedThrough < source.length) {\n\t\tsegments.push({ type: \"markdown\", text: source.slice(emittedThrough) });\n\t}\n\treturn segments;\n}\n\nexport type CopyableTextStatus = \"idle\" | \"copying\" | \"copied\" | { error: string };\n\nexport class CopyableTextBlockComponent implements Component {\n\tprivate buttonRow = -1;\n\tprivate buttonStart = -1;\n\tprivate buttonEnd = -1;\n\tprivate readonly payload: string;\n\tprivate readonly complete: boolean;\n\tprivate readonly outputPad: number;\n\tprivate readonly markdownTheme: MarkdownTheme;\n\tprivate readonly status: CopyableTextStatus;\n\tprivate readonly onCopy: () => void;\n\n\tconstructor(\n\t\tpayload: string,\n\t\tcomplete: boolean,\n\t\toutputPad: number,\n\t\tmarkdownTheme: MarkdownTheme,\n\t\tstatus: CopyableTextStatus,\n\t\tonCopy: () => void,\n\t) {\n\t\tthis.payload = payload;\n\t\tthis.complete = complete;\n\t\tthis.outputPad = outputPad;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.status = status;\n\t\tthis.onCopy = onCopy;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.buttonRow = -1;\n\t\tthis.buttonStart = -1;\n\t\tthis.buttonEnd = -1;\n\t}\n\n\trender(width: number): string[] {\n\t\tconst pad = \" \".repeat(this.outputPad);\n\t\tconst contentWidth = Math.max(1, width - this.outputPad - 2);\n\t\tconst lines = [truncateToWidth(`${pad}${this.markdownTheme.codeBlockBorder(\"╭─ lunr-copy\")}`, width, \"\")];\n\t\tconst payloadLines = this.payload.replace(/\\t/g, \" \").split(\"\\n\");\n\n\t\tfor (const payloadLine of payloadLines) {\n\t\t\tfor (const wrappedLine of wrapTextWithAnsi(payloadLine, contentWidth)) {\n\t\t\t\tlines.push(\n\t\t\t\t\ttruncateToWidth(\n\t\t\t\t\t\t`${pad}${this.markdownTheme.codeBlockBorder(\"│ \")}${this.markdownTheme.codeBlock(wrappedLine)}`,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\"\",\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tlines.push(\n\t\t\ttruncateToWidth(\n\t\t\t\t`${pad}${this.markdownTheme.codeBlockBorder(this.complete ? \"╰─\" : \"╰─ receiving\")}`,\n\t\t\t\twidth,\n\t\t\t\t\"\",\n\t\t\t),\n\t\t);\n\n\t\tthis.buttonRow = -1;\n\t\tthis.buttonStart = -1;\n\t\tthis.buttonEnd = -1;\n\t\tif (this.complete) {\n\t\t\tconst button = \"[ Copy ]\";\n\t\t\tlet feedback = \"\";\n\t\t\tif (this.status === \"copying\") feedback = theme.fg(\"dim\", \" Copying...\");\n\t\t\telse if (this.status === \"copied\") feedback = theme.fg(\"success\", \" Copied\");\n\t\t\telse if (typeof this.status === \"object\") feedback = theme.fg(\"error\", ` Copy failed: ${this.status.error}`);\n\t\t\tthis.buttonRow = lines.length;\n\t\t\tthis.buttonStart = this.outputPad;\n\t\t\tthis.buttonEnd = Math.min(width, this.buttonStart + button.length);\n\t\t\tlines.push(truncateToWidth(`${pad}${theme.fg(\"accent\", button)}${feedback}`, width, \"\"));\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\thandleClick(localY: number, width: number, localX?: number): boolean {\n\t\tthis.render(width);\n\t\tif (\n\t\t\t!this.complete ||\n\t\t\tthis.status === \"copying\" ||\n\t\t\tlocalX === undefined ||\n\t\t\tlocalY !== this.buttonRow ||\n\t\t\tlocalX < this.buttonStart ||\n\t\t\tlocalX >= this.buttonEnd\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.onCopy();\n\t\treturn true;\n\t}\n}\n"]}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { truncateToWidth, wrapTextWithAnsi } from "@ashx-j/lunr-tui";
|
|
2
|
+
import { theme } from "../theme/theme.js";
|
|
3
|
+
function sourceLines(source) {
|
|
4
|
+
const lines = [];
|
|
5
|
+
const pattern = /([^\r\n]*)(\r\n|\r|\n|$)/g;
|
|
6
|
+
for (const match of source.matchAll(pattern)) {
|
|
7
|
+
const start = match.index;
|
|
8
|
+
const text = match[1];
|
|
9
|
+
const newline = match[2];
|
|
10
|
+
lines.push({ start, end: start + text.length + newline.length, text });
|
|
11
|
+
if (!newline)
|
|
12
|
+
break;
|
|
13
|
+
}
|
|
14
|
+
return lines;
|
|
15
|
+
}
|
|
16
|
+
function parseFenceOpening(line) {
|
|
17
|
+
const match = /^( {0,3})(`{3,}|~{3,})(.*)$/.exec(line);
|
|
18
|
+
if (!match)
|
|
19
|
+
return undefined;
|
|
20
|
+
const fence = match[2];
|
|
21
|
+
const info = match[3];
|
|
22
|
+
if (fence[0] === "`" && info.includes("`"))
|
|
23
|
+
return undefined;
|
|
24
|
+
return {
|
|
25
|
+
marker: fence[0],
|
|
26
|
+
length: fence.length,
|
|
27
|
+
copyable: info.trim() === "lunr-copy",
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function isFenceClosing(line, opening) {
|
|
31
|
+
const match = /^( {0,3})(`+|~+)[ \t]*$/.exec(line);
|
|
32
|
+
if (!match)
|
|
33
|
+
return false;
|
|
34
|
+
const fence = match[2];
|
|
35
|
+
return fence[0] === opening.marker && fence.length >= opening.length;
|
|
36
|
+
}
|
|
37
|
+
function payloadEndBeforeClosing(source, closingStart) {
|
|
38
|
+
if (closingStart >= 2 && source.slice(closingStart - 2, closingStart) === "\r\n")
|
|
39
|
+
return closingStart - 2;
|
|
40
|
+
if (closingStart >= 1 && (source[closingStart - 1] === "\n" || source[closingStart - 1] === "\r")) {
|
|
41
|
+
return closingStart - 1;
|
|
42
|
+
}
|
|
43
|
+
return closingStart;
|
|
44
|
+
}
|
|
45
|
+
export function parseCopyableTextSegments(source) {
|
|
46
|
+
const lines = sourceLines(source);
|
|
47
|
+
const segments = [];
|
|
48
|
+
let emittedThrough = 0;
|
|
49
|
+
let lineIndex = 0;
|
|
50
|
+
while (lineIndex < lines.length) {
|
|
51
|
+
const openingLine = lines[lineIndex];
|
|
52
|
+
const opening = parseFenceOpening(openingLine.text);
|
|
53
|
+
if (!opening) {
|
|
54
|
+
lineIndex++;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
let closingIndex = -1;
|
|
58
|
+
for (let i = lineIndex + 1; i < lines.length; i++) {
|
|
59
|
+
if (isFenceClosing(lines[i].text, opening)) {
|
|
60
|
+
closingIndex = i;
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (!opening.copyable) {
|
|
65
|
+
if (closingIndex < 0)
|
|
66
|
+
break;
|
|
67
|
+
lineIndex = closingIndex + 1;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (openingLine.start > emittedThrough) {
|
|
71
|
+
segments.push({ type: "markdown", text: source.slice(emittedThrough, openingLine.start) });
|
|
72
|
+
}
|
|
73
|
+
const payloadStart = openingLine.end;
|
|
74
|
+
if (closingIndex < 0) {
|
|
75
|
+
segments.push({
|
|
76
|
+
type: "copyable",
|
|
77
|
+
payload: source.slice(payloadStart),
|
|
78
|
+
complete: false,
|
|
79
|
+
start: openingLine.start,
|
|
80
|
+
});
|
|
81
|
+
return segments;
|
|
82
|
+
}
|
|
83
|
+
const closingLine = lines[closingIndex];
|
|
84
|
+
segments.push({
|
|
85
|
+
type: "copyable",
|
|
86
|
+
payload: source.slice(payloadStart, payloadEndBeforeClosing(source, closingLine.start)),
|
|
87
|
+
complete: true,
|
|
88
|
+
start: openingLine.start,
|
|
89
|
+
});
|
|
90
|
+
emittedThrough = closingLine.end;
|
|
91
|
+
lineIndex = closingIndex + 1;
|
|
92
|
+
}
|
|
93
|
+
if (emittedThrough < source.length) {
|
|
94
|
+
segments.push({ type: "markdown", text: source.slice(emittedThrough) });
|
|
95
|
+
}
|
|
96
|
+
return segments;
|
|
97
|
+
}
|
|
98
|
+
export class CopyableTextBlockComponent {
|
|
99
|
+
buttonRow = -1;
|
|
100
|
+
buttonStart = -1;
|
|
101
|
+
buttonEnd = -1;
|
|
102
|
+
payload;
|
|
103
|
+
complete;
|
|
104
|
+
outputPad;
|
|
105
|
+
markdownTheme;
|
|
106
|
+
status;
|
|
107
|
+
onCopy;
|
|
108
|
+
constructor(payload, complete, outputPad, markdownTheme, status, onCopy) {
|
|
109
|
+
this.payload = payload;
|
|
110
|
+
this.complete = complete;
|
|
111
|
+
this.outputPad = outputPad;
|
|
112
|
+
this.markdownTheme = markdownTheme;
|
|
113
|
+
this.status = status;
|
|
114
|
+
this.onCopy = onCopy;
|
|
115
|
+
}
|
|
116
|
+
invalidate() {
|
|
117
|
+
this.buttonRow = -1;
|
|
118
|
+
this.buttonStart = -1;
|
|
119
|
+
this.buttonEnd = -1;
|
|
120
|
+
}
|
|
121
|
+
render(width) {
|
|
122
|
+
const pad = " ".repeat(this.outputPad);
|
|
123
|
+
const contentWidth = Math.max(1, width - this.outputPad - 2);
|
|
124
|
+
const lines = [truncateToWidth(`${pad}${this.markdownTheme.codeBlockBorder("╭─ lunr-copy")}`, width, "")];
|
|
125
|
+
const payloadLines = this.payload.replace(/\t/g, " ").split("\n");
|
|
126
|
+
for (const payloadLine of payloadLines) {
|
|
127
|
+
for (const wrappedLine of wrapTextWithAnsi(payloadLine, contentWidth)) {
|
|
128
|
+
lines.push(truncateToWidth(`${pad}${this.markdownTheme.codeBlockBorder("│ ")}${this.markdownTheme.codeBlock(wrappedLine)}`, width, ""));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
lines.push(truncateToWidth(`${pad}${this.markdownTheme.codeBlockBorder(this.complete ? "╰─" : "╰─ receiving")}`, width, ""));
|
|
132
|
+
this.buttonRow = -1;
|
|
133
|
+
this.buttonStart = -1;
|
|
134
|
+
this.buttonEnd = -1;
|
|
135
|
+
if (this.complete) {
|
|
136
|
+
const button = "[ Copy ]";
|
|
137
|
+
let feedback = "";
|
|
138
|
+
if (this.status === "copying")
|
|
139
|
+
feedback = theme.fg("dim", " Copying...");
|
|
140
|
+
else if (this.status === "copied")
|
|
141
|
+
feedback = theme.fg("success", " Copied");
|
|
142
|
+
else if (typeof this.status === "object")
|
|
143
|
+
feedback = theme.fg("error", ` Copy failed: ${this.status.error}`);
|
|
144
|
+
this.buttonRow = lines.length;
|
|
145
|
+
this.buttonStart = this.outputPad;
|
|
146
|
+
this.buttonEnd = Math.min(width, this.buttonStart + button.length);
|
|
147
|
+
lines.push(truncateToWidth(`${pad}${theme.fg("accent", button)}${feedback}`, width, ""));
|
|
148
|
+
}
|
|
149
|
+
return lines;
|
|
150
|
+
}
|
|
151
|
+
handleClick(localY, width, localX) {
|
|
152
|
+
this.render(width);
|
|
153
|
+
if (!this.complete ||
|
|
154
|
+
this.status === "copying" ||
|
|
155
|
+
localX === undefined ||
|
|
156
|
+
localY !== this.buttonRow ||
|
|
157
|
+
localX < this.buttonStart ||
|
|
158
|
+
localX >= this.buttonEnd) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
this.onCopy();
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=copyable-text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copyable-text.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/copyable-text.ts"],"names":[],"mappings":"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","sourcesContent":["import type { MarkdownTheme } from \"@ashx-j/lunr-tui\";\nimport { type Component, truncateToWidth, wrapTextWithAnsi } from \"@ashx-j/lunr-tui\";\nimport { theme } from \"../theme/theme.ts\";\n\nexport type CopyableTextSegment =\n\t| { type: \"markdown\"; text: string }\n\t| { type: \"copyable\"; payload: string; complete: boolean; start: number };\n\ninterface SourceLine {\n\tstart: number;\n\tend: number;\n\ttext: string;\n}\n\ninterface FenceOpening {\n\tmarker: \"`\" | \"~\";\n\tlength: number;\n\tcopyable: boolean;\n}\n\nfunction sourceLines(source: string): SourceLine[] {\n\tconst lines: SourceLine[] = [];\n\tconst pattern = /([^\\r\\n]*)(\\r\\n|\\r|\\n|$)/g;\n\tfor (const match of source.matchAll(pattern)) {\n\t\tconst start = match.index;\n\t\tconst text = match[1];\n\t\tconst newline = match[2];\n\t\tlines.push({ start, end: start + text.length + newline.length, text });\n\t\tif (!newline) break;\n\t}\n\treturn lines;\n}\n\nfunction parseFenceOpening(line: string): FenceOpening | undefined {\n\tconst match = /^( {0,3})(`{3,}|~{3,})(.*)$/.exec(line);\n\tif (!match) return undefined;\n\tconst fence = match[2];\n\tconst info = match[3];\n\tif (fence[0] === \"`\" && info.includes(\"`\")) return undefined;\n\treturn {\n\t\tmarker: fence[0] as \"`\" | \"~\",\n\t\tlength: fence.length,\n\t\tcopyable: info.trim() === \"lunr-copy\",\n\t};\n}\n\nfunction isFenceClosing(line: string, opening: FenceOpening): boolean {\n\tconst match = /^( {0,3})(`+|~+)[ \\t]*$/.exec(line);\n\tif (!match) return false;\n\tconst fence = match[2];\n\treturn fence[0] === opening.marker && fence.length >= opening.length;\n}\n\nfunction payloadEndBeforeClosing(source: string, closingStart: number): number {\n\tif (closingStart >= 2 && source.slice(closingStart - 2, closingStart) === \"\\r\\n\") return closingStart - 2;\n\tif (closingStart >= 1 && (source[closingStart - 1] === \"\\n\" || source[closingStart - 1] === \"\\r\")) {\n\t\treturn closingStart - 1;\n\t}\n\treturn closingStart;\n}\n\nexport function parseCopyableTextSegments(source: string): CopyableTextSegment[] {\n\tconst lines = sourceLines(source);\n\tconst segments: CopyableTextSegment[] = [];\n\tlet emittedThrough = 0;\n\tlet lineIndex = 0;\n\n\twhile (lineIndex < lines.length) {\n\t\tconst openingLine = lines[lineIndex];\n\t\tconst opening = parseFenceOpening(openingLine.text);\n\t\tif (!opening) {\n\t\t\tlineIndex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tlet closingIndex = -1;\n\t\tfor (let i = lineIndex + 1; i < lines.length; i++) {\n\t\t\tif (isFenceClosing(lines[i].text, opening)) {\n\t\t\t\tclosingIndex = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (!opening.copyable) {\n\t\t\tif (closingIndex < 0) break;\n\t\t\tlineIndex = closingIndex + 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (openingLine.start > emittedThrough) {\n\t\t\tsegments.push({ type: \"markdown\", text: source.slice(emittedThrough, openingLine.start) });\n\t\t}\n\n\t\tconst payloadStart = openingLine.end;\n\t\tif (closingIndex < 0) {\n\t\t\tsegments.push({\n\t\t\t\ttype: \"copyable\",\n\t\t\t\tpayload: source.slice(payloadStart),\n\t\t\t\tcomplete: false,\n\t\t\t\tstart: openingLine.start,\n\t\t\t});\n\t\t\treturn segments;\n\t\t}\n\n\t\tconst closingLine = lines[closingIndex];\n\t\tsegments.push({\n\t\t\ttype: \"copyable\",\n\t\t\tpayload: source.slice(payloadStart, payloadEndBeforeClosing(source, closingLine.start)),\n\t\t\tcomplete: true,\n\t\t\tstart: openingLine.start,\n\t\t});\n\t\temittedThrough = closingLine.end;\n\t\tlineIndex = closingIndex + 1;\n\t}\n\n\tif (emittedThrough < source.length) {\n\t\tsegments.push({ type: \"markdown\", text: source.slice(emittedThrough) });\n\t}\n\treturn segments;\n}\n\nexport type CopyableTextStatus = \"idle\" | \"copying\" | \"copied\" | { error: string };\n\nexport class CopyableTextBlockComponent implements Component {\n\tprivate buttonRow = -1;\n\tprivate buttonStart = -1;\n\tprivate buttonEnd = -1;\n\tprivate readonly payload: string;\n\tprivate readonly complete: boolean;\n\tprivate readonly outputPad: number;\n\tprivate readonly markdownTheme: MarkdownTheme;\n\tprivate readonly status: CopyableTextStatus;\n\tprivate readonly onCopy: () => void;\n\n\tconstructor(\n\t\tpayload: string,\n\t\tcomplete: boolean,\n\t\toutputPad: number,\n\t\tmarkdownTheme: MarkdownTheme,\n\t\tstatus: CopyableTextStatus,\n\t\tonCopy: () => void,\n\t) {\n\t\tthis.payload = payload;\n\t\tthis.complete = complete;\n\t\tthis.outputPad = outputPad;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.status = status;\n\t\tthis.onCopy = onCopy;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.buttonRow = -1;\n\t\tthis.buttonStart = -1;\n\t\tthis.buttonEnd = -1;\n\t}\n\n\trender(width: number): string[] {\n\t\tconst pad = \" \".repeat(this.outputPad);\n\t\tconst contentWidth = Math.max(1, width - this.outputPad - 2);\n\t\tconst lines = [truncateToWidth(`${pad}${this.markdownTheme.codeBlockBorder(\"╭─ lunr-copy\")}`, width, \"\")];\n\t\tconst payloadLines = this.payload.replace(/\\t/g, \" \").split(\"\\n\");\n\n\t\tfor (const payloadLine of payloadLines) {\n\t\t\tfor (const wrappedLine of wrapTextWithAnsi(payloadLine, contentWidth)) {\n\t\t\t\tlines.push(\n\t\t\t\t\ttruncateToWidth(\n\t\t\t\t\t\t`${pad}${this.markdownTheme.codeBlockBorder(\"│ \")}${this.markdownTheme.codeBlock(wrappedLine)}`,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\"\",\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tlines.push(\n\t\t\ttruncateToWidth(\n\t\t\t\t`${pad}${this.markdownTheme.codeBlockBorder(this.complete ? \"╰─\" : \"╰─ receiving\")}`,\n\t\t\t\twidth,\n\t\t\t\t\"\",\n\t\t\t),\n\t\t);\n\n\t\tthis.buttonRow = -1;\n\t\tthis.buttonStart = -1;\n\t\tthis.buttonEnd = -1;\n\t\tif (this.complete) {\n\t\t\tconst button = \"[ Copy ]\";\n\t\t\tlet feedback = \"\";\n\t\t\tif (this.status === \"copying\") feedback = theme.fg(\"dim\", \" Copying...\");\n\t\t\telse if (this.status === \"copied\") feedback = theme.fg(\"success\", \" Copied\");\n\t\t\telse if (typeof this.status === \"object\") feedback = theme.fg(\"error\", ` Copy failed: ${this.status.error}`);\n\t\t\tthis.buttonRow = lines.length;\n\t\t\tthis.buttonStart = this.outputPad;\n\t\t\tthis.buttonEnd = Math.min(width, this.buttonStart + button.length);\n\t\t\tlines.push(truncateToWidth(`${pad}${theme.fg(\"accent\", button)}${feedback}`, width, \"\"));\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\thandleClick(localY: number, width: number, localX?: number): boolean {\n\t\tthis.render(width);\n\t\tif (\n\t\t\t!this.complete ||\n\t\t\tthis.status === \"copying\" ||\n\t\t\tlocalX === undefined ||\n\t\t\tlocalY !== this.buttonRow ||\n\t\t\tlocalX < this.buttonStart ||\n\t\t\tlocalX >= this.buttonEnd\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.onCopy();\n\t\treturn true;\n\t}\n}\n"]}
|