@pentoshi/clai 2.0.62 → 3.0.0
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 +262 -368
- package/dist/agent/context-manager.d.ts +5 -0
- package/dist/agent/context-manager.js +14 -2
- package/dist/agent/context-manager.js.map +1 -1
- package/dist/agent/events.d.ts +4 -1
- package/dist/agent/runner.js +150 -83
- package/dist/agent/runner.js.map +1 -1
- package/dist/agent/tool-call-parser.d.ts +15 -0
- package/dist/agent/tool-call-parser.js +171 -2
- package/dist/agent/tool-call-parser.js.map +1 -1
- package/dist/app/adapters/agent-event-adapter.d.ts +29 -0
- package/dist/app/adapters/agent-event-adapter.js +143 -0
- package/dist/app/adapters/agent-event-adapter.js.map +1 -0
- package/dist/app/adapters/current-agent-adapter.d.ts +7 -0
- package/dist/app/adapters/current-agent-adapter.js +27 -0
- package/dist/app/adapters/current-agent-adapter.js.map +1 -0
- package/dist/app/adapters/current-jobs-adapter.d.ts +4 -0
- package/dist/app/adapters/current-jobs-adapter.js +13 -0
- package/dist/app/adapters/current-jobs-adapter.js.map +1 -0
- package/dist/app/adapters/current-store-adapter.d.ts +3 -0
- package/dist/app/adapters/current-store-adapter.js +22 -0
- package/dist/app/adapters/current-store-adapter.js.map +1 -0
- package/dist/app/adapters/current-terminal-adapter.d.ts +9 -0
- package/dist/app/adapters/current-terminal-adapter.js +31 -0
- package/dist/app/adapters/current-terminal-adapter.js.map +1 -0
- package/dist/app/adapters/current-updates-adapter.d.ts +7 -0
- package/dist/app/adapters/current-updates-adapter.js +31 -0
- package/dist/app/adapters/current-updates-adapter.js.map +1 -0
- package/dist/app/adapters/in-memory-clipboard-adapter.d.ts +10 -0
- package/dist/app/adapters/in-memory-clipboard-adapter.js +20 -0
- package/dist/app/adapters/in-memory-clipboard-adapter.js.map +1 -0
- package/dist/app/commands/command.d.ts +24 -0
- package/dist/app/commands/command.js +4 -0
- package/dist/app/commands/command.js.map +1 -0
- package/dist/app/commands/registry.d.ts +45 -0
- package/dist/app/commands/registry.js +164 -0
- package/dist/app/commands/registry.js.map +1 -0
- package/dist/app/controllers/disposable.d.ts +15 -0
- package/dist/app/controllers/disposable.js +38 -0
- package/dist/app/controllers/disposable.js.map +1 -0
- package/dist/app/controllers/job-controller.d.ts +22 -0
- package/dist/app/controllers/job-controller.js +35 -0
- package/dist/app/controllers/job-controller.js.map +1 -0
- package/dist/app/controllers/plan-controller.d.ts +31 -0
- package/dist/app/controllers/plan-controller.js +69 -0
- package/dist/app/controllers/plan-controller.js.map +1 -0
- package/dist/app/controllers/session-controller.d.ts +167 -0
- package/dist/app/controllers/session-controller.js +467 -0
- package/dist/app/controllers/session-controller.js.map +1 -0
- package/dist/app/controllers/turn-controller.d.ts +52 -0
- package/dist/app/controllers/turn-controller.js +118 -0
- package/dist/app/controllers/turn-controller.js.map +1 -0
- package/dist/app/events/app-event.d.ts +118 -0
- package/dist/app/events/app-event.js +25 -0
- package/dist/app/events/app-event.js.map +1 -0
- package/dist/app/events/event-buffer.d.ts +51 -0
- package/dist/app/events/event-buffer.js +109 -0
- package/dist/app/events/event-buffer.js.map +1 -0
- package/dist/app/events/sequencer.d.ts +32 -0
- package/dist/app/events/sequencer.js +55 -0
- package/dist/app/events/sequencer.js.map +1 -0
- package/dist/app/ports/agent-port.d.ts +29 -0
- package/dist/app/ports/agent-port.js +2 -0
- package/dist/app/ports/agent-port.js.map +1 -0
- package/dist/app/ports/clipboard-port.d.ts +9 -0
- package/dist/app/ports/clipboard-port.js +2 -0
- package/dist/app/ports/clipboard-port.js.map +1 -0
- package/dist/app/ports/confirm-port.d.ts +17 -0
- package/dist/app/ports/confirm-port.js +2 -0
- package/dist/app/ports/confirm-port.js.map +1 -0
- package/dist/app/ports/jobs-port.d.ts +18 -0
- package/dist/app/ports/jobs-port.js +2 -0
- package/dist/app/ports/jobs-port.js.map +1 -0
- package/dist/app/ports/persistence-port.d.ts +21 -0
- package/dist/app/ports/persistence-port.js +2 -0
- package/dist/app/ports/persistence-port.js.map +1 -0
- package/dist/app/ports/secret-port.d.ts +12 -0
- package/dist/app/ports/secret-port.js +2 -0
- package/dist/app/ports/secret-port.js.map +1 -0
- package/dist/app/ports/terminal-port.d.ts +18 -0
- package/dist/app/ports/terminal-port.js +2 -0
- package/dist/app/ports/terminal-port.js.map +1 -0
- package/dist/app/ports/updates-port.d.ts +12 -0
- package/dist/app/ports/updates-port.js +2 -0
- package/dist/app/ports/updates-port.js.map +1 -0
- package/dist/commands/doctor.js +9 -0
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/update.js +1 -1
- package/dist/commands/update.js.map +1 -1
- package/dist/index.js +9 -6
- package/dist/index.js.map +1 -1
- package/dist/llm/router.js +4 -2
- package/dist/llm/router.js.map +1 -1
- package/dist/prompts/index.d.ts +1 -1
- package/dist/prompts/index.js +5 -3
- package/dist/prompts/index.js.map +1 -1
- package/dist/repl/slash-commands.js +1 -1
- package/dist/repl/slash-commands.js.map +1 -1
- package/dist/repl.js +35 -107
- package/dist/repl.js.map +1 -1
- package/dist/store/config.js +3 -1
- package/dist/store/config.js.map +1 -1
- package/dist/store/history.d.ts +26 -2
- package/dist/store/history.js +383 -72
- package/dist/store/history.js.map +1 -1
- package/dist/store/logs.js +3 -3
- package/dist/store/logs.js.map +1 -1
- package/dist/store/paths.d.ts +6 -0
- package/dist/store/paths.js +38 -0
- package/dist/store/paths.js.map +1 -0
- package/dist/store/plan.js +8 -5
- package/dist/store/plan.js.map +1 -1
- package/dist/tools/jobs.js +2 -2
- package/dist/tools/jobs.js.map +1 -1
- package/dist/tools/registry.js +117 -46
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/shell.js +2 -2
- package/dist/tools/shell.js.map +1 -1
- package/dist/tui/state.js +20 -17
- package/dist/tui/state.js.map +1 -1
- package/dist/tui-v2/actions/action-id.d.ts +14 -0
- package/dist/tui-v2/actions/action-id.js +109 -0
- package/dist/tui-v2/actions/action-id.js.map +1 -0
- package/dist/tui-v2/actions/action-router.d.ts +18 -0
- package/dist/tui-v2/actions/action-router.js +62 -0
- package/dist/tui-v2/actions/action-router.js.map +1 -0
- package/dist/tui-v2/actions/chord-from-key.d.ts +26 -0
- package/dist/tui-v2/actions/chord-from-key.js +45 -0
- package/dist/tui-v2/actions/chord-from-key.js.map +1 -0
- package/dist/tui-v2/actions/keymap.d.ts +24 -0
- package/dist/tui-v2/actions/keymap.js +134 -0
- package/dist/tui-v2/actions/keymap.js.map +1 -0
- package/dist/tui-v2/app/App.d.ts +13 -0
- package/dist/tui-v2/app/App.js +320 -0
- package/dist/tui-v2/app/App.js.map +1 -0
- package/dist/tui-v2/app/command-handlers.d.ts +8 -0
- package/dist/tui-v2/app/command-handlers.js +66 -0
- package/dist/tui-v2/app/command-handlers.js.map +1 -0
- package/dist/tui-v2/app/commands/config-commands.d.ts +14 -0
- package/dist/tui-v2/app/commands/config-commands.js +161 -0
- package/dist/tui-v2/app/commands/config-commands.js.map +1 -0
- package/dist/tui-v2/app/commands/key-commands.d.ts +9 -0
- package/dist/tui-v2/app/commands/key-commands.js +263 -0
- package/dist/tui-v2/app/commands/key-commands.js.map +1 -0
- package/dist/tui-v2/app/commands/picker-commands.d.ts +24 -0
- package/dist/tui-v2/app/commands/picker-commands.js +423 -0
- package/dist/tui-v2/app/commands/picker-commands.js.map +1 -0
- package/dist/tui-v2/app/commands/session-commands.d.ts +19 -0
- package/dist/tui-v2/app/commands/session-commands.js +162 -0
- package/dist/tui-v2/app/commands/session-commands.js.map +1 -0
- package/dist/tui-v2/app/plan-lifecycle.d.ts +16 -0
- package/dist/tui-v2/app/plan-lifecycle.js +59 -0
- package/dist/tui-v2/app/plan-lifecycle.js.map +1 -0
- package/dist/tui-v2/app/providers.d.ts +17 -0
- package/dist/tui-v2/app/providers.js +32 -0
- package/dist/tui-v2/app/providers.js.map +1 -0
- package/dist/tui-v2/bootstrap/capabilities.d.ts +35 -0
- package/dist/tui-v2/bootstrap/capabilities.js +93 -0
- package/dist/tui-v2/bootstrap/capabilities.js.map +1 -0
- package/dist/tui-v2/bootstrap/composition-root.d.ts +85 -0
- package/dist/tui-v2/bootstrap/composition-root.js +131 -0
- package/dist/tui-v2/bootstrap/composition-root.js.map +1 -0
- package/dist/tui-v2/bootstrap/disable-native-selection.d.ts +11 -0
- package/dist/tui-v2/bootstrap/disable-native-selection.js +13 -0
- package/dist/tui-v2/bootstrap/disable-native-selection.js.map +1 -0
- package/dist/tui-v2/bootstrap/lifecycle.d.ts +62 -0
- package/dist/tui-v2/bootstrap/lifecycle.js +123 -0
- package/dist/tui-v2/bootstrap/lifecycle.js.map +1 -0
- package/dist/tui-v2/bootstrap/osc52-clipboard.d.ts +28 -0
- package/dist/tui-v2/bootstrap/osc52-clipboard.js +44 -0
- package/dist/tui-v2/bootstrap/osc52-clipboard.js.map +1 -0
- package/dist/tui-v2/bootstrap/overlay-ports.d.ts +12 -0
- package/dist/{tui/confirm.js → tui-v2/bootstrap/overlay-ports.js} +17 -25
- package/dist/tui-v2/bootstrap/overlay-ports.js.map +1 -0
- package/dist/tui-v2/bootstrap/pager-export.d.ts +24 -0
- package/dist/tui-v2/bootstrap/pager-export.js +87 -0
- package/dist/tui-v2/bootstrap/pager-export.js.map +1 -0
- package/dist/tui-v2/bootstrap/start-tui-v2.d.ts +15 -0
- package/dist/tui-v2/bootstrap/start-tui-v2.js +95 -0
- package/dist/tui-v2/bootstrap/start-tui-v2.js.map +1 -0
- package/dist/tui-v2/bootstrap/ui-selection.d.ts +30 -0
- package/dist/tui-v2/bootstrap/ui-selection.js +59 -0
- package/dist/tui-v2/bootstrap/ui-selection.js.map +1 -0
- package/dist/tui-v2/components/completion/completion-menu.d.ts +23 -0
- package/dist/tui-v2/components/completion/completion-menu.js +84 -0
- package/dist/tui-v2/components/completion/completion-menu.js.map +1 -0
- package/dist/tui-v2/components/jobs/jobs-panel.d.ts +16 -0
- package/dist/tui-v2/components/jobs/jobs-panel.js +92 -0
- package/dist/tui-v2/components/jobs/jobs-panel.js.map +1 -0
- package/dist/tui-v2/components/modal/confirm-modal.d.ts +21 -0
- package/dist/tui-v2/components/modal/confirm-modal.js +71 -0
- package/dist/tui-v2/components/modal/confirm-modal.js.map +1 -0
- package/dist/tui-v2/components/modal/prompt-actions-modal.d.ts +15 -0
- package/dist/tui-v2/components/modal/prompt-actions-modal.js +80 -0
- package/dist/tui-v2/components/modal/prompt-actions-modal.js.map +1 -0
- package/dist/tui-v2/components/modal/secret-modal.d.ts +24 -0
- package/dist/tui-v2/components/modal/secret-modal.js +50 -0
- package/dist/tui-v2/components/modal/secret-modal.js.map +1 -0
- package/dist/tui-v2/components/overlay/overlay-host.d.ts +17 -0
- package/dist/tui-v2/components/overlay/overlay-host.js +28 -0
- package/dist/tui-v2/components/overlay/overlay-host.js.map +1 -0
- package/dist/tui-v2/components/pager/pager.d.ts +20 -0
- package/dist/tui-v2/components/pager/pager.js +396 -0
- package/dist/tui-v2/components/pager/pager.js.map +1 -0
- package/dist/tui-v2/components/picker/picker.d.ts +17 -0
- package/dist/tui-v2/components/picker/picker.js +222 -0
- package/dist/tui-v2/components/picker/picker.js.map +1 -0
- package/dist/tui-v2/components/plan/plan-view.d.ts +20 -0
- package/dist/tui-v2/components/plan/plan-view.js +116 -0
- package/dist/tui-v2/components/plan/plan-view.js.map +1 -0
- package/dist/tui-v2/components/queue/queue-panel.d.ts +23 -0
- package/dist/tui-v2/components/queue/queue-panel.js +58 -0
- package/dist/tui-v2/components/queue/queue-panel.js.map +1 -0
- package/dist/tui-v2/components/status/status-line.d.ts +27 -0
- package/dist/tui-v2/components/status/status-line.js +158 -0
- package/dist/tui-v2/components/status/status-line.js.map +1 -0
- package/dist/tui-v2/components/toast/toast-host.d.ts +15 -0
- package/dist/tui-v2/components/toast/toast-host.js +48 -0
- package/dist/tui-v2/components/toast/toast-host.js.map +1 -0
- package/dist/tui-v2/components/transcript/assistant-message.d.ts +20 -0
- package/dist/tui-v2/components/transcript/assistant-message.js +35 -0
- package/dist/tui-v2/components/transcript/assistant-message.js.map +1 -0
- package/dist/tui-v2/components/transcript/compacted-row.d.ts +19 -0
- package/dist/tui-v2/components/transcript/compacted-row.js +94 -0
- package/dist/tui-v2/components/transcript/compacted-row.js.map +1 -0
- package/dist/tui-v2/components/transcript/intro-card.d.ts +19 -0
- package/dist/tui-v2/components/transcript/intro-card.js +50 -0
- package/dist/tui-v2/components/transcript/intro-card.js.map +1 -0
- package/dist/tui-v2/components/transcript/linkable-text.d.ts +21 -0
- package/dist/tui-v2/components/transcript/linkable-text.js +46 -0
- package/dist/tui-v2/components/transcript/linkable-text.js.map +1 -0
- package/dist/tui-v2/components/transcript/notice-row.d.ts +14 -0
- package/dist/tui-v2/components/transcript/notice-row.js +40 -0
- package/dist/tui-v2/components/transcript/notice-row.js.map +1 -0
- package/dist/tui-v2/components/transcript/search-bar.d.ts +19 -0
- package/dist/tui-v2/components/transcript/search-bar.js +7 -0
- package/dist/tui-v2/components/transcript/search-bar.js.map +1 -0
- package/dist/tui-v2/components/transcript/thinking-block.d.ts +22 -0
- package/dist/tui-v2/components/transcript/thinking-block.js +27 -0
- package/dist/tui-v2/components/transcript/thinking-block.js.map +1 -0
- package/dist/tui-v2/components/transcript/tool-card.d.ts +26 -0
- package/dist/tui-v2/components/transcript/tool-card.js +175 -0
- package/dist/tui-v2/components/transcript/tool-card.js.map +1 -0
- package/dist/tui-v2/components/transcript/transcript-row.d.ts +25 -0
- package/dist/tui-v2/components/transcript/transcript-row.js +30 -0
- package/dist/tui-v2/components/transcript/transcript-row.js.map +1 -0
- package/dist/tui-v2/components/transcript/transcript-scroll-port.d.ts +52 -0
- package/dist/tui-v2/components/transcript/transcript-scroll-port.js +86 -0
- package/dist/tui-v2/components/transcript/transcript-scroll-port.js.map +1 -0
- package/dist/tui-v2/components/transcript/transcript-view.d.ts +24 -0
- package/dist/tui-v2/components/transcript/transcript-view.js +403 -0
- package/dist/tui-v2/components/transcript/transcript-view.js.map +1 -0
- package/dist/tui-v2/components/transcript/use-click-without-drag.d.ts +13 -0
- package/dist/tui-v2/components/transcript/use-click-without-drag.js +35 -0
- package/dist/tui-v2/components/transcript/use-click-without-drag.js.map +1 -0
- package/dist/tui-v2/components/transcript/use-native-selection-copy.d.ts +10 -0
- package/dist/tui-v2/components/transcript/use-native-selection-copy.js +37 -0
- package/dist/tui-v2/components/transcript/use-native-selection-copy.js.map +1 -0
- package/dist/tui-v2/components/transcript/use-transcript-selection.d.ts +23 -0
- package/dist/tui-v2/components/transcript/use-transcript-selection.js +136 -0
- package/dist/tui-v2/components/transcript/use-transcript-selection.js.map +1 -0
- package/dist/tui-v2/components/transcript/user-message.d.ts +10 -0
- package/dist/tui-v2/components/transcript/user-message.js +23 -0
- package/dist/tui-v2/components/transcript/user-message.js.map +1 -0
- package/dist/tui-v2/composer/arrow-intent.d.ts +23 -0
- package/dist/tui-v2/composer/arrow-intent.js +35 -0
- package/dist/tui-v2/composer/arrow-intent.js.map +1 -0
- package/dist/tui-v2/composer/completion.d.ts +37 -0
- package/dist/tui-v2/composer/completion.js +67 -0
- package/dist/tui-v2/composer/completion.js.map +1 -0
- package/dist/tui-v2/composer/composer-editor.d.ts +33 -0
- package/dist/tui-v2/composer/composer-editor.js +620 -0
- package/dist/tui-v2/composer/composer-editor.js.map +1 -0
- package/dist/tui-v2/composer/composer-height.d.ts +21 -0
- package/dist/tui-v2/composer/composer-height.js +29 -0
- package/dist/tui-v2/composer/composer-height.js.map +1 -0
- package/dist/tui-v2/composer/composer-meta.d.ts +9 -0
- package/dist/tui-v2/composer/composer-meta.js +38 -0
- package/dist/tui-v2/composer/composer-meta.js.map +1 -0
- package/dist/tui-v2/composer/history-nav.d.ts +15 -0
- package/dist/tui-v2/composer/history-nav.js +16 -0
- package/dist/tui-v2/composer/history-nav.js.map +1 -0
- package/dist/tui-v2/composer/newline-hint.d.ts +13 -0
- package/dist/tui-v2/composer/newline-hint.js +13 -0
- package/dist/tui-v2/composer/newline-hint.js.map +1 -0
- package/dist/tui-v2/composer/paste-placeholder.d.ts +35 -0
- package/dist/tui-v2/composer/paste-placeholder.js +55 -0
- package/dist/tui-v2/composer/paste-placeholder.js.map +1 -0
- package/dist/tui-v2/composer/prompt-history.d.ts +22 -0
- package/dist/tui-v2/composer/prompt-history.js +51 -0
- package/dist/tui-v2/composer/prompt-history.js.map +1 -0
- package/dist/tui-v2/composer/secret-buffer.d.ts +20 -0
- package/dist/tui-v2/composer/secret-buffer.js +42 -0
- package/dist/tui-v2/composer/secret-buffer.js.map +1 -0
- package/dist/tui-v2/composer/textarea-keybindings.d.ts +22 -0
- package/dist/tui-v2/composer/textarea-keybindings.js +27 -0
- package/dist/tui-v2/composer/textarea-keybindings.js.map +1 -0
- package/dist/tui-v2/controllers/focus-controller.d.ts +30 -0
- package/dist/tui-v2/controllers/focus-controller.js +80 -0
- package/dist/tui-v2/controllers/focus-controller.js.map +1 -0
- package/dist/tui-v2/controllers/overlay-controller.d.ts +99 -0
- package/dist/tui-v2/controllers/overlay-controller.js +195 -0
- package/dist/tui-v2/controllers/overlay-controller.js.map +1 -0
- package/dist/tui-v2/controllers/selection-controller.d.ts +76 -0
- package/dist/tui-v2/controllers/selection-controller.js +238 -0
- package/dist/tui-v2/controllers/selection-controller.js.map +1 -0
- package/dist/tui-v2/controllers/toast-controller.d.ts +35 -0
- package/dist/tui-v2/controllers/toast-controller.js +88 -0
- package/dist/tui-v2/controllers/toast-controller.js.map +1 -0
- package/dist/tui-v2/layout/compute-layout.d.ts +59 -0
- package/dist/tui-v2/layout/compute-layout.js +170 -0
- package/dist/tui-v2/layout/compute-layout.js.map +1 -0
- package/dist/tui-v2/rendering/ansi-to-styled.d.ts +17 -0
- package/dist/tui-v2/rendering/ansi-to-styled.js +217 -0
- package/dist/tui-v2/rendering/ansi-to-styled.js.map +1 -0
- package/dist/tui-v2/rendering/batch-sections.d.ts +45 -0
- package/dist/tui-v2/rendering/batch-sections.js +109 -0
- package/dist/tui-v2/rendering/batch-sections.js.map +1 -0
- package/dist/tui-v2/rendering/link-detector.d.ts +16 -0
- package/dist/tui-v2/rendering/link-detector.js +43 -0
- package/dist/tui-v2/rendering/link-detector.js.map +1 -0
- package/dist/tui-v2/rendering/open-tool-output.d.ts +28 -0
- package/dist/tui-v2/rendering/open-tool-output.js +138 -0
- package/dist/tui-v2/rendering/open-tool-output.js.map +1 -0
- package/dist/tui-v2/rendering/picker-filter.d.ts +22 -0
- package/dist/tui-v2/rendering/picker-filter.js +68 -0
- package/dist/tui-v2/rendering/picker-filter.js.map +1 -0
- package/dist/tui-v2/rendering/plan-view.d.ts +32 -0
- package/dist/tui-v2/rendering/plan-view.js +196 -0
- package/dist/tui-v2/rendering/plan-view.js.map +1 -0
- package/dist/tui-v2/rendering/render-markdown-lines.d.ts +29 -0
- package/dist/tui-v2/rendering/render-markdown-lines.js +46 -0
- package/dist/tui-v2/rendering/render-markdown-lines.js.map +1 -0
- package/dist/tui-v2/rendering/sanitize-display.d.ts +13 -0
- package/dist/tui-v2/rendering/sanitize-display.js +24 -0
- package/dist/tui-v2/rendering/sanitize-display.js.map +1 -0
- package/dist/tui-v2/rendering/theme.d.ts +67 -0
- package/dist/tui-v2/rendering/theme.js +74 -0
- package/dist/tui-v2/rendering/theme.js.map +1 -0
- package/dist/tui-v2/rendering/tool-presenter.d.ts +39 -0
- package/dist/tui-v2/rendering/tool-presenter.js +207 -0
- package/dist/tui-v2/rendering/tool-presenter.js.map +1 -0
- package/dist/tui-v2/rendering/transcript-export.d.ts +11 -0
- package/dist/tui-v2/rendering/transcript-export.js +18 -0
- package/dist/tui-v2/rendering/transcript-export.js.map +1 -0
- package/dist/tui-v2/rendering/transcript-semantic.d.ts +17 -0
- package/dist/tui-v2/rendering/transcript-semantic.js +67 -0
- package/dist/tui-v2/rendering/transcript-semantic.js.map +1 -0
- package/dist/tui-v2/state/pager-search.d.ts +22 -0
- package/dist/tui-v2/state/pager-search.js +78 -0
- package/dist/tui-v2/state/pager-search.js.map +1 -0
- package/dist/tui-v2/state/semantic-document.d.ts +34 -0
- package/dist/tui-v2/state/semantic-document.js +201 -0
- package/dist/tui-v2/state/semantic-document.js.map +1 -0
- package/dist/tui-v2/state/transcript-compaction.d.ts +24 -0
- package/dist/tui-v2/state/transcript-compaction.js +79 -0
- package/dist/tui-v2/state/transcript-compaction.js.map +1 -0
- package/dist/tui-v2/state/transcript-hydrate.d.ts +27 -0
- package/dist/tui-v2/state/transcript-hydrate.js +272 -0
- package/dist/tui-v2/state/transcript-hydrate.js.map +1 -0
- package/dist/tui-v2/state/transcript-reducer.d.ts +10 -0
- package/dist/tui-v2/state/transcript-reducer.js +281 -0
- package/dist/tui-v2/state/transcript-reducer.js.map +1 -0
- package/dist/tui-v2/state/transcript-search.d.ts +17 -0
- package/dist/tui-v2/state/transcript-search.js +38 -0
- package/dist/tui-v2/state/transcript-search.js.map +1 -0
- package/dist/tui-v2/state/transcript-store.d.ts +32 -0
- package/dist/tui-v2/state/transcript-store.js +66 -0
- package/dist/tui-v2/state/transcript-store.js.map +1 -0
- package/dist/tui-v2/state/transcript-struct.d.ts +15 -0
- package/dist/tui-v2/state/transcript-struct.js +133 -0
- package/dist/tui-v2/state/transcript-struct.js.map +1 -0
- package/dist/tui-v2/state/transcript-types.d.ts +76 -0
- package/dist/tui-v2/state/transcript-types.js +65 -0
- package/dist/tui-v2/state/transcript-types.js.map +1 -0
- package/dist/tui-v2/state/use-overlay.d.ts +3 -0
- package/dist/tui-v2/state/use-overlay.js +6 -0
- package/dist/tui-v2/state/use-overlay.js.map +1 -0
- package/dist/tui-v2/state/use-plan.d.ts +4 -0
- package/dist/tui-v2/state/use-plan.js +6 -0
- package/dist/tui-v2/state/use-plan.js.map +1 -0
- package/dist/tui-v2/state/use-session-state.d.ts +2 -0
- package/dist/tui-v2/state/use-session-state.js +7 -0
- package/dist/tui-v2/state/use-session-state.js.map +1 -0
- package/dist/tui-v2/state/use-toast.d.ts +3 -0
- package/dist/tui-v2/state/use-toast.js +15 -0
- package/dist/tui-v2/state/use-toast.js.map +1 -0
- package/dist/tui-v2/state/use-transcript-store.d.ts +10 -0
- package/dist/tui-v2/state/use-transcript-store.js +12 -0
- package/dist/tui-v2/state/use-transcript-store.js.map +1 -0
- package/dist/ui/intro-card.js +3 -3
- package/dist/ui/intro-card.js.map +1 -1
- package/dist/ui/intro-header.d.ts +23 -0
- package/dist/ui/intro-header.js +232 -0
- package/dist/ui/intro-header.js.map +1 -0
- package/dist/ui/markdown.js +0 -1
- package/dist/ui/markdown.js.map +1 -1
- package/dist/ui/mentions.d.ts +9 -2
- package/dist/ui/mentions.js +102 -4
- package/dist/ui/mentions.js.map +1 -1
- package/dist/ui/output-pane.js +1 -1
- package/dist/ui/output-pane.js.map +1 -1
- package/dist/ui/plan-pane.d.ts +8 -0
- package/dist/ui/plan-pane.js +38 -0
- package/dist/ui/plan-pane.js.map +1 -1
- package/dist/ui/wordmark.d.ts +5 -0
- package/dist/ui/wordmark.js +6 -1
- package/dist/ui/wordmark.js.map +1 -1
- package/package.json +14 -10
- package/dist/tui/App.d.ts +0 -12
- package/dist/tui/App.js +0 -2174
- package/dist/tui/App.js.map +0 -1
- package/dist/tui/components/ConfirmModal.d.ts +0 -9
- package/dist/tui/components/ConfirmModal.js +0 -55
- package/dist/tui/components/ConfirmModal.js.map +0 -1
- package/dist/tui/components/JobsPanel.d.ts +0 -11
- package/dist/tui/components/JobsPanel.js +0 -55
- package/dist/tui/components/JobsPanel.js.map +0 -1
- package/dist/tui/components/Pager.d.ts +0 -14
- package/dist/tui/components/Pager.js +0 -56
- package/dist/tui/components/Pager.js.map +0 -1
- package/dist/tui/components/PickerPanel.d.ts +0 -15
- package/dist/tui/components/PickerPanel.js +0 -126
- package/dist/tui/components/PickerPanel.js.map +0 -1
- package/dist/tui/components/PlanSidebar.d.ts +0 -6
- package/dist/tui/components/PlanSidebar.js +0 -99
- package/dist/tui/components/PlanSidebar.js.map +0 -1
- package/dist/tui/components/SecretInputPanel.d.ts +0 -7
- package/dist/tui/components/SecretInputPanel.js +0 -38
- package/dist/tui/components/SecretInputPanel.js.map +0 -1
- package/dist/tui/confirm.d.ts +0 -16
- package/dist/tui/confirm.js.map +0 -1
- package/dist/tui/default.d.ts +0 -6
- package/dist/tui/default.js +0 -11
- package/dist/tui/default.js.map +0 -1
- package/dist/tui/hooks/useAgentRunner.d.ts +0 -73
- package/dist/tui/hooks/useAgentRunner.js +0 -277
- package/dist/tui/hooks/useAgentRunner.js.map +0 -1
- package/dist/tui/hooks/useJobs.d.ts +0 -7
- package/dist/tui/hooks/useJobs.js +0 -39
- package/dist/tui/hooks/useJobs.js.map +0 -1
- package/dist/tui/hooks/useSpinner.d.ts +0 -5
- package/dist/tui/hooks/useSpinner.js +0 -21
- package/dist/tui/hooks/useSpinner.js.map +0 -1
- package/dist/tui/hooks/useTerminalSize.d.ts +0 -9
- package/dist/tui/hooks/useTerminalSize.js +0 -26
- package/dist/tui/hooks/useTerminalSize.js.map +0 -1
- package/dist/tui/index.d.ts +0 -10
- package/dist/tui/index.js +0 -37
- package/dist/tui/index.js.map +0 -1
- package/dist/tui/key-intent.d.ts +0 -36
- package/dist/tui/key-intent.js +0 -54
- package/dist/tui/key-intent.js.map +0 -1
- package/dist/tui/mouse.d.ts +0 -8
- package/dist/tui/mouse.js +0 -34
- package/dist/tui/mouse.js.map +0 -1
- package/dist/tui/plan-sidebar-lines.d.ts +0 -2
- package/dist/tui/plan-sidebar-lines.js +0 -140
- package/dist/tui/plan-sidebar-lines.js.map +0 -1
- package/dist/tui/render-lines.d.ts +0 -22
- package/dist/tui/render-lines.js +0 -611
- package/dist/tui/render-lines.js.map +0 -1
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command context = the focused surface a command is allowed to run in
|
|
3
|
+
* (PICK-002, CMD-002). `global` commands run anywhere the focused surface
|
|
4
|
+
* permits; others are scoped.
|
|
5
|
+
*/
|
|
6
|
+
export type CommandContext = "global" | "composer" | "picker" | "modal" | "secret" | "plan" | "transcript" | "transcript-search";
|
|
7
|
+
export interface CommandDefinition {
|
|
8
|
+
/** Canonical name without the leading slash, e.g. "model". */
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly aliases?: readonly string[];
|
|
11
|
+
readonly usage?: string | undefined;
|
|
12
|
+
readonly description: string;
|
|
13
|
+
/** Surfaces this command is available in; defaults to ["global"]. */
|
|
14
|
+
readonly contexts?: readonly CommandContext[];
|
|
15
|
+
}
|
|
16
|
+
export interface CommandInvocation {
|
|
17
|
+
/** Canonical resolved name (aliases are already resolved). */
|
|
18
|
+
readonly name: string;
|
|
19
|
+
/** Raw argument string, trimmed. */
|
|
20
|
+
readonly args: string;
|
|
21
|
+
readonly context: CommandContext;
|
|
22
|
+
}
|
|
23
|
+
export type CommandHandler = (invocation: CommandInvocation) => void | Promise<void>;
|
|
24
|
+
export declare function normalizeCommandName(nameOrAlias: string): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../../../src/app/commands/command.ts"],"names":[],"mappings":"AAqCA,MAAM,UAAU,oBAAoB,CAAC,WAAmB;IACtD,OAAO,WAAW,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type CommandContext, type CommandDefinition, type CommandHandler, type CommandInvocation } from "./command.js";
|
|
2
|
+
export interface CommandHelpEntry {
|
|
3
|
+
readonly command: string;
|
|
4
|
+
readonly usage?: string | undefined;
|
|
5
|
+
readonly description: string;
|
|
6
|
+
readonly aliases: readonly string[];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* One typed source of truth for slash commands. Registration is closed once
|
|
10
|
+
* seeded; handlers are attached by whichever frontend consumes the registry so
|
|
11
|
+
* UI-coupled handler bodies are not duplicated across legacy and v2.
|
|
12
|
+
*/
|
|
13
|
+
export declare class CommandRegistry {
|
|
14
|
+
private readonly byName;
|
|
15
|
+
private readonly aliasToName;
|
|
16
|
+
private readonly handlers;
|
|
17
|
+
register(definition: CommandDefinition): void;
|
|
18
|
+
resolve(nameOrAlias: string): string | undefined;
|
|
19
|
+
has(nameOrAlias: string): boolean;
|
|
20
|
+
get(nameOrAlias: string): CommandDefinition | undefined;
|
|
21
|
+
all(): CommandDefinition[];
|
|
22
|
+
setHandler(nameOrAlias: string, handler: CommandHandler): void;
|
|
23
|
+
/** Prefix match over canonical names and aliases (for completion menus). */
|
|
24
|
+
suggestions(prefix: string): CommandDefinition[];
|
|
25
|
+
help(): CommandHelpEntry[];
|
|
26
|
+
/** Parse a raw `/name args` line into a resolved invocation, or undefined. */
|
|
27
|
+
parse(line: string, context?: CommandContext): CommandInvocation | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* True when a submitted line should be treated as a slash-command attempt
|
|
30
|
+
* (known name, unique prefix, or command-shaped word) rather than a prompt.
|
|
31
|
+
* Paths like `/Users/...` return false.
|
|
32
|
+
*/
|
|
33
|
+
looksLikeCommand(line: string): boolean;
|
|
34
|
+
/** Resolve + run the registered handler. Returns false if unknown/unhandled. */
|
|
35
|
+
dispatch(invocation: {
|
|
36
|
+
name: string;
|
|
37
|
+
args?: string | undefined;
|
|
38
|
+
context?: CommandContext | undefined;
|
|
39
|
+
}): Promise<boolean>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Seed a registry from the shared legacy command catalogue so v2 and the
|
|
43
|
+
* classic REPL agree on the command set without a second hand-maintained list.
|
|
44
|
+
*/
|
|
45
|
+
export declare function buildDefaultCommandRegistry(): CommandRegistry;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { slashCommands } from "../../repl/slash-commands.js";
|
|
2
|
+
import { normalizeCommandName, } from "./command.js";
|
|
3
|
+
/**
|
|
4
|
+
* Canonical command -> alias names. The legacy catalogue lists aliases as
|
|
5
|
+
* separate rows ("alias for /X"); here they collapse onto one canonical
|
|
6
|
+
* command so menus, help, keybindings, and dispatch all derive from a single
|
|
7
|
+
* definition (CMD-002, FEATURE_PARITY "aliases point to the same handler").
|
|
8
|
+
*/
|
|
9
|
+
const ALIAS_GROUPS = {
|
|
10
|
+
provider: ["use"],
|
|
11
|
+
search: ["search-provider"],
|
|
12
|
+
variants: ["reasoning"],
|
|
13
|
+
think: ["thinking"],
|
|
14
|
+
exit: ["quit"],
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* One typed source of truth for slash commands. Registration is closed once
|
|
18
|
+
* seeded; handlers are attached by whichever frontend consumes the registry so
|
|
19
|
+
* UI-coupled handler bodies are not duplicated across legacy and v2.
|
|
20
|
+
*/
|
|
21
|
+
export class CommandRegistry {
|
|
22
|
+
byName = new Map();
|
|
23
|
+
aliasToName = new Map();
|
|
24
|
+
handlers = new Map();
|
|
25
|
+
register(definition) {
|
|
26
|
+
const name = normalizeCommandName(definition.name);
|
|
27
|
+
if (this.byName.has(name) || this.aliasToName.has(name)) {
|
|
28
|
+
throw new Error(`duplicate command name: ${name}`);
|
|
29
|
+
}
|
|
30
|
+
this.byName.set(name, { ...definition, name });
|
|
31
|
+
for (const alias of definition.aliases ?? []) {
|
|
32
|
+
const normalized = normalizeCommandName(alias);
|
|
33
|
+
if (this.aliasToName.has(normalized) || this.byName.has(normalized)) {
|
|
34
|
+
throw new Error(`duplicate command alias: ${normalized}`);
|
|
35
|
+
}
|
|
36
|
+
this.aliasToName.set(normalized, name);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
resolve(nameOrAlias) {
|
|
40
|
+
const name = normalizeCommandName(nameOrAlias);
|
|
41
|
+
if (this.byName.has(name))
|
|
42
|
+
return name;
|
|
43
|
+
return this.aliasToName.get(name);
|
|
44
|
+
}
|
|
45
|
+
has(nameOrAlias) {
|
|
46
|
+
return this.resolve(nameOrAlias) !== undefined;
|
|
47
|
+
}
|
|
48
|
+
get(nameOrAlias) {
|
|
49
|
+
const name = this.resolve(nameOrAlias);
|
|
50
|
+
return name ? this.byName.get(name) : undefined;
|
|
51
|
+
}
|
|
52
|
+
all() {
|
|
53
|
+
return [...this.byName.values()];
|
|
54
|
+
}
|
|
55
|
+
setHandler(nameOrAlias, handler) {
|
|
56
|
+
const name = this.resolve(nameOrAlias);
|
|
57
|
+
if (!name)
|
|
58
|
+
throw new Error(`unknown command: ${nameOrAlias}`);
|
|
59
|
+
this.handlers.set(name, handler);
|
|
60
|
+
}
|
|
61
|
+
/** Prefix match over canonical names and aliases (for completion menus). */
|
|
62
|
+
suggestions(prefix) {
|
|
63
|
+
const needle = normalizeCommandName(prefix);
|
|
64
|
+
const matches = [];
|
|
65
|
+
for (const def of this.byName.values()) {
|
|
66
|
+
const names = [def.name, ...(def.aliases ?? [])];
|
|
67
|
+
if (names.some((n) => n.startsWith(needle)))
|
|
68
|
+
matches.push(def);
|
|
69
|
+
}
|
|
70
|
+
return matches;
|
|
71
|
+
}
|
|
72
|
+
help() {
|
|
73
|
+
return this.all().map((def) => ({
|
|
74
|
+
command: `/${def.name}`,
|
|
75
|
+
usage: def.usage,
|
|
76
|
+
description: def.description,
|
|
77
|
+
aliases: (def.aliases ?? []).map((a) => `/${a}`),
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
/** Parse a raw `/name args` line into a resolved invocation, or undefined. */
|
|
81
|
+
parse(line, context = "global") {
|
|
82
|
+
if (!line.startsWith("/"))
|
|
83
|
+
return undefined;
|
|
84
|
+
const rest = line.slice(1);
|
|
85
|
+
const boundary = rest.search(/\s/);
|
|
86
|
+
const rawName = boundary === -1 ? rest : rest.slice(0, boundary);
|
|
87
|
+
const args = boundary === -1 ? "" : rest.slice(boundary + 1).trim();
|
|
88
|
+
// Absolute paths (/Users/..., /tmp/foo) are prompts, not commands.
|
|
89
|
+
if (!rawName || rawName.includes("/") || rawName.includes("\\")) {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
const exact = this.resolve(rawName);
|
|
93
|
+
if (exact)
|
|
94
|
+
return { name: exact, args, context };
|
|
95
|
+
// Unique prefix match so a broken completion menu still dispatches
|
|
96
|
+
// "/mod" → /model, "/imp" → /implement, etc.
|
|
97
|
+
if (rawName.length === 0)
|
|
98
|
+
return undefined;
|
|
99
|
+
const matches = this.suggestions(rawName);
|
|
100
|
+
if (matches.length === 1) {
|
|
101
|
+
return { name: matches[0].name, args, context };
|
|
102
|
+
}
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* True when a submitted line should be treated as a slash-command attempt
|
|
107
|
+
* (known name, unique prefix, or command-shaped word) rather than a prompt.
|
|
108
|
+
* Paths like `/Users/...` return false.
|
|
109
|
+
*/
|
|
110
|
+
looksLikeCommand(line) {
|
|
111
|
+
if (!line.startsWith("/") || line.length < 2)
|
|
112
|
+
return false;
|
|
113
|
+
const firstToken = line.slice(1).split(/\s/)[0] ?? "";
|
|
114
|
+
if (!firstToken || firstToken.includes("/") || firstToken.includes("\\")) {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
if (this.resolve(firstToken))
|
|
118
|
+
return true;
|
|
119
|
+
if (this.suggestions(firstToken).length > 0)
|
|
120
|
+
return true;
|
|
121
|
+
return /^[a-z][a-z0-9-]*$/i.test(firstToken);
|
|
122
|
+
}
|
|
123
|
+
/** Resolve + run the registered handler. Returns false if unknown/unhandled. */
|
|
124
|
+
async dispatch(invocation) {
|
|
125
|
+
const name = this.resolve(invocation.name);
|
|
126
|
+
if (!name)
|
|
127
|
+
return false;
|
|
128
|
+
const handler = this.handlers.get(name);
|
|
129
|
+
if (!handler)
|
|
130
|
+
return false;
|
|
131
|
+
await handler({
|
|
132
|
+
name,
|
|
133
|
+
args: invocation.args ?? "",
|
|
134
|
+
context: invocation.context ?? "global",
|
|
135
|
+
});
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Seed a registry from the shared legacy command catalogue so v2 and the
|
|
141
|
+
* classic REPL agree on the command set without a second hand-maintained list.
|
|
142
|
+
*/
|
|
143
|
+
export function buildDefaultCommandRegistry() {
|
|
144
|
+
const registry = new CommandRegistry();
|
|
145
|
+
const aliasNames = new Set();
|
|
146
|
+
for (const aliases of Object.values(ALIAS_GROUPS)) {
|
|
147
|
+
for (const alias of aliases)
|
|
148
|
+
aliasNames.add(alias);
|
|
149
|
+
}
|
|
150
|
+
for (const command of slashCommands) {
|
|
151
|
+
const name = normalizeCommandName(command.command);
|
|
152
|
+
if (aliasNames.has(name))
|
|
153
|
+
continue; // attached to its canonical below
|
|
154
|
+
const aliases = ALIAS_GROUPS[name];
|
|
155
|
+
registry.register({
|
|
156
|
+
name,
|
|
157
|
+
description: command.description,
|
|
158
|
+
usage: command.usage,
|
|
159
|
+
...(aliases ? { aliases } : {}),
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
return registry;
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/app/commands/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EACL,oBAAoB,GAKrB,MAAM,cAAc,CAAC;AAEtB;;;;;GAKG;AACH,MAAM,YAAY,GAAsC;IACtD,QAAQ,EAAE,CAAC,KAAK,CAAC;IACjB,MAAM,EAAE,CAAC,iBAAiB,CAAC;IAC3B,QAAQ,EAAE,CAAC,WAAW,CAAC;IACvB,KAAK,EAAE,CAAC,UAAU,CAAC;IACnB,IAAI,EAAE,CAAC,MAAM,CAAC;CACf,CAAC;AASF;;;;GAIG;AACH,MAAM,OAAO,eAAe;IACT,MAAM,GAAG,IAAI,GAAG,EAA6B,CAAC;IAC9C,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,QAAQ,GAAG,IAAI,GAAG,EAA0B,CAAC;IAE9D,QAAQ,CAAC,UAA6B;QACpC,MAAM,IAAI,GAAG,oBAAoB,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACnD,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACxD,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,GAAG,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;YAC7C,MAAM,UAAU,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;YAC/C,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;gBACpE,MAAM,IAAI,KAAK,CAAC,4BAA4B,UAAU,EAAE,CAAC,CAAC;YAC5D,CAAC;YACD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,OAAO,CAAC,WAAmB;QACzB,MAAM,IAAI,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;QAC/C,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACvC,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,GAAG,CAAC,WAAmB;QACrB,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,SAAS,CAAC;IACjD,CAAC;IAED,GAAG,CAAC,WAAmB;QACrB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACvC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAClD,CAAC;IAED,GAAG;QACD,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,UAAU,CAAC,WAAmB,EAAE,OAAuB;QACrD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,WAAW,EAAE,CAAC,CAAC;QAC9D,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,4EAA4E;IAC5E,WAAW,CAAC,MAAc;QACxB,MAAM,MAAM,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAwB,EAAE,CAAC;QACxC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;YACjD,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YAC9B,OAAO,EAAE,IAAI,GAAG,CAAC,IAAI,EAAE;YACvB,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,OAAO,EAAE,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;SACjD,CAAC,CAAC,CAAC;IACN,CAAC;IAED,8EAA8E;IAC9E,KAAK,CACH,IAAY,EACZ,UAA0B,QAAQ;QAElC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,SAAS,CAAC;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QACjE,MAAM,IAAI,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACpE,mEAAmE;QACnE,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAChE,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACpC,IAAI,KAAK;YAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QACjD,mEAAmE;QACnE,6CAA6C;QAC7C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAC1C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QACnD,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;OAIG;IACH,gBAAgB,CAAC,IAAY;QAC3B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QAC3D,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACtD,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACzE,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1C,IAAI,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QACzD,OAAO,oBAAoB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/C,CAAC;IAED,gFAAgF;IAChF,KAAK,CAAC,QAAQ,CAAC,UAId;QACC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QACxB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,OAAO;YAAE,OAAO,KAAK,CAAC;QAC3B,MAAM,OAAO,CAAC;YACZ,IAAI;YACJ,IAAI,EAAE,UAAU,CAAC,IAAI,IAAI,EAAE;YAC3B,OAAO,EAAE,UAAU,CAAC,OAAO,IAAI,QAAQ;SACxC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,2BAA2B;IACzC,MAAM,QAAQ,GAAG,IAAI,eAAe,EAAE,CAAC;IACvC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;QAClD,KAAK,MAAM,KAAK,IAAI,OAAO;YAAE,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,aAAa,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,oBAAoB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACnD,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS,CAAC,kCAAkC;QACtE,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACnC,QAAQ,CAAC,QAAQ,CAAC;YAChB,IAAI;YACJ,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface Disposable {
|
|
2
|
+
dispose(): void;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Owns a set of disposables and tears them down in reverse creation order
|
|
6
|
+
* (ARCHITECTURE.md lifecycle). Disposal is idempotent (REL-001): a second call
|
|
7
|
+
* is a no-op, and one throwing disposer does not prevent the rest from running.
|
|
8
|
+
*/
|
|
9
|
+
export declare class CompositeDisposable implements Disposable {
|
|
10
|
+
private readonly items;
|
|
11
|
+
private disposed;
|
|
12
|
+
add<T extends Disposable>(item: T): T;
|
|
13
|
+
get isDisposed(): boolean;
|
|
14
|
+
dispose(): void;
|
|
15
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Owns a set of disposables and tears them down in reverse creation order
|
|
3
|
+
* (ARCHITECTURE.md lifecycle). Disposal is idempotent (REL-001): a second call
|
|
4
|
+
* is a no-op, and one throwing disposer does not prevent the rest from running.
|
|
5
|
+
*/
|
|
6
|
+
export class CompositeDisposable {
|
|
7
|
+
items = [];
|
|
8
|
+
disposed = false;
|
|
9
|
+
add(item) {
|
|
10
|
+
if (this.disposed) {
|
|
11
|
+
item.dispose();
|
|
12
|
+
return item;
|
|
13
|
+
}
|
|
14
|
+
this.items.push(item);
|
|
15
|
+
return item;
|
|
16
|
+
}
|
|
17
|
+
get isDisposed() {
|
|
18
|
+
return this.disposed;
|
|
19
|
+
}
|
|
20
|
+
dispose() {
|
|
21
|
+
if (this.disposed)
|
|
22
|
+
return;
|
|
23
|
+
this.disposed = true;
|
|
24
|
+
const errors = [];
|
|
25
|
+
for (let i = this.items.length - 1; i >= 0; i -= 1) {
|
|
26
|
+
try {
|
|
27
|
+
this.items[i]?.dispose();
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
errors.push(error);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
this.items.length = 0;
|
|
34
|
+
if (errors.length > 0)
|
|
35
|
+
throw errors[0];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=disposable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"disposable.js","sourceRoot":"","sources":["../../../src/app/controllers/disposable.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,MAAM,OAAO,mBAAmB;IACb,KAAK,GAAiB,EAAE,CAAC;IAClC,QAAQ,GAAG,KAAK,CAAC;IAEzB,GAAG,CAAuB,IAAO;QAC/B,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,OAAO;QACL,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,MAAM,MAAM,GAAc,EAAE,CAAC;QAC7B,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACnD,IAAI,CAAC;gBACH,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;YAC3B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QACtB,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC;CACF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ToolResult } from "../../types.js";
|
|
2
|
+
import type { BackgroundJob, JobsPort } from "../ports/jobs-port.js";
|
|
3
|
+
import type { Disposable } from "./disposable.js";
|
|
4
|
+
/**
|
|
5
|
+
* Thin lifecycle wrapper over `JobsPort` (CORE-004). Jobs live in the core
|
|
6
|
+
* manager and survive UI rerenders; this controller only observes and commands.
|
|
7
|
+
*/
|
|
8
|
+
export declare class JobController implements Disposable {
|
|
9
|
+
private readonly jobs;
|
|
10
|
+
constructor(jobs: JobsPort);
|
|
11
|
+
list(): ToolResult;
|
|
12
|
+
running(): BackgroundJob[];
|
|
13
|
+
get(id: string): BackgroundJob | undefined;
|
|
14
|
+
tail(id: string, bytes?: number): Promise<ToolResult>;
|
|
15
|
+
stop(id: string): ToolResult;
|
|
16
|
+
start(command: string, options?: {
|
|
17
|
+
cwd?: string | undefined;
|
|
18
|
+
name?: string | undefined;
|
|
19
|
+
}): Promise<ToolResult>;
|
|
20
|
+
hasRunning(): boolean;
|
|
21
|
+
dispose(): void;
|
|
22
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin lifecycle wrapper over `JobsPort` (CORE-004). Jobs live in the core
|
|
3
|
+
* manager and survive UI rerenders; this controller only observes and commands.
|
|
4
|
+
*/
|
|
5
|
+
export class JobController {
|
|
6
|
+
jobs;
|
|
7
|
+
constructor(jobs) {
|
|
8
|
+
this.jobs = jobs;
|
|
9
|
+
}
|
|
10
|
+
list() {
|
|
11
|
+
return this.jobs.list();
|
|
12
|
+
}
|
|
13
|
+
running() {
|
|
14
|
+
return this.jobs.running();
|
|
15
|
+
}
|
|
16
|
+
get(id) {
|
|
17
|
+
return this.jobs.get(id);
|
|
18
|
+
}
|
|
19
|
+
tail(id, bytes) {
|
|
20
|
+
return this.jobs.tail(id, bytes);
|
|
21
|
+
}
|
|
22
|
+
stop(id) {
|
|
23
|
+
return this.jobs.stop(id);
|
|
24
|
+
}
|
|
25
|
+
start(command, options) {
|
|
26
|
+
return this.jobs.start(command, options);
|
|
27
|
+
}
|
|
28
|
+
hasRunning() {
|
|
29
|
+
return this.running().length > 0;
|
|
30
|
+
}
|
|
31
|
+
dispose() {
|
|
32
|
+
// Jobs intentionally outlive the UI; nothing to tear down here.
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=job-controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-controller.js","sourceRoot":"","sources":["../../../src/app/controllers/job-controller.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,MAAM,OAAO,aAAa;IACK;IAA7B,YAA6B,IAAc;QAAd,SAAI,GAAJ,IAAI,CAAU;IAAG,CAAC;IAE/C,IAAI;QACF,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAC1B,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC3B,CAAC;IAED,IAAI,CAAC,EAAU,EAAE,KAAc;QAC7B,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IACnC,CAAC;IAED,IAAI,CAAC,EAAU;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,CACH,OAAe,EACf,OAAiE;QAEjE,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;IACnC,CAAC;IAED,OAAO;QACL,gEAAgE;IAClE,CAAC;CACF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { SessionPlan } from "../../store/plan.js";
|
|
2
|
+
import type { AnyAppEvent } from "../events/app-event.js";
|
|
3
|
+
import type { PersistencePort } from "../ports/persistence-port.js";
|
|
4
|
+
import type { Disposable } from "./disposable.js";
|
|
5
|
+
export type PlanListener = () => void;
|
|
6
|
+
/**
|
|
7
|
+
* Holds the one current plan entity and keeps it in sync with the event stream
|
|
8
|
+
* (PLAN-003: mutate the existing plan, never append duplicates). Approval and
|
|
9
|
+
* discard mutate persisted status through the persistence port. Observable so
|
|
10
|
+
* the UI can bind reactively without polling (PLAN-002).
|
|
11
|
+
*/
|
|
12
|
+
export declare class PlanController implements Disposable {
|
|
13
|
+
private readonly persistence;
|
|
14
|
+
private plan;
|
|
15
|
+
private readonly listeners;
|
|
16
|
+
constructor(persistence: PersistencePort);
|
|
17
|
+
current(): SessionPlan | undefined;
|
|
18
|
+
subscribe(listener: PlanListener): () => void;
|
|
19
|
+
observe(event: AnyAppEvent): void;
|
|
20
|
+
/**
|
|
21
|
+
* Load the plan for `sessionId` from disk into memory. Clears the in-memory
|
|
22
|
+
* plan when none is stored (so switching sessions never leaves a stale card).
|
|
23
|
+
*/
|
|
24
|
+
load(sessionId: string): Promise<SessionPlan | undefined>;
|
|
25
|
+
/** Drop the in-memory plan without touching disk. */
|
|
26
|
+
clear(): void;
|
|
27
|
+
approve(): Promise<SessionPlan | undefined>;
|
|
28
|
+
discard(): Promise<void>;
|
|
29
|
+
dispose(): void;
|
|
30
|
+
private notify;
|
|
31
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Holds the one current plan entity and keeps it in sync with the event stream
|
|
3
|
+
* (PLAN-003: mutate the existing plan, never append duplicates). Approval and
|
|
4
|
+
* discard mutate persisted status through the persistence port. Observable so
|
|
5
|
+
* the UI can bind reactively without polling (PLAN-002).
|
|
6
|
+
*/
|
|
7
|
+
export class PlanController {
|
|
8
|
+
persistence;
|
|
9
|
+
plan;
|
|
10
|
+
listeners = new Set();
|
|
11
|
+
constructor(persistence) {
|
|
12
|
+
this.persistence = persistence;
|
|
13
|
+
}
|
|
14
|
+
current() {
|
|
15
|
+
return this.plan;
|
|
16
|
+
}
|
|
17
|
+
subscribe(listener) {
|
|
18
|
+
this.listeners.add(listener);
|
|
19
|
+
return () => this.listeners.delete(listener);
|
|
20
|
+
}
|
|
21
|
+
observe(event) {
|
|
22
|
+
if (event.type === "plan-updated") {
|
|
23
|
+
this.plan = event.payload.plan;
|
|
24
|
+
this.notify();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Load the plan for `sessionId` from disk into memory. Clears the in-memory
|
|
29
|
+
* plan when none is stored (so switching sessions never leaves a stale card).
|
|
30
|
+
*/
|
|
31
|
+
async load(sessionId) {
|
|
32
|
+
this.plan = await this.persistence.loadPlan(sessionId);
|
|
33
|
+
this.notify();
|
|
34
|
+
return this.plan;
|
|
35
|
+
}
|
|
36
|
+
/** Drop the in-memory plan without touching disk. */
|
|
37
|
+
clear() {
|
|
38
|
+
if (!this.plan)
|
|
39
|
+
return;
|
|
40
|
+
this.plan = undefined;
|
|
41
|
+
this.notify();
|
|
42
|
+
}
|
|
43
|
+
async approve() {
|
|
44
|
+
if (!this.plan)
|
|
45
|
+
return undefined;
|
|
46
|
+
const next = { ...this.plan, status: "approved" };
|
|
47
|
+
this.plan = next;
|
|
48
|
+
await this.persistence.savePlan(next);
|
|
49
|
+
this.notify();
|
|
50
|
+
return next;
|
|
51
|
+
}
|
|
52
|
+
async discard() {
|
|
53
|
+
if (!this.plan)
|
|
54
|
+
return;
|
|
55
|
+
const { sessionId } = this.plan;
|
|
56
|
+
this.plan = undefined;
|
|
57
|
+
await this.persistence.deletePlan(sessionId);
|
|
58
|
+
this.notify();
|
|
59
|
+
}
|
|
60
|
+
dispose() {
|
|
61
|
+
this.plan = undefined;
|
|
62
|
+
this.listeners.clear();
|
|
63
|
+
}
|
|
64
|
+
notify() {
|
|
65
|
+
for (const listener of this.listeners)
|
|
66
|
+
listener();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=plan-controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-controller.js","sourceRoot":"","sources":["../../../src/app/controllers/plan-controller.ts"],"names":[],"mappings":"AAOA;;;;;GAKG;AACH,MAAM,OAAO,cAAc;IAII;IAHrB,IAAI,CAA0B;IACrB,SAAS,GAAG,IAAI,GAAG,EAAgB,CAAC;IAErD,YAA6B,WAA4B;QAA5B,gBAAW,GAAX,WAAW,CAAiB;IAAG,CAAC;IAE7D,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,SAAS,CAAC,QAAsB;QAC9B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,CAAC,KAAkB;QACxB,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAClC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;YAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI,CAAC,SAAiB;QAC1B,IAAI,CAAC,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QACvD,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,qDAAqD;IACrD,KAAK;QACH,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,OAAO;QACvB,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;QACtB,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,OAAO,SAAS,CAAC;QACjC,MAAM,IAAI,GAAgB,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;QAC/D,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,OAAO;QACvB,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;QACtB,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAED,OAAO;QACL,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;QACtB,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC;IAEO,MAAM;QACZ,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS;YAAE,QAAQ,EAAE,CAAC;IACpD,CAAC;CACF"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import type { ChatMessage, Mode, ProviderId } from "../../types.js";
|
|
2
|
+
import { type CompactResult } from "../../agent/context-manager.js";
|
|
3
|
+
import type { TranscriptItem as ClassicTranscriptItem } from "../../tui/state.js";
|
|
4
|
+
import { type AnyAppEvent, type SessionId, type TurnId } from "../events/app-event.js";
|
|
5
|
+
import { type Clock, type IdFactory } from "../events/sequencer.js";
|
|
6
|
+
import { OutputSpool } from "../events/event-buffer.js";
|
|
7
|
+
import type { AgentPort } from "../ports/agent-port.js";
|
|
8
|
+
import type { PersistencePort } from "../ports/persistence-port.js";
|
|
9
|
+
import type { ConfirmationPort } from "../ports/confirm-port.js";
|
|
10
|
+
import type { SecretPort } from "../ports/secret-port.js";
|
|
11
|
+
import { type TurnResult } from "./turn-controller.js";
|
|
12
|
+
import { type Disposable } from "./disposable.js";
|
|
13
|
+
export interface SessionState {
|
|
14
|
+
readonly sessionId: SessionId;
|
|
15
|
+
readonly mode: Mode;
|
|
16
|
+
readonly provider: ProviderId | undefined;
|
|
17
|
+
readonly model: string | undefined;
|
|
18
|
+
readonly running: boolean;
|
|
19
|
+
/** True while /compact is awaiting the summarizer (status strip). */
|
|
20
|
+
readonly compacting: boolean;
|
|
21
|
+
readonly historyLength: number;
|
|
22
|
+
readonly queued: readonly string[];
|
|
23
|
+
/** AI-generated (or last known) display name for this session. */
|
|
24
|
+
readonly title: string | undefined;
|
|
25
|
+
}
|
|
26
|
+
export type NoticeLevel = "info" | "warn";
|
|
27
|
+
export interface SessionControllerDeps {
|
|
28
|
+
readonly agent: AgentPort;
|
|
29
|
+
readonly persistence: PersistencePort;
|
|
30
|
+
readonly emit: (event: AnyAppEvent) => void;
|
|
31
|
+
readonly sessionId?: string | undefined;
|
|
32
|
+
readonly provider?: ProviderId | undefined;
|
|
33
|
+
readonly model?: string | undefined;
|
|
34
|
+
readonly mode?: Mode | undefined;
|
|
35
|
+
readonly confirm?: ConfirmationPort | undefined;
|
|
36
|
+
readonly requestSecret?: SecretPort["request"] | undefined;
|
|
37
|
+
readonly idFactory?: IdFactory | undefined;
|
|
38
|
+
readonly clock?: Clock | undefined;
|
|
39
|
+
readonly mintTurnId?: (() => TurnId) | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* Optional snapshot of the visual transcript for history.db (classic shape).
|
|
42
|
+
* When provided, completed turns upsert session + transcript so /history
|
|
43
|
+
* can restore tools and prompts, not only ChatMessage[].
|
|
44
|
+
*/
|
|
45
|
+
readonly getTranscriptSnapshot?: (() => ClassicTranscriptItem[] | undefined) | undefined;
|
|
46
|
+
/** When true, never persist sessions or generate AI titles (CLI --no-history). */
|
|
47
|
+
readonly noHistory?: boolean | undefined;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Owns session-level state (mode, provider/model, cumulative history, queued
|
|
51
|
+
* drafts) and runs turns through a single `TurnController`. Cumulative history
|
|
52
|
+
* follows the current runner contract: `onMessages` hands back the full
|
|
53
|
+
* conversation for the turn (prior context + this turn), which replaces the
|
|
54
|
+
* stored history and is persisted on completion.
|
|
55
|
+
*/
|
|
56
|
+
export type TurnEndListener = (result: TurnResult) => void;
|
|
57
|
+
export type SessionStateListener = () => void;
|
|
58
|
+
export declare class SessionController implements Disposable {
|
|
59
|
+
private readonly deps;
|
|
60
|
+
readonly spool: OutputSpool;
|
|
61
|
+
private sessionIdValue;
|
|
62
|
+
private readonly sequencer;
|
|
63
|
+
private readonly turn;
|
|
64
|
+
private policy;
|
|
65
|
+
private readonly disposables;
|
|
66
|
+
private readonly turnEndListeners;
|
|
67
|
+
private readonly stateListeners;
|
|
68
|
+
private history;
|
|
69
|
+
private readonly queue;
|
|
70
|
+
/**
|
|
71
|
+
* Prompt promoted by "Send now" while a turn was running. After the abort
|
|
72
|
+
* settles, {@link continueQueue} runs this before any remaining queue items.
|
|
73
|
+
*/
|
|
74
|
+
private priorityPrompt;
|
|
75
|
+
/** Re-entrancy guard for {@link continueQueue}. */
|
|
76
|
+
private continuingQueue;
|
|
77
|
+
private provider;
|
|
78
|
+
private model;
|
|
79
|
+
private mode;
|
|
80
|
+
private compactingFlag;
|
|
81
|
+
/** Display name written into history.db (AI title or explicit /save name). */
|
|
82
|
+
private sessionTitle;
|
|
83
|
+
/** User-message count at last successful AI title (classic refresh cadence). */
|
|
84
|
+
private titledAtUserCount;
|
|
85
|
+
private titleInFlight;
|
|
86
|
+
constructor(deps: SessionControllerDeps);
|
|
87
|
+
get sessionId(): SessionId;
|
|
88
|
+
getState(): SessionState;
|
|
89
|
+
get messages(): readonly ChatMessage[];
|
|
90
|
+
/** Subscribe to transient UI state such as running/queue status. */
|
|
91
|
+
subscribe(listener: SessionStateListener): () => void;
|
|
92
|
+
setProvider(provider: ProviderId | undefined): void;
|
|
93
|
+
setModel(model: string | undefined): void;
|
|
94
|
+
setMode(mode: Mode): void;
|
|
95
|
+
/**
|
|
96
|
+
* Replace model history (and optionally rebind the session id so later
|
|
97
|
+
* autosaves update the resumed history row).
|
|
98
|
+
*/
|
|
99
|
+
loadHistory(messages: readonly ChatMessage[], options?: {
|
|
100
|
+
sessionId?: string;
|
|
101
|
+
title?: string | undefined;
|
|
102
|
+
}): void;
|
|
103
|
+
notice(level: NoticeLevel, text: string): void;
|
|
104
|
+
allowTool(name: string): void;
|
|
105
|
+
disallowTool(name: string): void;
|
|
106
|
+
allowedTools(): readonly string[];
|
|
107
|
+
/**
|
|
108
|
+
* Clear conversation state. When `mintNewId` is true (for `/new`/`/clean`),
|
|
109
|
+
* remint the session id so subsequent autosave does not overwrite the prior
|
|
110
|
+
* history row.
|
|
111
|
+
*/
|
|
112
|
+
reset(options?: {
|
|
113
|
+
mintNewId?: boolean;
|
|
114
|
+
}): void;
|
|
115
|
+
compact(sessionTranscript?: string, keepRecent?: number, signal?: AbortSignal): Promise<CompactResult>;
|
|
116
|
+
/** Persist current messages (+ optional visual transcript) under this session id. */
|
|
117
|
+
persistNow(name?: string): Promise<void>;
|
|
118
|
+
/**
|
|
119
|
+
* Ask the model for a short conversation title and upsert it into history.
|
|
120
|
+
* Cadence matches classic TUI: first completed exchange, then every +2 user
|
|
121
|
+
* turns so the name tracks the evolving topic.
|
|
122
|
+
*/
|
|
123
|
+
maybeRefreshTitle(): Promise<void>;
|
|
124
|
+
estimateContext(): {
|
|
125
|
+
messages: number;
|
|
126
|
+
tokens: number;
|
|
127
|
+
};
|
|
128
|
+
enqueue(prompt: string): void;
|
|
129
|
+
queued(): readonly string[];
|
|
130
|
+
removeQueued(index: number): void;
|
|
131
|
+
/**
|
|
132
|
+
* Remove a queued draft and return its text (for "Edit" → composer).
|
|
133
|
+
* Returns undefined when the index is out of range.
|
|
134
|
+
*/
|
|
135
|
+
takeQueued(index: number): string | undefined;
|
|
136
|
+
/** Edit a queued draft in place before it runs (INPUT-007). */
|
|
137
|
+
editQueued(index: number, text: string): void;
|
|
138
|
+
/** Move a queued draft to a new position before it runs (INPUT-007). */
|
|
139
|
+
reorderQueued(fromIndex: number, toIndex: number): void;
|
|
140
|
+
/**
|
|
141
|
+
* Send a queued prompt immediately. If a turn is running, abort it first;
|
|
142
|
+
* the chosen prompt runs next (ahead of any remaining queue). If idle,
|
|
143
|
+
* submit it now.
|
|
144
|
+
*/
|
|
145
|
+
sendQueuedNow(index: number): void;
|
|
146
|
+
abort(): void;
|
|
147
|
+
/**
|
|
148
|
+
* After a turn settles, run any "send now" priority prompt, then drain the
|
|
149
|
+
* queue one-by-one. Safe to call from onTurnEnd (re-entrancy guarded).
|
|
150
|
+
*/
|
|
151
|
+
continueQueue(): Promise<void>;
|
|
152
|
+
/** In-memory plan-approval flag consumed by the agent gate (CORE-005). */
|
|
153
|
+
setPlanApproved(value: boolean): void;
|
|
154
|
+
isPlanApproved(): boolean;
|
|
155
|
+
/** Fires after every turn settles (completed/aborted/error), including drain. */
|
|
156
|
+
onTurnEnd(listener: TurnEndListener): () => void;
|
|
157
|
+
submit(prompt: string): Promise<TurnResult>;
|
|
158
|
+
/**
|
|
159
|
+
* Runs queued prompts one at a time while idle; stops on first
|
|
160
|
+
* non-completion. Prefer {@link continueQueue} from the UI so priority
|
|
161
|
+
* ("send now") prompts are honored too.
|
|
162
|
+
*/
|
|
163
|
+
drain(): Promise<TurnResult[]>;
|
|
164
|
+
private runTurn;
|
|
165
|
+
dispose(): void;
|
|
166
|
+
private notifyState;
|
|
167
|
+
}
|