@oh-my-pi/pi-coding-agent 8.0.20 → 8.2.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/CHANGELOG.md +125 -0
- package/docs/session.md +111 -46
- package/examples/custom-tools/hello/index.ts +1 -1
- package/examples/custom-tools/todo/index.ts +3 -4
- package/examples/extensions/api-demo.ts +0 -1
- package/examples/extensions/chalk-logger.ts +2 -3
- package/examples/extensions/hello.ts +0 -1
- package/examples/extensions/pirate.ts +0 -1
- package/examples/extensions/plan-mode.ts +15 -16
- package/examples/extensions/todo.ts +3 -4
- package/examples/extensions/tools.ts +1 -2
- package/examples/extensions/with-deps/index.ts +0 -1
- package/examples/hooks/auto-commit-on-exit.ts +1 -2
- package/examples/hooks/confirm-destructive.ts +0 -1
- package/examples/hooks/custom-compaction.ts +1 -2
- package/examples/hooks/dirty-repo-guard.ts +0 -1
- package/examples/hooks/file-trigger.ts +3 -4
- package/examples/hooks/git-checkpoint.ts +0 -1
- package/examples/hooks/handoff.ts +3 -4
- package/examples/hooks/permission-gate.ts +1 -2
- package/examples/hooks/protected-paths.ts +1 -2
- package/examples/hooks/qna.ts +2 -3
- package/examples/hooks/snake.ts +4 -5
- package/examples/hooks/status-line.ts +0 -1
- package/examples/sdk/01-minimal.ts +2 -3
- package/examples/sdk/02-custom-model.ts +2 -3
- package/examples/sdk/03-custom-prompt.ts +3 -4
- package/examples/sdk/04-skills.ts +2 -3
- package/examples/sdk/06-extensions.ts +1 -2
- package/examples/sdk/06-hooks.ts +6 -7
- package/examples/sdk/07-context-files.ts +0 -1
- package/examples/sdk/08-prompt-templates.ts +0 -1
- package/examples/sdk/08-slash-commands.ts +0 -1
- package/examples/sdk/09-api-keys-and-oauth.ts +0 -1
- package/examples/sdk/10-settings.ts +0 -1
- package/examples/sdk/11-sessions.ts +0 -1
- package/package.json +54 -23
- package/scripts/format-prompts.ts +0 -1
- package/src/capability/context-file.ts +3 -4
- package/src/capability/extension-module.ts +3 -4
- package/src/capability/extension.ts +3 -4
- package/src/capability/fs.ts +20 -21
- package/src/capability/hook.ts +3 -4
- package/src/capability/index.ts +15 -16
- package/src/capability/instruction.ts +3 -4
- package/src/capability/mcp.ts +3 -4
- package/src/capability/prompt.ts +3 -4
- package/src/capability/rule.ts +3 -4
- package/src/capability/settings.ts +2 -3
- package/src/capability/skill.ts +3 -4
- package/src/capability/slash-command.ts +3 -4
- package/src/capability/ssh.ts +3 -4
- package/src/capability/system-prompt.ts +3 -4
- package/src/capability/tool.ts +3 -4
- package/src/cli/args.ts +5 -6
- package/src/cli/config-cli.ts +6 -7
- package/src/cli/file-processor.ts +19 -17
- package/src/cli/jupyter-cli.ts +105 -0
- package/src/cli/list-models.ts +10 -11
- package/src/cli/plugin-cli.ts +20 -25
- package/src/cli/session-picker.ts +2 -3
- package/src/cli/setup-cli.ts +2 -3
- package/src/cli/stats-cli.ts +2 -3
- package/src/cli/update-cli.ts +25 -22
- package/src/commit/agentic/agent.ts +307 -0
- package/src/commit/agentic/fallback.ts +96 -0
- package/src/commit/agentic/index.ts +351 -0
- package/src/commit/agentic/prompts/analyze-file.md +22 -0
- package/src/commit/agentic/prompts/session-user.md +26 -0
- package/src/commit/agentic/prompts/split-confirm.md +1 -0
- package/src/commit/agentic/prompts/system.md +40 -0
- package/src/commit/agentic/state.ts +69 -0
- package/src/commit/agentic/tools/analyze-file.ts +131 -0
- package/src/commit/agentic/tools/git-file-diff.ts +194 -0
- package/src/commit/agentic/tools/git-hunk.ts +50 -0
- package/src/commit/agentic/tools/git-overview.ts +84 -0
- package/src/commit/agentic/tools/index.ts +56 -0
- package/src/commit/agentic/tools/propose-changelog.ts +128 -0
- package/src/commit/agentic/tools/propose-commit.ts +154 -0
- package/src/commit/agentic/tools/recent-commits.ts +81 -0
- package/src/commit/agentic/tools/split-commit.ts +280 -0
- package/src/commit/agentic/topo-sort.ts +44 -0
- package/src/commit/agentic/trivial.ts +51 -0
- package/src/commit/agentic/validation.ts +200 -0
- package/src/commit/analysis/conventional.ts +165 -0
- package/src/commit/analysis/index.ts +4 -0
- package/src/commit/analysis/scope.ts +242 -0
- package/src/commit/analysis/summary.ts +112 -0
- package/src/commit/analysis/validation.ts +66 -0
- package/src/commit/changelog/detect.ts +36 -0
- package/src/commit/changelog/generate.ts +110 -0
- package/src/commit/changelog/index.ts +233 -0
- package/src/commit/changelog/parse.ts +44 -0
- package/src/commit/cli.ts +93 -0
- package/src/commit/git/diff.ts +148 -0
- package/src/commit/git/errors.ts +11 -0
- package/src/commit/git/index.ts +212 -0
- package/src/commit/git/operations.ts +53 -0
- package/src/commit/index.ts +5 -0
- package/src/commit/map-reduce/index.ts +63 -0
- package/src/commit/map-reduce/map-phase.ts +178 -0
- package/src/commit/map-reduce/reduce-phase.ts +145 -0
- package/src/commit/map-reduce/utils.ts +9 -0
- package/src/commit/message.ts +11 -0
- package/src/commit/model-selection.ts +80 -0
- package/src/commit/pipeline.ts +240 -0
- package/src/commit/prompts/analysis-system.md +155 -0
- package/src/commit/prompts/analysis-user.md +41 -0
- package/src/commit/prompts/changelog-system.md +56 -0
- package/src/commit/prompts/changelog-user.md +19 -0
- package/src/commit/prompts/file-observer-system.md +26 -0
- package/src/commit/prompts/file-observer-user.md +9 -0
- package/src/commit/prompts/reduce-system.md +60 -0
- package/src/commit/prompts/reduce-user.md +17 -0
- package/src/commit/prompts/summary-retry.md +4 -0
- package/src/commit/prompts/summary-system.md +52 -0
- package/src/commit/prompts/summary-user.md +13 -0
- package/src/commit/prompts/types-description.md +2 -0
- package/src/commit/types.ts +109 -0
- package/src/commit/utils/exclusions.ts +42 -0
- package/src/config/file-lock.ts +121 -0
- package/src/config/keybindings.ts +6 -8
- package/src/config/model-registry.ts +65 -38
- package/src/config/model-resolver.ts +18 -19
- package/src/config/prompt-templates.ts +11 -11
- package/src/config/settings-manager.ts +141 -50
- package/src/config.ts +64 -66
- package/src/cursor.ts +11 -9
- package/src/discovery/agents-md.ts +11 -12
- package/src/discovery/builtin.ts +68 -73
- package/src/discovery/claude.ts +41 -42
- package/src/discovery/cline.ts +11 -12
- package/src/discovery/codex.ts +52 -53
- package/src/discovery/cursor.ts +9 -10
- package/src/discovery/gemini.ts +17 -22
- package/src/discovery/github.ts +13 -14
- package/src/discovery/helpers.ts +35 -34
- package/src/discovery/index.ts +22 -24
- package/src/discovery/mcp-json.ts +8 -9
- package/src/discovery/ssh.ts +8 -9
- package/src/discovery/vscode.ts +4 -5
- package/src/discovery/windsurf.ts +6 -7
- package/src/exa/company.ts +1 -2
- package/src/exa/index.ts +2 -3
- package/src/exa/linkedin.ts +1 -2
- package/src/exa/mcp-client.ts +14 -16
- package/src/exa/render.ts +10 -11
- package/src/exa/researcher.ts +1 -2
- package/src/exa/search.ts +1 -2
- package/src/exa/types.ts +0 -1
- package/src/exa/websets.ts +1 -2
- package/src/exec/bash-executor.ts +3 -4
- package/src/exec/exec.ts +0 -1
- package/src/export/custom-share.ts +5 -6
- package/src/export/html/index.ts +24 -21
- package/src/export/ttsr.ts +2 -3
- package/src/extensibility/custom-commands/bundled/review/index.ts +7 -8
- package/src/extensibility/custom-commands/loader.ts +18 -15
- package/src/extensibility/custom-commands/types.ts +2 -3
- package/src/extensibility/custom-tools/loader.ts +11 -12
- package/src/extensibility/custom-tools/types.ts +7 -8
- package/src/extensibility/custom-tools/wrapper.ts +2 -3
- package/src/extensibility/extensions/loader.ts +76 -54
- package/src/extensibility/extensions/runner.ts +11 -12
- package/src/extensibility/extensions/types.ts +20 -27
- package/src/extensibility/extensions/wrapper.ts +3 -4
- package/src/extensibility/hooks/index.ts +1 -1
- package/src/extensibility/hooks/loader.ts +9 -10
- package/src/extensibility/hooks/runner.ts +7 -8
- package/src/extensibility/hooks/tool-wrapper.ts +0 -1
- package/src/extensibility/hooks/types.ts +11 -18
- package/src/extensibility/plugins/doctor.ts +3 -3
- package/src/extensibility/plugins/installer.ts +27 -27
- package/src/extensibility/plugins/loader.ts +59 -56
- package/src/extensibility/plugins/manager.ts +211 -171
- package/src/extensibility/plugins/parser.ts +1 -1
- package/src/extensibility/plugins/paths.ts +8 -8
- package/src/extensibility/skills.ts +63 -60
- package/src/extensibility/slash-commands.ts +10 -10
- package/src/index.ts +54 -54
- package/src/internal-urls/agent-protocol.ts +21 -11
- package/src/internal-urls/artifact-protocol.ts +17 -13
- package/src/internal-urls/router.ts +1 -2
- package/src/internal-urls/rule-protocol.ts +3 -4
- package/src/internal-urls/skill-protocol.ts +3 -4
- package/src/ipy/executor.ts +109 -9
- package/src/ipy/gateway-coordinator.ts +79 -90
- package/src/ipy/kernel.ts +32 -30
- package/src/ipy/modules.ts +13 -13
- package/src/lsp/client.ts +21 -10
- package/src/lsp/clients/biome-client.ts +1 -2
- package/src/lsp/clients/index.ts +3 -3
- package/src/lsp/clients/lsp-linter-client.ts +4 -5
- package/src/lsp/config.ts +15 -15
- package/src/lsp/edits.ts +4 -5
- package/src/lsp/index.ts +43 -44
- package/src/lsp/lspmux.ts +8 -8
- package/src/lsp/render.ts +99 -61
- package/src/lsp/utils.ts +3 -3
- package/src/main.ts +71 -37
- package/src/mcp/client.ts +2 -3
- package/src/mcp/config.ts +5 -6
- package/src/mcp/json-rpc.ts +0 -1
- package/src/mcp/loader.ts +6 -7
- package/src/mcp/manager.ts +17 -18
- package/src/mcp/tool-bridge.ts +4 -9
- package/src/mcp/tool-cache.ts +2 -3
- package/src/mcp/transports/http.ts +2 -4
- package/src/mcp/transports/stdio.ts +1 -2
- package/src/migrations.ts +63 -52
- package/src/modes/components/armin.ts +4 -5
- package/src/modes/components/assistant-message.ts +33 -5
- package/src/modes/components/bash-execution.ts +7 -8
- package/src/modes/components/bordered-loader.ts +3 -3
- package/src/modes/components/branch-summary-message.ts +3 -3
- package/src/modes/components/compaction-summary-message.ts +3 -3
- package/src/modes/components/countdown-timer.ts +0 -1
- package/src/modes/components/custom-message.ts +5 -5
- package/src/modes/components/diff.ts +1 -1
- package/src/modes/components/dynamic-border.ts +2 -2
- package/src/modes/components/extensions/extension-dashboard.ts +6 -7
- package/src/modes/components/extensions/extension-list.ts +2 -3
- package/src/modes/components/extensions/inspector-panel.ts +3 -4
- package/src/modes/components/extensions/state-manager.ts +25 -26
- package/src/modes/components/extensions/types.ts +1 -2
- package/src/modes/components/footer.ts +47 -43
- package/src/modes/components/history-search.ts +2 -2
- package/src/modes/components/hook-editor.ts +3 -4
- package/src/modes/components/hook-input.ts +2 -3
- package/src/modes/components/hook-message.ts +5 -5
- package/src/modes/components/hook-selector.ts +2 -3
- package/src/modes/components/keybinding-hints.ts +2 -3
- package/src/modes/components/login-dialog.ts +2 -2
- package/src/modes/components/model-selector.ts +12 -12
- package/src/modes/components/oauth-selector.ts +2 -2
- package/src/modes/components/plugin-settings.ts +20 -20
- package/src/modes/components/python-execution.ts +7 -8
- package/src/modes/components/queue-mode-selector.ts +3 -3
- package/src/modes/components/read-tool-group.ts +2 -2
- package/src/modes/components/session-selector.ts +4 -4
- package/src/modes/components/settings-defs.ts +77 -69
- package/src/modes/components/settings-selector.ts +16 -16
- package/src/modes/components/show-images-selector.ts +2 -2
- package/src/modes/components/status-line/segments.ts +4 -4
- package/src/modes/components/status-line/separators.ts +1 -1
- package/src/modes/components/status-line/types.ts +2 -2
- package/src/modes/components/status-line-segment-editor.ts +7 -8
- package/src/modes/components/status-line.ts +12 -12
- package/src/modes/components/theme-selector.ts +8 -7
- package/src/modes/components/thinking-selector.ts +4 -4
- package/src/modes/components/todo-display.ts +2 -2
- package/src/modes/components/todo-reminder.ts +4 -4
- package/src/modes/components/tool-execution.ts +16 -19
- package/src/modes/components/tree-selector.ts +12 -12
- package/src/modes/components/ttsr-notification.ts +5 -5
- package/src/modes/components/user-message-selector.ts +1 -1
- package/src/modes/components/user-message.ts +1 -1
- package/src/modes/components/visual-truncate.ts +0 -1
- package/src/modes/components/welcome.ts +4 -4
- package/src/modes/controllers/command-controller.ts +46 -47
- package/src/modes/controllers/event-controller.ts +16 -20
- package/src/modes/controllers/extension-ui-controller.ts +40 -46
- package/src/modes/controllers/input-controller.ts +17 -18
- package/src/modes/controllers/selector-controller.ts +103 -91
- package/src/modes/index.ts +3 -3
- package/src/modes/interactive-mode.ts +31 -31
- package/src/modes/print-mode.ts +12 -13
- package/src/modes/rpc/rpc-client.ts +7 -8
- package/src/modes/rpc/rpc-mode.ts +24 -28
- package/src/modes/rpc/rpc-types.ts +3 -4
- package/src/modes/theme/mermaid-cache.ts +89 -0
- package/src/modes/theme/theme.ts +130 -53
- package/src/modes/types.ts +10 -10
- package/src/modes/utils/ui-helpers.ts +17 -17
- package/src/patch/applicator.ts +18 -19
- package/src/patch/diff.ts +1 -2
- package/src/patch/fuzzy.ts +1 -2
- package/src/patch/index.ts +11 -18
- package/src/patch/normalize.ts +4 -4
- package/src/patch/normative.ts +1 -2
- package/src/patch/parser.ts +8 -9
- package/src/patch/shared.ts +43 -16
- package/src/prompts/tools/task.md +2 -0
- package/src/sdk.ts +100 -65
- package/src/session/agent-session.ts +84 -85
- package/src/session/agent-storage.ts +43 -39
- package/src/session/artifacts.ts +32 -10
- package/src/session/auth-storage.ts +50 -39
- package/src/session/compaction/branch-summarization.ts +7 -10
- package/src/session/compaction/compaction.ts +8 -19
- package/src/session/compaction/utils.ts +6 -9
- package/src/session/history-storage.ts +10 -10
- package/src/session/messages.ts +4 -5
- package/src/session/session-manager.ts +76 -65
- package/src/session/session-storage.ts +57 -69
- package/src/session/storage-migration.ts +14 -56
- package/src/session/streaming-output.ts +2 -2
- package/src/ssh/connection-manager.ts +43 -50
- package/src/ssh/ssh-executor.ts +2 -2
- package/src/ssh/sshfs-mount.ts +11 -18
- package/src/system-prompt.ts +28 -35
- package/src/task/agents.ts +45 -30
- package/src/task/commands.ts +6 -7
- package/src/task/discovery.ts +39 -76
- package/src/task/executor.ts +14 -15
- package/src/task/index.ts +40 -34
- package/src/task/output-manager.ts +93 -0
- package/src/task/parallel.ts +0 -1
- package/src/task/render.ts +24 -30
- package/src/task/subprocess-tool-registry.ts +1 -2
- package/src/task/worker-protocol.ts +3 -3
- package/src/task/worker.ts +33 -39
- package/src/task/worktree.ts +19 -19
- package/src/tools/ask.ts +41 -20
- package/src/tools/bash-interceptor.ts +1 -5
- package/src/tools/bash.ts +91 -97
- package/src/tools/calculator.ts +49 -47
- package/src/tools/complete.ts +4 -5
- package/src/tools/context.ts +2 -2
- package/src/tools/fetch.ts +84 -124
- package/src/tools/find.ts +94 -98
- package/src/tools/gemini-image.ts +14 -14
- package/src/tools/grep.ts +100 -116
- package/src/tools/index.ts +80 -55
- package/src/tools/list-limit.ts +1 -1
- package/src/tools/ls.ts +44 -70
- package/src/tools/notebook.ts +51 -67
- package/src/tools/output-meta.ts +3 -4
- package/src/tools/output-utils.ts +2 -2
- package/src/tools/path-utils.ts +5 -5
- package/src/tools/python.ts +104 -217
- package/src/tools/read.ts +92 -33
- package/src/tools/render-utils.ts +8 -23
- package/src/tools/renderers.ts +6 -7
- package/src/tools/review.ts +8 -11
- package/src/tools/ssh.ts +69 -49
- package/src/tools/todo-write.ts +37 -25
- package/src/tools/tool-errors.ts +3 -3
- package/src/tools/tool-result.ts +3 -8
- package/src/tools/write.ts +99 -75
- package/src/tui/code-cell.ts +109 -0
- package/src/tui/file-list.ts +47 -0
- package/src/tui/index.ts +11 -0
- package/src/tui/output-block.ts +72 -0
- package/src/tui/status-line.ts +39 -0
- package/src/tui/tree-list.ts +55 -0
- package/src/tui/types.ts +16 -0
- package/src/tui/utils.ts +48 -0
- package/src/utils/changelog.ts +9 -10
- package/src/utils/clipboard.ts +11 -11
- package/src/utils/file-mentions.ts +4 -10
- package/src/utils/frontmatter.ts +6 -3
- package/src/utils/fuzzy.ts +2 -2
- package/src/utils/image-convert.ts +1 -1
- package/src/utils/image-resize.ts +1 -1
- package/src/utils/mime.ts +2 -2
- package/src/utils/shell-snapshot.ts +11 -13
- package/src/utils/shell.ts +4 -5
- package/src/utils/title-generator.ts +8 -9
- package/src/utils/tools-manager.ts +23 -23
- package/src/vendor/photon/index.js +1099 -1059
- package/src/vendor/photon/photon_rs_bg.wasm +0 -0
- package/src/web/scrapers/artifacthub.ts +1 -1
- package/src/web/scrapers/arxiv.ts +2 -2
- package/src/web/scrapers/bluesky.ts +2 -2
- package/src/web/scrapers/cheatsh.ts +1 -1
- package/src/web/scrapers/chocolatey.ts +2 -2
- package/src/web/scrapers/choosealicense.ts +5 -5
- package/src/web/scrapers/cisa-kev.ts +1 -1
- package/src/web/scrapers/crossref.ts +2 -2
- package/src/web/scrapers/devto.ts +3 -3
- package/src/web/scrapers/discogs.ts +3 -4
- package/src/web/scrapers/discourse.ts +1 -1
- package/src/web/scrapers/dockerhub.ts +1 -1
- package/src/web/scrapers/fdroid.ts +2 -2
- package/src/web/scrapers/firefox-addons.ts +3 -3
- package/src/web/scrapers/flathub.ts +1 -1
- package/src/web/scrapers/github.ts +3 -3
- package/src/web/scrapers/gitlab.ts +4 -4
- package/src/web/scrapers/hackernews.ts +2 -2
- package/src/web/scrapers/huggingface.ts +1 -1
- package/src/web/scrapers/iacr.ts +2 -2
- package/src/web/scrapers/index.ts +0 -1
- package/src/web/scrapers/jetbrains-marketplace.ts +1 -1
- package/src/web/scrapers/lemmy.ts +2 -2
- package/src/web/scrapers/maven.ts +2 -2
- package/src/web/scrapers/mdn.ts +2 -4
- package/src/web/scrapers/metacpan.ts +2 -2
- package/src/web/scrapers/musicbrainz.ts +1 -2
- package/src/web/scrapers/npm.ts +1 -1
- package/src/web/scrapers/nuget.ts +2 -2
- package/src/web/scrapers/nvd.ts +3 -3
- package/src/web/scrapers/ollama.ts +7 -9
- package/src/web/scrapers/opencorporates.ts +2 -2
- package/src/web/scrapers/openlibrary.ts +6 -6
- package/src/web/scrapers/orcid.ts +0 -1
- package/src/web/scrapers/osv.ts +2 -2
- package/src/web/scrapers/packagist.ts +1 -1
- package/src/web/scrapers/pubmed.ts +1 -2
- package/src/web/scrapers/rawg.ts +2 -2
- package/src/web/scrapers/readthedocs.ts +1 -2
- package/src/web/scrapers/repology.ts +2 -2
- package/src/web/scrapers/rfc.ts +1 -1
- package/src/web/scrapers/searchcode.ts +2 -2
- package/src/web/scrapers/semantic-scholar.ts +1 -1
- package/src/web/scrapers/snapcraft.ts +2 -2
- package/src/web/scrapers/sourcegraph.ts +1 -1
- package/src/web/scrapers/spdx.ts +3 -3
- package/src/web/scrapers/spotify.ts +0 -1
- package/src/web/scrapers/twitter.ts +1 -1
- package/src/web/scrapers/types.ts +1 -2
- package/src/web/scrapers/utils.ts +5 -5
- package/src/web/scrapers/wikidata.ts +3 -3
- package/src/web/scrapers/youtube.ts +9 -14
- package/src/web/search/auth.ts +5 -10
- package/src/web/search/index.ts +11 -21
- package/src/web/search/providers/anthropic.ts +3 -9
- package/src/web/search/providers/exa.ts +6 -10
- package/src/web/search/providers/perplexity.ts +5 -5
- package/src/web/search/render.ts +129 -175
- package/tsconfig.json +0 -42
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { APP_NAME } from "@oh-my-pi/pi-coding-agent/config";
|
|
2
|
-
import { theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
|
|
3
1
|
import { type Component, truncateToWidth, visibleWidth } from "@oh-my-pi/pi-tui";
|
|
2
|
+
import { APP_NAME } from "../../config";
|
|
3
|
+
import { theme } from "../../modes/theme/theme";
|
|
4
4
|
|
|
5
5
|
export interface RecentSession {
|
|
6
6
|
name: string;
|
|
@@ -65,14 +65,14 @@ export class WelcomeComponent implements Component {
|
|
|
65
65
|
const piLogo = ["▀████████████▀", " ╘███ ███ ", " ███ ███ ", " ███ ███ ", " ▄███▄ ▄███▄ "];
|
|
66
66
|
|
|
67
67
|
// Apply gradient to logo
|
|
68
|
-
const logoColored = piLogo.map(
|
|
68
|
+
const logoColored = piLogo.map(line => this.gradientLine(line));
|
|
69
69
|
|
|
70
70
|
// Left column - centered content
|
|
71
71
|
const leftLines = [
|
|
72
72
|
"",
|
|
73
73
|
this.centerText(theme.bold("Welcome back!"), leftCol),
|
|
74
74
|
"",
|
|
75
|
-
...logoColored.map(
|
|
75
|
+
...logoColored.map(l => this.centerText(l, leftCol)),
|
|
76
76
|
"",
|
|
77
77
|
this.centerText(theme.fg("muted", this.modelName), leftCol),
|
|
78
78
|
this.centerText(theme.fg("borderMuted", this.providerName), leftCol),
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
2
|
import * as os from "node:os";
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import type { UsageLimit, UsageReport } from "@oh-my-pi/pi-ai";
|
|
5
|
-
import { getDebugLogPath } from "@oh-my-pi/pi-coding-agent/config";
|
|
6
|
-
import { loadCustomShare } from "@oh-my-pi/pi-coding-agent/export/custom-share";
|
|
7
|
-
import type { CompactOptions } from "@oh-my-pi/pi-coding-agent/extensibility/extensions/types";
|
|
8
|
-
import { getGatewayStatus } from "@oh-my-pi/pi-coding-agent/ipy/gateway-coordinator";
|
|
9
|
-
import { ArminComponent } from "@oh-my-pi/pi-coding-agent/modes/components/armin";
|
|
10
|
-
import { BashExecutionComponent } from "@oh-my-pi/pi-coding-agent/modes/components/bash-execution";
|
|
11
|
-
import { BorderedLoader } from "@oh-my-pi/pi-coding-agent/modes/components/bordered-loader";
|
|
12
|
-
import { DynamicBorder } from "@oh-my-pi/pi-coding-agent/modes/components/dynamic-border";
|
|
13
|
-
import { PythonExecutionComponent } from "@oh-my-pi/pi-coding-agent/modes/components/python-execution";
|
|
14
|
-
import { getMarkdownTheme, getSymbolTheme, theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
|
|
15
|
-
import type { InteractiveModeContext } from "@oh-my-pi/pi-coding-agent/modes/types";
|
|
16
|
-
import { createCompactionSummaryMessage } from "@oh-my-pi/pi-coding-agent/session/messages";
|
|
17
|
-
import { outputMeta } from "@oh-my-pi/pi-coding-agent/tools/output-meta";
|
|
18
|
-
import { getChangelogPath, parseChangelog } from "@oh-my-pi/pi-coding-agent/utils/changelog";
|
|
19
|
-
import { copyToClipboard } from "@oh-my-pi/pi-coding-agent/utils/clipboard";
|
|
20
5
|
import { Loader, Markdown, Spacer, Text, visibleWidth } from "@oh-my-pi/pi-tui";
|
|
21
6
|
import { $ } from "bun";
|
|
22
7
|
import { nanoid } from "nanoid";
|
|
8
|
+
import { getDebugLogPath } from "../../config";
|
|
9
|
+
import { loadCustomShare } from "../../export/custom-share";
|
|
10
|
+
import type { CompactOptions } from "../../extensibility/extensions/types";
|
|
11
|
+
import { getGatewayStatus } from "../../ipy/gateway-coordinator";
|
|
12
|
+
import { ArminComponent } from "../../modes/components/armin";
|
|
13
|
+
import { BashExecutionComponent } from "../../modes/components/bash-execution";
|
|
14
|
+
import { BorderedLoader } from "../../modes/components/bordered-loader";
|
|
15
|
+
import { DynamicBorder } from "../../modes/components/dynamic-border";
|
|
16
|
+
import { PythonExecutionComponent } from "../../modes/components/python-execution";
|
|
17
|
+
import { getMarkdownTheme, getSymbolTheme, theme } from "../../modes/theme/theme";
|
|
18
|
+
import type { InteractiveModeContext } from "../../modes/types";
|
|
19
|
+
import { createCompactionSummaryMessage } from "../../session/messages";
|
|
20
|
+
import { outputMeta } from "../../tools/output-meta";
|
|
21
|
+
import { getChangelogPath, parseChangelog } from "../../utils/changelog";
|
|
22
|
+
import { copyToClipboard } from "../../utils/clipboard";
|
|
23
23
|
|
|
24
24
|
export class CommandController {
|
|
25
25
|
constructor(private readonly ctx: InteractiveModeContext) {}
|
|
@@ -77,7 +77,7 @@ export class CommandController {
|
|
|
77
77
|
const tmpFile = path.join(os.tmpdir(), `${nanoid()}.html`);
|
|
78
78
|
const cleanupTempFile = async () => {
|
|
79
79
|
try {
|
|
80
|
-
await rm(tmpFile, { force: true });
|
|
80
|
+
await fs.rm(tmpFile, { force: true });
|
|
81
81
|
} catch {
|
|
82
82
|
// Ignore cleanup errors
|
|
83
83
|
}
|
|
@@ -212,7 +212,7 @@ export class CommandController {
|
|
|
212
212
|
}
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
-
handleSessionCommand(): void {
|
|
215
|
+
async handleSessionCommand(): Promise<void> {
|
|
216
216
|
const stats = this.ctx.session.getSessionStats();
|
|
217
217
|
|
|
218
218
|
let info = `${theme.bold("Session Info")}\n\n`;
|
|
@@ -240,7 +240,7 @@ export class CommandController {
|
|
|
240
240
|
info += `${theme.fg("dim", "Total:")} ${stats.cost.toFixed(4)}\n`;
|
|
241
241
|
}
|
|
242
242
|
|
|
243
|
-
const gateway = getGatewayStatus();
|
|
243
|
+
const gateway = await getGatewayStatus();
|
|
244
244
|
info += `\n${theme.bold("Python Gateway")}\n`;
|
|
245
245
|
if (gateway.active) {
|
|
246
246
|
info += `${theme.fg("dim", "Status:")} ${theme.fg("success", "Active (Global)")}\n`;
|
|
@@ -316,15 +316,15 @@ export class CommandController {
|
|
|
316
316
|
this.ctx.ui.requestRender();
|
|
317
317
|
}
|
|
318
318
|
|
|
319
|
-
handleChangelogCommand(): void {
|
|
319
|
+
async handleChangelogCommand(): Promise<void> {
|
|
320
320
|
const changelogPath = getChangelogPath();
|
|
321
|
-
const allEntries = parseChangelog(changelogPath);
|
|
321
|
+
const allEntries = await parseChangelog(changelogPath);
|
|
322
322
|
|
|
323
323
|
const changelogMarkdown =
|
|
324
324
|
allEntries.length > 0
|
|
325
325
|
? allEntries
|
|
326
326
|
.reverse()
|
|
327
|
-
.map(
|
|
327
|
+
.map(e => e.content)
|
|
328
328
|
.join("\n\n")
|
|
329
329
|
: "No changelog entries found.";
|
|
330
330
|
|
|
@@ -434,12 +434,11 @@ export class CommandController {
|
|
|
434
434
|
}),
|
|
435
435
|
"",
|
|
436
436
|
"=== Agent messages (JSONL) ===",
|
|
437
|
-
...this.ctx.session.messages.map(
|
|
437
|
+
...this.ctx.session.messages.map(msg => JSON.stringify(msg)),
|
|
438
438
|
"",
|
|
439
439
|
].join("\n");
|
|
440
440
|
|
|
441
441
|
try {
|
|
442
|
-
await mkdir(path.dirname(debugLogPath), { recursive: true });
|
|
443
442
|
await Bun.write(debugLogPath, debugData);
|
|
444
443
|
} catch (error) {
|
|
445
444
|
this.ctx.showError(`Failed to write debug log: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -478,7 +477,7 @@ export class CommandController {
|
|
|
478
477
|
try {
|
|
479
478
|
const result = await this.ctx.session.executeBash(
|
|
480
479
|
command,
|
|
481
|
-
|
|
480
|
+
chunk => {
|
|
482
481
|
if (this.ctx.bashComponent) {
|
|
483
482
|
this.ctx.bashComponent.appendOutput(chunk);
|
|
484
483
|
this.ctx.ui.requestRender();
|
|
@@ -520,7 +519,7 @@ export class CommandController {
|
|
|
520
519
|
try {
|
|
521
520
|
const result = await this.ctx.session.executePython(
|
|
522
521
|
code,
|
|
523
|
-
|
|
522
|
+
chunk => {
|
|
524
523
|
if (this.ctx.pythonComponent) {
|
|
525
524
|
this.ctx.pythonComponent.appendOutput(chunk);
|
|
526
525
|
this.ctx.ui.requestRender();
|
|
@@ -549,7 +548,7 @@ export class CommandController {
|
|
|
549
548
|
|
|
550
549
|
async handleCompactCommand(customInstructions?: string): Promise<void> {
|
|
551
550
|
const entries = this.ctx.sessionManager.getEntries();
|
|
552
|
-
const messageCount = entries.filter(
|
|
551
|
+
const messageCount = entries.filter(e => e.type === "message").length;
|
|
553
552
|
|
|
554
553
|
if (messageCount < 2) {
|
|
555
554
|
this.ctx.showWarning("Nothing to compact (no messages yet)");
|
|
@@ -590,8 +589,8 @@ export class CommandController {
|
|
|
590
589
|
const label = isAuto ? "Auto-compacting context... (esc to cancel)" : "Compacting context... (esc to cancel)";
|
|
591
590
|
const compactingLoader = new Loader(
|
|
592
591
|
this.ctx.ui,
|
|
593
|
-
|
|
594
|
-
|
|
592
|
+
spinner => theme.fg("accent", spinner),
|
|
593
|
+
text => theme.fg("muted", text),
|
|
595
594
|
label,
|
|
596
595
|
getSymbolTheme().spinnerFrames,
|
|
597
596
|
);
|
|
@@ -635,7 +634,7 @@ const COLUMN_WIDTH = BAR_WIDTH + 2;
|
|
|
635
634
|
function formatProviderName(provider: string): string {
|
|
636
635
|
return provider
|
|
637
636
|
.split(/[-_]/g)
|
|
638
|
-
.map(
|
|
637
|
+
.map(part => (part ? part[0].toUpperCase() + part.slice(1) : ""))
|
|
639
638
|
.join(" ");
|
|
640
639
|
}
|
|
641
640
|
|
|
@@ -688,8 +687,8 @@ function resolveFraction(limit: UsageLimit): number | undefined {
|
|
|
688
687
|
|
|
689
688
|
function resolveProviderUsageTotal(reports: UsageReport[]): number {
|
|
690
689
|
return reports
|
|
691
|
-
.flatMap(
|
|
692
|
-
.map(
|
|
690
|
+
.flatMap(report => report.limits)
|
|
691
|
+
.map(limit => resolveFraction(limit) ?? 0)
|
|
693
692
|
.reduce((sum, value) => sum + value, 0);
|
|
694
693
|
}
|
|
695
694
|
|
|
@@ -741,9 +740,9 @@ function padColumn(text: string, width: number): string {
|
|
|
741
740
|
}
|
|
742
741
|
|
|
743
742
|
function resolveAggregateStatus(limits: UsageLimit[]): UsageLimit["status"] {
|
|
744
|
-
const hasOk = limits.some(
|
|
745
|
-
const hasWarning = limits.some(
|
|
746
|
-
const hasExhausted = limits.some(
|
|
743
|
+
const hasOk = limits.some(limit => limit.status === "ok");
|
|
744
|
+
const hasWarning = limits.some(limit => limit.status === "warning");
|
|
745
|
+
const hasExhausted = limits.some(limit => limit.status === "exhausted");
|
|
747
746
|
if (!hasOk && !hasWarning && !hasExhausted) return "unknown";
|
|
748
747
|
if (hasOk) {
|
|
749
748
|
return hasWarning || hasExhausted ? "warning" : "ok";
|
|
@@ -762,12 +761,12 @@ function isZeroUsage(limit: UsageLimit): boolean {
|
|
|
762
761
|
}
|
|
763
762
|
|
|
764
763
|
function isZeroUsageGroup(limits: UsageLimit[]): boolean {
|
|
765
|
-
return limits.length > 0 && limits.every(
|
|
764
|
+
return limits.length > 0 && limits.every(limit => isZeroUsage(limit));
|
|
766
765
|
}
|
|
767
766
|
|
|
768
767
|
function formatAggregateAmount(limits: UsageLimit[]): string {
|
|
769
768
|
const fractions = limits
|
|
770
|
-
.map(
|
|
769
|
+
.map(limit => resolveFraction(limit))
|
|
771
770
|
.filter((value): value is number => value !== undefined);
|
|
772
771
|
if (fractions.length === limits.length && fractions.length > 0) {
|
|
773
772
|
const sum = fractions.reduce((total, value) => total + value, 0);
|
|
@@ -778,8 +777,8 @@ function formatAggregateAmount(limits: UsageLimit[]): string {
|
|
|
778
777
|
}
|
|
779
778
|
|
|
780
779
|
const amounts = limits
|
|
781
|
-
.map(
|
|
782
|
-
.filter(
|
|
780
|
+
.map(limit => limit.amount)
|
|
781
|
+
.filter(amount => amount.used !== undefined && amount.limit !== undefined && amount.limit > 0);
|
|
783
782
|
if (amounts.length === limits.length && amounts.length > 0) {
|
|
784
783
|
const totalUsed = amounts.reduce((sum, amount) => sum + (amount.used ?? 0), 0);
|
|
785
784
|
const totalLimit = amounts.reduce((sum, amount) => sum + (amount.limit ?? 0), 0);
|
|
@@ -794,11 +793,11 @@ function formatAggregateAmount(limits: UsageLimit[]): string {
|
|
|
794
793
|
|
|
795
794
|
function resolveResetRange(limits: UsageLimit[], nowMs: number): string | null {
|
|
796
795
|
const resets = limits
|
|
797
|
-
.map(
|
|
796
|
+
.map(limit => limit.window?.resetInMs ?? undefined)
|
|
798
797
|
.filter((value): value is number => value !== undefined && Number.isFinite(value) && value > 0);
|
|
799
798
|
if (resets.length === 0) {
|
|
800
799
|
const absolute = limits
|
|
801
|
-
.map(
|
|
800
|
+
.map(limit => limit.window?.resetsAt)
|
|
802
801
|
.filter((value): value is number => value !== undefined && Number.isFinite(value) && value > nowMs);
|
|
803
802
|
if (absolute.length === 0) return null;
|
|
804
803
|
const earliest = Math.min(...absolute);
|
|
@@ -841,7 +840,7 @@ function renderUsageBar(limit: UsageLimit, uiTheme: typeof theme): string {
|
|
|
841
840
|
|
|
842
841
|
function renderUsageReports(reports: UsageReport[], uiTheme: typeof theme, nowMs: number): string {
|
|
843
842
|
const lines: string[] = [];
|
|
844
|
-
const latestFetchedAt = Math.max(...reports.map(
|
|
843
|
+
const latestFetchedAt = Math.max(...reports.map(report => report.fetchedAt ?? 0));
|
|
845
844
|
const headerSuffix = latestFetchedAt ? ` (${formatDuration(nowMs - latestFetchedAt)} ago)` : "";
|
|
846
845
|
lines.push(uiTheme.bold(uiTheme.fg("accent", `Usage${headerSuffix}`)));
|
|
847
846
|
const grouped = new Map<string, UsageReport[]>();
|
|
@@ -886,7 +885,7 @@ function renderUsageReports(reports: UsageReport[], uiTheme: typeof theme, nowMs
|
|
|
886
885
|
}
|
|
887
886
|
}
|
|
888
887
|
|
|
889
|
-
const providerAllZero = isZeroUsageGroup(Array.from(limitGroups.values()).flatMap(
|
|
888
|
+
const providerAllZero = isZeroUsageGroup(Array.from(limitGroups.values()).flatMap(group => group.limits));
|
|
890
889
|
if (providerAllZero) {
|
|
891
890
|
const providerTitle = `${resolveStatusIcon("ok", uiTheme)} ${uiTheme.fg("accent", `${providerName} (0%)`)}`;
|
|
892
891
|
lines.push(uiTheme.bold(providerTitle));
|
|
@@ -908,8 +907,8 @@ function renderUsageReports(reports: UsageReport[], uiTheme: typeof theme, nowMs
|
|
|
908
907
|
if (aFraction !== bFraction) return bFraction - aFraction;
|
|
909
908
|
return a.index - b.index;
|
|
910
909
|
});
|
|
911
|
-
const sortedLimits = entries.map(
|
|
912
|
-
const sortedReports = entries.map(
|
|
910
|
+
const sortedLimits = entries.map(entry => entry.limit);
|
|
911
|
+
const sortedReports = entries.map(entry => entry.report);
|
|
913
912
|
|
|
914
913
|
const status = resolveAggregateStatus(sortedLimits);
|
|
915
914
|
const statusIcon = resolveStatusIcon(status, uiTheme);
|
|
@@ -932,13 +931,13 @@ function renderUsageReports(reports: UsageReport[], uiTheme: typeof theme, nowMs
|
|
|
932
931
|
padColumn(formatAccountHeader(limit, sortedReports[index], index, nowMs), COLUMN_WIDTH),
|
|
933
932
|
);
|
|
934
933
|
lines.push(` ${accountLabels.join(" ")}`.trimEnd());
|
|
935
|
-
const bars = sortedLimits.map(
|
|
934
|
+
const bars = sortedLimits.map(limit => padColumn(renderUsageBar(limit, uiTheme), COLUMN_WIDTH));
|
|
936
935
|
lines.push(` ${bars.join(" ")} ${formatAggregateAmount(sortedLimits)}`.trimEnd());
|
|
937
936
|
const resetText = sortedLimits.length <= 1 ? resolveResetRange(sortedLimits, nowMs) : null;
|
|
938
937
|
if (resetText) {
|
|
939
938
|
lines.push(` ${uiTheme.fg("dim", resetText)}`.trimEnd());
|
|
940
939
|
}
|
|
941
|
-
const notes = sortedLimits.flatMap(
|
|
940
|
+
const notes = sortedLimits.flatMap(limit => limit.notes ?? []);
|
|
942
941
|
if (notes.length > 0) {
|
|
943
942
|
lines.push(` ${uiTheme.fg("dim", notes.join(" • "))}`.trimEnd());
|
|
944
943
|
}
|
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
import { AssistantMessageComponent } from "@oh-my-pi/pi-coding-agent/modes/components/assistant-message";
|
|
2
|
-
import { ReadToolGroupComponent } from "@oh-my-pi/pi-coding-agent/modes/components/read-tool-group";
|
|
3
|
-
import { TodoReminderComponent } from "@oh-my-pi/pi-coding-agent/modes/components/todo-reminder";
|
|
4
|
-
import { ToolExecutionComponent } from "@oh-my-pi/pi-coding-agent/modes/components/tool-execution";
|
|
5
|
-
import { TtsrNotificationComponent } from "@oh-my-pi/pi-coding-agent/modes/components/ttsr-notification";
|
|
6
|
-
import { getSymbolTheme, theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
|
|
7
|
-
import type { InteractiveModeContext, TodoItem } from "@oh-my-pi/pi-coding-agent/modes/types";
|
|
8
|
-
import type { AgentSessionEvent } from "@oh-my-pi/pi-coding-agent/session/agent-session";
|
|
9
|
-
import {
|
|
10
|
-
detectNotificationProtocol,
|
|
11
|
-
isNotificationSuppressed,
|
|
12
|
-
sendNotification,
|
|
13
|
-
} from "@oh-my-pi/pi-coding-agent/utils/terminal-notify";
|
|
14
1
|
import { Loader, Text } from "@oh-my-pi/pi-tui";
|
|
2
|
+
import { AssistantMessageComponent } from "../../modes/components/assistant-message";
|
|
3
|
+
import { ReadToolGroupComponent } from "../../modes/components/read-tool-group";
|
|
4
|
+
import { TodoReminderComponent } from "../../modes/components/todo-reminder";
|
|
5
|
+
import { ToolExecutionComponent } from "../../modes/components/tool-execution";
|
|
6
|
+
import { TtsrNotificationComponent } from "../../modes/components/ttsr-notification";
|
|
7
|
+
import { getSymbolTheme, theme } from "../../modes/theme/theme";
|
|
8
|
+
import type { InteractiveModeContext, TodoItem } from "../../modes/types";
|
|
9
|
+
import type { AgentSessionEvent } from "../../session/agent-session";
|
|
10
|
+
import { detectNotificationProtocol, isNotificationSuppressed, sendNotification } from "../../utils/terminal-notify";
|
|
15
11
|
|
|
16
12
|
export class EventController {
|
|
17
13
|
private lastReadGroup: ReadToolGroupComponent | undefined = undefined;
|
|
@@ -66,8 +62,8 @@ export class EventController {
|
|
|
66
62
|
this.ctx.statusContainer.clear();
|
|
67
63
|
this.ctx.loadingAnimation = new Loader(
|
|
68
64
|
this.ctx.ui,
|
|
69
|
-
|
|
70
|
-
|
|
65
|
+
spinner => theme.fg("accent", spinner),
|
|
66
|
+
text => theme.fg("muted", text),
|
|
71
67
|
`Working${theme.format.ellipsis} (esc to interrupt)`,
|
|
72
68
|
getSymbolTheme().spinnerFrames,
|
|
73
69
|
);
|
|
@@ -111,7 +107,7 @@ export class EventController {
|
|
|
111
107
|
this.ctx.streamingComponent.updateContent(this.ctx.streamingMessage);
|
|
112
108
|
|
|
113
109
|
const thinkingCount = this.ctx.streamingMessage.content.filter(
|
|
114
|
-
|
|
110
|
+
content => content.type === "thinking" && content.thinking.trim(),
|
|
115
111
|
).length;
|
|
116
112
|
if (thinkingCount > this.lastThinkingCount) {
|
|
117
113
|
this.resetReadGroup();
|
|
@@ -277,8 +273,8 @@ export class EventController {
|
|
|
277
273
|
const reasonText = event.reason === "overflow" ? "Context overflow detected, " : "";
|
|
278
274
|
this.ctx.autoCompactionLoader = new Loader(
|
|
279
275
|
this.ctx.ui,
|
|
280
|
-
|
|
281
|
-
|
|
276
|
+
spinner => theme.fg("accent", spinner),
|
|
277
|
+
text => theme.fg("muted", text),
|
|
282
278
|
`${reasonText}Auto-compacting${theme.format.ellipsis} (esc to cancel)`,
|
|
283
279
|
getSymbolTheme().spinnerFrames,
|
|
284
280
|
);
|
|
@@ -327,8 +323,8 @@ export class EventController {
|
|
|
327
323
|
const delaySeconds = Math.round(event.delayMs / 1000);
|
|
328
324
|
this.ctx.retryLoader = new Loader(
|
|
329
325
|
this.ctx.ui,
|
|
330
|
-
|
|
331
|
-
|
|
326
|
+
spinner => theme.fg("warning", spinner),
|
|
327
|
+
text => theme.fg("muted", text),
|
|
332
328
|
`Retrying (${event.attempt}/${event.maxAttempts}) in ${delaySeconds}s${theme.format.ellipsis} (esc to cancel)`,
|
|
333
329
|
getSymbolTheme().spinnerFrames,
|
|
334
330
|
);
|
|
@@ -1,26 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Component, TUI } from "@oh-my-pi/pi-tui";
|
|
2
|
+
import { Spacer, Text } from "@oh-my-pi/pi-tui";
|
|
3
|
+
import { logger } from "@oh-my-pi/pi-utils";
|
|
4
|
+
import { KeybindingsManager } from "../../config/keybindings";
|
|
2
5
|
import type {
|
|
3
6
|
ExtensionActions,
|
|
4
7
|
ExtensionCommandContextActions,
|
|
5
8
|
ExtensionContextActions,
|
|
6
9
|
ExtensionError,
|
|
7
10
|
ExtensionUIContext,
|
|
8
|
-
} from "
|
|
9
|
-
import { HookEditorComponent } from "
|
|
10
|
-
import { HookInputComponent } from "
|
|
11
|
-
import { HookSelectorComponent } from "
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
setTheme,
|
|
16
|
-
type Theme,
|
|
17
|
-
theme,
|
|
18
|
-
} from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
|
|
19
|
-
import type { InteractiveModeContext } from "@oh-my-pi/pi-coding-agent/modes/types";
|
|
20
|
-
import { setTerminalTitle } from "@oh-my-pi/pi-coding-agent/utils/title-generator";
|
|
21
|
-
import type { Component, TUI } from "@oh-my-pi/pi-tui";
|
|
22
|
-
import { Spacer, Text } from "@oh-my-pi/pi-tui";
|
|
23
|
-
import { logger } from "@oh-my-pi/pi-utils";
|
|
11
|
+
} from "../../extensibility/extensions";
|
|
12
|
+
import { HookEditorComponent } from "../../modes/components/hook-editor";
|
|
13
|
+
import { HookInputComponent } from "../../modes/components/hook-input";
|
|
14
|
+
import { HookSelectorComponent } from "../../modes/components/hook-selector";
|
|
15
|
+
import { getAvailableThemesWithPaths, getThemeByName, setTheme, type Theme, theme } from "../../modes/theme/theme";
|
|
16
|
+
import type { InteractiveModeContext } from "../../modes/types";
|
|
17
|
+
import { setTerminalTitle } from "../../utils/title-generator";
|
|
24
18
|
|
|
25
19
|
export class ExtensionUiController {
|
|
26
20
|
constructor(private ctx: InteractiveModeContext) {}
|
|
@@ -37,22 +31,22 @@ export class ExtensionUiController {
|
|
|
37
31
|
notify: (message, type) => this.showHookNotify(message, type),
|
|
38
32
|
setStatus: (key, text) => this.setHookStatus(key, text),
|
|
39
33
|
setWidget: (key, content) => this.setHookWidget(key, content),
|
|
40
|
-
setTitle:
|
|
34
|
+
setTitle: title => setTerminalTitle(title),
|
|
41
35
|
custom: (factory, _options) => this.showHookCustom(factory),
|
|
42
|
-
setEditorText:
|
|
36
|
+
setEditorText: text => this.ctx.editor.setText(text),
|
|
43
37
|
getEditorText: () => this.ctx.editor.getText(),
|
|
44
38
|
editor: (title, prefill) => this.showHookEditor(title, prefill),
|
|
45
39
|
get theme() {
|
|
46
40
|
return theme;
|
|
47
41
|
},
|
|
48
|
-
getAllThemes: () => getAvailableThemesWithPaths().map(
|
|
49
|
-
getTheme:
|
|
50
|
-
setTheme:
|
|
42
|
+
getAllThemes: async () => (await getAvailableThemesWithPaths()).map(t => ({ name: t.name, path: t.path })),
|
|
43
|
+
getTheme: name => getThemeByName(name),
|
|
44
|
+
setTheme: async themeArg => {
|
|
51
45
|
if (typeof themeArg === "string") {
|
|
52
|
-
return setTheme(themeArg, true);
|
|
46
|
+
return await setTheme(themeArg, true);
|
|
53
47
|
}
|
|
54
48
|
// Theme object passed directly - not supported in current implementation
|
|
55
|
-
return { success: false, error: "Direct theme object not supported" };
|
|
49
|
+
return Promise.resolve({ success: false, error: "Direct theme object not supported" });
|
|
56
50
|
},
|
|
57
51
|
setFooter: () => {},
|
|
58
52
|
setHeader: () => {},
|
|
@@ -98,15 +92,15 @@ export class ExtensionUiController {
|
|
|
98
92
|
},
|
|
99
93
|
getActiveTools: () => this.ctx.session.getActiveToolNames(),
|
|
100
94
|
getAllTools: () => this.ctx.session.getAllToolNames(),
|
|
101
|
-
setActiveTools:
|
|
102
|
-
setModel: async
|
|
95
|
+
setActiveTools: toolNames => this.ctx.session.setActiveToolsByName(toolNames),
|
|
96
|
+
setModel: async model => {
|
|
103
97
|
const key = await this.ctx.session.modelRegistry.getApiKey(model);
|
|
104
98
|
if (!key) return false;
|
|
105
99
|
await this.ctx.session.setModel(model);
|
|
106
100
|
return true;
|
|
107
101
|
},
|
|
108
102
|
getThinkingLevel: () => this.ctx.session.thinkingLevel,
|
|
109
|
-
setThinkingLevel:
|
|
103
|
+
setThinkingLevel: level => this.ctx.session.setThinkingLevel(level),
|
|
110
104
|
};
|
|
111
105
|
const contextActions: ExtensionContextActions = {
|
|
112
106
|
getModel: () => this.ctx.session.model,
|
|
@@ -117,7 +111,7 @@ export class ExtensionUiController {
|
|
|
117
111
|
// Signal shutdown request (will be handled by main loop)
|
|
118
112
|
},
|
|
119
113
|
getContextUsage: () => this.ctx.session.getContextUsage(),
|
|
120
|
-
compact: async
|
|
114
|
+
compact: async instructionsOrOptions => {
|
|
121
115
|
const instructions = typeof instructionsOrOptions === "string" ? instructionsOrOptions : undefined;
|
|
122
116
|
const options =
|
|
123
117
|
instructionsOrOptions && typeof instructionsOrOptions === "object" ? instructionsOrOptions : undefined;
|
|
@@ -127,7 +121,7 @@ export class ExtensionUiController {
|
|
|
127
121
|
const commandActions: ExtensionCommandContextActions = {
|
|
128
122
|
getContextUsage: () => this.ctx.session.getContextUsage(),
|
|
129
123
|
waitForIdle: () => this.ctx.session.agent.waitForIdle(),
|
|
130
|
-
newSession: async
|
|
124
|
+
newSession: async options => {
|
|
131
125
|
// Stop any loading animation
|
|
132
126
|
if (this.ctx.loadingAnimation) {
|
|
133
127
|
this.ctx.loadingAnimation.stop();
|
|
@@ -163,7 +157,7 @@ export class ExtensionUiController {
|
|
|
163
157
|
|
|
164
158
|
return { cancelled: false };
|
|
165
159
|
},
|
|
166
|
-
branch: async
|
|
160
|
+
branch: async entryId => {
|
|
167
161
|
const result = await this.ctx.session.branch(entryId);
|
|
168
162
|
if (result.cancelled) {
|
|
169
163
|
return { cancelled: true };
|
|
@@ -195,7 +189,7 @@ export class ExtensionUiController {
|
|
|
195
189
|
|
|
196
190
|
return { cancelled: false };
|
|
197
191
|
},
|
|
198
|
-
compact: async
|
|
192
|
+
compact: async instructionsOrOptions => {
|
|
199
193
|
const instructions = typeof instructionsOrOptions === "string" ? instructionsOrOptions : undefined;
|
|
200
194
|
const options =
|
|
201
195
|
instructionsOrOptions && typeof instructionsOrOptions === "object" ? instructionsOrOptions : undefined;
|
|
@@ -267,15 +261,15 @@ export class ExtensionUiController {
|
|
|
267
261
|
},
|
|
268
262
|
getActiveTools: () => this.ctx.session.getActiveToolNames(),
|
|
269
263
|
getAllTools: () => this.ctx.session.getAllToolNames(),
|
|
270
|
-
setActiveTools:
|
|
271
|
-
setModel: async
|
|
264
|
+
setActiveTools: toolNames => this.ctx.session.setActiveToolsByName(toolNames),
|
|
265
|
+
setModel: async model => {
|
|
272
266
|
const key = await this.ctx.session.modelRegistry.getApiKey(model);
|
|
273
267
|
if (!key) return false;
|
|
274
268
|
await this.ctx.session.setModel(model);
|
|
275
269
|
return true;
|
|
276
270
|
},
|
|
277
271
|
getThinkingLevel: () => this.ctx.session.thinkingLevel,
|
|
278
|
-
setThinkingLevel:
|
|
272
|
+
setThinkingLevel: level => this.ctx.session.setThinkingLevel(level),
|
|
279
273
|
};
|
|
280
274
|
const contextActions: ExtensionContextActions = {
|
|
281
275
|
getModel: () => this.ctx.session.model,
|
|
@@ -286,7 +280,7 @@ export class ExtensionUiController {
|
|
|
286
280
|
// Signal shutdown request (will be handled by main loop)
|
|
287
281
|
},
|
|
288
282
|
getContextUsage: () => this.ctx.session.getContextUsage(),
|
|
289
|
-
compact: async
|
|
283
|
+
compact: async instructionsOrOptions => {
|
|
290
284
|
const instructions = typeof instructionsOrOptions === "string" ? instructionsOrOptions : undefined;
|
|
291
285
|
const options =
|
|
292
286
|
instructionsOrOptions && typeof instructionsOrOptions === "object" ? instructionsOrOptions : undefined;
|
|
@@ -296,7 +290,7 @@ export class ExtensionUiController {
|
|
|
296
290
|
const commandActions: ExtensionCommandContextActions = {
|
|
297
291
|
getContextUsage: () => this.ctx.session.getContextUsage(),
|
|
298
292
|
waitForIdle: () => this.ctx.session.agent.waitForIdle(),
|
|
299
|
-
newSession: async
|
|
293
|
+
newSession: async options => {
|
|
300
294
|
if (this.ctx.isBackgrounded) {
|
|
301
295
|
return { cancelled: true };
|
|
302
296
|
}
|
|
@@ -335,7 +329,7 @@ export class ExtensionUiController {
|
|
|
335
329
|
|
|
336
330
|
return { cancelled: false };
|
|
337
331
|
},
|
|
338
|
-
branch: async
|
|
332
|
+
branch: async entryId => {
|
|
339
333
|
if (this.ctx.isBackgrounded) {
|
|
340
334
|
return { cancelled: true };
|
|
341
335
|
}
|
|
@@ -373,7 +367,7 @@ export class ExtensionUiController {
|
|
|
373
367
|
|
|
374
368
|
return { cancelled: false };
|
|
375
369
|
},
|
|
376
|
-
compact: async
|
|
370
|
+
compact: async instructionsOrOptions => {
|
|
377
371
|
const instructions = typeof instructionsOrOptions === "string" ? instructionsOrOptions : undefined;
|
|
378
372
|
const options =
|
|
379
373
|
instructionsOrOptions && typeof instructionsOrOptions === "object" ? instructionsOrOptions : undefined;
|
|
@@ -404,9 +398,9 @@ export class ExtensionUiController {
|
|
|
404
398
|
get theme() {
|
|
405
399
|
return theme;
|
|
406
400
|
},
|
|
407
|
-
getAllThemes: () => [],
|
|
408
|
-
getTheme: () => undefined,
|
|
409
|
-
setTheme: () => ({ success: false, error: "Background mode" }),
|
|
401
|
+
getAllThemes: () => Promise.resolve([]),
|
|
402
|
+
getTheme: () => Promise.resolve(undefined),
|
|
403
|
+
setTheme: () => Promise.resolve({ success: false, error: "Background mode" }),
|
|
410
404
|
setFooter: () => {},
|
|
411
405
|
setHeader: () => {},
|
|
412
406
|
setEditorComponent: () => {},
|
|
@@ -431,7 +425,7 @@ export class ExtensionUiController {
|
|
|
431
425
|
await registeredTool.definition.onSession(event, {
|
|
432
426
|
ui: uiContext,
|
|
433
427
|
getContextUsage: () => this.ctx.session.getContextUsage(),
|
|
434
|
-
compact: async
|
|
428
|
+
compact: async instructionsOrOptions => {
|
|
435
429
|
const instructions = typeof instructionsOrOptions === "string" ? instructionsOrOptions : undefined;
|
|
436
430
|
const options =
|
|
437
431
|
instructionsOrOptions && typeof instructionsOrOptions === "object"
|
|
@@ -493,7 +487,7 @@ export class ExtensionUiController {
|
|
|
493
487
|
this.ctx.hookSelector = new HookSelectorComponent(
|
|
494
488
|
title,
|
|
495
489
|
options,
|
|
496
|
-
|
|
490
|
+
option => {
|
|
497
491
|
this.hideHookSelector();
|
|
498
492
|
resolve(option);
|
|
499
493
|
},
|
|
@@ -538,7 +532,7 @@ export class ExtensionUiController {
|
|
|
538
532
|
this.ctx.hookInput = new HookInputComponent(
|
|
539
533
|
title,
|
|
540
534
|
placeholder,
|
|
541
|
-
|
|
535
|
+
value => {
|
|
542
536
|
this.hideHookInput();
|
|
543
537
|
resolve(value);
|
|
544
538
|
},
|
|
@@ -575,7 +569,7 @@ export class ExtensionUiController {
|
|
|
575
569
|
this.ctx.ui,
|
|
576
570
|
title,
|
|
577
571
|
prefill,
|
|
578
|
-
|
|
572
|
+
value => {
|
|
579
573
|
this.hideHookEditor();
|
|
580
574
|
resolve(value);
|
|
581
575
|
},
|
|
@@ -643,7 +637,7 @@ export class ExtensionUiController {
|
|
|
643
637
|
resolve(result);
|
|
644
638
|
};
|
|
645
639
|
|
|
646
|
-
Promise.try(() => factory(this.ctx.ui, theme, keybindings, close)).then(
|
|
640
|
+
Promise.try(() => factory(this.ctx.ui, theme, keybindings, close)).then(c => {
|
|
647
641
|
component = c;
|
|
648
642
|
this.ctx.editorContainer.clear();
|
|
649
643
|
this.ctx.editorContainer.addChild(component);
|