@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
|
@@ -18,14 +18,89 @@ import { feishuCommand } from "./feishu.js";
|
|
|
18
18
|
import { GROK_LOCAL_COMMAND_HELP } from "../external-runtime/grok-input-policy.js";
|
|
19
19
|
import { isGrokSubscriptionProviderId } from "../external-runtime/grok-provider.js";
|
|
20
20
|
import { classifyExternalRuntimeBinding } from "../external-runtime/session-policy.js";
|
|
21
|
+
import { providerModelPolicyError } from "../provider-model-policy.js";
|
|
22
|
+
import { executeRewind } from "../rewind.js";
|
|
21
23
|
const VALID_SCOPES = ["user", "project", "local"];
|
|
22
24
|
const VALID_LISTS = ["allow", "deny"];
|
|
25
|
+
function isAbortLike(error) {
|
|
26
|
+
return error instanceof Error && (error.name === "AbortError" || error.name === "AgentAbortError");
|
|
27
|
+
}
|
|
28
|
+
function formatCompactDuration(elapsedMs) {
|
|
29
|
+
if (elapsedMs < 1_000)
|
|
30
|
+
return `${Math.max(0, Math.round(elapsedMs))}ms`;
|
|
31
|
+
return `${(elapsedMs / 1_000).toFixed(1)}s`;
|
|
32
|
+
}
|
|
23
33
|
function isScope(value) {
|
|
24
34
|
return VALID_SCOPES.includes(value);
|
|
25
35
|
}
|
|
26
36
|
function isList(value) {
|
|
27
37
|
return VALID_LISTS.includes(value);
|
|
28
38
|
}
|
|
39
|
+
async function handleRewindCommand(args, ctx) {
|
|
40
|
+
const session = ctx.sessionManager;
|
|
41
|
+
if (!session)
|
|
42
|
+
return "Rewind requires an active session.";
|
|
43
|
+
const turns = session.listUserTurns();
|
|
44
|
+
if (turns.length === 0)
|
|
45
|
+
return "Nothing to rewind: no user messages in this session.";
|
|
46
|
+
const tokens = args.trim().split(/\s+/).filter(Boolean);
|
|
47
|
+
const flags = tokens.filter((token) => token.startsWith("--"));
|
|
48
|
+
const positional = tokens.filter((token) => !token.startsWith("--"));
|
|
49
|
+
const checkpoints = session.getCheckpoints();
|
|
50
|
+
if (positional.length === 0) {
|
|
51
|
+
if (ctx.openRewindPicker) {
|
|
52
|
+
ctx.openRewindPicker();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const lines = ["Rewind points (oldest first):", ""];
|
|
56
|
+
turns.forEach((turn, index) => {
|
|
57
|
+
const time = new Date(turn.timestamp).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
58
|
+
const files = checkpoints.filesTouchedAt(turn.id).length;
|
|
59
|
+
const fileNote = files > 0 ? ` [${files} file${files === 1 ? "" : "s"} changed]` : "";
|
|
60
|
+
lines.push(` ${index + 1}. ${time} ${turn.preview}${fileNote}`);
|
|
61
|
+
});
|
|
62
|
+
lines.push("", "Usage:", " /rewind <n> restore conversation AND files to just before message n", " /rewind <n> --chat conversation only", " /rewind <n> --code files only", "", "Note: only edits made by the edit/write tools are tracked; changes from", "bash commands are not. Checkpoints complement git, they don't replace it.");
|
|
63
|
+
return lines.join("\n");
|
|
64
|
+
}
|
|
65
|
+
const n = Number(positional[0]);
|
|
66
|
+
if (!Number.isInteger(n) || n < 1 || n > turns.length) {
|
|
67
|
+
return `Invalid rewind point "${positional[0]}". Run /rewind to list points (1-${turns.length}).`;
|
|
68
|
+
}
|
|
69
|
+
const target = turns[n - 1];
|
|
70
|
+
const codeOnly = flags.includes("--code");
|
|
71
|
+
const chatOnly = flags.includes("--chat") || flags.includes("--conversation");
|
|
72
|
+
if (codeOnly && chatOnly)
|
|
73
|
+
return "Pick at most one of --code / --chat.";
|
|
74
|
+
const scope = codeOnly ? "code" : chatOnly ? "chat" : "all";
|
|
75
|
+
const result = await executeRewind(session, ctx.agent, target.id, scope);
|
|
76
|
+
const lines = [
|
|
77
|
+
codeOnly
|
|
78
|
+
? `Files restored to just before: ${target.preview}`
|
|
79
|
+
: `⏪ Rewound to before: ${target.preview}`,
|
|
80
|
+
];
|
|
81
|
+
if (scope !== "chat") {
|
|
82
|
+
const touched = result.files.restored.length + result.files.deleted.length;
|
|
83
|
+
if (touched === 0 && result.files.failed.length === 0) {
|
|
84
|
+
lines.push("Files: no tracked edits to undo.");
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
for (const file of result.files.restored)
|
|
88
|
+
lines.push(`Restored ${file}`);
|
|
89
|
+
for (const file of result.files.deleted)
|
|
90
|
+
lines.push(`Deleted ${file} (created after this point)`);
|
|
91
|
+
for (const file of result.files.failed)
|
|
92
|
+
lines.push(`FAILED to restore ${file}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (scope !== "code") {
|
|
96
|
+
ctx.rebuildTranscript?.();
|
|
97
|
+
if (ctx.fillComposer)
|
|
98
|
+
ctx.fillComposer(target.text);
|
|
99
|
+
else
|
|
100
|
+
lines.push("", "Rewound message (copy to re-edit):", target.text);
|
|
101
|
+
}
|
|
102
|
+
return lines.join("\n");
|
|
103
|
+
}
|
|
29
104
|
function handlePermissionsMutation(sub, tokens, ctx) {
|
|
30
105
|
if (!ctx.settingsManager) {
|
|
31
106
|
return "No settings manager is attached to this session.";
|
|
@@ -449,7 +524,12 @@ const builtinSlashCommandEntries = [
|
|
|
449
524
|
name: "context",
|
|
450
525
|
description: "Show current context window usage and breakdown",
|
|
451
526
|
async handler(_args, ctx) {
|
|
452
|
-
|
|
527
|
+
const snapshot = ctx.agent.getContextUsageSnapshot();
|
|
528
|
+
if (ctx.openContextInfo) {
|
|
529
|
+
ctx.openContextInfo(snapshot);
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
return `${formatContextUsage(snapshot)}\n\n${formatMcpContextStatus(ctx)}`;
|
|
453
533
|
},
|
|
454
534
|
},
|
|
455
535
|
{
|
|
@@ -496,81 +576,12 @@ const builtinSlashCommandEntries = [
|
|
|
496
576
|
{
|
|
497
577
|
name: "rewind",
|
|
498
578
|
description: "Rewind conversation and/or file edits to before an earlier message. Usage: /rewind [n] [--code|--chat]",
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
if (turns.length === 0) {
|
|
506
|
-
return "Nothing to rewind: no user messages in this session.";
|
|
507
|
-
}
|
|
508
|
-
const tokens = args.trim().split(/\s+/).filter(Boolean);
|
|
509
|
-
const flags = tokens.filter((token) => token.startsWith("--"));
|
|
510
|
-
const positional = tokens.filter((token) => !token.startsWith("--"));
|
|
511
|
-
const checkpoints = session.getCheckpoints();
|
|
512
|
-
if (positional.length === 0) {
|
|
513
|
-
if (ctx.openRewindPicker) {
|
|
514
|
-
ctx.openRewindPicker();
|
|
515
|
-
return;
|
|
516
|
-
}
|
|
517
|
-
const lines = ["Rewind points (oldest first):", ""];
|
|
518
|
-
turns.forEach((turn, index) => {
|
|
519
|
-
const time = new Date(turn.timestamp).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
520
|
-
const files = checkpoints.filesTouchedAt(turn.id).length;
|
|
521
|
-
const fileNote = files > 0 ? ` [${files} file${files === 1 ? "" : "s"} changed]` : "";
|
|
522
|
-
lines.push(` ${index + 1}. ${time} ${turn.preview}${fileNote}`);
|
|
523
|
-
});
|
|
524
|
-
lines.push("", "Usage:", " /rewind <n> restore conversation AND files to just before message n", " /rewind <n> --chat conversation only", " /rewind <n> --code files only", "", "Note: only edits made by the edit/write tools are tracked; changes from", "bash commands are not. Checkpoints complement git, they don't replace it.");
|
|
525
|
-
return lines.join("\n");
|
|
526
|
-
}
|
|
527
|
-
const n = Number(positional[0]);
|
|
528
|
-
if (!Number.isInteger(n) || n < 1 || n > turns.length) {
|
|
529
|
-
return `Invalid rewind point "${positional[0]}". Run /rewind to list points (1-${turns.length}).`;
|
|
530
|
-
}
|
|
531
|
-
const target = turns[n - 1];
|
|
532
|
-
const codeOnly = flags.includes("--code");
|
|
533
|
-
const chatOnly = flags.includes("--chat") || flags.includes("--conversation");
|
|
534
|
-
if (codeOnly && chatOnly) {
|
|
535
|
-
return "Pick at most one of --code / --chat.";
|
|
536
|
-
}
|
|
537
|
-
// The "⏪" prefix is recognized by the TUIs: they rebuild the visible
|
|
538
|
-
// transcript from the rewound agent.messages before showing this text.
|
|
539
|
-
const lines = [
|
|
540
|
-
codeOnly
|
|
541
|
-
? `Files restored to just before: ${target.preview}`
|
|
542
|
-
: `⏪ Rewound to before: ${target.preview}`,
|
|
543
|
-
];
|
|
544
|
-
if (!chatOnly) {
|
|
545
|
-
const restore = await checkpoints.restoreTo(target.id);
|
|
546
|
-
const touched = restore.restored.length + restore.deleted.length;
|
|
547
|
-
if (touched === 0 && restore.failed.length === 0) {
|
|
548
|
-
lines.push("Files: no tracked edits to undo.");
|
|
549
|
-
}
|
|
550
|
-
else {
|
|
551
|
-
for (const file of restore.restored)
|
|
552
|
-
lines.push(`Restored ${file}`);
|
|
553
|
-
for (const file of restore.deleted)
|
|
554
|
-
lines.push(`Deleted ${file} (created after this point)`);
|
|
555
|
-
for (const file of restore.failed)
|
|
556
|
-
lines.push(`FAILED to restore ${file}`);
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
if (!codeOnly) {
|
|
560
|
-
session.rewindToEntry(target.id);
|
|
561
|
-
const head = ctx.agent.messages.filter((m) => m.role === "system" || m.role === "meta");
|
|
562
|
-
ctx.agent.messages = [...head, ...session.getMessages()];
|
|
563
|
-
ctx.agent.resetContextUsageAnchor();
|
|
564
|
-
if (ctx.fillComposer) {
|
|
565
|
-
// Put the rewound message back into the input box for re-editing.
|
|
566
|
-
ctx.fillComposer(target.text);
|
|
567
|
-
}
|
|
568
|
-
else {
|
|
569
|
-
lines.push("", "Rewound message (copy to re-edit):", target.text);
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
return lines.join("\n");
|
|
573
|
-
},
|
|
579
|
+
handler: handleRewindCommand,
|
|
580
|
+
},
|
|
581
|
+
{
|
|
582
|
+
name: "undo",
|
|
583
|
+
description: "Alias for /rewind",
|
|
584
|
+
handler: handleRewindCommand,
|
|
574
585
|
},
|
|
575
586
|
{
|
|
576
587
|
name: "session",
|
|
@@ -796,6 +807,9 @@ const builtinSlashCommandEntries = [
|
|
|
796
807
|
const next = parsed.model.includes(":") ? parsed.model : encodeModel(defaultProvider, parsed.model);
|
|
797
808
|
const { providerId, modelId } = decodeModel(next);
|
|
798
809
|
const targetProviderId = providerId || defaultProvider;
|
|
810
|
+
const modelPolicyError = providerModelPolicyError(targetProviderId, modelId);
|
|
811
|
+
if (modelPolicyError)
|
|
812
|
+
return modelPolicyError;
|
|
799
813
|
await ctx.registry.prepareProvider(targetProviderId);
|
|
800
814
|
const targetProvider = ctx.registry.getConfigured().find((item) => item.id === targetProviderId);
|
|
801
815
|
if (!targetProvider?.apiKey) {
|
|
@@ -842,6 +856,15 @@ const builtinSlashCommandEntries = [
|
|
|
842
856
|
return `OAuth credentials for ${providerId} removed.`;
|
|
843
857
|
},
|
|
844
858
|
},
|
|
859
|
+
{
|
|
860
|
+
name: "goal",
|
|
861
|
+
description: "Set, manage, or inspect an autonomous goal. Usage: /goal <objective> [--budget N] | status | pause | resume | edit | clear",
|
|
862
|
+
async handler(args, ctx) {
|
|
863
|
+
if (!ctx.handleGoalCommand)
|
|
864
|
+
return "Goals are not available in this host.";
|
|
865
|
+
await ctx.handleGoalCommand(`/goal${args.trim() ? ` ${args.trim()}` : ""}`);
|
|
866
|
+
},
|
|
867
|
+
},
|
|
845
868
|
{
|
|
846
869
|
name: "plan",
|
|
847
870
|
description: "Toggle plan mode on/off (Tab switches Build/Plan)",
|
|
@@ -1068,8 +1091,8 @@ const builtinSlashCommandEntries = [
|
|
|
1068
1091
|
},
|
|
1069
1092
|
{
|
|
1070
1093
|
name: "compact",
|
|
1071
|
-
description: "
|
|
1072
|
-
async handler(
|
|
1094
|
+
description: "Compact session context; optional text says what to preserve",
|
|
1095
|
+
async handler(args, ctx) {
|
|
1073
1096
|
if (!ctx.sessionManager) {
|
|
1074
1097
|
return "Compaction requires session persistence. Start an interactive session first.";
|
|
1075
1098
|
}
|
|
@@ -1087,6 +1110,8 @@ const builtinSlashCommandEntries = [
|
|
|
1087
1110
|
if (preHook?.decision === "deny") {
|
|
1088
1111
|
return preHook.reason ?? `Compaction blocked by hook ${preHook.sourceHookId ?? "<unknown>"}.`;
|
|
1089
1112
|
}
|
|
1113
|
+
if (ctx.compactionAbortSignal?.aborted)
|
|
1114
|
+
return "Compaction cancelled.";
|
|
1090
1115
|
// Plan first so we can report "already compact" without spending a model
|
|
1091
1116
|
// call, and so the LLM summarizer gets the exact set of evicted messages.
|
|
1092
1117
|
const plan = ctx.sessionManager.getCompactionPlan();
|
|
@@ -1105,15 +1130,23 @@ const builtinSlashCommandEntries = [
|
|
|
1105
1130
|
// On any failure (or empty output) fall back to the instant heuristic
|
|
1106
1131
|
// compaction so /compact always makes progress.
|
|
1107
1132
|
let result;
|
|
1133
|
+
const startedAt = Date.now();
|
|
1108
1134
|
try {
|
|
1109
1135
|
ctx.compactionProgress?.({ phase: "collecting", streamedChars: 0 });
|
|
1110
1136
|
let summary = "";
|
|
1111
1137
|
try {
|
|
1112
1138
|
summary = await ctx.agent.summarizeForCompaction(plan.oldMessages, (full) => {
|
|
1113
1139
|
ctx.compactionProgress?.({ phase: "summarizing", streamedChars: full.length });
|
|
1114
|
-
});
|
|
1140
|
+
}, ctx.compactionAbortSignal, args);
|
|
1141
|
+
// The signal is authoritative even if a provider finishes normally
|
|
1142
|
+
// after ignoring or racing its abort notification.
|
|
1143
|
+
if (ctx.compactionAbortSignal?.aborted)
|
|
1144
|
+
return "Compaction cancelled.";
|
|
1115
1145
|
}
|
|
1116
|
-
catch {
|
|
1146
|
+
catch (error) {
|
|
1147
|
+
if (ctx.compactionAbortSignal?.aborted || isAbortLike(error)) {
|
|
1148
|
+
return "Compaction cancelled.";
|
|
1149
|
+
}
|
|
1117
1150
|
summary = "";
|
|
1118
1151
|
}
|
|
1119
1152
|
if (summary) {
|
|
@@ -1160,7 +1193,13 @@ const builtinSlashCommandEntries = [
|
|
|
1160
1193
|
droppedEntries: dropped,
|
|
1161
1194
|
},
|
|
1162
1195
|
});
|
|
1163
|
-
return
|
|
1196
|
+
return {
|
|
1197
|
+
result: `Compaction completed in ${formatCompactDuration(Date.now() - startedAt)}.`,
|
|
1198
|
+
detail: {
|
|
1199
|
+
kind: "compaction-summary",
|
|
1200
|
+
content: result.summary ?? "",
|
|
1201
|
+
},
|
|
1202
|
+
};
|
|
1164
1203
|
},
|
|
1165
1204
|
},
|
|
1166
1205
|
{
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SlashCommand, SlashCommandContext } from "./types.js";
|
|
1
|
+
import type { SlashCommand, SlashCommandContext, SlashCommandResultDetail } from "./types.js";
|
|
2
2
|
import { type CommandSource, type UnifiedCommand } from "./unified.js";
|
|
3
3
|
/**
|
|
4
4
|
* Dynamic source: called at lookup time to produce extra commands (e.g. MCP
|
|
@@ -27,5 +27,6 @@ export declare class SlashCommandRegistry {
|
|
|
27
27
|
handled: boolean;
|
|
28
28
|
result?: string;
|
|
29
29
|
inject?: string;
|
|
30
|
+
detail?: SlashCommandResultDetail;
|
|
30
31
|
}>;
|
|
31
32
|
}
|
|
@@ -61,6 +61,9 @@ export class SlashCommandRegistry {
|
|
|
61
61
|
if (output && typeof output === "object" && "inject" in output) {
|
|
62
62
|
return { handled: true, inject: output.inject };
|
|
63
63
|
}
|
|
64
|
+
if (output && typeof output === "object" && "result" in output) {
|
|
65
|
+
return { handled: true, result: output.result, detail: output.detail };
|
|
66
|
+
}
|
|
64
67
|
return { handled: true, result: typeof output === "string" ? output : undefined };
|
|
65
68
|
}
|
|
66
69
|
catch (err) {
|
|
@@ -11,16 +11,21 @@ import type { MemoryScope } from "../memory/index.js";
|
|
|
11
11
|
import type { ThemeMode } from "../config.js";
|
|
12
12
|
import type { ExternalHookController } from "../hooks/controller.js";
|
|
13
13
|
import type { ExternalRuntimeManager } from "../external-runtime/types.js";
|
|
14
|
+
import type { ContextUsageSnapshot } from "../context/usage.js";
|
|
14
15
|
/**
|
|
15
|
-
* Live progress for a manual `/compact` run
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
16
|
+
* Live progress for a manual `/compact` run. `phase` advances collecting →
|
|
17
|
+
* summarizing → applying; interactive hosts can use it for diagnostics while
|
|
18
|
+
* the visible Grok-style activity lane remains a stable `Compacting…` state.
|
|
19
|
+
* Hosts without a UI omit the sink.
|
|
19
20
|
*/
|
|
20
21
|
export interface CompactionProgress {
|
|
21
22
|
phase: "collecting" | "summarizing" | "applying";
|
|
22
23
|
streamedChars: number;
|
|
23
24
|
}
|
|
25
|
+
export interface SlashCommandResultDetail {
|
|
26
|
+
kind: "compaction-summary";
|
|
27
|
+
content: string;
|
|
28
|
+
}
|
|
24
29
|
export interface SlashCommandContext {
|
|
25
30
|
agent: Agent;
|
|
26
31
|
addMessage: (role: "user" | "assistant" | "error", content: string) => void;
|
|
@@ -55,13 +60,21 @@ export interface SlashCommandContext {
|
|
|
55
60
|
openSessionPicker?: () => void;
|
|
56
61
|
/** Replace the composer/input box content (e.g. /rewind restores the rewound message for re-editing). */
|
|
57
62
|
fillComposer?: (text: string) => void;
|
|
63
|
+
/** Re-project host transcript state after a command rewrites agent.messages. */
|
|
64
|
+
rebuildTranscript?: () => void;
|
|
58
65
|
/** Open the interactive usage stats panel. */
|
|
59
66
|
openStats?: () => void;
|
|
67
|
+
/** Open the interactive context-usage panel. Text-only hosts omit this. */
|
|
68
|
+
openContextInfo?: (snapshot: ContextUsageSnapshot) => void;
|
|
69
|
+
/** Execute the persistent autonomous Goal lifecycle in an interactive host. */
|
|
70
|
+
handleGoalCommand?: (input: string) => void | Promise<void>;
|
|
60
71
|
/**
|
|
61
72
|
* Push live compaction progress to the running TUI. Pass a progress object
|
|
62
73
|
* while compacting and `null` to clear the indicator. Absent in non-TUI hosts.
|
|
63
74
|
*/
|
|
64
75
|
compactionProgress?: (progress: CompactionProgress | null) => void;
|
|
76
|
+
/** Cancellation signal owned by the interactive host's Compact activity. */
|
|
77
|
+
compactionAbortSignal?: AbortSignal;
|
|
65
78
|
/** External agent runtime used by Grok subscription chat. */
|
|
66
79
|
externalRuntime?: ExternalRuntimeManager;
|
|
67
80
|
/**
|
|
@@ -80,9 +93,14 @@ export interface SlashCommandContext {
|
|
|
80
93
|
* - string | void: the string (if any) is displayed as an assistant message
|
|
81
94
|
* - { inject }: the content is sent to the agent as the user's next turn
|
|
82
95
|
* (used by MCP prompts that expand a template into a user message)
|
|
96
|
+
* - { result, detail }: keep the visible result terse while exposing
|
|
97
|
+
* structured, host-rendered detail such as an inspectable Compact summary
|
|
83
98
|
*/
|
|
84
99
|
export type SlashCommandOutput = string | void | {
|
|
85
100
|
inject: string;
|
|
101
|
+
} | {
|
|
102
|
+
result: string;
|
|
103
|
+
detail?: SlashCommandResultDetail;
|
|
86
104
|
};
|
|
87
105
|
export interface SlashCommand {
|
|
88
106
|
name: string;
|
package/dist/stats/usage.d.ts
CHANGED
|
@@ -51,7 +51,9 @@ export declare function collectUsageStatsBundle(options?: {
|
|
|
51
51
|
sessionsRoot?: string;
|
|
52
52
|
}): UsageStatsBundle;
|
|
53
53
|
export declare function formatStatsText(bundle: UsageStatsBundle, range?: StatsRange, width?: number): string;
|
|
54
|
-
export declare function formatStatsPanelBody(stats: UsageStats, width?: number
|
|
54
|
+
export declare function formatStatsPanelBody(stats: UsageStats, width?: number, options?: {
|
|
55
|
+
expandedModels?: boolean;
|
|
56
|
+
}): string;
|
|
55
57
|
export declare function rangeLabel(range: StatsRange): string;
|
|
56
58
|
export declare function formatCompactNumber(value: number): string;
|
|
57
59
|
export declare function formatCurrency(value: number): string;
|
package/dist/stats/usage.js
CHANGED
|
@@ -9,7 +9,7 @@ const RANGES = [
|
|
|
9
9
|
];
|
|
10
10
|
const WEEKDAY_LABELS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
|
|
11
11
|
const EMPTY_CELL = " ";
|
|
12
|
-
const HEAT_LEVELS = ["
|
|
12
|
+
const HEAT_LEVELS = ["·", "○", "◉", "●"];
|
|
13
13
|
const MAX_MODEL_ROWS = 5;
|
|
14
14
|
export function collectUsageStatsBundle(options = {}) {
|
|
15
15
|
const now = options.now ?? new Date();
|
|
@@ -34,14 +34,14 @@ export function formatStatsText(bundle, range = "30d", width = 78) {
|
|
|
34
34
|
formatStatsPanelBody(stats, width),
|
|
35
35
|
].join("\n");
|
|
36
36
|
}
|
|
37
|
-
export function formatStatsPanelBody(stats, width = 72) {
|
|
37
|
+
export function formatStatsPanelBody(stats, width = 72, options = {}) {
|
|
38
38
|
const bodyWidth = Math.max(48, width);
|
|
39
39
|
const lines = [];
|
|
40
40
|
lines.push("Activity");
|
|
41
41
|
lines.push(...formatHeatmapLines(stats));
|
|
42
42
|
lines.push("");
|
|
43
43
|
lines.push("Model usage");
|
|
44
|
-
lines.push(...formatModelUsageLines(stats, bodyWidth));
|
|
44
|
+
lines.push(...formatModelUsageLines(stats, bodyWidth, options.expandedModels ?? false));
|
|
45
45
|
lines.push("");
|
|
46
46
|
lines.push("Summary");
|
|
47
47
|
lines.push(...formatSummaryLines(stats, bodyWidth));
|
|
@@ -131,7 +131,7 @@ function processSessionFile(file, accumulators) {
|
|
|
131
131
|
markActiveDay(accumulator, timestamp, usage);
|
|
132
132
|
if (message && usage && model) {
|
|
133
133
|
flags.hasUsage = true;
|
|
134
|
-
addModelUsage(accumulator, model, message, usage);
|
|
134
|
+
addModelUsage(accumulator, model, message, usage, timestamp);
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
137
|
}
|
|
@@ -172,7 +172,7 @@ function finalizeAccumulator(accumulator) {
|
|
|
172
172
|
sessionsWithoutTokenData: accumulator.sessionsWithoutTokenData,
|
|
173
173
|
};
|
|
174
174
|
}
|
|
175
|
-
function addModelUsage(accumulator, model, message, usage) {
|
|
175
|
+
function addModelUsage(accumulator, model, message, usage, timestamp) {
|
|
176
176
|
const decoded = decodeModel(model);
|
|
177
177
|
const providerId = typeof message.providerId === "string" ? message.providerId : decoded.providerId;
|
|
178
178
|
const modelId = typeof message.modelId === "string" ? message.modelId : decoded.modelId;
|
|
@@ -200,7 +200,7 @@ function addModelUsage(accumulator, model, message, usage) {
|
|
|
200
200
|
existing.reasoningTokens += usage.reasoningTokens ?? 0;
|
|
201
201
|
existing.totalTokens += tokenTotal(usage);
|
|
202
202
|
if (providerId && modelId) {
|
|
203
|
-
const cost = calculateUsageCost(providerId, modelId, usage);
|
|
203
|
+
const cost = calculateUsageCost(providerId, modelId, usage, timestamp);
|
|
204
204
|
if (cost) {
|
|
205
205
|
existing.cost = (existing.cost ?? 0) + cost.cost;
|
|
206
206
|
existing.costCurrency = cost.currency;
|
|
@@ -253,28 +253,34 @@ function formatHeatmapLines(stats) {
|
|
|
253
253
|
lines.push(` Less ${HEAT_LEVELS.join(" ")} More`);
|
|
254
254
|
return lines;
|
|
255
255
|
}
|
|
256
|
-
function formatModelUsageLines(stats, width) {
|
|
256
|
+
function formatModelUsageLines(stats, width, expanded) {
|
|
257
257
|
if (stats.models.length === 0) {
|
|
258
258
|
return [" No precise token usage recorded yet."];
|
|
259
259
|
}
|
|
260
260
|
const showCost = stats.models.some((model) => model.cost !== undefined);
|
|
261
|
-
const
|
|
262
|
-
const
|
|
263
|
-
const
|
|
261
|
+
const visibleModels = expanded ? stats.models : stats.models.slice(0, MAX_MODEL_ROWS);
|
|
262
|
+
const turnsWidth = Math.max(6, ...visibleModels.map((model) => formatTurnCount(model.turns).length));
|
|
263
|
+
const overhead = (showCost ? 25 : 17) + turnsWidth;
|
|
264
|
+
const minBarWidth = 4;
|
|
265
|
+
const longestLabelWidth = Math.max(...visibleModels.map((model) => model.displayName.length));
|
|
266
|
+
const labelWidth = Math.max(8, Math.min(longestLabelWidth, width - overhead - minBarWidth));
|
|
264
267
|
const barWidth = Math.max(minBarWidth, Math.min(20, width - labelWidth - overhead));
|
|
265
|
-
const rows =
|
|
268
|
+
const rows = visibleModels.map((model) => {
|
|
266
269
|
const percent = stats.totalTokens > 0 ? model.totalTokens / stats.totalTokens : 0;
|
|
267
270
|
const bar = usageBar(percent, barWidth);
|
|
268
271
|
const percentText = `${Math.round(percent * 100)}%`.padStart(4, " ");
|
|
269
272
|
const tokenText = formatCompactNumber(model.totalTokens).padStart(6, " ");
|
|
270
|
-
const turnsText =
|
|
273
|
+
const turnsText = formatTurnCount(model.turns).padStart(turnsWidth, " ");
|
|
271
274
|
const costText = showCost
|
|
272
275
|
? ` ${(model.cost !== undefined ? formatCurrencyFor(model.cost, model.costCurrency ?? "USD") : "").padStart(7, " ")}`
|
|
273
276
|
: "";
|
|
274
277
|
return ` ${truncate(model.displayName, labelWidth).padEnd(labelWidth, " ")} ${bar} ${percentText} ${tokenText} ${turnsText}${costText}`.trimEnd();
|
|
275
278
|
});
|
|
276
279
|
if (stats.models.length > MAX_MODEL_ROWS) {
|
|
277
|
-
|
|
280
|
+
const remaining = stats.models.length - MAX_MODEL_ROWS;
|
|
281
|
+
rows.push(expanded
|
|
282
|
+
? " ⌃ Show fewer models"
|
|
283
|
+
: ` › Show ${remaining} more model${remaining === 1 ? "" : "s"}`);
|
|
278
284
|
}
|
|
279
285
|
return rows;
|
|
280
286
|
}
|
|
@@ -356,6 +362,9 @@ function usageBar(percent, width) {
|
|
|
356
362
|
filled = Math.max(0, Math.min(width, filled));
|
|
357
363
|
return "█".repeat(filled) + "░".repeat(width - filled);
|
|
358
364
|
}
|
|
365
|
+
function formatTurnCount(turns) {
|
|
366
|
+
return `${turns} ${turns === 1 ? "turn" : "turns"}`;
|
|
367
|
+
}
|
|
359
368
|
function assistantPayload(entry) {
|
|
360
369
|
if (entry.type === "assistant_message")
|
|
361
370
|
return entry.message;
|
package/dist/tasks/manager.d.ts
CHANGED
|
@@ -65,6 +65,8 @@ export interface BackgroundTaskInfo {
|
|
|
65
65
|
startedAt: number;
|
|
66
66
|
endedAt?: number;
|
|
67
67
|
outputTruncated: boolean;
|
|
68
|
+
/** Total stdout/stderr lines observed, including lines no longer in the tail buffer. */
|
|
69
|
+
outputLines: number;
|
|
68
70
|
/** Wake fired or model read the task via task_output (design §2.3a). */
|
|
69
71
|
deliveredAt?: number;
|
|
70
72
|
ownerSessionId?: string;
|
|
@@ -76,7 +78,7 @@ export interface StartBackgroundTaskInput {
|
|
|
76
78
|
ownerSessionId?: string;
|
|
77
79
|
}
|
|
78
80
|
export interface AdoptBackgroundTaskInput extends StartBackgroundTaskInput {
|
|
79
|
-
/** Already-running child handed over by Ctrl+
|
|
81
|
+
/** Already-running child handed over by Ctrl+B promotion (design §2.5). */
|
|
80
82
|
child: ChildProcess;
|
|
81
83
|
/** Output accumulated before promotion, seeds the ring buffer. */
|
|
82
84
|
outputSoFar?: string;
|
|
@@ -93,7 +95,7 @@ export declare class ProcessManager {
|
|
|
93
95
|
private readonly finishListeners;
|
|
94
96
|
getTaskStateVersion(): number;
|
|
95
97
|
startTask(input: StartBackgroundTaskInput): BackgroundTaskInfo;
|
|
96
|
-
/** Ctrl+
|
|
98
|
+
/** Ctrl+B promotion: adopt a child the bash tool already spawned (§2.5). */
|
|
97
99
|
adoptTask(input: AdoptBackgroundTaskInput): BackgroundTaskInfo;
|
|
98
100
|
private reserveTaskSlot;
|
|
99
101
|
private registerTaskChild;
|
package/dist/tasks/manager.js
CHANGED
|
@@ -30,6 +30,19 @@ const MAX_LOG_BYTES = 96 * 1024;
|
|
|
30
30
|
const STOP_FORCE_AFTER_MS = 1000;
|
|
31
31
|
const MAX_RUNNING_TASKS_PER_SESSION = 8;
|
|
32
32
|
const MAX_FINISHED_TASKS = 20;
|
|
33
|
+
function countLineBreaks(value) {
|
|
34
|
+
let count = 0;
|
|
35
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
36
|
+
if (value.charCodeAt(index) === 10)
|
|
37
|
+
count += 1;
|
|
38
|
+
}
|
|
39
|
+
return count;
|
|
40
|
+
}
|
|
41
|
+
function logicalLineCount(lineBreaks, hasData, endsWithNewline) {
|
|
42
|
+
if (!hasData)
|
|
43
|
+
return 0;
|
|
44
|
+
return lineBreaks + (endsWithNewline ? 0 : 1);
|
|
45
|
+
}
|
|
33
46
|
// ---------------------------------------------------------------------------
|
|
34
47
|
// Manager
|
|
35
48
|
// ---------------------------------------------------------------------------
|
|
@@ -72,7 +85,7 @@ export class ProcessManager {
|
|
|
72
85
|
}
|
|
73
86
|
return this.registerTaskChild(child, { ...input, command });
|
|
74
87
|
}
|
|
75
|
-
/** Ctrl+
|
|
88
|
+
/** Ctrl+B promotion: adopt a child the bash tool already spawned (§2.5). */
|
|
76
89
|
adoptTask(input) {
|
|
77
90
|
this.reserveTaskSlot(input.ownerSessionId);
|
|
78
91
|
return this.registerTaskChild(input.child, input, {
|
|
@@ -89,6 +102,8 @@ export class ProcessManager {
|
|
|
89
102
|
}
|
|
90
103
|
registerTaskChild(child, input, seed) {
|
|
91
104
|
const id = `task_${String(this.nextTaskId++).padStart(4, "0")}`;
|
|
105
|
+
const seedOutput = seed?.outputSoFar ?? "";
|
|
106
|
+
const seedLineBreaks = countLineBreaks(seedOutput);
|
|
92
107
|
const record = {
|
|
93
108
|
kind: "task",
|
|
94
109
|
id,
|
|
@@ -98,15 +113,26 @@ export class ProcessManager {
|
|
|
98
113
|
pid: child.pid,
|
|
99
114
|
status: "running",
|
|
100
115
|
startedAt: seed?.startedAt ?? Date.now(),
|
|
101
|
-
output:
|
|
116
|
+
output: seedOutput,
|
|
102
117
|
outputTruncated: false,
|
|
118
|
+
outputLines: logicalLineCount(seedLineBreaks, seedOutput.length > 0, seedOutput.endsWith("\n")),
|
|
119
|
+
outputLineBreaks: seedLineBreaks,
|
|
120
|
+
outputHasData: seedOutput.length > 0,
|
|
121
|
+
outputEndsWithNewline: seedOutput.endsWith("\n"),
|
|
103
122
|
ownerSessionId: input.ownerSessionId,
|
|
104
123
|
child,
|
|
105
124
|
};
|
|
106
125
|
this.registry.set(id, record);
|
|
107
126
|
const append = (data) => {
|
|
127
|
+
const chunk = data.toString();
|
|
108
128
|
const before = record.output;
|
|
109
|
-
record.output = appendTailCapped(record.output,
|
|
129
|
+
record.output = appendTailCapped(record.output, chunk, MAX_LOG_BYTES);
|
|
130
|
+
record.outputLineBreaks += countLineBreaks(chunk);
|
|
131
|
+
if (chunk.length > 0) {
|
|
132
|
+
record.outputHasData = true;
|
|
133
|
+
record.outputEndsWithNewline = chunk.endsWith("\n");
|
|
134
|
+
}
|
|
135
|
+
record.outputLines = logicalLineCount(record.outputLineBreaks, record.outputHasData, record.outputEndsWithNewline);
|
|
110
136
|
if (!record.outputTruncated && before.length + data.length > record.output.length) {
|
|
111
137
|
record.outputTruncated = true;
|
|
112
138
|
}
|
|
@@ -114,7 +140,7 @@ export class ProcessManager {
|
|
|
114
140
|
child.stdout?.on("data", append);
|
|
115
141
|
child.stderr?.on("data", append);
|
|
116
142
|
child.once("error", (error) => {
|
|
117
|
-
|
|
143
|
+
append(Buffer.from(`\n[task failed to start: ${error.message}]\n`));
|
|
118
144
|
this.finalizeTask(record, "failed", null);
|
|
119
145
|
});
|
|
120
146
|
child.once("exit", (code) => {
|
|
@@ -169,10 +195,9 @@ export class ProcessManager {
|
|
|
169
195
|
return;
|
|
170
196
|
if (record.deliveredAt === undefined) {
|
|
171
197
|
record.deliveredAt = Date.now();
|
|
172
|
-
//
|
|
173
|
-
//
|
|
174
|
-
|
|
175
|
-
record.output = "";
|
|
198
|
+
// Delivery suppresses duplicate Agent wakes, but the task inspector and
|
|
199
|
+
// `y` copy action must retain the output for the complete UI lifecycle.
|
|
200
|
+
// The existing 96KB-per-task cap and 20-task eviction bound memory.
|
|
176
201
|
}
|
|
177
202
|
}
|
|
178
203
|
async waitTasks(ids, options = {}) {
|
|
@@ -293,7 +318,7 @@ export class ProcessManager {
|
|
|
293
318
|
return [...this.registry.values()].filter((record) => record.kind === "task");
|
|
294
319
|
}
|
|
295
320
|
publicTask(record) {
|
|
296
|
-
const { child: _child, output: _output, ...info } = record;
|
|
321
|
+
const { child: _child, output: _output, outputLineBreaks: _outputLineBreaks, outputHasData: _outputHasData, outputEndsWithNewline: _outputEndsWithNewline, ...info } = record;
|
|
297
322
|
return { ...info };
|
|
298
323
|
}
|
|
299
324
|
// -- servers (moved verbatim from server-manager.ts, kind-filtered) --------
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Ctrl+
|
|
2
|
+
* Ctrl+B send-to-background promotion channel (background-tasks design §2.5).
|
|
3
3
|
*
|
|
4
4
|
* A running foreground bash tool call registers a promotion handler keyed by
|
|
5
5
|
* its toolCall id at spawn; the TUI requests promotion when the user presses
|
|
6
|
-
* Ctrl+
|
|
6
|
+
* Ctrl+B. The handler returns the new task id on success, or undefined when
|
|
7
7
|
* it is too late (the command already reached a terminal state — exit,
|
|
8
8
|
* timeout, cancel — a benign race, not an error).
|
|
9
9
|
*/
|
package/dist/tasks/promotion.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Ctrl+
|
|
2
|
+
* Ctrl+B send-to-background promotion channel (background-tasks design §2.5).
|
|
3
3
|
*
|
|
4
4
|
* A running foreground bash tool call registers a promotion handler keyed by
|
|
5
5
|
* its toolCall id at spawn; the TUI requests promotion when the user presses
|
|
6
|
-
* Ctrl+
|
|
6
|
+
* Ctrl+B. The handler returns the new task id on success, or undefined when
|
|
7
7
|
* it is too late (the command already reached a terminal state — exit,
|
|
8
8
|
* timeout, cancel — a benign race, not an error).
|
|
9
9
|
*/
|
|
@@ -700,6 +700,7 @@ function formatRouteLines(snapshot) {
|
|
|
700
700
|
function snapshotToMetadata(snapshot) {
|
|
701
701
|
return {
|
|
702
702
|
subAgentId: snapshot.agentId,
|
|
703
|
+
runId: snapshot.runId,
|
|
703
704
|
agentName: snapshot.agentName,
|
|
704
705
|
nickname: snapshot.nickname,
|
|
705
706
|
status: snapshot.status === "closed" ? "cancelled" : snapshot.status,
|
|
@@ -707,12 +708,15 @@ function snapshotToMetadata(snapshot) {
|
|
|
707
708
|
resumable: snapshot.resumable,
|
|
708
709
|
profileSource: snapshot.profileSource,
|
|
709
710
|
category: snapshot.category,
|
|
711
|
+
phase: snapshot.phase,
|
|
710
712
|
route: snapshot.route,
|
|
711
713
|
task: snapshot.task,
|
|
712
714
|
summary: snapshot.summary,
|
|
713
715
|
toolNotes: snapshot.toolNotes,
|
|
714
716
|
usage: snapshot.usage,
|
|
715
717
|
error: snapshot.error,
|
|
718
|
+
createdAt: snapshot.createdAt,
|
|
719
|
+
updatedAt: snapshot.updatedAt,
|
|
716
720
|
};
|
|
717
721
|
}
|
|
718
722
|
function unsupportedProfile(profile) {
|