@bubblebrain-ai/bubble 0.0.52 → 0.0.54
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/README.md +4 -12
- package/dist/agent/routing-catalog.js +3 -2
- package/dist/agent/subagent/router.js +5 -0
- package/dist/agent/subagent/runtime.d.ts +1 -0
- package/dist/agent/subagent/runtime.js +13 -1
- package/dist/agent/subagent-control.d.ts +4 -0
- package/dist/agent/subagent-control.js +1 -0
- package/dist/agent/subagent-store.js +2 -0
- package/dist/agent/workflow/control.d.ts +2 -0
- package/dist/agent/workflow/runs.d.ts +1 -0
- package/dist/agent/workflow/runs.js +3 -0
- package/dist/agent.d.ts +11 -1
- package/dist/agent.js +158 -57
- package/dist/bin.js +2 -44
- package/dist/config.d.ts +14 -1
- package/dist/config.js +45 -4
- package/dist/context/budget.d.ts +7 -1
- package/dist/context/budget.js +25 -2
- package/dist/context/compact-llm.d.ts +1 -1
- package/dist/context/compact-llm.js +5 -2
- package/dist/context/overflow.js +2 -0
- package/dist/context/projector.d.ts +8 -0
- package/dist/context/projector.js +55 -6
- package/dist/context/tool-output-truncate.d.ts +17 -1
- package/dist/context/tool-output-truncate.js +171 -49
- package/dist/feishu/agent-host/run-driver.js +3 -0
- package/dist/feishu/serve.js +2 -0
- package/dist/goal/command.d.ts +1 -1
- package/dist/goal/command.js +7 -2
- package/dist/main.d.ts +1 -1
- package/dist/main.js +38 -8
- package/dist/memory/db.js +0 -7
- package/dist/model-catalog.js +25 -6
- package/dist/model-config.js +3 -2
- package/dist/model-pricing.d.ts +24 -5
- package/dist/model-pricing.js +0 -0
- package/dist/model-selection.js +13 -4
- package/dist/network/chatgpt-transport.js +0 -34
- package/dist/network/errors.d.ts +19 -0
- package/dist/network/errors.js +24 -0
- package/dist/network/provider-transport.d.ts +0 -4
- package/dist/network/provider-transport.js +3 -35
- package/dist/network/retry.d.ts +6 -1
- package/dist/network/retry.js +9 -0
- package/dist/provider-model-policy.d.ts +16 -0
- package/dist/provider-model-policy.js +33 -0
- package/dist/provider-registry.d.ts +1 -1
- package/dist/provider-registry.js +73 -10
- package/dist/provider-transform.js +32 -4
- package/dist/provider.d.ts +6 -2
- package/dist/provider.js +95 -6
- package/dist/question/controller.js +5 -4
- package/dist/question/normalize.d.ts +6 -0
- package/dist/question/normalize.js +11 -0
- package/dist/rewind.d.ts +20 -0
- package/dist/rewind.js +29 -0
- package/dist/sdk/index.d.ts +1 -1
- package/dist/sdk/index.js +11 -3
- package/dist/session.d.ts +7 -0
- package/dist/session.js +20 -0
- package/dist/skills/discovery.js +18 -0
- package/dist/skills/registry.d.ts +12 -2
- package/dist/skills/registry.js +40 -5
- package/dist/skills/types.d.ts +2 -0
- package/dist/slash-commands/commands.js +120 -81
- package/dist/slash-commands/registry.d.ts +2 -1
- package/dist/slash-commands/registry.js +3 -0
- package/dist/slash-commands/types.d.ts +22 -4
- package/dist/stats/usage.d.ts +3 -1
- package/dist/stats/usage.js +22 -13
- package/dist/tasks/manager.d.ts +4 -2
- package/dist/tasks/manager.js +34 -9
- package/dist/tasks/promotion.d.ts +2 -2
- package/dist/tasks/promotion.js +2 -2
- package/dist/tools/agent-lifecycle.js +4 -0
- package/dist/tools/bash.d.ts +3 -1
- package/dist/tools/bash.js +13 -2
- package/dist/tools/grep.d.ts +5 -1
- package/dist/tools/grep.js +318 -69
- package/dist/tools/index.d.ts +3 -1
- package/dist/tools/index.js +1 -0
- package/dist/tools/question.js +5 -4
- package/dist/tools/read.js +40 -21
- package/dist/tui/animation-clock.d.ts +14 -0
- package/dist/tui/animation-clock.js +34 -0
- package/dist/tui/app.d.ts +176 -0
- package/dist/tui/app.js +1647 -0
- package/dist/tui/components/approval-dialog.d.ts +43 -0
- package/dist/tui/components/approval-dialog.js +247 -0
- package/dist/tui/components/bottom-sheet.d.ts +9 -0
- package/dist/tui/components/bottom-sheet.js +32 -0
- package/dist/tui/components/context-info.d.ts +54 -0
- package/dist/tui/components/context-info.js +388 -0
- package/dist/tui/components/feedback-dialog.d.ts +56 -0
- package/dist/tui/components/feedback-dialog.js +262 -0
- package/dist/tui/components/feishu-setup-dialog.d.ts +65 -0
- package/dist/tui/components/feishu-setup-dialog.js +332 -0
- package/dist/tui/components/image-preview.d.ts +32 -0
- package/dist/tui/components/image-preview.js +130 -0
- package/dist/tui/components/plan-dialog.d.ts +34 -0
- package/dist/tui/components/plan-dialog.js +196 -0
- package/dist/tui/components/provider-key-input.d.ts +18 -0
- package/dist/tui/components/provider-key-input.js +49 -0
- package/dist/tui/components/question-dialog.d.ts +25 -0
- package/dist/tui/components/question-dialog.js +263 -0
- package/dist/tui/components/responsive-transcript.d.ts +31 -0
- package/dist/tui/components/responsive-transcript.js +77 -0
- package/dist/tui/components/rewind-picker.d.ts +62 -0
- package/dist/tui/components/rewind-picker.js +317 -0
- package/dist/tui/components/session-picker.d.ts +49 -0
- package/dist/tui/components/session-picker.js +303 -0
- package/dist/tui/components/skills-panel.d.ts +59 -0
- package/dist/tui/components/skills-panel.js +568 -0
- package/dist/tui/components/stats-panel.d.ts +40 -0
- package/dist/tui/components/stats-panel.js +301 -0
- package/dist/tui/components/streaming-message.d.ts +69 -0
- package/dist/tui/components/streaming-message.js +393 -0
- package/dist/tui/components/subagent-inspector.d.ts +28 -0
- package/dist/tui/components/subagent-inspector.js +127 -0
- package/dist/tui/components/task-inspector.d.ts +26 -0
- package/dist/tui/components/task-inspector.js +70 -0
- package/dist/tui/components/tasks-pane.d.ts +88 -0
- package/dist/tui/components/tasks-pane.js +416 -0
- package/dist/tui/components/transcript.d.ts +96 -0
- package/dist/tui/components/transcript.js +771 -0
- package/dist/tui/components/welcome.d.ts +20 -0
- package/dist/tui/components/welcome.js +133 -0
- package/dist/tui/components/workflow-inspector.d.ts +30 -0
- package/dist/tui/components/workflow-inspector.js +136 -0
- package/dist/tui/composer-autocomplete.d.ts +61 -0
- package/dist/tui/composer-autocomplete.js +383 -0
- package/dist/tui/composer-style.d.ts +7 -0
- package/dist/tui/composer-style.js +29 -0
- package/dist/tui/controller/agent-event-reducer.d.ts +75 -0
- package/dist/tui/controller/agent-event-reducer.js +238 -0
- package/dist/tui/controller/composer-controller.d.ts +95 -0
- package/dist/tui/controller/composer-controller.js +502 -0
- package/dist/tui/controller/controller.d.ts +194 -0
- package/dist/tui/controller/controller.js +1035 -0
- package/dist/tui/controller/effects.d.ts +71 -0
- package/dist/tui/controller/effects.js +1 -0
- package/dist/tui/controller/goal-runtime-controller.d.ts +47 -0
- package/dist/tui/controller/goal-runtime-controller.js +202 -0
- package/dist/tui/controller/input-queue-machine.d.ts +71 -0
- package/dist/tui/controller/input-queue-machine.js +121 -0
- package/dist/tui/controller/intents.d.ts +56 -0
- package/dist/tui/controller/intents.js +6 -0
- package/dist/tui/controller/overlay-controller.d.ts +64 -0
- package/dist/tui/controller/overlay-controller.js +129 -0
- package/dist/tui/controller/ports.d.ts +57 -0
- package/dist/tui/controller/ports.js +9 -0
- package/dist/tui/controller/session-transition.d.ts +54 -0
- package/dist/tui/controller/session-transition.js +68 -0
- package/dist/tui/controller/state.d.ts +14 -0
- package/dist/tui/controller/state.js +36 -0
- package/dist/tui/controller/task-runtime-controller.d.ts +66 -0
- package/dist/tui/controller/task-runtime-controller.js +158 -0
- package/dist/tui/footer.d.ts +37 -0
- package/dist/tui/footer.js +80 -0
- package/dist/{tui-ink → tui/formatting}/edit-diff.d.ts +1 -1
- package/dist/{tui-ink → tui/formatting}/edit-diff.js +1 -1
- package/dist/{tui-ink/app-helpers.d.ts → tui/formatting/summary.d.ts} +4 -4
- package/dist/{tui-ink/app-helpers.js → tui/formatting/summary.js} +2 -2
- package/dist/tui/fullscreen.d.ts +48 -0
- package/dist/tui/fullscreen.js +255 -0
- package/dist/tui/image-display.d.ts +4 -0
- package/dist/tui/image-display.js +30 -12
- package/dist/tui/markdown-style.d.ts +5 -0
- package/dist/tui/markdown-style.js +23 -0
- package/dist/{tui-ink → tui/model}/composer-buffer.js +1 -1
- package/dist/tui/model/composer-types.d.ts +17 -0
- package/dist/tui/model/composer-types.js +1 -0
- package/dist/{tui-ink → tui/model}/display-history.d.ts +7 -1
- package/dist/{tui-ink → tui/model}/display-reconstruct.d.ts +1 -1
- package/dist/{tui-ink → tui/model}/display-reconstruct.js +54 -6
- package/dist/{tui-ink → tui/model}/file-mentions.d.ts +2 -0
- package/dist/{tui-ink → tui/model}/file-mentions.js +4 -0
- package/dist/tui/model/image-attachment.d.ts +15 -0
- package/dist/tui/model/image-attachment.js +1 -0
- package/dist/{tui-ink → tui/model}/image-paste.d.ts +7 -1
- package/dist/{tui-ink → tui/model}/image-paste.js +46 -0
- package/dist/tui/model/input-history.d.ts +1 -0
- package/dist/tui/model/input-history.js +1 -0
- package/dist/{tui-ink → tui/model}/input-queue.d.ts +1 -1
- package/dist/{tui-ink → tui/model}/recent-activity.js +1 -1
- package/dist/{tui-ink → tui/model}/subagent-view.d.ts +17 -2
- package/dist/{tui-ink → tui/model}/subagent-view.js +125 -4
- package/dist/{tui-ink → tui/model}/submit-dedupe.d.ts +1 -1
- package/dist/tui/model/theme-style.d.ts +10 -0
- package/dist/tui/model/theme-style.js +79 -0
- package/dist/{tui-ink → tui/model}/theme.d.ts +11 -23
- package/dist/{tui-ink → tui/model}/theme.js +23 -38
- package/dist/{tui-ink → tui/model}/trace-groups.d.ts +2 -0
- package/dist/{tui-ink → tui/model}/trace-groups.js +91 -30
- package/dist/tui/model/trace-interaction.d.ts +63 -0
- package/dist/tui/model/trace-interaction.js +87 -0
- package/dist/tui/model-picker-data.d.ts +1 -2
- package/dist/tui/model-picker-data.js +8 -1
- package/dist/tui/model-switch.js +2 -0
- package/dist/{tui-ink → tui}/run-session-picker.d.ts +2 -3
- package/dist/tui/run-session-picker.js +64 -0
- package/dist/tui/run.d.ts +72 -0
- package/dist/tui/run.js +139 -0
- package/dist/tui/terminal/multiplexer.d.ts +5 -0
- package/dist/tui/terminal/multiplexer.js +14 -0
- package/dist/tui/testing/fake-agent.d.ts +24 -0
- package/dist/tui/testing/fake-agent.js +22 -0
- package/dist/tui/testing/spy-host.d.ts +21 -0
- package/dist/tui/testing/spy-host.js +55 -0
- package/dist/tui/trace-groups.js +27 -6
- package/dist/types.d.ts +7 -0
- package/dist/update/index.d.ts +1 -0
- package/dist/update/index.js +22 -17
- package/node_modules/@bubblebrain-ai/pi-tui/LICENSE +21 -0
- package/node_modules/@bubblebrain-ai/pi-tui/README.md +854 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/alt-screen-search.d.ts +26 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/alt-screen-search.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/alt-screen-search.js +121 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/alt-screen-search.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/autocomplete.d.ts +86 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/autocomplete.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/autocomplete.js +649 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/autocomplete.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/alt-screen-flash.d.ts +13 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/alt-screen-flash.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/alt-screen-flash.js +36 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/alt-screen-flash.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/box.d.ts +22 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/box.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/box.js +99 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/box.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/cancellable-loader.d.ts +22 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/cancellable-loader.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/cancellable-loader.js +36 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/cancellable-loader.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/editor.d.ts +330 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/editor.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/editor.js +2344 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/editor.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/h-stack.d.ts +7 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/h-stack.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/h-stack.js +43 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/h-stack.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/image.d.ts +28 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/image.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/image.js +82 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/image.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/input.d.ts +48 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/input.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/input.js +390 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/input.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/loader.d.ts +31 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/loader.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/loader.js +67 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/loader.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/markdown.d.ts +103 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/markdown.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/markdown.js +797 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/markdown.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/scroll-view.d.ts +56 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/scroll-view.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/scroll-view.js +179 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/scroll-view.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/select-list.d.ts +53 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/select-list.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/select-list.js +175 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/select-list.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/settings-list.d.ts +50 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/settings-list.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/settings-list.js +174 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/settings-list.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/spacer.d.ts +12 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/spacer.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/spacer.js +22 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/spacer.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/stack.d.ts +32 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/stack.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/stack.js +109 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/stack.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/text.d.ts +19 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/text.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/text.js +81 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/text.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/truncated-text.d.ts +13 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/truncated-text.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/truncated-text.js +48 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/truncated-text.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/v-stack.d.ts +8 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/v-stack.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/v-stack.js +26 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/v-stack.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/editor-component.d.ts +39 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/editor-component.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/editor-component.js +2 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/editor-component.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/fuzzy.d.ts +16 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/fuzzy.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/fuzzy.js +110 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/fuzzy.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/index.d.ts +31 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/index.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/index.js +42 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/index.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keybindings.d.ts +273 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keybindings.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keybindings.js +231 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keybindings.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keys.d.ts +184 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keys.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keys.js +1174 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keys.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/kill-ring.d.ts +28 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/kill-ring.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/kill-ring.js +46 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/kill-ring.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/latex.d.ts +10 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/latex.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/latex.js +1268 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/latex.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout-node.d.ts +40 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout-node.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout-node.js +6 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout-node.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout.d.ts +42 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout.js +335 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/native-modifiers.d.ts +3 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/native-modifiers.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/native-modifiers.js +60 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/native-modifiers.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/stdin-buffer.d.ts +56 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/stdin-buffer.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/stdin-buffer.js +363 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/stdin-buffer.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-colors.d.ts +10 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-colors.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-colors.js +59 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-colors.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-image.d.ts +116 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-image.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-image.js +518 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-image.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal.d.ts +142 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal.js +544 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/testing.d.ts +11 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/testing.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/testing.js +11 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/testing.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-alt-screen.d.ts +140 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-alt-screen.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-alt-screen.js +1334 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-alt-screen.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-main-screen.d.ts +39 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-main-screen.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-main-screen.js +536 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-main-screen.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui.d.ts +338 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui.js +1016 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/undo-stack.d.ts +17 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/undo-stack.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/undo-stack.js +27 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/undo-stack.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/utils.d.ts +96 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/utils.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/utils.js +1193 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/utils.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/word-navigation.d.ts +25 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/word-navigation.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/word-navigation.js +96 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/word-navigation.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/test/virtual-terminal.d.ts +73 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/test/virtual-terminal.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/test/virtual-terminal.js +188 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/test/virtual-terminal.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/native/darwin/README.md +20 -0
- package/node_modules/@bubblebrain-ai/pi-tui/native/darwin/build.sh +62 -0
- package/node_modules/@bubblebrain-ai/pi-tui/native/darwin/prebuilds/darwin-arm64/darwin-modifiers.node +0 -0
- package/node_modules/@bubblebrain-ai/pi-tui/native/darwin/prebuilds/darwin-x64/darwin-modifiers.node +0 -0
- package/node_modules/@bubblebrain-ai/pi-tui/native/darwin/src/darwin-modifiers.c +70 -0
- package/node_modules/@bubblebrain-ai/pi-tui/native/win32/README.md +22 -0
- package/node_modules/@bubblebrain-ai/pi-tui/native/win32/build.mjs +229 -0
- package/node_modules/@bubblebrain-ai/pi-tui/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
- package/node_modules/@bubblebrain-ai/pi-tui/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
- package/node_modules/@bubblebrain-ai/pi-tui/native/win32/src/win32-console-mode.c +119 -0
- package/node_modules/@bubblebrain-ai/pi-tui/package.json +66 -0
- package/node_modules/get-east-asian-width/index.d.ts +60 -0
- package/node_modules/get-east-asian-width/index.js +30 -0
- package/node_modules/get-east-asian-width/license +9 -0
- package/node_modules/get-east-asian-width/lookup-data.js +21 -0
- package/node_modules/get-east-asian-width/lookup.js +138 -0
- package/node_modules/get-east-asian-width/package.json +71 -0
- package/node_modules/get-east-asian-width/readme.md +65 -0
- package/node_modules/get-east-asian-width/utilities.js +24 -0
- package/node_modules/marked/LICENSE +44 -0
- package/node_modules/marked/README.md +115 -0
- package/node_modules/marked/bin/main.js +284 -0
- package/node_modules/marked/bin/marked.js +16 -0
- package/node_modules/marked/lib/marked.d.ts +760 -0
- package/node_modules/marked/lib/marked.esm.js +77 -0
- package/node_modules/marked/lib/marked.esm.js.map +7 -0
- package/node_modules/marked/lib/marked.umd.js +79 -0
- package/node_modules/marked/lib/marked.umd.js.map +7 -0
- package/node_modules/marked/man/marked.1 +113 -0
- package/node_modules/marked/man/marked.1.md +93 -0
- package/node_modules/marked/package.json +103 -0
- package/package.json +25 -10
- package/dist/tui-ink/app.d.ts +0 -76
- package/dist/tui-ink/app.js +0 -2377
- package/dist/tui-ink/approval/approval-dialog.d.ts +0 -13
- package/dist/tui-ink/approval/approval-dialog.js +0 -184
- package/dist/tui-ink/approval/diff-view.d.ts +0 -7
- package/dist/tui-ink/approval/diff-view.js +0 -44
- package/dist/tui-ink/approval/select.d.ts +0 -35
- package/dist/tui-ink/approval/select.js +0 -98
- package/dist/tui-ink/code-highlight.d.ts +0 -8
- package/dist/tui-ink/code-highlight.js +0 -121
- package/dist/tui-ink/command-palette.d.ts +0 -32
- package/dist/tui-ink/command-palette.js +0 -158
- package/dist/tui-ink/compaction-progress.d.ts +0 -19
- package/dist/tui-ink/compaction-progress.js +0 -74
- package/dist/tui-ink/detect-theme.d.ts +0 -1
- package/dist/tui-ink/detect-theme.js +0 -1
- package/dist/tui-ink/feedback-dialog.d.ts +0 -19
- package/dist/tui-ink/feedback-dialog.js +0 -133
- package/dist/tui-ink/feishu-setup-picker.d.ts +0 -5
- package/dist/tui-ink/feishu-setup-picker.js +0 -271
- package/dist/tui-ink/footer.d.ts +0 -26
- package/dist/tui-ink/footer.js +0 -51
- package/dist/tui-ink/input-box.d.ts +0 -189
- package/dist/tui-ink/input-box.js +0 -1279
- package/dist/tui-ink/input-history.d.ts +0 -1
- package/dist/tui-ink/input-history.js +0 -1
- package/dist/tui-ink/markdown.d.ts +0 -103
- package/dist/tui-ink/markdown.js +0 -747
- package/dist/tui-ink/message-list.d.ts +0 -49
- package/dist/tui-ink/message-list.js +0 -841
- package/dist/tui-ink/model-picker.d.ts +0 -143
- package/dist/tui-ink/model-picker.js +0 -966
- package/dist/tui-ink/plan-confirm.d.ts +0 -7
- package/dist/tui-ink/plan-confirm.js +0 -115
- package/dist/tui-ink/question-dialog.d.ts +0 -8
- package/dist/tui-ink/question-dialog.js +0 -135
- package/dist/tui-ink/rewind-picker.d.ts +0 -8
- package/dist/tui-ink/rewind-picker.js +0 -102
- package/dist/tui-ink/run-session-picker.js +0 -22
- package/dist/tui-ink/run.d.ts +0 -62
- package/dist/tui-ink/run.js +0 -103
- package/dist/tui-ink/session-picker.d.ts +0 -10
- package/dist/tui-ink/session-picker.js +0 -113
- package/dist/tui-ink/stats-panel.d.ts +0 -11
- package/dist/tui-ink/stats-panel.js +0 -65
- package/dist/tui-ink/subagent-inspector.d.ts +0 -21
- package/dist/tui-ink/subagent-inspector.js +0 -205
- package/dist/tui-ink/use-terminal-size.d.ts +0 -4
- package/dist/tui-ink/use-terminal-size.js +0 -48
- package/dist/tui-ink/waiting-indicator.d.ts +0 -12
- package/dist/tui-ink/waiting-indicator.js +0 -129
- package/dist/tui-ink/welcome.d.ts +0 -25
- package/dist/tui-ink/welcome.js +0 -88
- package/dist/tui-ink/wordmark.d.ts +0 -8
- package/dist/tui-ink/wordmark.js +0 -103
- /package/dist/{tui-ink → tui/model}/composer-buffer.d.ts +0 -0
- /package/dist/{tui-ink → tui/model}/display-history.js +0 -0
- /package/dist/{tui-ink → tui/model}/input-queue.js +0 -0
- /package/dist/{tui-ink → tui/model}/key-events.d.ts +0 -0
- /package/dist/{tui-ink → tui/model}/key-events.js +0 -0
- /package/dist/{tui-ink → tui/model}/paste-operation-tracker.d.ts +0 -0
- /package/dist/{tui-ink → tui/model}/paste-operation-tracker.js +0 -0
- /package/dist/{tui-ink → tui/model}/recent-activity.d.ts +0 -0
- /package/dist/{tui-ink → tui/model}/submit-dedupe.js +0 -0
- /package/dist/{tui-ink → tui/model}/sync-output.d.ts +0 -0
- /package/dist/{tui-ink → tui/model}/sync-output.js +0 -0
- /package/dist/{tui-ink → tui/model}/terminal-env.d.ts +0 -0
- /package/dist/{tui-ink → tui/model}/terminal-env.js +0 -0
- /package/dist/{tui-ink → tui/model}/terminal-mouse.d.ts +0 -0
- /package/dist/{tui-ink → tui/model}/terminal-mouse.js +0 -0
- /package/dist/{tui-ink → tui/model}/width.d.ts +0 -0
- /package/dist/{tui-ink → tui/model}/width.js +0 -0
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
import { appendHistoryEntry, loadHistoryEntriesSync, pushHistoryEntry, stepHistory, } from "../model/input-history.js";
|
|
2
|
+
import { bareImageFilenameFromPaste, extractImagePathTokens, ingestClipboardImage, ingestImagePath, } from "../model/image-paste.js";
|
|
3
|
+
import { PasteOperationTracker } from "../model/paste-operation-tracker.js";
|
|
4
|
+
import { imageDisplayLabel, stripInlineImageLabels } from "../image-display.js";
|
|
5
|
+
import { darkTheme } from "../model/theme.js";
|
|
6
|
+
import { themeBackground, themeForeground } from "../model/theme-style.js";
|
|
7
|
+
const READING_IMAGE_PREFIX = "Reading image";
|
|
8
|
+
function cloneHistoryEntry(entry) {
|
|
9
|
+
return {
|
|
10
|
+
text: entry.text,
|
|
11
|
+
images: entry.images.map((image) => ({ ...image })),
|
|
12
|
+
...(entry.imageDisplayStart !== undefined ? { imageDisplayStart: entry.imageDisplayStart } : {}),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function normalizedScope(scope) {
|
|
16
|
+
return {
|
|
17
|
+
sessionFile: scope.sessionFile?.trim() || undefined,
|
|
18
|
+
cwd: scope.cwd?.trim() || undefined,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function scopesEqual(a, b) {
|
|
22
|
+
return a.sessionFile === b.sessionFile && a.cwd === b.cwd;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Owns semantic composer state that Pi Editor deliberately does not know about:
|
|
26
|
+
* image attachments, asynchronous paste operations and scoped persistent
|
|
27
|
+
* history. Text editing and cursor mechanics remain inside Editor.
|
|
28
|
+
*/
|
|
29
|
+
export class ComposerController {
|
|
30
|
+
options;
|
|
31
|
+
editor;
|
|
32
|
+
scope;
|
|
33
|
+
history = [];
|
|
34
|
+
historyIndex = null;
|
|
35
|
+
historyDraft = { text: "", images: [] };
|
|
36
|
+
attachments = [];
|
|
37
|
+
imageDisplayStart;
|
|
38
|
+
nextImageLabelStart;
|
|
39
|
+
pasteOperations = new PasteOperationTracker();
|
|
40
|
+
draftGeneration = 0;
|
|
41
|
+
applyingEditorState = false;
|
|
42
|
+
historyNavigationChangePending = false;
|
|
43
|
+
editorSubmitting = false;
|
|
44
|
+
disposed = false;
|
|
45
|
+
recentPreviewLabel;
|
|
46
|
+
recentPreviewCursorOffset;
|
|
47
|
+
openImageHandler;
|
|
48
|
+
constructor(options) {
|
|
49
|
+
this.options = options;
|
|
50
|
+
this.editor = options.editor;
|
|
51
|
+
this.scope = normalizedScope(options.scope);
|
|
52
|
+
this.nextImageLabelStart = Math.max(1, options.nextImageLabelStart);
|
|
53
|
+
this.openImageHandler = options.onOpenImage;
|
|
54
|
+
this.attachEditor(options.editor);
|
|
55
|
+
this.reloadHistory();
|
|
56
|
+
}
|
|
57
|
+
attachEditor(editor) {
|
|
58
|
+
if (this.editor !== editor) {
|
|
59
|
+
const previousText = this.editor.getText();
|
|
60
|
+
this.detachEditor(this.editor);
|
|
61
|
+
this.editor = editor;
|
|
62
|
+
this.applyingEditorState = true;
|
|
63
|
+
editor.setText(previousText);
|
|
64
|
+
this.applyingEditorState = false;
|
|
65
|
+
}
|
|
66
|
+
editor.onPaste = (text) => this.handlePaste(text);
|
|
67
|
+
editor.onHistoryNavigate = (direction, currentText) => this.navigateHistory(direction, currentText);
|
|
68
|
+
editor.onChange = () => this.handleEditorChange();
|
|
69
|
+
editor.onCursorMove = () => {
|
|
70
|
+
if (this.applyingEditorState)
|
|
71
|
+
return;
|
|
72
|
+
this.recentPreviewLabel = undefined;
|
|
73
|
+
this.recentPreviewCursorOffset = undefined;
|
|
74
|
+
this.options.onStateChange();
|
|
75
|
+
};
|
|
76
|
+
editor.onBeforeSubmit = () => {
|
|
77
|
+
this.editorSubmitting = true;
|
|
78
|
+
};
|
|
79
|
+
editor.onSubmit = (text) => this.handleEditorSubmit(text);
|
|
80
|
+
this.syncOpenImageActivation();
|
|
81
|
+
editor.disableSubmit = this.pasteOperations.hasPending;
|
|
82
|
+
this.syncEditorDecorations();
|
|
83
|
+
}
|
|
84
|
+
detachEditor(editor) {
|
|
85
|
+
editor.onPaste = undefined;
|
|
86
|
+
editor.onHistoryNavigate = undefined;
|
|
87
|
+
editor.onChange = undefined;
|
|
88
|
+
editor.onCursorMove = undefined;
|
|
89
|
+
editor.onBeforeSubmit = undefined;
|
|
90
|
+
editor.onSubmit = undefined;
|
|
91
|
+
editor.onInlineDecorationActivate = undefined;
|
|
92
|
+
editor.setInlineDecorations([]);
|
|
93
|
+
editor.disableSubmit = false;
|
|
94
|
+
}
|
|
95
|
+
dispose() {
|
|
96
|
+
if (this.disposed)
|
|
97
|
+
return;
|
|
98
|
+
this.disposed = true;
|
|
99
|
+
this.invalidateDraftAsyncWork();
|
|
100
|
+
this.detachEditor(this.editor);
|
|
101
|
+
}
|
|
102
|
+
pendingImageCount() {
|
|
103
|
+
return this.pasteOperations.pendingCount;
|
|
104
|
+
}
|
|
105
|
+
setOpenImageHandler(handler) {
|
|
106
|
+
this.openImageHandler = handler;
|
|
107
|
+
this.syncOpenImageActivation();
|
|
108
|
+
}
|
|
109
|
+
syncOpenImageActivation() {
|
|
110
|
+
this.editor.onInlineDecorationActivate = this.openImageHandler
|
|
111
|
+
? (id) => {
|
|
112
|
+
const item = this.attachments.find((candidate) => candidate.label === id);
|
|
113
|
+
if (item)
|
|
114
|
+
this.openImageHandler?.({ label: item.label, attachment: { ...item.attachment } });
|
|
115
|
+
}
|
|
116
|
+
: undefined;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Explicit keyboard-driven clipboard probe. Image-only clipboards do not
|
|
120
|
+
* produce text for many terminals, so Cmd+V may have no bracketed-paste body
|
|
121
|
+
* and Ctrl+V arrives as a key chord instead of a paste event.
|
|
122
|
+
*/
|
|
123
|
+
requestClipboardImagePaste() {
|
|
124
|
+
if (this.disposed)
|
|
125
|
+
return;
|
|
126
|
+
if (this.pasteOperations.hasPending)
|
|
127
|
+
return;
|
|
128
|
+
if (!(this.options.allowImageAttachments?.() ?? true)) {
|
|
129
|
+
this.options.onNotice("Image attachments are disabled in this runtime session.");
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
this.startClipboardPaste("", true);
|
|
133
|
+
}
|
|
134
|
+
historyTexts() {
|
|
135
|
+
return this.history.map((entry) => entry.text);
|
|
136
|
+
}
|
|
137
|
+
getText() {
|
|
138
|
+
return this.editor.getText();
|
|
139
|
+
}
|
|
140
|
+
snapshotDraft() {
|
|
141
|
+
return {
|
|
142
|
+
text: this.editor.getText(),
|
|
143
|
+
attachments: this.attachments.map((item) => ({
|
|
144
|
+
label: item.label,
|
|
145
|
+
attachment: { ...item.attachment },
|
|
146
|
+
})),
|
|
147
|
+
...(this.imageDisplayStart !== undefined ? { imageDisplayStart: this.imageDisplayStart } : {}),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
/** Image whose chip was just inserted, is under the cursor, or is hovered. */
|
|
151
|
+
previewAttachment() {
|
|
152
|
+
const recentStillAtInsertionPoint = this.recentPreviewCursorOffset === this.editor.getCursorOffset();
|
|
153
|
+
const activeLabel = this.editor.getActiveInlineDecorationId()
|
|
154
|
+
?? (recentStillAtInsertionPoint ? this.recentPreviewLabel : undefined);
|
|
155
|
+
const item = this.attachments.find((candidate) => candidate.label === activeLabel);
|
|
156
|
+
return item ? { label: item.label, attachment: { ...item.attachment } } : undefined;
|
|
157
|
+
}
|
|
158
|
+
restoreDraft(snapshot) {
|
|
159
|
+
this.invalidateDraftAsyncWork();
|
|
160
|
+
this.attachments = snapshot.attachments.map((item) => ({
|
|
161
|
+
label: item.label,
|
|
162
|
+
attachment: { ...item.attachment },
|
|
163
|
+
}));
|
|
164
|
+
this.imageDisplayStart = snapshot.imageDisplayStart;
|
|
165
|
+
this.historyIndex = null;
|
|
166
|
+
this.historyDraft = { text: "", images: [] };
|
|
167
|
+
this.applyingEditorState = true;
|
|
168
|
+
this.editor.setText(snapshot.text);
|
|
169
|
+
this.applyingEditorState = false;
|
|
170
|
+
this.syncEditorDecorations();
|
|
171
|
+
this.options.onStateChange();
|
|
172
|
+
}
|
|
173
|
+
/** Replace the complete draft and invalidate attachments/pastes/history browse. */
|
|
174
|
+
replaceDraft(text) {
|
|
175
|
+
this.invalidateDraftAsyncWork();
|
|
176
|
+
this.attachments = [];
|
|
177
|
+
this.imageDisplayStart = undefined;
|
|
178
|
+
this.historyIndex = null;
|
|
179
|
+
this.historyDraft = { text: "", images: [] };
|
|
180
|
+
this.applyingEditorState = true;
|
|
181
|
+
this.editor.setText(text);
|
|
182
|
+
this.applyingEditorState = false;
|
|
183
|
+
this.recentPreviewLabel = undefined;
|
|
184
|
+
this.recentPreviewCursorOffset = undefined;
|
|
185
|
+
this.syncEditorDecorations();
|
|
186
|
+
this.options.onStateChange();
|
|
187
|
+
}
|
|
188
|
+
/** Rebind persistent history after a successful session transition. */
|
|
189
|
+
setScope(scope, nextImageLabelStart) {
|
|
190
|
+
const nextScope = normalizedScope(scope);
|
|
191
|
+
const changed = !scopesEqual(this.scope, nextScope);
|
|
192
|
+
this.scope = nextScope;
|
|
193
|
+
this.nextImageLabelStart = Math.max(1, nextImageLabelStart);
|
|
194
|
+
if (!changed)
|
|
195
|
+
return;
|
|
196
|
+
this.invalidateDraftAsyncWork();
|
|
197
|
+
this.attachments = [];
|
|
198
|
+
this.imageDisplayStart = undefined;
|
|
199
|
+
this.historyIndex = null;
|
|
200
|
+
this.historyDraft = { text: "", images: [] };
|
|
201
|
+
this.reloadHistory();
|
|
202
|
+
this.applyingEditorState = true;
|
|
203
|
+
this.editor.setText("");
|
|
204
|
+
this.applyingEditorState = false;
|
|
205
|
+
this.recentPreviewLabel = undefined;
|
|
206
|
+
this.recentPreviewCursorOffset = undefined;
|
|
207
|
+
this.syncEditorDecorations();
|
|
208
|
+
this.options.onStateChange();
|
|
209
|
+
}
|
|
210
|
+
reloadHistory() {
|
|
211
|
+
if (this.options.persistHistory === false) {
|
|
212
|
+
this.history = [];
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
this.history = loadHistoryEntriesSync({
|
|
216
|
+
scope: this.scope,
|
|
217
|
+
...(this.options.historyFilePath ? { filePath: this.options.historyFilePath } : {}),
|
|
218
|
+
}).map(cloneHistoryEntry);
|
|
219
|
+
}
|
|
220
|
+
handleEditorChange() {
|
|
221
|
+
if (this.applyingEditorState)
|
|
222
|
+
return;
|
|
223
|
+
if (this.editorSubmitting)
|
|
224
|
+
return;
|
|
225
|
+
if (this.historyNavigationChangePending) {
|
|
226
|
+
this.historyNavigationChangePending = false;
|
|
227
|
+
this.syncEditorDecorations();
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
this.recentPreviewLabel = undefined;
|
|
231
|
+
this.recentPreviewCursorOffset = undefined;
|
|
232
|
+
// Editing a recalled entry starts a new draft, matching Editor's native
|
|
233
|
+
// history semantics. Attachments stay attached until their labels are gone.
|
|
234
|
+
if (this.historyIndex !== null) {
|
|
235
|
+
this.historyIndex = null;
|
|
236
|
+
this.historyDraft = { text: "", images: [] };
|
|
237
|
+
}
|
|
238
|
+
if (this.attachments.length > 0) {
|
|
239
|
+
const text = this.editor.getText();
|
|
240
|
+
const retained = this.attachments.filter((item) => text.includes(item.label));
|
|
241
|
+
if (retained.length !== this.attachments.length) {
|
|
242
|
+
if (retained.length === 0) {
|
|
243
|
+
this.attachments = [];
|
|
244
|
+
this.imageDisplayStart = undefined;
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
const labelStart = this.imageDisplayStart ?? this.nextImageLabelStart;
|
|
248
|
+
this.applyingEditorState = true;
|
|
249
|
+
for (let index = 0; index < retained.length; index++) {
|
|
250
|
+
const item = retained[index];
|
|
251
|
+
const nextLabel = imageDisplayLabel(labelStart + index);
|
|
252
|
+
if (item.label !== nextLabel) {
|
|
253
|
+
const current = this.editor.getText();
|
|
254
|
+
const offset = current.indexOf(item.label);
|
|
255
|
+
if (offset >= 0)
|
|
256
|
+
this.editor.replaceRange(offset, offset + item.label.length, nextLabel);
|
|
257
|
+
item.label = nextLabel;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
this.applyingEditorState = false;
|
|
261
|
+
this.attachments = retained;
|
|
262
|
+
this.imageDisplayStart = labelStart;
|
|
263
|
+
}
|
|
264
|
+
this.options.onStateChange();
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
this.syncEditorDecorations();
|
|
268
|
+
}
|
|
269
|
+
handleEditorSubmit(submittedText) {
|
|
270
|
+
this.editorSubmitting = false;
|
|
271
|
+
const labels = this.attachments.map((item) => item.label);
|
|
272
|
+
const modelText = stripInlineImageLabels(submittedText, labels).trim();
|
|
273
|
+
const isSlashCommand = modelText.startsWith("/");
|
|
274
|
+
const images = isSlashCommand ? [] : this.attachments.map((item) => ({ ...item.attachment }));
|
|
275
|
+
if (!modelText && images.length === 0) {
|
|
276
|
+
this.resetAfterSubmit();
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
if (isSlashCommand && this.attachments.length > 0) {
|
|
280
|
+
this.options.onNotice("Image attachments were ignored for the slash command.");
|
|
281
|
+
}
|
|
282
|
+
const payload = {
|
|
283
|
+
text: modelText,
|
|
284
|
+
...(images.length > 0 && submittedText !== modelText ? { displayText: submittedText } : {}),
|
|
285
|
+
images,
|
|
286
|
+
...(images.length > 0 && this.imageDisplayStart !== undefined
|
|
287
|
+
? { imageDisplayStart: this.imageDisplayStart }
|
|
288
|
+
: {}),
|
|
289
|
+
};
|
|
290
|
+
const historyEntry = {
|
|
291
|
+
// History restores the draft surface, not the provider prompt. Keep the
|
|
292
|
+
// chip exactly where it was submitted and derive modelText again on the
|
|
293
|
+
// next submit.
|
|
294
|
+
text: images.length > 0 ? submittedText : modelText,
|
|
295
|
+
images,
|
|
296
|
+
...(images.length > 0 && this.imageDisplayStart !== undefined
|
|
297
|
+
? { imageDisplayStart: this.imageDisplayStart }
|
|
298
|
+
: {}),
|
|
299
|
+
};
|
|
300
|
+
const nextHistory = pushHistoryEntry(this.history, historyEntry);
|
|
301
|
+
if (nextHistory !== this.history) {
|
|
302
|
+
this.history = nextHistory;
|
|
303
|
+
if (this.options.persistHistory !== false) {
|
|
304
|
+
appendHistoryEntry(historyEntry, {
|
|
305
|
+
scope: this.scope,
|
|
306
|
+
...(this.options.historyFilePath ? { filePath: this.options.historyFilePath } : {}),
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
if (images.length > 0) {
|
|
311
|
+
this.nextImageLabelStart = Math.max(this.nextImageLabelStart, (this.imageDisplayStart ?? this.nextImageLabelStart) + images.length);
|
|
312
|
+
}
|
|
313
|
+
this.resetAfterSubmit();
|
|
314
|
+
this.options.onSubmit(payload);
|
|
315
|
+
}
|
|
316
|
+
resetAfterSubmit() {
|
|
317
|
+
this.invalidateDraftAsyncWork();
|
|
318
|
+
this.attachments = [];
|
|
319
|
+
this.imageDisplayStart = undefined;
|
|
320
|
+
this.recentPreviewLabel = undefined;
|
|
321
|
+
this.recentPreviewCursorOffset = undefined;
|
|
322
|
+
this.syncEditorDecorations();
|
|
323
|
+
this.historyIndex = null;
|
|
324
|
+
this.historyDraft = { text: "", images: [] };
|
|
325
|
+
this.options.onStateChange();
|
|
326
|
+
}
|
|
327
|
+
navigateHistory(direction, currentText) {
|
|
328
|
+
if (this.pasteOperations.hasPending)
|
|
329
|
+
return undefined;
|
|
330
|
+
const currentEntry = {
|
|
331
|
+
text: currentText,
|
|
332
|
+
images: this.attachments.map((item) => ({ ...item.attachment })),
|
|
333
|
+
...(this.imageDisplayStart !== undefined ? { imageDisplayStart: this.imageDisplayStart } : {}),
|
|
334
|
+
};
|
|
335
|
+
const result = stepHistory({
|
|
336
|
+
history: this.history,
|
|
337
|
+
index: this.historyIndex,
|
|
338
|
+
draft: this.historyDraft,
|
|
339
|
+
}, direction, currentEntry);
|
|
340
|
+
if (!result.changed)
|
|
341
|
+
return undefined;
|
|
342
|
+
if (this.historyIndex === null && result.index !== null) {
|
|
343
|
+
this.historyDraft = cloneHistoryEntry(currentEntry);
|
|
344
|
+
}
|
|
345
|
+
const restoredImages = (result.images ?? []).map((image) => ({ ...image }));
|
|
346
|
+
const labelStart = restoredImages.length > 0
|
|
347
|
+
? result.imageDisplayStart ?? this.nextImageLabelStart
|
|
348
|
+
: undefined;
|
|
349
|
+
this.attachments = restoredImages.map((attachment, index) => ({
|
|
350
|
+
attachment,
|
|
351
|
+
label: imageDisplayLabel((labelStart ?? 1) + index),
|
|
352
|
+
}));
|
|
353
|
+
this.imageDisplayStart = labelStart;
|
|
354
|
+
this.historyIndex = result.index;
|
|
355
|
+
if (result.index === null)
|
|
356
|
+
this.historyDraft = { text: "", images: [] };
|
|
357
|
+
const labels = this.attachments.map((item) => item.label);
|
|
358
|
+
const restoredText = labels.length > 0 && !labels.some((label) => result.text.includes(label))
|
|
359
|
+
? `${labels.join(" ")} ${result.text}`.trimEnd()
|
|
360
|
+
: result.text;
|
|
361
|
+
this.historyNavigationChangePending = true;
|
|
362
|
+
this.options.onStateChange();
|
|
363
|
+
return { text: restoredText, active: result.index !== null };
|
|
364
|
+
}
|
|
365
|
+
handlePaste(raw) {
|
|
366
|
+
if (this.disposed)
|
|
367
|
+
return false;
|
|
368
|
+
const clean = raw
|
|
369
|
+
.replace(/\x1b\[I$/, "")
|
|
370
|
+
.replace(/\x1b\[O$/, "")
|
|
371
|
+
.replace(/\r\n?/g, "\n");
|
|
372
|
+
const allowImages = this.options.allowImageAttachments?.() ?? true;
|
|
373
|
+
const pathTokens = extractImagePathTokens(clean);
|
|
374
|
+
const bareName = bareImageFilenameFromPaste(clean);
|
|
375
|
+
const imageIntent = clean.length === 0 || pathTokens.length > 0 || bareName !== null;
|
|
376
|
+
if (!imageIntent)
|
|
377
|
+
return false;
|
|
378
|
+
if (!allowImages) {
|
|
379
|
+
this.options.onNotice("Image attachments are disabled in this runtime session.");
|
|
380
|
+
return true;
|
|
381
|
+
}
|
|
382
|
+
if (clean.length === 0 || bareName !== null) {
|
|
383
|
+
this.startClipboardPaste(clean);
|
|
384
|
+
return true;
|
|
385
|
+
}
|
|
386
|
+
this.startPathPaste(clean, pathTokens);
|
|
387
|
+
return true;
|
|
388
|
+
}
|
|
389
|
+
beginPastePlaceholder() {
|
|
390
|
+
const id = this.pasteOperations.begin();
|
|
391
|
+
const marker = `[${READING_IMAGE_PREFIX} #${id}…]`;
|
|
392
|
+
this.editor.disableSubmit = true;
|
|
393
|
+
this.editor.insertTextAtCursor(`${marker} `);
|
|
394
|
+
this.options.onStateChange();
|
|
395
|
+
return { id, marker, generation: this.draftGeneration };
|
|
396
|
+
}
|
|
397
|
+
finishPaste(id) {
|
|
398
|
+
this.pasteOperations.finish(id);
|
|
399
|
+
this.editor.disableSubmit = this.pasteOperations.hasPending;
|
|
400
|
+
this.options.onStateChange();
|
|
401
|
+
}
|
|
402
|
+
replacePasteMarker(marker, replacement, removeTrailingSeparator = false) {
|
|
403
|
+
const text = this.editor.getText();
|
|
404
|
+
const start = text.indexOf(marker);
|
|
405
|
+
if (start < 0)
|
|
406
|
+
return false;
|
|
407
|
+
const markerEnd = start + marker.length;
|
|
408
|
+
const end = removeTrailingSeparator && text[markerEnd] === " "
|
|
409
|
+
? markerEnd + 1
|
|
410
|
+
: markerEnd;
|
|
411
|
+
this.applyingEditorState = true;
|
|
412
|
+
this.editor.replaceRange(start, end, replacement);
|
|
413
|
+
this.applyingEditorState = false;
|
|
414
|
+
if (this.recentPreviewLabel && replacement.includes(this.recentPreviewLabel)) {
|
|
415
|
+
this.recentPreviewCursorOffset = this.editor.getCursorOffset();
|
|
416
|
+
}
|
|
417
|
+
return true;
|
|
418
|
+
}
|
|
419
|
+
startClipboardPaste(fallbackText, notifyWhenEmpty = false) {
|
|
420
|
+
const pending = this.beginPastePlaceholder();
|
|
421
|
+
const readClipboardImage = this.options.readClipboardImage ?? ingestClipboardImage;
|
|
422
|
+
void readClipboardImage()
|
|
423
|
+
.then(({ attachment, error }) => {
|
|
424
|
+
if (this.disposed || pending.generation !== this.draftGeneration)
|
|
425
|
+
return;
|
|
426
|
+
if (!attachment) {
|
|
427
|
+
this.replacePasteMarker(pending.marker, fallbackText, fallbackText.length === 0);
|
|
428
|
+
if (notifyWhenEmpty && error === "clipboard has no image") {
|
|
429
|
+
this.options.onNotice("Clipboard does not contain a supported image.");
|
|
430
|
+
}
|
|
431
|
+
else if (error && error !== "clipboard has no image") {
|
|
432
|
+
this.options.onNotice(`Image paste failed: ${error}`);
|
|
433
|
+
}
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
if (!this.editor.getText().includes(pending.marker))
|
|
437
|
+
return;
|
|
438
|
+
const item = this.registerAttachment(attachment);
|
|
439
|
+
this.replacePasteMarker(pending.marker, item.label);
|
|
440
|
+
})
|
|
441
|
+
.finally(() => this.finishPaste(pending.id));
|
|
442
|
+
}
|
|
443
|
+
startPathPaste(pastedText, tokens) {
|
|
444
|
+
const pending = this.beginPastePlaceholder();
|
|
445
|
+
void Promise.all(tokens.map(async (token) => ({ token, result: await ingestImagePath(token.rawPath) })))
|
|
446
|
+
.then((results) => {
|
|
447
|
+
if (this.disposed || pending.generation !== this.draftGeneration)
|
|
448
|
+
return;
|
|
449
|
+
if (!this.editor.getText().includes(pending.marker))
|
|
450
|
+
return;
|
|
451
|
+
let replacement = "";
|
|
452
|
+
let cursor = 0;
|
|
453
|
+
for (const { token, result } of results) {
|
|
454
|
+
replacement += pastedText.slice(cursor, token.start);
|
|
455
|
+
if (result.attachment) {
|
|
456
|
+
replacement += this.registerAttachment(result.attachment).label;
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
replacement += pastedText.slice(token.start, token.end);
|
|
460
|
+
this.options.onNotice(`${token.rawPath}: ${result.error ?? "could not attach image"}`);
|
|
461
|
+
}
|
|
462
|
+
cursor = token.end;
|
|
463
|
+
}
|
|
464
|
+
replacement += pastedText.slice(cursor);
|
|
465
|
+
this.replacePasteMarker(pending.marker, replacement);
|
|
466
|
+
})
|
|
467
|
+
.finally(() => this.finishPaste(pending.id));
|
|
468
|
+
}
|
|
469
|
+
registerAttachment(attachment) {
|
|
470
|
+
if (this.imageDisplayStart === undefined)
|
|
471
|
+
this.imageDisplayStart = this.nextImageLabelStart;
|
|
472
|
+
const item = {
|
|
473
|
+
attachment: { ...attachment },
|
|
474
|
+
label: imageDisplayLabel(this.imageDisplayStart + this.attachments.length),
|
|
475
|
+
};
|
|
476
|
+
this.attachments.push(item);
|
|
477
|
+
this.recentPreviewLabel = item.label;
|
|
478
|
+
this.syncEditorDecorations();
|
|
479
|
+
return item;
|
|
480
|
+
}
|
|
481
|
+
syncEditorDecorations() {
|
|
482
|
+
const decorations = this.attachments.map((item) => ({
|
|
483
|
+
id: item.label,
|
|
484
|
+
text: item.label,
|
|
485
|
+
style: (text, state) => {
|
|
486
|
+
const theme = this.options.getTheme?.() ?? darkTheme;
|
|
487
|
+
const background = state.focused
|
|
488
|
+
? theme.traceSelectedBg
|
|
489
|
+
: state.hovered
|
|
490
|
+
? theme.traceHoverBg
|
|
491
|
+
: theme.backgroundElement;
|
|
492
|
+
return themeForeground(theme.inputText, themeBackground(background, text));
|
|
493
|
+
},
|
|
494
|
+
}));
|
|
495
|
+
this.editor.setInlineDecorations(decorations);
|
|
496
|
+
}
|
|
497
|
+
invalidateDraftAsyncWork() {
|
|
498
|
+
this.draftGeneration++;
|
|
499
|
+
this.pasteOperations.invalidateAll();
|
|
500
|
+
this.editor.disableSubmit = false;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BubbleTuiController — the framework-neutral runtime orchestrator
|
|
3
|
+
* (design doc §8.1). Assembles the extracted sub-modules:
|
|
4
|
+
*
|
|
5
|
+
* - agent-event-reducer (stream/tool/turn semantics)
|
|
6
|
+
* - input-queue-machine (steer/queue lifecycle)
|
|
7
|
+
* - overlay-controller (blocking request lifecycle)
|
|
8
|
+
* - session-transition (two-phase atomic switch)
|
|
9
|
+
* - task-runtime-controller (task markers/wakes)
|
|
10
|
+
*
|
|
11
|
+
* The controller consumes an Agent event stream, applies effects, batches
|
|
12
|
+
* streaming updates behind the 40ms FlushScheduler, and publishes immutable
|
|
13
|
+
* snapshots. Renderers subscribe; they never mutate.
|
|
14
|
+
*/
|
|
15
|
+
import type { Agent, AgentRunOptions } from "../../agent.js";
|
|
16
|
+
import type { WorkflowRunSnapshot } from "../../agent/workflow/control.js";
|
|
17
|
+
import type { BackgroundTaskInfo, ProcessManager } from "../../tasks/manager.js";
|
|
18
|
+
import { SessionManager } from "../../session.js";
|
|
19
|
+
import type { GoalStore } from "../../goal/store.js";
|
|
20
|
+
import type { BubbleTuiPorts } from "./ports.js";
|
|
21
|
+
import type { ControllerEffect } from "./effects.js";
|
|
22
|
+
import { type DisplayMessage, type DisplayMessagePart, type DisplayToolCall } from "../model/display-history.js";
|
|
23
|
+
import { type SubagentGroup } from "../model/subagent-view.js";
|
|
24
|
+
import type { SubmitPayload } from "../model/composer-types.js";
|
|
25
|
+
import type { PromotionChannel } from "../../tasks/promotion.js";
|
|
26
|
+
import { type RewindExecutionResult, type RewindScope } from "../../rewind.js";
|
|
27
|
+
import type { Message } from "../../types.js";
|
|
28
|
+
export interface TuiExitSummary {
|
|
29
|
+
reason: string;
|
|
30
|
+
wallMs: number;
|
|
31
|
+
}
|
|
32
|
+
export interface BubbleTuiControllerDeps {
|
|
33
|
+
readonly agent: Pick<Agent, "run" | "messages" | "setSessionID" | "listSubAgents" | "listWorkflows" | "getSubAgentMessages" | "closeSubAgent" | "closeWorkflow" | "resetContextUsageAnchor"> & {
|
|
34
|
+
messages: Message[];
|
|
35
|
+
backgroundTasks?: Agent["backgroundTasks"];
|
|
36
|
+
};
|
|
37
|
+
readonly sessionManager: SessionManager;
|
|
38
|
+
readonly goalStore?: GoalStore;
|
|
39
|
+
readonly processManager?: ProcessManager;
|
|
40
|
+
readonly tasksAutoResume?: boolean;
|
|
41
|
+
readonly promotionChannel?: PromotionChannel;
|
|
42
|
+
readonly workspaceCwd?: string;
|
|
43
|
+
readonly ports: BubbleTuiPorts;
|
|
44
|
+
readonly onEffect?: (effect: ControllerEffect) => void;
|
|
45
|
+
}
|
|
46
|
+
export interface TuiAgentRunOptions extends AgentRunOptions {
|
|
47
|
+
/** Internal Goal continuation; never forwarded to Agent.run(). */
|
|
48
|
+
goalRun?: boolean;
|
|
49
|
+
}
|
|
50
|
+
export interface CommandActivity {
|
|
51
|
+
kind: "compact";
|
|
52
|
+
status: "running" | "cancelling";
|
|
53
|
+
startedAt: number;
|
|
54
|
+
}
|
|
55
|
+
export declare class BubbleTuiController {
|
|
56
|
+
private readonly deps;
|
|
57
|
+
private readonly state;
|
|
58
|
+
private readonly listeners;
|
|
59
|
+
private readonly overlays;
|
|
60
|
+
private readonly queue;
|
|
61
|
+
private readonly sessionTransition;
|
|
62
|
+
private readonly startedAtMs;
|
|
63
|
+
private readonly goalRuntime?;
|
|
64
|
+
private readonly taskRuntime?;
|
|
65
|
+
private readonly pendingTaskAnnouncements;
|
|
66
|
+
private sessionManager;
|
|
67
|
+
private transcript;
|
|
68
|
+
private runActive;
|
|
69
|
+
private runState;
|
|
70
|
+
/** Background subagent updates can outlive the provider turn that launched
|
|
71
|
+
* them. Keep their latest synthetic tool snapshot in the live trace. */
|
|
72
|
+
private readonly liveSubagentTools;
|
|
73
|
+
/** Provider-turn accumulators for true child-session inspection. */
|
|
74
|
+
private readonly childRuns;
|
|
75
|
+
private activeInputController;
|
|
76
|
+
private activeAbortController;
|
|
77
|
+
private commandActivity;
|
|
78
|
+
/** False after a provider turn commits, so settled and live rows never coexist. */
|
|
79
|
+
private liveStreamVisible;
|
|
80
|
+
private readonly backgroundTaskUnsubscribe?;
|
|
81
|
+
private disposed;
|
|
82
|
+
constructor(deps: BubbleTuiControllerDeps);
|
|
83
|
+
private externalGeneration;
|
|
84
|
+
private liveSubagentVersion;
|
|
85
|
+
subscribe(listener: (version: number) => void): () => void;
|
|
86
|
+
getSnapshotVersion(): number;
|
|
87
|
+
getTranscript(): readonly DisplayMessage[];
|
|
88
|
+
getSessionManager(): SessionManager;
|
|
89
|
+
getGoalIndicator(): string | undefined;
|
|
90
|
+
handleGoalCommand(input: string, cwd: string): void;
|
|
91
|
+
getSubagentGroups(): SubagentGroup[];
|
|
92
|
+
getWorkflows(): WorkflowRunSnapshot[];
|
|
93
|
+
getBackgroundTasks(): BackgroundTaskInfo[];
|
|
94
|
+
getChildTranscript(agentId: string): DisplayMessage[];
|
|
95
|
+
getChildStreamingTail(agentId: string): {
|
|
96
|
+
content: string;
|
|
97
|
+
reasoning: string;
|
|
98
|
+
tools: DisplayToolCall[];
|
|
99
|
+
parts: DisplayMessagePart[];
|
|
100
|
+
} | null;
|
|
101
|
+
stopSubagent(agentId: string): void;
|
|
102
|
+
stopWorkflow(runId: string): void;
|
|
103
|
+
stopBackgroundTask(id: string): void;
|
|
104
|
+
getBackgroundTaskOutput(id: string): string;
|
|
105
|
+
/** Called by the host after graceful task reaping on TUI exit. */
|
|
106
|
+
persistFinalTaskMarkers(): void;
|
|
107
|
+
private appendTaskMarker;
|
|
108
|
+
private announceTaskCompletion;
|
|
109
|
+
/** Move the newest live Bash Execute into the unified task manager. */
|
|
110
|
+
promoteActiveBash(): string | undefined;
|
|
111
|
+
/** Drop every transcript row (/clear). */
|
|
112
|
+
clearTranscript(): void;
|
|
113
|
+
/** Re-project the visible transcript after a non-controller command rewrites Agent history. */
|
|
114
|
+
rebuildTranscriptFromAgent(): void;
|
|
115
|
+
/**
|
|
116
|
+
* Rewind persistence and every renderer-facing mirror as one observable
|
|
117
|
+
* transition. File restoration can take time, but no partial transcript is
|
|
118
|
+
* published while it runs.
|
|
119
|
+
*/
|
|
120
|
+
rewindToTurn(targetId: string, scope: RewindScope): Promise<RewindExecutionResult>;
|
|
121
|
+
/** Host-side row injection (user echo, notices) — single append point. */
|
|
122
|
+
appendDisplayMessage(message: DisplayMessage): void;
|
|
123
|
+
isRunning(): boolean;
|
|
124
|
+
/** A slash command that owns the activity lane without masquerading as an
|
|
125
|
+
* Agent turn. This keeps streaming/steering state separate while still
|
|
126
|
+
* giving Escape and Ctrl+C one cancellation boundary. */
|
|
127
|
+
beginCommandActivity(kind: CommandActivity["kind"]): AbortSignal;
|
|
128
|
+
finishCommandActivity(kind: CommandActivity["kind"], event?: DisplayMessage): void;
|
|
129
|
+
getCommandActivity(): CommandActivity | null;
|
|
130
|
+
isBusy(): boolean;
|
|
131
|
+
/** Queue composer input while a command owns the pane. Grok keeps the
|
|
132
|
+
* composer available during Compact; the message starts after the command
|
|
133
|
+
* reaches its terminal event instead of racing the history rewrite. */
|
|
134
|
+
queueAfterCommand(input: string | SubmitPayload): boolean;
|
|
135
|
+
/** Queue a complete composer payload for the next provider turn. */
|
|
136
|
+
queueInput(input: string | SubmitPayload): void;
|
|
137
|
+
drainQueuedInputs(cwd: string, agentOptions?: AgentRunOptions): Promise<void>;
|
|
138
|
+
pendingSteerCount(): number;
|
|
139
|
+
queuedInputCount(): number;
|
|
140
|
+
private submitDisplayText;
|
|
141
|
+
private submitAgentInput;
|
|
142
|
+
/** Add input to the current Agent run without creating a second run that
|
|
143
|
+
* would overwrite the shared streaming accumulator. */
|
|
144
|
+
steer(content: string): boolean;
|
|
145
|
+
cancelActiveRun(reason?: string): boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Live streaming tail for the render loop: the in-flight accumulator's
|
|
148
|
+
* content/reasoning/tool summary. Renderers draw it in the live region
|
|
149
|
+
* (never committed to scrollback) until the turn commits.
|
|
150
|
+
*/
|
|
151
|
+
getStreamingTail(): {
|
|
152
|
+
content: string;
|
|
153
|
+
reasoning: string;
|
|
154
|
+
tools: DisplayToolCall[];
|
|
155
|
+
parts: DisplayMessagePart[];
|
|
156
|
+
phase: "thinking" | "working";
|
|
157
|
+
} | null;
|
|
158
|
+
pendingOverlayCount(): number;
|
|
159
|
+
/**
|
|
160
|
+
* Drive one agent run: reduce the event stream, apply effects, and finish.
|
|
161
|
+
* Mirrors runAgentInput (app.tsx:1438-1958) minus the rendering.
|
|
162
|
+
*/
|
|
163
|
+
runTurn(input: unknown, cwd: string, options?: TuiAgentRunOptions): Promise<void>;
|
|
164
|
+
/** Apply one reducer transition and publish exactly one observable snapshot. */
|
|
165
|
+
private applyEffects;
|
|
166
|
+
/** Mutate for one effect; callers own the surrounding transaction + notify. */
|
|
167
|
+
private applyEffectMutation;
|
|
168
|
+
private notify;
|
|
169
|
+
private reduceChildEvent;
|
|
170
|
+
private isAbortLike;
|
|
171
|
+
/** Drain leftover steers at run end (cancelled drops, normal requeues). */
|
|
172
|
+
drainLeftovers(leftovers: Array<{
|
|
173
|
+
id: string;
|
|
174
|
+
content: string;
|
|
175
|
+
}>, cancelled: boolean): void;
|
|
176
|
+
/** Atomic session switch through the two-phase transaction. */
|
|
177
|
+
switchSession(plan: {
|
|
178
|
+
targetFile: string;
|
|
179
|
+
notice?: string;
|
|
180
|
+
}): {
|
|
181
|
+
ok: boolean;
|
|
182
|
+
error?: string;
|
|
183
|
+
};
|
|
184
|
+
/** Start an empty native session using the same atomic lifecycle as resume. */
|
|
185
|
+
createFreshSession(cwd: string, notice?: string): {
|
|
186
|
+
ok: boolean;
|
|
187
|
+
error?: string;
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* Shutdown: settle overlays, cancel any run, and report the exit summary.
|
|
191
|
+
* Idempotent — a second call is a no-op.
|
|
192
|
+
*/
|
|
193
|
+
shutdown(reason: string): TuiExitSummary;
|
|
194
|
+
}
|