@oh-my-pi/pi-tui 18.4.2 → 18.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +56 -0
- package/dist/types/apps/cleanse-board.d.ts +17 -0
- package/dist/types/apps/git/help.d.ts +16 -0
- package/dist/types/apps/git/sidebar.d.ts +18 -0
- package/dist/types/apps/live-visualizer.d.ts +10 -0
- package/dist/types/apps/ps-top.d.ts +15 -0
- package/dist/types/apps/standalone-picker.d.ts +3 -0
- package/dist/types/autocomplete.d.ts +8 -0
- package/dist/types/chat/advisor-message.d.ts +12 -2
- package/dist/types/chat/assistant-message.d.ts +20 -0
- package/dist/types/chat/bash-execution.d.ts +9 -0
- package/dist/types/chat/chat-transcript-builder.d.ts +6 -1
- package/dist/types/chat/collab-prompt-message.d.ts +4 -0
- package/dist/types/chat/compaction-summary-message.d.ts +15 -0
- package/dist/types/chat/eval-execution.d.ts +8 -0
- package/dist/types/chat/execution-shared.d.ts +58 -0
- package/dist/types/chat/late-diagnostics-message.d.ts +15 -1
- package/dist/types/chat/read-tool-group.d.ts +15 -0
- package/dist/types/chat/skill-message.d.ts +9 -0
- package/dist/types/chat/stripped-tool-calls-placeholder.d.ts +3 -0
- package/dist/types/chat/thinking-display.d.ts +2 -0
- package/dist/types/chat/todo-reminder.d.ts +4 -1
- package/dist/types/chat/tool-execution.d.ts +25 -1
- package/dist/types/chat/transcript-actions.d.ts +37 -0
- package/dist/types/chat/transcript-entry.d.ts +3 -1
- package/dist/types/chat/user-message.d.ts +25 -0
- package/dist/types/chrome/collab-qrcode.d.ts +7 -0
- package/dist/types/chrome/context-thresholds.d.ts +11 -0
- package/dist/types/chrome/countdown-timer.d.ts +9 -3
- package/dist/types/chrome/diff.d.ts +12 -0
- package/dist/types/chrome/dynamic-border.d.ts +3 -0
- package/dist/types/chrome/format.d.ts +6 -0
- package/dist/types/chrome/message-divider.d.ts +13 -0
- package/dist/types/chrome/message-frame.d.ts +10 -0
- package/dist/types/chrome/message-notice.d.ts +23 -0
- package/dist/types/chrome/overlay-box.d.ts +11 -2
- package/dist/types/chrome/qrcode.d.ts +7 -0
- package/dist/types/chrome/segment-track.d.ts +7 -0
- package/dist/types/chrome/selector-helpers.d.ts +0 -6
- package/dist/types/chrome/status-notice.d.ts +14 -0
- package/dist/types/chrome/streaming-panel.d.ts +3 -0
- package/dist/types/chrome/tool-activity.d.ts +3 -0
- package/dist/types/chrome/transcript-container.d.ts +13 -0
- package/dist/types/chrome/transcript-status.d.ts +15 -3
- package/dist/types/components/box.d.ts +7 -0
- package/dist/types/components/disclosure.d.ts +9 -0
- package/dist/types/components/editor.d.ts +42 -0
- package/dist/types/components/form.d.ts +14 -0
- package/dist/types/components/image.d.ts +7 -0
- package/dist/types/components/input.d.ts +20 -1
- package/dist/types/components/key-value-list.d.ts +3 -0
- package/dist/types/components/layout/geometry.d.ts +16 -0
- package/dist/types/components/layout/row.d.ts +7 -0
- package/dist/types/components/layout/split-pane.d.ts +8 -0
- package/dist/types/components/layout/stack.d.ts +6 -0
- package/dist/types/components/loader.d.ts +48 -0
- package/dist/types/components/markdown.d.ts +8 -0
- package/dist/types/components/metric.d.ts +7 -0
- package/dist/types/components/progress-bar.d.ts +3 -0
- package/dist/types/components/scroll-view.d.ts +6 -0
- package/dist/types/components/section.d.ts +3 -0
- package/dist/types/components/select-list.d.ts +33 -0
- package/dist/types/components/settings-list.d.ts +68 -0
- package/dist/types/components/spacer.d.ts +4 -0
- package/dist/types/components/tab-bar.d.ts +9 -0
- package/dist/types/components/table.d.ts +7 -0
- package/dist/types/components/text.d.ts +6 -0
- package/dist/types/components/tree-view.d.ts +9 -0
- package/dist/types/components/truncated-text.d.ts +3 -0
- package/dist/types/components/wizard-step.d.ts +6 -0
- package/dist/types/hotkeys-markdown.d.ts +24 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/latex-block.d.ts +7 -0
- package/dist/types/loop-watchdog.d.ts +9 -0
- package/dist/types/native/apply.d.ts +39 -0
- package/dist/types/native/backend.d.ts +94 -0
- package/dist/types/native/blobs.d.ts +29 -0
- package/dist/types/native/describe.d.ts +56 -0
- package/dist/types/native/encode.d.ts +50 -0
- package/dist/types/native/icons.d.ts +18 -0
- package/dist/types/native/memo.d.ts +27 -0
- package/dist/types/native/node.d.ts +107 -0
- package/dist/types/native/overlay.d.ts +64 -0
- package/dist/types/native/picker.d.ts +124 -0
- package/dist/types/native/reconcile.d.ts +41 -0
- package/dist/types/native/settle.d.ts +11 -0
- package/dist/types/native/spans.d.ts +21 -0
- package/dist/types/native/state.d.ts +6 -0
- package/dist/types/native/tone.d.ts +24 -0
- package/dist/types/overlays/advisor-config.d.ts +20 -0
- package/dist/types/overlays/agent-hub-renderer.d.ts +27 -11
- package/dist/types/overlays/agent-hub.d.ts +10 -0
- package/dist/types/overlays/agent-transcript-viewer.d.ts +7 -0
- package/dist/types/overlays/agents-hub.d.ts +8 -0
- package/dist/types/overlays/annotation-overlay.d.ts +3 -0
- package/dist/types/overlays/ask-dialog.d.ts +23 -0
- package/dist/types/overlays/bordered-loader.d.ts +3 -0
- package/dist/types/overlays/btw-history-panel.d.ts +9 -0
- package/dist/types/overlays/btw-panel.d.ts +3 -0
- package/dist/types/overlays/cleanse-panel.d.ts +5 -2
- package/dist/types/overlays/composer-shape-preview.d.ts +7 -1
- package/dist/types/overlays/copy-selector.d.ts +38 -0
- package/dist/types/overlays/error-banner.d.ts +9 -0
- package/dist/types/overlays/extensions/extension-list.d.ts +1 -0
- package/dist/types/overlays/history-search.d.ts +18 -0
- package/dist/types/overlays/hook-editor.d.ts +28 -1
- package/dist/types/overlays/hook-input.d.ts +3 -0
- package/dist/types/overlays/hook-selector.d.ts +10 -0
- package/dist/types/overlays/hub-frame.d.ts +18 -0
- package/dist/types/overlays/jobs-panel.d.ts +24 -0
- package/dist/types/overlays/login-dialog.d.ts +10 -0
- package/dist/types/overlays/logout-account-selector.d.ts +4 -0
- package/dist/types/overlays/mcp-add-wizard.d.ts +4 -0
- package/dist/types/overlays/model-browser.d.ts +69 -0
- package/dist/types/overlays/model-hub.d.ts +7 -0
- package/dist/types/overlays/model-picker.d.ts +9 -1
- package/dist/types/overlays/move-overlay.d.ts +3 -0
- package/dist/types/overlays/oauth-selector.d.ts +4 -0
- package/dist/types/overlays/omfg-panel.d.ts +3 -0
- package/dist/types/overlays/pause-screen.d.ts +12 -0
- package/dist/types/overlays/plan-review-overlay.d.ts +5 -0
- package/dist/types/overlays/plan-save-overlay.d.ts +10 -0
- package/dist/types/overlays/plugin-selector.d.ts +4 -0
- package/dist/types/overlays/plugin-settings.d.ts +30 -0
- package/dist/types/overlays/queue-mode-selector.d.ts +4 -0
- package/dist/types/overlays/reset-usage-selector.d.ts +8 -0
- package/dist/types/overlays/rewind-selector.d.ts +5 -0
- package/dist/types/overlays/session-info-overlay.d.ts +19 -1
- package/dist/types/overlays/session-selector.d.ts +64 -1
- package/dist/types/overlays/settings-defs.d.ts +14 -0
- package/dist/types/overlays/settings-selector.d.ts +21 -0
- package/dist/types/overlays/show-images-selector.d.ts +4 -0
- package/dist/types/overlays/snapcompact-shape-preview.d.ts +2 -0
- package/dist/types/overlays/stats-notice.d.ts +8 -0
- package/dist/types/overlays/theme-selector.d.ts +11 -0
- package/dist/types/overlays/thinking-selector.d.ts +4 -0
- package/dist/types/overlays/tree-selector.d.ts +60 -2
- package/dist/types/overlays/usage-dashboard.d.ts +26 -3
- package/dist/types/overlays/usage-row.d.ts +36 -2
- package/dist/types/prompt/attachment-chips.d.ts +8 -0
- package/dist/types/prompt/composer-attachments.d.ts +15 -3
- package/dist/types/prompt/composer.d.ts +18 -1
- package/dist/types/prompt/custom-editor.d.ts +48 -2
- package/dist/types/prompt/editor-top-gap.d.ts +2 -0
- package/dist/types/prompt/macos-spelling.d.ts +6 -0
- package/dist/types/prompt/magic-keywords.d.ts +9 -0
- package/dist/types/prompt/queued-messages.d.ts +23 -0
- package/dist/types/prompt/skill-tokens.d.ts +4 -2
- package/dist/types/prompt/welcome.d.ts +16 -0
- package/dist/types/render/code-cell.d.ts +10 -0
- package/dist/types/render/file-list.d.ts +8 -0
- package/dist/types/render/hyperlink.d.ts +14 -0
- package/dist/types/render/output-block.d.ts +43 -0
- package/dist/types/render/output-pane.d.ts +17 -0
- package/dist/types/render/tool-card.d.ts +8 -0
- package/dist/types/render/tree-list.d.ts +8 -0
- package/dist/types/render/width-aware-text.d.ts +7 -0
- package/dist/types/setup/scenes/outro.d.ts +7 -0
- package/dist/types/setup/scenes/sign-in.d.ts +16 -9
- package/dist/types/setup/scenes/splash.d.ts +8 -0
- package/dist/types/setup/scenes/types.d.ts +6 -27
- package/dist/types/setup/wizard-overlay.d.ts +9 -0
- package/dist/types/status-line/component.d.ts +49 -5
- package/dist/types/status-line/context-usage.d.ts +20 -0
- package/dist/types/status-line/footer.d.ts +8 -0
- package/dist/types/status-line/metrics.d.ts +1 -2
- package/dist/types/status-line/segments.d.ts +10 -1
- package/dist/types/status-line/types.d.ts +40 -1
- package/dist/types/stdin-buffer.d.ts +10 -7
- package/dist/types/terminal-capabilities.d.ts +1 -1
- package/dist/types/terminal.d.ts +36 -0
- package/dist/types/theme/defaults/index.d.ts +100 -0
- package/dist/types/theme/schema.d.ts +2 -0
- package/dist/types/theme/shimmer.d.ts +8 -0
- package/dist/types/theme/theme-class.d.ts +2 -0
- package/dist/types/theme/theme.d.ts +33 -1
- package/dist/types/tools/ask.d.ts +3 -0
- package/dist/types/tools/ast-edit.d.ts +10 -1
- package/dist/types/tools/ast-grep.d.ts +10 -1
- package/dist/types/tools/autoresearch.d.ts +21 -4
- package/dist/types/tools/bash.d.ts +30 -1
- package/dist/types/tools/cfg-render.d.ts +5 -1
- package/dist/types/tools/debug.d.ts +3 -1
- package/dist/types/tools/default-renderer.d.ts +6 -1
- package/dist/types/tools/edit.d.ts +14 -1
- package/dist/types/tools/eval.d.ts +12 -1
- package/dist/types/tools/fetch.d.ts +16 -1
- package/dist/types/tools/find.d.ts +15 -1
- package/dist/types/tools/github.d.ts +3 -0
- package/dist/types/tools/glob.d.ts +14 -1
- package/dist/types/tools/goal.d.ts +3 -1
- package/dist/types/tools/grep.d.ts +14 -1
- package/dist/types/tools/grouped-file-output.d.ts +58 -0
- package/dist/types/tools/json-tree.d.ts +20 -0
- package/dist/types/tools/lsp.d.ts +3 -10
- package/dist/types/tools/mcp.d.ts +16 -1
- package/dist/types/tools/memory.d.ts +26 -0
- package/dist/types/tools/native-view.d.ts +90 -0
- package/dist/types/tools/proc-render.d.ts +7 -1
- package/dist/types/tools/read.d.ts +23 -1
- package/dist/types/tools/renderer.d.ts +57 -0
- package/dist/types/tools/report-tool-issue.d.ts +3 -0
- package/dist/types/tools/resolve.d.ts +14 -1
- package/dist/types/tools/task.d.ts +3 -0
- package/dist/types/tools/think.d.ts +3 -0
- package/dist/types/tools/todo.d.ts +12 -0
- package/dist/types/tools/vibe.d.ts +3 -1
- package/dist/types/tools/wait.d.ts +3 -0
- package/dist/types/tools/web-search-types.d.ts +90 -0
- package/dist/types/tools/web-search.d.ts +9 -168
- package/dist/types/tools/write.d.ts +14 -1
- package/dist/types/tools/xdev.d.ts +13 -0
- package/dist/types/tui.d.ts +49 -0
- package/package.json +9 -9
- package/src/apps/autoresearch-dashboard.ts +362 -4
- package/src/apps/cleanse-board.ts +219 -1
- package/src/apps/cleanse-picker.ts +9 -1
- package/src/apps/debug/log-viewer.ts +15 -15
- package/src/apps/debug/protocol-probe.ts +2 -20
- package/src/apps/git/avatar.ts +2 -22
- package/src/apps/git/git-tui.ts +406 -59
- package/src/apps/git/help.ts +130 -0
- package/src/apps/git/sidebar.ts +491 -0
- package/src/apps/live-visualizer.ts +65 -0
- package/src/apps/ps-top.ts +448 -17
- package/src/apps/session-picker.ts +1 -0
- package/src/apps/setup-model-picker.ts +5 -1
- package/src/apps/standalone-picker.ts +55 -1
- package/src/autocomplete.ts +44 -1
- package/src/chat/advisor-message.ts +72 -3
- package/src/chat/assistant-message.ts +538 -51
- package/src/chat/background-tan-message.ts +4 -4
- package/src/chat/bash-execution.ts +81 -0
- package/src/chat/cache-invalidation-marker.ts +8 -0
- package/src/chat/chat-transcript-builder.ts +37 -6
- package/src/chat/collab-prompt-message.ts +15 -3
- package/src/chat/compaction-summary-message.ts +74 -1
- package/src/chat/custom-message.ts +3 -1
- package/src/chat/eval-execution.ts +57 -0
- package/src/chat/execution-shared.ts +153 -1
- package/src/chat/hook-message.ts +1 -0
- package/src/chat/late-diagnostics-message.ts +85 -2
- package/src/chat/read-tool-group.ts +341 -1
- package/src/chat/served-model-marker.ts +8 -0
- package/src/chat/skill-message.ts +63 -0
- package/src/chat/stripped-tool-calls-placeholder.ts +18 -10
- package/src/chat/thinking-display.ts +73 -11
- package/src/chat/todo-reminder.ts +34 -4
- package/src/chat/tool-execution.ts +385 -10
- package/src/chat/transcript-actions.ts +38 -0
- package/src/chat/transcript-browser.ts +2 -9
- package/src/chat/transcript-entry.ts +10 -1
- package/src/chat/transcript-render-helpers.ts +16 -15
- package/src/chat/ttsr-notification.ts +38 -1
- package/src/chat/user-message.ts +167 -4
- package/src/chrome/collab-qrcode.ts +27 -2
- package/src/chrome/context-thresholds.ts +34 -0
- package/src/chrome/countdown-timer.ts +24 -1
- package/src/chrome/diff.ts +60 -1
- package/src/chrome/dynamic-border.ts +7 -0
- package/src/chrome/format.ts +12 -0
- package/src/chrome/message-divider.ts +33 -1
- package/src/chrome/message-frame.ts +53 -10
- package/src/chrome/message-notice.ts +71 -0
- package/src/chrome/overlay-box.ts +45 -2
- package/src/chrome/qrcode.ts +28 -0
- package/src/chrome/segment-track.ts +26 -0
- package/src/chrome/selector-helpers.ts +1 -17
- package/src/chrome/status-notice.ts +46 -0
- package/src/chrome/streaming-panel.ts +25 -1
- package/src/chrome/tool-activity.ts +20 -0
- package/src/chrome/transcript-container.ts +139 -17
- package/src/chrome/transcript-status.ts +40 -11
- package/src/components/box.ts +51 -0
- package/src/components/disclosure.ts +33 -0
- package/src/components/editor.ts +239 -36
- package/src/components/form.ts +93 -9
- package/src/components/image.ts +30 -0
- package/src/components/input.ts +77 -26
- package/src/components/key-value-list.ts +18 -0
- package/src/components/layout/geometry.ts +44 -0
- package/src/components/layout/row.ts +30 -0
- package/src/components/layout/split-pane.ts +65 -0
- package/src/components/layout/stack.ts +27 -0
- package/src/components/loader.ts +183 -1
- package/src/components/markdown.ts +131 -56
- package/src/components/metric.ts +39 -0
- package/src/components/progress-bar.ts +28 -0
- package/src/components/scroll-view.ts +23 -0
- package/src/components/section.ts +16 -0
- package/src/components/select-list.ts +174 -25
- package/src/components/settings-list.ts +264 -7
- package/src/components/spacer.ts +17 -0
- package/src/components/tab-bar.ts +42 -0
- package/src/components/table.ts +34 -0
- package/src/components/text.ts +23 -0
- package/src/components/tree-view.ts +65 -0
- package/src/components/truncated-text.ts +14 -0
- package/src/components/wizard-step.ts +18 -9
- package/src/debug-server.ts +14 -7
- package/src/hotkeys-markdown.ts +251 -69
- package/src/index.ts +6 -0
- package/src/latex-block.ts +11 -0
- package/src/loop-watchdog.ts +38 -10
- package/src/native/apply.ts +275 -0
- package/src/native/backend.ts +682 -0
- package/src/native/blobs.ts +70 -0
- package/src/native/describe.ts +124 -0
- package/src/native/encode.ts +233 -0
- package/src/native/icons.ts +184 -0
- package/src/native/memo.ts +64 -0
- package/src/native/node.ts +112 -0
- package/src/native/overlay.ts +131 -0
- package/src/native/picker.ts +333 -0
- package/src/native/reconcile.ts +1063 -0
- package/src/native/settle.ts +23 -0
- package/src/native/spans.ts +308 -0
- package/src/native/state.ts +28 -0
- package/src/native/tone.ts +79 -0
- package/src/overlays/advisor-config.ts +420 -0
- package/src/overlays/agent-hub-renderer.ts +155 -18
- package/src/overlays/agent-hub.ts +1037 -44
- package/src/overlays/agent-transcript-viewer.ts +129 -0
- package/src/overlays/agents-hub.ts +688 -53
- package/src/overlays/annotation-overlay.ts +391 -52
- package/src/overlays/ask-dialog.ts +435 -24
- package/src/overlays/bordered-loader.ts +17 -0
- package/src/overlays/btw-history-panel.ts +182 -0
- package/src/overlays/btw-panel.ts +68 -2
- package/src/overlays/cleanse-panel.ts +105 -15
- package/src/overlays/codex-reset-fireworks.ts +65 -5
- package/src/overlays/composer-shape-preview.ts +26 -1
- package/src/overlays/copy-selector.ts +545 -23
- package/src/overlays/error-banner.ts +44 -0
- package/src/overlays/extensions/extension-list.ts +23 -17
- package/src/overlays/history-search.ts +175 -33
- package/src/overlays/hook-editor.ts +113 -6
- package/src/overlays/hook-input.ts +22 -1
- package/src/overlays/hook-selector.ts +311 -22
- package/src/overlays/hub-frame.ts +80 -0
- package/src/overlays/jobs-panel.ts +112 -0
- package/src/overlays/login-dialog.ts +183 -1
- package/src/overlays/logout-account-selector.ts +102 -4
- package/src/overlays/mcp-add-wizard.ts +232 -53
- package/src/overlays/model-browser.ts +681 -22
- package/src/overlays/model-hub.ts +1402 -78
- package/src/overlays/model-picker.ts +184 -7
- package/src/overlays/move-overlay.ts +45 -0
- package/src/overlays/oauth-selector.ts +227 -23
- package/src/overlays/omfg-panel.ts +86 -2
- package/src/overlays/pause-screen.ts +55 -4
- package/src/overlays/plan-review-overlay.ts +352 -0
- package/src/overlays/plan-save-overlay.ts +45 -0
- package/src/overlays/plugin-selector.ts +21 -1
- package/src/overlays/plugin-settings.ts +195 -5
- package/src/overlays/queue-mode-selector.ts +19 -1
- package/src/overlays/reset-usage-selector.ts +110 -40
- package/src/overlays/rewind-selector.ts +458 -44
- package/src/overlays/session-account-selector.ts +1 -1
- package/src/overlays/session-info-overlay.ts +137 -1
- package/src/overlays/session-selector.ts +807 -46
- package/src/overlays/settings-defs.ts +41 -0
- package/src/overlays/settings-selector.ts +585 -33
- package/src/overlays/show-images-selector.ts +18 -1
- package/src/overlays/snapcompact-shape-preview.ts +48 -3
- package/src/overlays/stats-notice.ts +31 -0
- package/src/overlays/theme-selector.ts +31 -1
- package/src/overlays/thinking-selector.ts +22 -1
- package/src/overlays/tree-selector.ts +570 -110
- package/src/overlays/usage-dashboard.ts +587 -12
- package/src/overlays/usage-row.ts +161 -25
- package/src/prompt/attachment-chips.ts +60 -0
- package/src/prompt/composer-attachments.ts +31 -9
- package/src/prompt/composer.ts +55 -2
- package/src/prompt/custom-editor.ts +302 -4
- package/src/prompt/editor-top-gap.ts +8 -0
- package/src/prompt/macos-spelling.ts +24 -9
- package/src/prompt/magic-keywords.ts +22 -1
- package/src/prompt/model-mention-autocomplete.ts +1 -0
- package/src/prompt/queued-messages.ts +101 -0
- package/src/prompt/skill-tokens.ts +5 -3
- package/src/prompt/welcome.ts +213 -6
- package/src/render/code-cell.ts +103 -2
- package/src/render/file-list.ts +29 -0
- package/src/render/hyperlink.ts +32 -0
- package/src/render/output-block.ts +110 -0
- package/src/render/output-pane.ts +37 -0
- package/src/render/tool-card.ts +137 -0
- package/src/render/tree-list.ts +39 -0
- package/src/render/width-aware-text.ts +20 -0
- package/src/setup/scenes/composer.ts +29 -0
- package/src/setup/scenes/glyph.ts +15 -0
- package/src/setup/scenes/model.ts +36 -8
- package/src/setup/scenes/outro.ts +28 -1
- package/src/setup/scenes/sign-in.ts +138 -24
- package/src/setup/scenes/splash.ts +28 -1
- package/src/setup/scenes/theme.ts +88 -3
- package/src/setup/scenes/types.ts +7 -28
- package/src/setup/startup-splash.ts +46 -9
- package/src/setup/wizard-overlay.ts +140 -23
- package/src/setup/wizard.ts +1 -1
- package/src/status-line/component.ts +414 -18
- package/src/status-line/context-usage.ts +279 -50
- package/src/status-line/footer.ts +94 -1
- package/src/status-line/metrics.ts +3 -6
- package/src/status-line/segments.ts +463 -97
- package/src/status-line/separators.ts +3 -16
- package/src/status-line/types.ts +43 -1
- package/src/stdin-buffer.ts +27 -21
- package/src/terminal-capabilities.ts +7 -0
- package/src/terminal.ts +153 -11
- package/src/theme/defaults/dark-neon-noir.json +100 -0
- package/src/theme/defaults/index.ts +2 -0
- package/src/theme/defaults/light-prism.json +5 -5
- package/src/theme/defaults/onyx.json +62 -62
- package/src/theme/mermaid-cache.ts +10 -1
- package/src/theme/schema.ts +15 -0
- package/src/theme/shimmer.ts +33 -0
- package/src/theme/theme-class.ts +24 -19
- package/src/theme/theme.ts +111 -9
- package/src/theme/tui-adapters.ts +14 -1
- package/src/tools/ask.ts +157 -1
- package/src/tools/ast-edit.ts +174 -1
- package/src/tools/ast-grep.ts +82 -2
- package/src/tools/autoresearch.ts +149 -1
- package/src/tools/bash.ts +233 -62
- package/src/tools/cfg-render.ts +66 -1
- package/src/tools/debug.ts +78 -1
- package/src/tools/default-renderer.ts +35 -1
- package/src/tools/edit.ts +357 -31
- package/src/tools/eval.ts +257 -1
- package/src/tools/fetch.ts +102 -3
- package/src/tools/find.ts +127 -1
- package/src/tools/github.ts +119 -10
- package/src/tools/glob.ts +116 -1
- package/src/tools/goal.ts +56 -1
- package/src/tools/grep.ts +83 -2
- package/src/tools/grouped-file-output.ts +205 -0
- package/src/tools/json-tree.ts +116 -1
- package/src/tools/lsp.ts +318 -1
- package/src/tools/mcp.ts +80 -1
- package/src/tools/memory.ts +93 -11
- package/src/tools/native-view.ts +292 -0
- package/src/tools/proc-render.ts +221 -1
- package/src/tools/read.ts +199 -4
- package/src/tools/renderer.ts +61 -0
- package/src/tools/report-tool-issue.ts +7 -1
- package/src/tools/resolve.ts +63 -1
- package/src/tools/streaming-output.ts +79 -16
- package/src/tools/task.ts +406 -4
- package/src/tools/think.ts +19 -1
- package/src/tools/todo.ts +89 -0
- package/src/tools/vibe.ts +230 -2
- package/src/tools/wait.ts +181 -1
- package/src/tools/web-search-types.ts +99 -0
- package/src/tools/web-search.ts +111 -170
- package/src/tools/write.ts +144 -5
- package/src/tools/xdev.ts +64 -1
- package/src/tui.ts +295 -4
- package/dist/types/setup/scenes/providers.d.ts +0 -3
- package/dist/types/setup/scenes/web-search.d.ts +0 -22
- package/src/setup/scenes/providers.ts +0 -110
- package/src/setup/scenes/web-search.ts +0 -165
|
@@ -5,6 +5,11 @@ import { type KeyId, matchesKey } from "../keys";
|
|
|
5
5
|
import { sliceWithWidth, truncateToWidth, visibleWidth } from "../utils";
|
|
6
6
|
import { sanitizeDisplaySingleLine } from "../overlays/extensions/display-text";
|
|
7
7
|
import { type ThemeColor, theme } from "../theme/theme";
|
|
8
|
+
import type { TspTone } from "@oh-my-pi/pi-wire";
|
|
9
|
+
import { card, node, row, span, text } from "../native/describe";
|
|
10
|
+
import type { DescribeContext, NativeNode, NativeUiEvent } from "../native/node";
|
|
11
|
+
import { actionBar, actionButton } from "../native/overlay";
|
|
12
|
+
import { Memo } from "../native/memo";
|
|
8
13
|
|
|
9
14
|
/** Distinct states of a realtime call connection. */
|
|
10
15
|
export type LivePhase = "connecting" | "listening" | "working" | "speaking" | "muted" | "error";
|
|
@@ -25,7 +30,17 @@ const PHASE_COLORS: Record<LivePhase, ThemeColor> = {
|
|
|
25
30
|
muted: "dim",
|
|
26
31
|
error: "error",
|
|
27
32
|
};
|
|
33
|
+
const PHASE_TONES: Record<LivePhase, TspTone> = {
|
|
34
|
+
connecting: "muted",
|
|
35
|
+
listening: "success",
|
|
36
|
+
working: "warning",
|
|
37
|
+
speaking: "accent",
|
|
38
|
+
muted: "muted",
|
|
39
|
+
error: "error",
|
|
40
|
+
};
|
|
28
41
|
const SPECTRUM_BLOCKS = [" ", "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"] as const;
|
|
42
|
+
/** Native mic meter resolution: the level snaps to 1/20 steps so decay ticks don't rebuild every frame. */
|
|
43
|
+
const METER_STEPS = 20;
|
|
29
44
|
|
|
30
45
|
/** Configuration callbacks for user interactions in the visualizer. */
|
|
31
46
|
export interface LiveVisualizerOptions {
|
|
@@ -56,6 +71,7 @@ export class LiveVisualizer implements Component {
|
|
|
56
71
|
#displayLevel = 0;
|
|
57
72
|
#frame = 0;
|
|
58
73
|
#userTranscript = "";
|
|
74
|
+
readonly #native = new Memo();
|
|
59
75
|
|
|
60
76
|
#cache:
|
|
61
77
|
| {
|
|
@@ -135,6 +151,55 @@ export class LiveVisualizer implements Component {
|
|
|
135
151
|
this.#panel.invalidate();
|
|
136
152
|
}
|
|
137
153
|
|
|
154
|
+
/** The call panel's buttons run the same code as their keys. */
|
|
155
|
+
handleNativeEvent(event: NativeUiEvent): void {
|
|
156
|
+
if (event.type !== "action") return;
|
|
157
|
+
if (event.act === "mute") this.#options.onToggleMute();
|
|
158
|
+
else if (event.act === "end") this.#options.onStop();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Native call panel: phase status (a spinner while working), the mic level
|
|
163
|
+
* as a `meter` (a `progress` bar on terminals without it), the streaming
|
|
164
|
+
* transcript and the Mute/End buttons. The spectrum animation is
|
|
165
|
+
* ANSI-only; frame ticks leave this node unchanged.
|
|
166
|
+
*/
|
|
167
|
+
describe(cx: DescribeContext): NativeNode {
|
|
168
|
+
const energy = this.#phase === "muted" ? 0 : Math.min(1, Math.sqrt(this.#displayLevel * 5));
|
|
169
|
+
const level = Math.round(energy * METER_STEPS) / METER_STEPS;
|
|
170
|
+
const meter = cx.supports("meter");
|
|
171
|
+
return this.#native.get([this.#phase, level, this.#userTranscript, meter], () => {
|
|
172
|
+
const phase = this.#phase;
|
|
173
|
+
const status =
|
|
174
|
+
phase === "working"
|
|
175
|
+
? node("spinner", { label: [span(phase, PHASE_COLORS[phase])], tone: PHASE_TONES[phase] })
|
|
176
|
+
: text([span(`${PHASE_ICONS[phase]} ${phase}`, PHASE_COLORS[phase])]);
|
|
177
|
+
const tone = phase === "muted" ? "muted" : phase === "error" ? "error" : "success";
|
|
178
|
+
return card({ role: "omp.app.live", tone: PHASE_TONES[phase] }, [
|
|
179
|
+
node("row", { gap: "sm", align: "center" }, [status], "head"),
|
|
180
|
+
meter
|
|
181
|
+
? row(
|
|
182
|
+
[
|
|
183
|
+
text([span("mic", "muted")]),
|
|
184
|
+
node("meter", { value: level, style: "bar", size: "md", tone, grow: 1 }),
|
|
185
|
+
],
|
|
186
|
+
{
|
|
187
|
+
gap: "sm",
|
|
188
|
+
align: "center",
|
|
189
|
+
role: "omp.app.live.level",
|
|
190
|
+
},
|
|
191
|
+
)
|
|
192
|
+
: node("progress", { value: level, tone, label: [span("mic", "muted")] }),
|
|
193
|
+
text([span(this.#userTranscript, "accent")], { wrap: "none", truncate: "start" }),
|
|
194
|
+
actionBar([
|
|
195
|
+
null,
|
|
196
|
+
actionButton(phase === "muted" ? "Unmute" : "Mute", "mute", { keys: "space" }),
|
|
197
|
+
actionButton("End call", "end", { keys: "escape", tone: "error" }),
|
|
198
|
+
]),
|
|
199
|
+
]);
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
|
|
138
203
|
/** Renders the microphone spectrum into a compact fixed-height panel. */
|
|
139
204
|
render(width: number): readonly string[] {
|
|
140
205
|
if (
|
package/src/apps/ps-top.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* `x` kill, `r` restart, `a` toggle all scopes, `q`/`esc`/`ctrl+c` quit.
|
|
7
7
|
* Sub-views (info, logs): `esc`/`q` back.
|
|
8
8
|
*/
|
|
9
|
+
import * as path from "node:path";
|
|
9
10
|
import { formatKeyHint, formatKeyHints } from "../app-keybindings";
|
|
10
11
|
import { KeyValueList, type KeyValueRow } from "../components/key-value-list";
|
|
11
12
|
import { ScrollView } from "../components/scroll-view";
|
|
@@ -13,6 +14,11 @@ import { renderTableRow, type TableColumn } from "../components/table";
|
|
|
13
14
|
import { matchesKey } from "../keys";
|
|
14
15
|
import { ProcessTerminal } from "../terminal";
|
|
15
16
|
import { type Component, TUI } from "../tui";
|
|
17
|
+
import type { TspSpan, TspText, TspTone } from "@oh-my-pi/pi-wire";
|
|
18
|
+
import { col, compact, elapsed, keyed, node, row, span, stableKey, text } from "../native/describe";
|
|
19
|
+
import type { NativeNode, NativeUiEvent } from "../native/node";
|
|
20
|
+
import { actionBar, actionButton } from "../native/overlay";
|
|
21
|
+
import { Memo } from "../native/memo";
|
|
16
22
|
import { truncateToWidth } from "../utils";
|
|
17
23
|
import { formatDuration } from "@oh-my-pi/pi-utils";
|
|
18
24
|
import chalk from "@oh-my-pi/pi-utils/chalk";
|
|
@@ -26,6 +32,7 @@ import {
|
|
|
26
32
|
type PsScopeReport,
|
|
27
33
|
type PsTarget,
|
|
28
34
|
scopeHeader,
|
|
35
|
+
flagsCell,
|
|
29
36
|
TABLE_HEADER,
|
|
30
37
|
TERMINAL_STATES,
|
|
31
38
|
tableCells,
|
|
@@ -42,6 +49,15 @@ interface FlatRow {
|
|
|
42
49
|
|
|
43
50
|
type PsTopView = "table" | "info" | "logs";
|
|
44
51
|
|
|
52
|
+
type PsStatusTone = "success" | "warning" | "error" | "muted";
|
|
53
|
+
|
|
54
|
+
const STATUS_PAINT: Record<PsStatusTone, (text: string) => string> = {
|
|
55
|
+
success: chalk.green,
|
|
56
|
+
warning: chalk.yellow,
|
|
57
|
+
error: chalk.red,
|
|
58
|
+
muted: chalk.dim,
|
|
59
|
+
};
|
|
60
|
+
|
|
45
61
|
/** Options accepted by the interactive monitor: scope selection from the list flags. */
|
|
46
62
|
export interface PsTopOptions extends PsTarget {
|
|
47
63
|
all: boolean;
|
|
@@ -81,8 +97,14 @@ export class PsTopComponent implements Component {
|
|
|
81
97
|
#refreshing = false;
|
|
82
98
|
#lastRefresh = 0;
|
|
83
99
|
#status = "";
|
|
100
|
+
#statusText = "";
|
|
101
|
+
#statusTone: PsStatusTone = "muted";
|
|
84
102
|
#statusAt = 0;
|
|
103
|
+
#logsError: string | undefined;
|
|
104
|
+
/** Process key a pointer `Kill` waits on for confirmation. */
|
|
105
|
+
#killConfirm: string | undefined;
|
|
85
106
|
#disposed = false;
|
|
107
|
+
readonly #native = new Memo();
|
|
86
108
|
|
|
87
109
|
constructor(ui: TUI, options: PsTopOptions, host: PsTopHost) {
|
|
88
110
|
this.#ui = ui;
|
|
@@ -122,7 +144,7 @@ export class PsTopComponent implements Component {
|
|
|
122
144
|
this.#restoreSelection();
|
|
123
145
|
this.#ui.requestRender();
|
|
124
146
|
} catch (error) {
|
|
125
|
-
this.#setStatus(
|
|
147
|
+
this.#setStatus("error", error instanceof Error ? error.message : String(error));
|
|
126
148
|
} finally {
|
|
127
149
|
this.#refreshing = false;
|
|
128
150
|
}
|
|
@@ -140,8 +162,10 @@ export class PsTopComponent implements Component {
|
|
|
140
162
|
this.#selectedKey = this.#flat[this.#selected] ? flatKey(this.#flat[this.#selected]) : undefined;
|
|
141
163
|
}
|
|
142
164
|
|
|
143
|
-
#setStatus(text: string): void {
|
|
144
|
-
this.#status = text;
|
|
165
|
+
#setStatus(tone: PsStatusTone, text: string): void {
|
|
166
|
+
this.#status = STATUS_PAINT[tone](text);
|
|
167
|
+
this.#statusText = text;
|
|
168
|
+
this.#statusTone = tone;
|
|
145
169
|
this.#statusAt = Date.now();
|
|
146
170
|
this.#ui.requestRender();
|
|
147
171
|
}
|
|
@@ -152,19 +176,16 @@ export class PsTopComponent implements Component {
|
|
|
152
176
|
const entry = this.#flat[this.#selected];
|
|
153
177
|
if (!entry) return;
|
|
154
178
|
const name = entry.row.snapshot.name;
|
|
155
|
-
this.#setStatus(
|
|
179
|
+
this.#setStatus("warning", `${verb} ${name}…`);
|
|
156
180
|
try {
|
|
157
181
|
const daemon = await this.#host.act(entry.scope, name, verb);
|
|
158
182
|
this.#setStatus(
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
),
|
|
183
|
+
"success",
|
|
184
|
+
`${verb === "restart" ? "Restarted" : verb === "kill" ? "Killed" : "Stopped"} ${daemonLabel(daemon)}`,
|
|
162
185
|
);
|
|
163
186
|
void this.#refresh();
|
|
164
187
|
} catch (error) {
|
|
165
|
-
this.#setStatus(
|
|
166
|
-
chalk.red(`${verb} ${name} failed: ${error instanceof Error ? error.message : String(error)}`),
|
|
167
|
-
);
|
|
188
|
+
this.#setStatus("error", `${verb} ${name} failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
168
189
|
}
|
|
169
190
|
}
|
|
170
191
|
|
|
@@ -176,7 +197,7 @@ export class PsTopComponent implements Component {
|
|
|
176
197
|
this.#view = "info";
|
|
177
198
|
this.#ui.requestRender();
|
|
178
199
|
} catch (error) {
|
|
179
|
-
this.#setStatus(
|
|
200
|
+
this.#setStatus("error", error instanceof Error ? error.message : String(error));
|
|
180
201
|
}
|
|
181
202
|
}
|
|
182
203
|
|
|
@@ -186,6 +207,7 @@ export class PsTopComponent implements Component {
|
|
|
186
207
|
this.#view = "logs";
|
|
187
208
|
this.#logsLines = [];
|
|
188
209
|
this.#logsState = "";
|
|
210
|
+
this.#logsError = undefined;
|
|
189
211
|
const poll = async (): Promise<void> => {
|
|
190
212
|
const current = this.#flat[this.#selected];
|
|
191
213
|
if (this.#disposed || this.#view !== "logs" || !current) return;
|
|
@@ -197,9 +219,11 @@ export class PsTopComponent implements Component {
|
|
|
197
219
|
);
|
|
198
220
|
this.#logsLines = result.terminalRows ?? result.text.replace(/\n$/, "").split("\n");
|
|
199
221
|
this.#logsState = result.state;
|
|
222
|
+
this.#logsError = undefined;
|
|
200
223
|
this.#ui.requestRender();
|
|
201
224
|
} catch (error) {
|
|
202
|
-
this.#
|
|
225
|
+
this.#logsError = error instanceof Error ? error.message : String(error);
|
|
226
|
+
this.#logsLines = [chalk.red(this.#logsError)];
|
|
203
227
|
this.#ui.requestRender();
|
|
204
228
|
}
|
|
205
229
|
};
|
|
@@ -236,17 +260,20 @@ export class PsTopComponent implements Component {
|
|
|
236
260
|
}
|
|
237
261
|
if (matchesKey(data, "up") || data === "k") this.#moveSelection(-1);
|
|
238
262
|
else if (matchesKey(data, "down") || data === "j") this.#moveSelection(1);
|
|
239
|
-
else if (data === "a")
|
|
240
|
-
|
|
241
|
-
this.#setStatus(chalk.dim(this.#all ? "Showing all scopes" : "Showing current scope"));
|
|
242
|
-
void this.#refresh();
|
|
243
|
-
} else if (matchesKey(data, "enter") || data === "i") void this.#openInfo();
|
|
263
|
+
else if (data === "a") this.#toggleAll();
|
|
264
|
+
else if (matchesKey(data, "enter") || data === "i") void this.#openInfo();
|
|
244
265
|
else if (data === "l") this.#openLogs();
|
|
245
266
|
else if (data === "s") void this.#act("stop");
|
|
246
267
|
else if (data === "x") void this.#act("kill");
|
|
247
268
|
else if (data === "r") void this.#act("restart");
|
|
248
269
|
}
|
|
249
270
|
|
|
271
|
+
#toggleAll(): void {
|
|
272
|
+
this.#all = !this.#all;
|
|
273
|
+
this.#setStatus("muted", this.#all ? "Showing all scopes" : "Showing current scope");
|
|
274
|
+
void this.#refresh();
|
|
275
|
+
}
|
|
276
|
+
|
|
250
277
|
#moveSelection(delta: number): void {
|
|
251
278
|
if (this.#flat.length === 0) return;
|
|
252
279
|
this.#selected = Math.max(0, Math.min(this.#flat.length - 1, this.#selected + delta));
|
|
@@ -254,6 +281,340 @@ export class PsTopComponent implements Component {
|
|
|
254
281
|
this.#ui.requestRender();
|
|
255
282
|
}
|
|
256
283
|
|
|
284
|
+
// -- native --------------------------------------------------------------
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Pointer actions: a click selects a process, a double click opens its info
|
|
288
|
+
* (Enter); the scope control switches between the current and all scopes;
|
|
289
|
+
* the action bar runs the same code as the keys, except that a pointer
|
|
290
|
+
* `Kill` asks first (the `x` key stays immediate).
|
|
291
|
+
*/
|
|
292
|
+
handleNativeEvent(event: NativeUiEvent): void {
|
|
293
|
+
if (event.type === "action") {
|
|
294
|
+
this.#nativeAction(event.act);
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
if (event.type !== "select" && event.type !== "activate") return;
|
|
298
|
+
if (event.item === "current" || event.item === "all") {
|
|
299
|
+
if ((event.item === "all") !== this.#all) this.#toggleAll();
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
if (this.#view !== "table") return;
|
|
303
|
+
const index = this.#flat.findIndex(entry => stableKey(flatKey(entry)) === event.item);
|
|
304
|
+
if (index < 0) return;
|
|
305
|
+
this.#selected = index;
|
|
306
|
+
this.#selectedKey = flatKey(this.#flat[index]);
|
|
307
|
+
this.#killConfirm = undefined;
|
|
308
|
+
if (event.type === "activate") void this.#openInfo();
|
|
309
|
+
else this.#ui.requestRender();
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
#nativeAction(act: string): void {
|
|
313
|
+
switch (act) {
|
|
314
|
+
case "info":
|
|
315
|
+
void this.#openInfo();
|
|
316
|
+
return;
|
|
317
|
+
case "logs":
|
|
318
|
+
this.#openLogs();
|
|
319
|
+
return;
|
|
320
|
+
case "stop":
|
|
321
|
+
case "restart":
|
|
322
|
+
void this.#act(act);
|
|
323
|
+
return;
|
|
324
|
+
case "kill":
|
|
325
|
+
this.#killConfirm = this.#selectedKey;
|
|
326
|
+
this.#ui.requestRender();
|
|
327
|
+
return;
|
|
328
|
+
case "kill-confirm":
|
|
329
|
+
this.#killConfirm = undefined;
|
|
330
|
+
void this.#act("kill");
|
|
331
|
+
return;
|
|
332
|
+
case "kill-cancel":
|
|
333
|
+
this.#killConfirm = undefined;
|
|
334
|
+
this.#ui.requestRender();
|
|
335
|
+
return;
|
|
336
|
+
case "back":
|
|
337
|
+
this.#closeView();
|
|
338
|
+
return;
|
|
339
|
+
case "quit":
|
|
340
|
+
this.#done.resolve();
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* The process monitor as a native page: a head (title, counts, the scope
|
|
347
|
+
* control, freshness, close), one section per broker scope with a
|
|
348
|
+
* selectable process list, the transient status, and an action bar that
|
|
349
|
+
* mirrors the keys. Info and logs replace the list.
|
|
350
|
+
*/
|
|
351
|
+
describe(): NativeNode {
|
|
352
|
+
const statusVisible = Date.now() - this.#statusAt < STATUS_TTL_MS;
|
|
353
|
+
return this.#native.get(
|
|
354
|
+
[
|
|
355
|
+
this.#view,
|
|
356
|
+
this.#reports,
|
|
357
|
+
this.#selected,
|
|
358
|
+
this.#all,
|
|
359
|
+
this.#lastRefresh,
|
|
360
|
+
this.#info,
|
|
361
|
+
this.#logsLines,
|
|
362
|
+
this.#logsState,
|
|
363
|
+
this.#logsError,
|
|
364
|
+
statusVisible,
|
|
365
|
+
this.#statusText,
|
|
366
|
+
this.#statusTone,
|
|
367
|
+
this.#killConfirm,
|
|
368
|
+
],
|
|
369
|
+
() => {
|
|
370
|
+
const body =
|
|
371
|
+
this.#view === "info"
|
|
372
|
+
? this.#describeInfo()
|
|
373
|
+
: this.#view === "logs"
|
|
374
|
+
? this.#describeLogs()
|
|
375
|
+
: this.#describeTable();
|
|
376
|
+
return col(
|
|
377
|
+
compact([
|
|
378
|
+
this.#describeHead(),
|
|
379
|
+
body,
|
|
380
|
+
statusVisible &&
|
|
381
|
+
this.#statusText !== "" &&
|
|
382
|
+
keyed(
|
|
383
|
+
text([span(this.#statusText, this.#statusTone)], { wrap: "word", role: "omp.app.status" }),
|
|
384
|
+
"status",
|
|
385
|
+
),
|
|
386
|
+
this.#describeActions(),
|
|
387
|
+
]),
|
|
388
|
+
{ role: "omp.app.ps", gap: "md" },
|
|
389
|
+
);
|
|
390
|
+
},
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
#describeHead(): NativeNode {
|
|
395
|
+
const entry = this.#flat[this.#selected];
|
|
396
|
+
const left: NativeNode[] = [];
|
|
397
|
+
if (this.#view === "table") {
|
|
398
|
+
const running = this.#flat.filter(flat => !TERMINAL_STATES[flat.row.snapshot.state]).length;
|
|
399
|
+
const stopped = this.#flat.length - running;
|
|
400
|
+
left.push(
|
|
401
|
+
text("Processes", { role: "omp.app.title" }),
|
|
402
|
+
text(
|
|
403
|
+
[
|
|
404
|
+
span(`${running} running`, running > 0 ? "success" : "muted"),
|
|
405
|
+
...(stopped > 0 ? [span(` · ${stopped} stopped`, "muted")] : []),
|
|
406
|
+
span(` · ${this.#reports.length} scope${this.#reports.length === 1 ? "" : "s"}`, "muted"),
|
|
407
|
+
],
|
|
408
|
+
{ truncate: "end" },
|
|
409
|
+
),
|
|
410
|
+
);
|
|
411
|
+
} else {
|
|
412
|
+
left.push(
|
|
413
|
+
node("icon", {
|
|
414
|
+
name: "back",
|
|
415
|
+
role: "omp.app.ibtn",
|
|
416
|
+
title: "Back esc",
|
|
417
|
+
aria: "Back",
|
|
418
|
+
actions: { click: "back" },
|
|
419
|
+
}),
|
|
420
|
+
text(
|
|
421
|
+
this.#view === "logs" ? `Logs · ${entry?.row.snapshot.name ?? "?"}` : (entry?.row.snapshot.name ?? "?"),
|
|
422
|
+
{
|
|
423
|
+
role: "omp.app.title",
|
|
424
|
+
truncate: "end",
|
|
425
|
+
},
|
|
426
|
+
),
|
|
427
|
+
);
|
|
428
|
+
const daemon = this.#view === "info" ? this.#info?.daemon : entry?.row.snapshot;
|
|
429
|
+
if (daemon) left.push(node("badge", { text: stateLabel(daemon), tone: daemonTone(daemon) }));
|
|
430
|
+
if (this.#view === "logs" && this.#logsState) left.push(text([span(this.#logsState, "muted")]));
|
|
431
|
+
}
|
|
432
|
+
const right: NativeNode[] = [];
|
|
433
|
+
if (this.#view === "table") {
|
|
434
|
+
right.push(
|
|
435
|
+
node(
|
|
436
|
+
"tabs",
|
|
437
|
+
{
|
|
438
|
+
items: [
|
|
439
|
+
{
|
|
440
|
+
id: "current",
|
|
441
|
+
label:
|
|
442
|
+
this.#target.dir !== undefined || this.#target.global !== undefined
|
|
443
|
+
? "Target"
|
|
444
|
+
: "This project",
|
|
445
|
+
},
|
|
446
|
+
{ id: "all", label: "All scopes" },
|
|
447
|
+
],
|
|
448
|
+
active: this.#all ? "all" : "current",
|
|
449
|
+
role: "omp.app.seg",
|
|
450
|
+
},
|
|
451
|
+
undefined,
|
|
452
|
+
"scope",
|
|
453
|
+
),
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
right.push(
|
|
457
|
+
this.#lastRefresh
|
|
458
|
+
? row(
|
|
459
|
+
[text([span("updated", "dim")]), elapsed(Date.now() - this.#lastRefresh), text([span("ago", "dim")])],
|
|
460
|
+
{
|
|
461
|
+
gap: "xs",
|
|
462
|
+
align: "center",
|
|
463
|
+
role: "omp.app.fresh",
|
|
464
|
+
},
|
|
465
|
+
)
|
|
466
|
+
: row([node("spinner", { style: "dots" }), text([span("updating", "dim")])], {
|
|
467
|
+
gap: "xs",
|
|
468
|
+
align: "center",
|
|
469
|
+
role: "omp.app.fresh",
|
|
470
|
+
}),
|
|
471
|
+
node("icon", { name: "x", role: "omp.app.ibtn", title: "Quit q", aria: "Quit", actions: { click: "quit" } }),
|
|
472
|
+
);
|
|
473
|
+
return keyed(
|
|
474
|
+
row(
|
|
475
|
+
[
|
|
476
|
+
row(left, { gap: "sm", align: "center", role: "omp.app.where" }),
|
|
477
|
+
row(right, { gap: "md", align: "center", role: "omp.app.tools" }),
|
|
478
|
+
],
|
|
479
|
+
{ justify: "between", align: "center", role: "omp.app.head" },
|
|
480
|
+
),
|
|
481
|
+
"head",
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/** The action bar for the view, or the kill confirmation that replaces it. */
|
|
486
|
+
#describeActions(): NativeNode {
|
|
487
|
+
const entry = this.#flat[this.#selected];
|
|
488
|
+
if (
|
|
489
|
+
this.#view === "table" &&
|
|
490
|
+
entry &&
|
|
491
|
+
this.#killConfirm === this.#selectedKey &&
|
|
492
|
+
this.#killConfirm !== undefined
|
|
493
|
+
) {
|
|
494
|
+
const pid = entry.row.snapshot.pid;
|
|
495
|
+
return keyed(
|
|
496
|
+
row(
|
|
497
|
+
[
|
|
498
|
+
text(
|
|
499
|
+
[
|
|
500
|
+
span(`Kill ${entry.row.snapshot.name}${pid === undefined ? "" : ` (pid ${pid})`}?`, "strong"),
|
|
501
|
+
span(" It stops at once, without cleanup.", "muted"),
|
|
502
|
+
],
|
|
503
|
+
{ truncate: "end", grow: 1 },
|
|
504
|
+
),
|
|
505
|
+
actionButton("Cancel", "kill-cancel"),
|
|
506
|
+
actionButton("Kill", "kill-confirm", { tone: "error" }),
|
|
507
|
+
],
|
|
508
|
+
{ gap: "sm", align: "center", role: "omp.app.confirm", tone: "error" },
|
|
509
|
+
),
|
|
510
|
+
"actions",
|
|
511
|
+
);
|
|
512
|
+
}
|
|
513
|
+
if (this.#view !== "table") {
|
|
514
|
+
return actionBar([
|
|
515
|
+
actionButton("Back", "back", { keys: "escape", tone: "accent" }),
|
|
516
|
+
...(this.#view === "info" ? [actionButton("Logs", "logs")] : []),
|
|
517
|
+
]);
|
|
518
|
+
}
|
|
519
|
+
if (!entry) return actionBar([null, actionButton("Quit", "quit", { keys: "q" })]);
|
|
520
|
+
return actionBar([
|
|
521
|
+
actionButton("Info", "info", { keys: "enter", tone: "accent" }),
|
|
522
|
+
actionButton("Logs", "logs", { keys: "l" }),
|
|
523
|
+
actionButton("Restart", "restart", { keys: "r" }),
|
|
524
|
+
actionButton("Stop", "stop", { keys: "s" }),
|
|
525
|
+
actionButton("Kill", "kill", { keys: "x", tone: "error", title: "Kill the process (asks first)" }),
|
|
526
|
+
null,
|
|
527
|
+
actionButton("Quit", "quit", { keys: "q" }),
|
|
528
|
+
]);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
#describeTable(): NativeNode {
|
|
532
|
+
if (this.#reports.length === 0) {
|
|
533
|
+
return keyed(
|
|
534
|
+
col(
|
|
535
|
+
[
|
|
536
|
+
text("No broker scopes", { role: "omp.app.empty-title" }),
|
|
537
|
+
text([
|
|
538
|
+
span("No omp process broker runs here. ", "muted"),
|
|
539
|
+
span(this.#all ? "Nothing runs anywhere." : "Show every scope with ", "muted"),
|
|
540
|
+
...(this.#all ? [] : [span("a", "key"), span(".", "muted")]),
|
|
541
|
+
]),
|
|
542
|
+
],
|
|
543
|
+
{ gap: "xs", align: "center", role: "omp.app.empty" },
|
|
544
|
+
),
|
|
545
|
+
"empty",
|
|
546
|
+
);
|
|
547
|
+
}
|
|
548
|
+
const selected = this.#flat[this.#selected];
|
|
549
|
+
const sections = this.#reports.map(report =>
|
|
550
|
+
node(
|
|
551
|
+
"section",
|
|
552
|
+
{ head: scopeSpans(report.scope), role: "omp.app.ps.scope" },
|
|
553
|
+
[
|
|
554
|
+
node(
|
|
555
|
+
"list",
|
|
556
|
+
{
|
|
557
|
+
selected:
|
|
558
|
+
selected && selected.scope.runtimeDir === report.scope.runtimeDir
|
|
559
|
+
? stableKey(flatKey(selected))
|
|
560
|
+
: null,
|
|
561
|
+
empty: "No processes",
|
|
562
|
+
role: "omp.ps.processes",
|
|
563
|
+
},
|
|
564
|
+
report.daemons.map(daemon => describeProcess(report.scope, daemon)),
|
|
565
|
+
),
|
|
566
|
+
],
|
|
567
|
+
stableKey(report.scope.runtimeDir),
|
|
568
|
+
),
|
|
569
|
+
);
|
|
570
|
+
return keyed(col(sections, { gap: "lg", grow: 1, role: "omp.app.ps.scopes" }), "scopes");
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
#describeInfo(): NativeNode {
|
|
574
|
+
const info = this.#info;
|
|
575
|
+
if (!info) {
|
|
576
|
+
return keyed(
|
|
577
|
+
row([node("spinner", { style: "dots" }), text([span("Loading…", "muted")])], { gap: "sm" }),
|
|
578
|
+
"info",
|
|
579
|
+
);
|
|
580
|
+
}
|
|
581
|
+
const { daemon, spec } = info;
|
|
582
|
+
const items: { k: string; v: TspText }[] = [
|
|
583
|
+
{ k: "Command", v: [span(collapseCommand(formatCommand(spec)), "mono")] },
|
|
584
|
+
{ k: "Directory", v: [span(spec.cwd, "path")] },
|
|
585
|
+
];
|
|
586
|
+
if (daemon.pid !== undefined && !TERMINAL_STATES[daemon.state])
|
|
587
|
+
items.push({ k: "PID", v: [span(String(daemon.pid), "num")] });
|
|
588
|
+
if (daemon.exitReason) items.push({ k: "Exit", v: [span(daemon.exitReason, "error")] });
|
|
589
|
+
items.push({ k: "Restarts", v: `${daemon.restartCount} (policy ${spec.restart})` });
|
|
590
|
+
items.push({ k: "Owner", v: daemon.owner ?? "—" });
|
|
591
|
+
const flags = [spec.pty && "pty", spec.persist && "persist", spec.detached && "detached"].filter(Boolean);
|
|
592
|
+
items.push({ k: "Flags", v: flags.length > 0 ? flags.join(" · ") : "—" });
|
|
593
|
+
const body: NativeNode[] = [];
|
|
594
|
+
if (!TERMINAL_STATES[daemon.state]) {
|
|
595
|
+
body.push(
|
|
596
|
+
row([text([span("Up for", "muted")]), elapsed(Date.now() - daemon.startedAt)], {
|
|
597
|
+
gap: "xs",
|
|
598
|
+
role: "omp.app.fresh",
|
|
599
|
+
}),
|
|
600
|
+
);
|
|
601
|
+
}
|
|
602
|
+
body.push(node("kv", { items, layout: "grid" }));
|
|
603
|
+
return keyed(col(body, { role: "omp.ps.info", gap: "md" }), "info");
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
#describeLogs(): NativeNode {
|
|
607
|
+
if (this.#logsError) {
|
|
608
|
+
return keyed(text([span(this.#logsError, "error mono")], { wrap: "word", role: "omp.ps.logs" }), "logs");
|
|
609
|
+
}
|
|
610
|
+
return node(
|
|
611
|
+
"ansi",
|
|
612
|
+
{ text: this.#logsLines.join("\n"), follow: true, role: "omp.ps.logs", grow: 1 },
|
|
613
|
+
undefined,
|
|
614
|
+
"logs",
|
|
615
|
+
);
|
|
616
|
+
}
|
|
617
|
+
|
|
257
618
|
// -- render ------------------------------------------------------------
|
|
258
619
|
|
|
259
620
|
render(width: number): readonly string[] {
|
|
@@ -407,6 +768,76 @@ function flatKey(entry: FlatRow): string {
|
|
|
407
768
|
return `${entry.scope.runtimeDir}\u0000${entry.row.snapshot.name}`;
|
|
408
769
|
}
|
|
409
770
|
|
|
771
|
+
/** Semantic tone of a process state (the ANSI STATE cell's colour). */
|
|
772
|
+
function daemonTone(snapshot: DaemonSnapshot): TspTone {
|
|
773
|
+
if (snapshot.state === "ready" || snapshot.state === "running") return "success";
|
|
774
|
+
if (snapshot.state === "failed") return "error";
|
|
775
|
+
return TERMINAL_STATES[snapshot.state] ? "muted" : "warning";
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
/** Scope heading spans, e.g. `project /work/pi — broker pid 1234`. */
|
|
779
|
+
function scopeSpans(scope: PsScope): TspSpan[] {
|
|
780
|
+
const spans =
|
|
781
|
+
scope.kind === "global"
|
|
782
|
+
? [span("global "), span(scope.service ?? path.basename(scope.runtimeDir), "strong")]
|
|
783
|
+
: [span("project "), span(scope.projectDir ?? path.basename(scope.runtimeDir), "strong path")];
|
|
784
|
+
spans.push(span(" — ", "dim"));
|
|
785
|
+
spans.push(
|
|
786
|
+
scope.brokerPid !== undefined
|
|
787
|
+
? span(`broker pid ${scope.brokerPid}`, "success")
|
|
788
|
+
: span("broker not running", "dim"),
|
|
789
|
+
);
|
|
790
|
+
return spans;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
/** A state as the table shows it: `ready`, `exited(143)`. */
|
|
794
|
+
function stateLabel(snapshot: DaemonSnapshot): string {
|
|
795
|
+
return TERMINAL_STATES[snapshot.state] && snapshot.exitCode !== undefined
|
|
796
|
+
? `${snapshot.state}(${snapshot.exitCode})`
|
|
797
|
+
: snapshot.state;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
/** Status icon of a process state (tinted by {@link daemonTone}). */
|
|
801
|
+
const STATE_ICON: Record<TspTone, string> = {
|
|
802
|
+
success: "check",
|
|
803
|
+
error: "x",
|
|
804
|
+
muted: "stop",
|
|
805
|
+
warning: "clock",
|
|
806
|
+
neutral: "activity",
|
|
807
|
+
accent: "activity",
|
|
808
|
+
info: "activity",
|
|
809
|
+
pending: "clock",
|
|
810
|
+
user: "user",
|
|
811
|
+
};
|
|
812
|
+
|
|
813
|
+
/** One selectable process row: name, state/pid/uptime/restarts/flags, and the launch command. */
|
|
814
|
+
function describeProcess(scope: PsScope, daemon: PsDaemonRow): NativeNode {
|
|
815
|
+
const { snapshot } = daemon;
|
|
816
|
+
const terminal = TERMINAL_STATES[snapshot.state] === true;
|
|
817
|
+
const state = stateLabel(snapshot);
|
|
818
|
+
const meta = [
|
|
819
|
+
snapshot.pid !== undefined && !terminal ? `pid ${snapshot.pid}` : undefined,
|
|
820
|
+
terminal ? undefined : formatDuration(Date.now() - snapshot.startedAt),
|
|
821
|
+
`${snapshot.restartCount} restart${snapshot.restartCount === 1 ? "" : "s"}`,
|
|
822
|
+
flagsCell(daemon) || undefined,
|
|
823
|
+
].filter(part => part !== undefined);
|
|
824
|
+
const command = collapseCommand(daemon.command);
|
|
825
|
+
const tone = daemonTone(snapshot);
|
|
826
|
+
return node(
|
|
827
|
+
"item",
|
|
828
|
+
{
|
|
829
|
+
label: [span(snapshot.name, terminal ? "dim" : "strong")],
|
|
830
|
+
detail: command ? [span(command, "mono muted")] : undefined,
|
|
831
|
+
value: [span(state, tone === "muted" ? "dim" : tone), span(` · ${meta.join(" · ")}`, "muted")],
|
|
832
|
+
icon: STATE_ICON[tone],
|
|
833
|
+
tone,
|
|
834
|
+
title: daemonLabel(snapshot),
|
|
835
|
+
},
|
|
836
|
+
undefined,
|
|
837
|
+
stableKey(flatKey({ scope, row: daemon })),
|
|
838
|
+
);
|
|
839
|
+
}
|
|
840
|
+
|
|
410
841
|
/** Run the fullscreen interactive process monitor until the user quits. */
|
|
411
842
|
export async function runPsTop(options: PsTopOptions, host: PsTopHost): Promise<void> {
|
|
412
843
|
const ui = new TUI(new ProcessTerminal());
|
|
@@ -68,6 +68,7 @@ export async function selectSession<T extends SessionSelectorEntry>(
|
|
|
68
68
|
allSessions: options.allSessions,
|
|
69
69
|
getTerminalRows: () => ui.terminal.rows,
|
|
70
70
|
fillHeight: true,
|
|
71
|
+
standalone: true,
|
|
71
72
|
title: options.title,
|
|
72
73
|
scopeLabel: options.scopeLabel,
|
|
73
74
|
showCwd: options.showCwd,
|
|
@@ -17,5 +17,9 @@ export async function selectSetupModel(
|
|
|
17
17
|
items: SelectItem[],
|
|
18
18
|
currentValue: string,
|
|
19
19
|
): Promise<string | null> {
|
|
20
|
-
return selectStandaloneItem(title, items, {
|
|
20
|
+
return selectStandaloneItem(title, items, {
|
|
21
|
+
currentValue,
|
|
22
|
+
maxVisible: 10,
|
|
23
|
+
picker: { icon: "model", noun: "models" },
|
|
24
|
+
});
|
|
21
25
|
}
|