@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,16 +1,15 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
-
import
|
|
3
|
-
import { open, rm } from "node:fs/promises";
|
|
2
|
+
import * as fs from "node:fs/promises";
|
|
4
3
|
import * as os from "node:os";
|
|
5
4
|
import * as path from "node:path";
|
|
6
5
|
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
7
|
-
import { theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
|
|
8
|
-
import type { InteractiveModeContext } from "@oh-my-pi/pi-coding-agent/modes/types";
|
|
9
|
-
import type { AgentSessionEvent } from "@oh-my-pi/pi-coding-agent/session/agent-session";
|
|
10
|
-
import { readImageFromClipboard } from "@oh-my-pi/pi-coding-agent/utils/clipboard";
|
|
11
|
-
import { resizeImage } from "@oh-my-pi/pi-coding-agent/utils/image-resize";
|
|
12
|
-
import { generateSessionTitle, setTerminalTitle } from "@oh-my-pi/pi-coding-agent/utils/title-generator";
|
|
13
6
|
import { nanoid } from "nanoid";
|
|
7
|
+
import { theme } from "../../modes/theme/theme";
|
|
8
|
+
import type { InteractiveModeContext } from "../../modes/types";
|
|
9
|
+
import type { AgentSessionEvent } from "../../session/agent-session";
|
|
10
|
+
import { readImageFromClipboard } from "../../utils/clipboard";
|
|
11
|
+
import { resizeImage } from "../../utils/image-resize";
|
|
12
|
+
import { generateSessionTitle, setTerminalTitle } from "../../utils/title-generator";
|
|
14
13
|
|
|
15
14
|
interface Expandable {
|
|
16
15
|
setExpanded(expanded: boolean): void;
|
|
@@ -207,7 +206,7 @@ export class InputController {
|
|
|
207
206
|
return;
|
|
208
207
|
}
|
|
209
208
|
if (text === "/session") {
|
|
210
|
-
this.ctx.handleSessionCommand();
|
|
209
|
+
await this.ctx.handleSessionCommand();
|
|
211
210
|
this.ctx.editor.setText("");
|
|
212
211
|
return;
|
|
213
212
|
}
|
|
@@ -217,7 +216,7 @@ export class InputController {
|
|
|
217
216
|
return;
|
|
218
217
|
}
|
|
219
218
|
if (text === "/changelog") {
|
|
220
|
-
this.ctx.handleChangelogCommand();
|
|
219
|
+
await this.ctx.handleChangelogCommand();
|
|
221
220
|
this.ctx.editor.setText("");
|
|
222
221
|
return;
|
|
223
222
|
}
|
|
@@ -386,7 +385,7 @@ export class InputController {
|
|
|
386
385
|
const registry = this.ctx.session.modelRegistry;
|
|
387
386
|
const smolModel = this.ctx.settingsManager.getModelRole("smol");
|
|
388
387
|
generateSessionTitle(text, registry, smolModel, this.ctx.session.sessionId)
|
|
389
|
-
.then(async
|
|
388
|
+
.then(async title => {
|
|
390
389
|
if (title) {
|
|
391
390
|
await this.ctx.sessionManager.setSessionTitle(title);
|
|
392
391
|
setTerminalTitle(`π: ${title}`);
|
|
@@ -455,7 +454,7 @@ export class InputController {
|
|
|
455
454
|
}
|
|
456
455
|
const queuedText = allQueued.join("\n\n");
|
|
457
456
|
const currentText = options?.currentText ?? this.ctx.editor.getText();
|
|
458
|
-
const combinedText = [queuedText, currentText].filter(
|
|
457
|
+
const combinedText = [queuedText, currentText].filter(t => t.trim()).join("\n\n");
|
|
459
458
|
this.ctx.editor.setText(combinedText);
|
|
460
459
|
this.ctx.updatePendingMessagesDisplay();
|
|
461
460
|
if (options?.abort) {
|
|
@@ -586,7 +585,7 @@ export class InputController {
|
|
|
586
585
|
const tempLabel = options?.temporary ? " (temporary)" : "";
|
|
587
586
|
const cycleSeparator = theme.fg("dim", " > ");
|
|
588
587
|
const cycleLabel = roleOrder
|
|
589
|
-
.map(
|
|
588
|
+
.map(role => {
|
|
590
589
|
if (role === result.role) {
|
|
591
590
|
return theme.bold(theme.fg("accent", role));
|
|
592
591
|
}
|
|
@@ -638,13 +637,13 @@ export class InputController {
|
|
|
638
637
|
return "/dev/tty";
|
|
639
638
|
}
|
|
640
639
|
|
|
641
|
-
private async openEditorTerminalHandle(): Promise<FileHandle | null> {
|
|
640
|
+
private async openEditorTerminalHandle(): Promise<fs.FileHandle | null> {
|
|
642
641
|
const terminalPath = this.getEditorTerminalPath();
|
|
643
642
|
if (!terminalPath) {
|
|
644
643
|
return null;
|
|
645
644
|
}
|
|
646
645
|
try {
|
|
647
|
-
return await open(terminalPath, "r+");
|
|
646
|
+
return await fs.open(terminalPath, "r+");
|
|
648
647
|
} catch {
|
|
649
648
|
return null;
|
|
650
649
|
}
|
|
@@ -661,7 +660,7 @@ export class InputController {
|
|
|
661
660
|
const currentText = this.ctx.editor.getText();
|
|
662
661
|
const tmpFile = path.join(os.tmpdir(), `omp-editor-${nanoid()}.omp.md`);
|
|
663
662
|
|
|
664
|
-
let ttyHandle: FileHandle | null = null;
|
|
663
|
+
let ttyHandle: fs.FileHandle | null = null;
|
|
665
664
|
try {
|
|
666
665
|
// Write current content to temp file
|
|
667
666
|
await Bun.write(tmpFile, currentText);
|
|
@@ -680,7 +679,7 @@ export class InputController {
|
|
|
680
679
|
const child = spawn(editor, [...editorArgs, tmpFile], { stdio });
|
|
681
680
|
const exitCode = await new Promise<number>((resolve, reject) => {
|
|
682
681
|
child.once("exit", (code, signal) => resolve(code ?? (signal ? -1 : 0)));
|
|
683
|
-
child.once("error",
|
|
682
|
+
child.once("error", error => reject(error));
|
|
684
683
|
});
|
|
685
684
|
|
|
686
685
|
// On successful exit (exitCode 0), replace editor content
|
|
@@ -696,7 +695,7 @@ export class InputController {
|
|
|
696
695
|
} finally {
|
|
697
696
|
// Clean up temp file
|
|
698
697
|
try {
|
|
699
|
-
await rm(tmpFile, { force: true });
|
|
698
|
+
await fs.rm(tmpFile, { force: true });
|
|
700
699
|
} catch {
|
|
701
700
|
// Ignore cleanup errors
|
|
702
701
|
}
|
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
2
2
|
import type { OAuthProvider } from "@oh-my-pi/pi-ai";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
3
|
+
import type { Component } from "@oh-my-pi/pi-tui";
|
|
4
|
+
import { Input, Loader, Spacer, Text } from "@oh-my-pi/pi-tui";
|
|
5
|
+
import { getAgentDbPath } from "../../config";
|
|
6
|
+
import { disableProvider, enableProvider } from "../../discovery";
|
|
7
|
+
import { AssistantMessageComponent } from "../../modes/components/assistant-message";
|
|
8
|
+
import { ExtensionDashboard } from "../../modes/components/extensions";
|
|
9
|
+
import { HistorySearchComponent } from "../../modes/components/history-search";
|
|
10
|
+
import { ModelSelectorComponent } from "../../modes/components/model-selector";
|
|
11
|
+
import { OAuthSelectorComponent } from "../../modes/components/oauth-selector";
|
|
12
|
+
import { SessionSelectorComponent } from "../../modes/components/session-selector";
|
|
13
|
+
import { SettingsSelectorComponent } from "../../modes/components/settings-selector";
|
|
14
|
+
import { ToolExecutionComponent } from "../../modes/components/tool-execution";
|
|
15
|
+
import { TreeSelectorComponent } from "../../modes/components/tree-selector";
|
|
16
|
+
import { UserMessageSelectorComponent } from "../../modes/components/user-message-selector";
|
|
15
17
|
import {
|
|
16
18
|
getAvailableThemes,
|
|
17
19
|
getSymbolTheme,
|
|
20
|
+
setColorBlindMode,
|
|
18
21
|
setSymbolPreset,
|
|
19
22
|
setTheme,
|
|
20
23
|
theme,
|
|
21
|
-
} from "
|
|
22
|
-
import type { InteractiveModeContext } from "
|
|
23
|
-
import { SessionManager } from "
|
|
24
|
-
import { setPreferredImageProvider, setPreferredWebSearchProvider } from "
|
|
25
|
-
import type { Component } from "@oh-my-pi/pi-tui";
|
|
26
|
-
import { Input, Loader, Spacer, Text } from "@oh-my-pi/pi-tui";
|
|
24
|
+
} from "../../modes/theme/theme";
|
|
25
|
+
import type { InteractiveModeContext } from "../../modes/types";
|
|
26
|
+
import { SessionManager } from "../../session/session-manager";
|
|
27
|
+
import { setPreferredImageProvider, setPreferredWebSearchProvider } from "../../tools";
|
|
27
28
|
|
|
28
29
|
export class SelectorController {
|
|
29
30
|
constructor(private ctx: InteractiveModeContext) {}
|
|
@@ -46,49 +47,52 @@ export class SelectorController {
|
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
showSettingsSelector(): void {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
{
|
|
59
|
-
onChange: (id, value) => this.handleSettingChange(id, value),
|
|
60
|
-
onThemePreview: (themeName) => {
|
|
61
|
-
const result = setTheme(themeName, true);
|
|
62
|
-
if (result.success) {
|
|
63
|
-
this.ctx.ui.invalidate();
|
|
64
|
-
this.ctx.ui.requestRender();
|
|
65
|
-
}
|
|
50
|
+
getAvailableThemes().then(availableThemes => {
|
|
51
|
+
this.showSelector(done => {
|
|
52
|
+
const selector = new SettingsSelectorComponent(
|
|
53
|
+
this.ctx.settingsManager,
|
|
54
|
+
{
|
|
55
|
+
availableThinkingLevels: this.ctx.session.getAvailableThinkingLevels(),
|
|
56
|
+
thinkingLevel: this.ctx.session.thinkingLevel,
|
|
57
|
+
availableThemes,
|
|
58
|
+
cwd: process.cwd(),
|
|
66
59
|
},
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
60
|
+
{
|
|
61
|
+
onChange: (id, value) => this.handleSettingChange(id, value),
|
|
62
|
+
onThemePreview: themeName => {
|
|
63
|
+
setTheme(themeName, true).then(result => {
|
|
64
|
+
if (result.success) {
|
|
65
|
+
this.ctx.ui.invalidate();
|
|
66
|
+
this.ctx.ui.requestRender();
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
},
|
|
70
|
+
onStatusLinePreview: settings => {
|
|
71
|
+
// Update status line with preview settings
|
|
72
|
+
const currentSettings = this.ctx.settingsManager.getStatusLineSettings();
|
|
73
|
+
this.ctx.statusLine.updateSettings({ ...currentSettings, ...settings });
|
|
74
|
+
this.ctx.updateEditorTopBorder();
|
|
75
|
+
this.ctx.ui.requestRender();
|
|
76
|
+
},
|
|
77
|
+
getStatusLinePreview: () => {
|
|
78
|
+
// Return the rendered status line for inline preview
|
|
79
|
+
const width = this.ctx.ui.getWidth();
|
|
80
|
+
return this.ctx.statusLine.getTopBorder(width).content;
|
|
81
|
+
},
|
|
82
|
+
onPluginsChanged: () => {
|
|
83
|
+
this.ctx.ui.requestRender();
|
|
84
|
+
},
|
|
85
|
+
onCancel: () => {
|
|
86
|
+
done();
|
|
87
|
+
// Restore status line to saved settings
|
|
88
|
+
this.ctx.statusLine.updateSettings(this.ctx.settingsManager.getStatusLineSettings());
|
|
89
|
+
this.ctx.updateEditorTopBorder();
|
|
90
|
+
this.ctx.ui.requestRender();
|
|
91
|
+
},
|
|
88
92
|
},
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
93
|
+
);
|
|
94
|
+
return { component: selector, focus: selector };
|
|
95
|
+
});
|
|
92
96
|
});
|
|
93
97
|
}
|
|
94
98
|
|
|
@@ -96,10 +100,10 @@ export class SelectorController {
|
|
|
96
100
|
const historyStorage = this.ctx.historyStorage;
|
|
97
101
|
if (!historyStorage) return;
|
|
98
102
|
|
|
99
|
-
this.showSelector(
|
|
103
|
+
this.showSelector(done => {
|
|
100
104
|
const component = new HistorySearchComponent(
|
|
101
105
|
historyStorage,
|
|
102
|
-
|
|
106
|
+
prompt => {
|
|
103
107
|
done();
|
|
104
108
|
this.ctx.editor.setText(prompt);
|
|
105
109
|
this.ctx.ui.requestRender();
|
|
@@ -123,7 +127,7 @@ export class SelectorController {
|
|
|
123
127
|
this.ctx.settingsManager,
|
|
124
128
|
this.ctx.ui.terminal.rows,
|
|
125
129
|
);
|
|
126
|
-
this.showSelector(
|
|
130
|
+
this.showSelector(done => {
|
|
127
131
|
dashboard.onClose = () => {
|
|
128
132
|
done();
|
|
129
133
|
this.ctx.ui.requestRender();
|
|
@@ -189,20 +193,28 @@ export class SelectorController {
|
|
|
189
193
|
this.ctx.rebuildChatFromMessages();
|
|
190
194
|
break;
|
|
191
195
|
case "theme": {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
196
|
+
setTheme(value as string, true).then(result => {
|
|
197
|
+
this.ctx.statusLine.invalidate();
|
|
198
|
+
this.ctx.updateEditorTopBorder();
|
|
199
|
+
this.ctx.ui.invalidate();
|
|
200
|
+
if (!result.success) {
|
|
201
|
+
this.ctx.showError(`Failed to load theme "${value}": ${result.error}\nFell back to dark theme.`);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
199
204
|
break;
|
|
200
205
|
}
|
|
201
206
|
case "symbolPreset": {
|
|
202
|
-
setSymbolPreset(value as "unicode" | "nerd" | "ascii")
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
207
|
+
setSymbolPreset(value as "unicode" | "nerd" | "ascii").then(() => {
|
|
208
|
+
this.ctx.statusLine.invalidate();
|
|
209
|
+
this.ctx.updateEditorTopBorder();
|
|
210
|
+
this.ctx.ui.invalidate();
|
|
211
|
+
});
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
case "colorBlindMode": {
|
|
215
|
+
setColorBlindMode(value === "true" || value === true).then(() => {
|
|
216
|
+
this.ctx.ui.invalidate();
|
|
217
|
+
});
|
|
206
218
|
break;
|
|
207
219
|
}
|
|
208
220
|
case "statusLinePreset":
|
|
@@ -239,7 +251,7 @@ export class SelectorController {
|
|
|
239
251
|
}
|
|
240
252
|
|
|
241
253
|
showModelSelector(options?: { temporaryOnly?: boolean }): void {
|
|
242
|
-
this.showSelector(
|
|
254
|
+
this.showSelector(done => {
|
|
243
255
|
const selector = new ModelSelectorComponent(
|
|
244
256
|
this.ctx.ui,
|
|
245
257
|
this.ctx.session.model,
|
|
@@ -291,10 +303,10 @@ export class SelectorController {
|
|
|
291
303
|
return;
|
|
292
304
|
}
|
|
293
305
|
|
|
294
|
-
this.showSelector(
|
|
306
|
+
this.showSelector(done => {
|
|
295
307
|
const selector = new UserMessageSelectorComponent(
|
|
296
|
-
userMessages.map(
|
|
297
|
-
async
|
|
308
|
+
userMessages.map(m => ({ id: m.entryId, text: m.text })),
|
|
309
|
+
async entryId => {
|
|
298
310
|
const result = await this.ctx.session.branch(entryId);
|
|
299
311
|
if (result.cancelled) {
|
|
300
312
|
// Hook cancelled the branch
|
|
@@ -336,12 +348,12 @@ export class SelectorController {
|
|
|
336
348
|
return;
|
|
337
349
|
}
|
|
338
350
|
|
|
339
|
-
this.showSelector(
|
|
351
|
+
this.showSelector(done => {
|
|
340
352
|
const selector = new TreeSelectorComponent(
|
|
341
353
|
tree,
|
|
342
354
|
visibleLeafId,
|
|
343
355
|
this.ctx.ui.terminal.rows,
|
|
344
|
-
async
|
|
356
|
+
async entryId => {
|
|
345
357
|
// Selecting the visible leaf is a no-op (already there)
|
|
346
358
|
if (entryId === visibleLeafId) {
|
|
347
359
|
done();
|
|
@@ -396,8 +408,8 @@ export class SelectorController {
|
|
|
396
408
|
this.ctx.chatContainer.addChild(new Spacer(1));
|
|
397
409
|
summaryLoader = new Loader(
|
|
398
410
|
this.ctx.ui,
|
|
399
|
-
|
|
400
|
-
|
|
411
|
+
spinner => theme.fg("accent", spinner),
|
|
412
|
+
text => theme.fg("muted", text),
|
|
401
413
|
"Summarizing branch... (esc to cancel)",
|
|
402
414
|
getSymbolTheme().spinnerFrames,
|
|
403
415
|
);
|
|
@@ -453,15 +465,15 @@ export class SelectorController {
|
|
|
453
465
|
});
|
|
454
466
|
}
|
|
455
467
|
|
|
456
|
-
showSessionSelector(): void {
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
468
|
+
async showSessionSelector(): Promise<void> {
|
|
469
|
+
const sessions = await SessionManager.list(
|
|
470
|
+
this.ctx.sessionManager.getCwd(),
|
|
471
|
+
this.ctx.sessionManager.getSessionDir(),
|
|
472
|
+
);
|
|
473
|
+
this.showSelector(done => {
|
|
462
474
|
const selector = new SessionSelectorComponent(
|
|
463
475
|
sessions,
|
|
464
|
-
async
|
|
476
|
+
async sessionPath => {
|
|
465
477
|
done();
|
|
466
478
|
await this.handleResumeSession(sessionPath);
|
|
467
479
|
},
|
|
@@ -505,14 +517,14 @@ export class SelectorController {
|
|
|
505
517
|
async showOAuthSelector(mode: "login" | "logout"): Promise<void> {
|
|
506
518
|
if (mode === "logout") {
|
|
507
519
|
const providers = this.ctx.session.modelRegistry.authStorage.list();
|
|
508
|
-
const loggedInProviders = providers.filter(
|
|
520
|
+
const loggedInProviders = providers.filter(p => this.ctx.session.modelRegistry.authStorage.hasOAuth(p));
|
|
509
521
|
if (loggedInProviders.length === 0) {
|
|
510
522
|
this.ctx.showStatus("No OAuth providers logged in. Use /login first.");
|
|
511
523
|
return;
|
|
512
524
|
}
|
|
513
525
|
}
|
|
514
526
|
|
|
515
|
-
this.showSelector(
|
|
527
|
+
this.showSelector(done => {
|
|
516
528
|
const selector = new OAuthSelectorComponent(
|
|
517
529
|
mode,
|
|
518
530
|
this.ctx.session.modelRegistry.authStorage,
|
|
@@ -546,7 +558,7 @@ export class SelectorController {
|
|
|
546
558
|
}
|
|
547
559
|
this.ctx.ui.requestRender();
|
|
548
560
|
|
|
549
|
-
return new Promise<string>(
|
|
561
|
+
return new Promise<string>(resolve => {
|
|
550
562
|
const codeInput = new Input();
|
|
551
563
|
codeInput.onSubmit = () => {
|
|
552
564
|
const code = codeInput.getValue();
|
package/src/modes/index.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { emergencyTerminalRestore } from "@oh-my-pi/pi-tui";
|
|
2
|
+
import { postmortem } from "@oh-my-pi/pi-utils";
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* Run modes for the coding agent.
|
|
3
6
|
*/
|
|
@@ -7,9 +10,6 @@ export { type ModelInfo, RpcClient, type RpcClientOptions, type RpcEventListener
|
|
|
7
10
|
export { runRpcMode } from "./rpc/rpc-mode";
|
|
8
11
|
export type { RpcCommand, RpcResponse, RpcSessionState } from "./rpc/rpc-types";
|
|
9
12
|
|
|
10
|
-
import { emergencyTerminalRestore } from "@oh-my-pi/pi-tui";
|
|
11
|
-
import { postmortem } from "@oh-my-pi/pi-utils";
|
|
12
|
-
|
|
13
13
|
postmortem.register("terminal-restore", () => {
|
|
14
14
|
emergencyTerminalRestore();
|
|
15
15
|
});
|
|
@@ -2,20 +2,9 @@
|
|
|
2
2
|
* Interactive mode for the coding agent.
|
|
3
3
|
* Handles TUI rendering and user interaction, delegating business logic to AgentSession.
|
|
4
4
|
*/
|
|
5
|
-
|
|
6
5
|
import * as path from "node:path";
|
|
7
6
|
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
8
7
|
import type { AssistantMessage, ImageContent, Message, UsageReport } from "@oh-my-pi/pi-ai";
|
|
9
|
-
import { KeybindingsManager } from "@oh-my-pi/pi-coding-agent/config/keybindings";
|
|
10
|
-
import type { SettingsManager } from "@oh-my-pi/pi-coding-agent/config/settings-manager";
|
|
11
|
-
import type { ExtensionUIContext } from "@oh-my-pi/pi-coding-agent/extensibility/extensions/index";
|
|
12
|
-
import type { CompactOptions } from "@oh-my-pi/pi-coding-agent/extensibility/extensions/types";
|
|
13
|
-
import { loadSlashCommands } from "@oh-my-pi/pi-coding-agent/extensibility/slash-commands";
|
|
14
|
-
import type { AgentSession, AgentSessionEvent } from "@oh-my-pi/pi-coding-agent/session/agent-session";
|
|
15
|
-
import { HistoryStorage } from "@oh-my-pi/pi-coding-agent/session/history-storage";
|
|
16
|
-
import type { SessionContext, SessionManager } from "@oh-my-pi/pi-coding-agent/session/session-manager";
|
|
17
|
-
import { getRecentSessions } from "@oh-my-pi/pi-coding-agent/session/session-manager";
|
|
18
|
-
import { setTerminalTitle } from "@oh-my-pi/pi-coding-agent/utils/title-generator";
|
|
19
8
|
import type { Component, Loader, SlashCommand } from "@oh-my-pi/pi-tui";
|
|
20
9
|
import {
|
|
21
10
|
CombinedAutocompleteProvider,
|
|
@@ -26,8 +15,18 @@ import {
|
|
|
26
15
|
Text,
|
|
27
16
|
TUI,
|
|
28
17
|
} from "@oh-my-pi/pi-tui";
|
|
29
|
-
import { logger, postmortem } from "@oh-my-pi/pi-utils";
|
|
18
|
+
import { isEnoent, logger, postmortem } from "@oh-my-pi/pi-utils";
|
|
30
19
|
import chalk from "chalk";
|
|
20
|
+
import { KeybindingsManager } from "../config/keybindings";
|
|
21
|
+
import type { SettingsManager } from "../config/settings-manager";
|
|
22
|
+
import type { ExtensionUIContext } from "../extensibility/extensions";
|
|
23
|
+
import type { CompactOptions } from "../extensibility/extensions/types";
|
|
24
|
+
import { loadSlashCommands } from "../extensibility/slash-commands";
|
|
25
|
+
import type { AgentSession, AgentSessionEvent } from "../session/agent-session";
|
|
26
|
+
import { HistoryStorage } from "../session/history-storage";
|
|
27
|
+
import type { SessionContext, SessionManager } from "../session/session-manager";
|
|
28
|
+
import { getRecentSessions } from "../session/session-manager";
|
|
29
|
+
import { setTerminalTitle } from "../utils/title-generator";
|
|
31
30
|
import type { AssistantMessageComponent } from "./components/assistant-message";
|
|
32
31
|
import type { BashExecutionComponent } from "./components/bash-execution";
|
|
33
32
|
import { CustomEditor } from "./components/custom-editor";
|
|
@@ -44,6 +43,7 @@ import { EventController } from "./controllers/event-controller";
|
|
|
44
43
|
import { ExtensionUiController } from "./controllers/extension-ui-controller";
|
|
45
44
|
import { InputController } from "./controllers/input-controller";
|
|
46
45
|
import { SelectorController } from "./controllers/selector-controller";
|
|
46
|
+
import { setMermaidRenderCallback } from "./theme/mermaid-cache";
|
|
47
47
|
import type { Theme } from "./theme/theme";
|
|
48
48
|
import { getEditorTheme, getMarkdownTheme, onThemeChange, theme } from "./theme/theme";
|
|
49
49
|
import type { CompactionQueuedMessage, InteractiveModeContext, TodoItem } from "./types";
|
|
@@ -124,7 +124,7 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
124
124
|
private readonly changelogMarkdown: string | undefined;
|
|
125
125
|
public readonly lspServers: Array<{ name: string; status: "ready" | "error"; fileTypes: string[] }> | undefined =
|
|
126
126
|
undefined;
|
|
127
|
-
public mcpManager?: import("@oh-my-pi/pi-coding-agent/mcp
|
|
127
|
+
public mcpManager?: import("@oh-my-pi/pi-coding-agent/mcp").MCPManager;
|
|
128
128
|
private readonly toolUiContextSetter: (uiContext: ExtensionUIContext, hasUI: boolean) => void;
|
|
129
129
|
|
|
130
130
|
private readonly commandController: CommandController;
|
|
@@ -140,7 +140,7 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
140
140
|
changelogMarkdown: string | undefined = undefined,
|
|
141
141
|
setToolUIContext: (uiContext: ExtensionUIContext, hasUI: boolean) => void = () => {},
|
|
142
142
|
lspServers: Array<{ name: string; status: "ready" | "error"; fileTypes: string[] }> | undefined = undefined,
|
|
143
|
-
mcpManager?: import("@oh-my-pi/pi-coding-agent/mcp
|
|
143
|
+
mcpManager?: import("@oh-my-pi/pi-coding-agent/mcp").MCPManager,
|
|
144
144
|
) {
|
|
145
145
|
this.session = session;
|
|
146
146
|
this.sessionManager = session.sessionManager;
|
|
@@ -154,6 +154,7 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
154
154
|
this.mcpManager = mcpManager;
|
|
155
155
|
|
|
156
156
|
this.ui = new TUI(new ProcessTerminal(), this.settingsManager.getShowHardwareCursor());
|
|
157
|
+
setMermaidRenderCallback(() => this.ui.requestRender());
|
|
157
158
|
this.chatContainer = new Container();
|
|
158
159
|
this.pendingMessagesContainer = new Container();
|
|
159
160
|
this.statusContainer = new Container();
|
|
@@ -205,14 +206,14 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
205
206
|
];
|
|
206
207
|
|
|
207
208
|
// Convert hook commands to SlashCommand format
|
|
208
|
-
const hookCommands: SlashCommand[] = (this.session.extensionRunner?.getRegisteredCommands() ?? []).map(
|
|
209
|
+
const hookCommands: SlashCommand[] = (this.session.extensionRunner?.getRegisteredCommands() ?? []).map(cmd => ({
|
|
209
210
|
name: cmd.name,
|
|
210
211
|
description: cmd.description ?? "(hook command)",
|
|
211
212
|
getArgumentCompletions: cmd.getArgumentCompletions,
|
|
212
213
|
}));
|
|
213
214
|
|
|
214
215
|
// Convert custom commands (TypeScript) to SlashCommand format
|
|
215
|
-
const customCommands: SlashCommand[] = this.session.customCommands.map(
|
|
216
|
+
const customCommands: SlashCommand[] = this.session.customCommands.map(loaded => ({
|
|
216
217
|
name: loaded.command.name,
|
|
217
218
|
description: `${loaded.command.description} (${loaded.source})`,
|
|
218
219
|
}));
|
|
@@ -248,8 +249,8 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
248
249
|
|
|
249
250
|
// Load and convert file commands to SlashCommand format (async)
|
|
250
251
|
const fileCommands = await loadSlashCommands({ cwd: process.cwd() });
|
|
251
|
-
this.fileSlashCommands = new Set(fileCommands.map(
|
|
252
|
-
const fileSlashCommands: SlashCommand[] = fileCommands.map(
|
|
252
|
+
this.fileSlashCommands = new Set(fileCommands.map(cmd => cmd.name));
|
|
253
|
+
const fileSlashCommands: SlashCommand[] = fileCommands.map(cmd => ({
|
|
253
254
|
name: cmd.name,
|
|
254
255
|
description: cmd.description,
|
|
255
256
|
}));
|
|
@@ -266,14 +267,14 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
266
267
|
const providerName = this.session.model?.provider ?? "Unknown";
|
|
267
268
|
|
|
268
269
|
// Get recent sessions
|
|
269
|
-
const recentSessions = getRecentSessions(this.sessionManager.getSessionDir()).map(
|
|
270
|
+
const recentSessions = (await getRecentSessions(this.sessionManager.getSessionDir())).map(s => ({
|
|
270
271
|
name: s.name,
|
|
271
272
|
timeAgo: s.timeAgo,
|
|
272
273
|
}));
|
|
273
274
|
|
|
274
275
|
// Convert LSP servers to welcome format
|
|
275
276
|
const lspServerInfo =
|
|
276
|
-
this.lspServers?.map(
|
|
277
|
+
this.lspServers?.map(s => ({
|
|
277
278
|
name: s.name,
|
|
278
279
|
status: s.status as "ready" | "error" | "connecting",
|
|
279
280
|
fileTypes: s.fileTypes,
|
|
@@ -362,7 +363,7 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
362
363
|
|
|
363
364
|
async getUserInput(): Promise<{ text: string; images?: ImageContent[] }> {
|
|
364
365
|
const { promise, resolve } = Promise.withResolvers<{ text: string; images?: ImageContent[] }>();
|
|
365
|
-
this.onInputCallback =
|
|
366
|
+
this.onInputCallback = input => {
|
|
366
367
|
this.onInputCallback = undefined;
|
|
367
368
|
resolve(input);
|
|
368
369
|
};
|
|
@@ -450,17 +451,16 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
450
451
|
}
|
|
451
452
|
const artifactsDir = sessionFile.slice(0, -6);
|
|
452
453
|
const todoPath = path.join(artifactsDir, TODO_FILE_NAME);
|
|
453
|
-
const file = Bun.file(todoPath);
|
|
454
|
-
if (!(await file.exists())) {
|
|
455
|
-
this.renderTodoList();
|
|
456
|
-
return;
|
|
457
|
-
}
|
|
458
454
|
try {
|
|
459
|
-
const data = (await file.json()) as { todos?: TodoItem[] };
|
|
455
|
+
const data = (await Bun.file(todoPath).json()) as { todos?: TodoItem[] };
|
|
460
456
|
if (data?.todos && Array.isArray(data.todos)) {
|
|
461
457
|
this.todoItems = data.todos;
|
|
462
458
|
}
|
|
463
459
|
} catch (error) {
|
|
460
|
+
if (isEnoent(error)) {
|
|
461
|
+
this.renderTodoList();
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
464
|
logger.warn("Failed to load todos", { path: todoPath, error: String(error) });
|
|
465
465
|
}
|
|
466
466
|
this.renderTodoList();
|
|
@@ -610,16 +610,16 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
610
610
|
return this.commandController.handleCopyCommand();
|
|
611
611
|
}
|
|
612
612
|
|
|
613
|
-
handleSessionCommand(): void {
|
|
614
|
-
this.commandController.handleSessionCommand();
|
|
613
|
+
handleSessionCommand(): Promise<void> {
|
|
614
|
+
return this.commandController.handleSessionCommand();
|
|
615
615
|
}
|
|
616
616
|
|
|
617
617
|
handleUsageCommand(reports?: UsageReport[] | null): Promise<void> {
|
|
618
618
|
return this.commandController.handleUsageCommand(reports);
|
|
619
619
|
}
|
|
620
620
|
|
|
621
|
-
handleChangelogCommand(): void {
|
|
622
|
-
this.commandController.handleChangelogCommand();
|
|
621
|
+
async handleChangelogCommand(): Promise<void> {
|
|
622
|
+
await this.commandController.handleChangelogCommand();
|
|
623
623
|
}
|
|
624
624
|
|
|
625
625
|
handleHotkeysCommand(): void {
|