@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
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session-scoped manager for agent output IDs.
|
|
3
|
+
*
|
|
4
|
+
* Ensures unique output IDs across task tool invocations within a session.
|
|
5
|
+
* Prefixes each ID with a sequential number (e.g., "0-AuthProvider", "1-AuthApi").
|
|
6
|
+
*
|
|
7
|
+
* This enables reliable agent:// URL resolution and prevents artifact collisions.
|
|
8
|
+
*/
|
|
9
|
+
import * as fs from "node:fs/promises";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Manages agent output ID allocation to ensure uniqueness.
|
|
13
|
+
*
|
|
14
|
+
* Each allocated ID gets a numeric prefix based on allocation order.
|
|
15
|
+
* On resume, scans existing files to find the next available index.
|
|
16
|
+
*/
|
|
17
|
+
export class AgentOutputManager {
|
|
18
|
+
#nextId = 0;
|
|
19
|
+
#initialized = false;
|
|
20
|
+
readonly #getArtifactsDir: () => string | null;
|
|
21
|
+
|
|
22
|
+
constructor(getArtifactsDir: () => string | null) {
|
|
23
|
+
this.#getArtifactsDir = getArtifactsDir;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Scan existing agent output files to find the next available ID.
|
|
28
|
+
* This ensures we don't overwrite outputs when resuming a session.
|
|
29
|
+
*/
|
|
30
|
+
async #ensureInitialized(): Promise<void> {
|
|
31
|
+
if (this.#initialized) return;
|
|
32
|
+
this.#initialized = true;
|
|
33
|
+
|
|
34
|
+
const dir = this.#getArtifactsDir();
|
|
35
|
+
if (!dir) return;
|
|
36
|
+
|
|
37
|
+
let files: string[];
|
|
38
|
+
try {
|
|
39
|
+
files = await fs.readdir(dir);
|
|
40
|
+
} catch {
|
|
41
|
+
return; // Directory doesn't exist yet
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let maxId = -1;
|
|
45
|
+
for (const file of files) {
|
|
46
|
+
// Agent outputs are named: {index}-{id}.md (e.g., "0-AuthProvider.md")
|
|
47
|
+
const match = file.match(/^(\d+)-.*\.md$/);
|
|
48
|
+
if (match) {
|
|
49
|
+
const id = parseInt(match[1], 10);
|
|
50
|
+
if (id > maxId) maxId = id;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
this.#nextId = maxId + 1;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Allocate a unique ID with numeric prefix.
|
|
58
|
+
*
|
|
59
|
+
* @param id Requested ID (e.g., "AuthProvider")
|
|
60
|
+
* @returns Unique ID with prefix (e.g., "0-AuthProvider")
|
|
61
|
+
*/
|
|
62
|
+
async allocate(id: string): Promise<string> {
|
|
63
|
+
await this.#ensureInitialized();
|
|
64
|
+
return `${this.#nextId++}-${id}`;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Allocate unique IDs for a batch of tasks.
|
|
69
|
+
*
|
|
70
|
+
* @param ids Array of requested IDs
|
|
71
|
+
* @returns Array of unique IDs in same order
|
|
72
|
+
*/
|
|
73
|
+
async allocateBatch(ids: string[]): Promise<string[]> {
|
|
74
|
+
await this.#ensureInitialized();
|
|
75
|
+
return ids.map(id => `${this.#nextId++}-${id}`);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Get the next ID that would be allocated (without allocating).
|
|
80
|
+
*/
|
|
81
|
+
async peekNextIndex(): Promise<number> {
|
|
82
|
+
await this.#ensureInitialized();
|
|
83
|
+
return this.#nextId;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Reset state (primarily for testing).
|
|
88
|
+
*/
|
|
89
|
+
reset(): void {
|
|
90
|
+
this.#nextId = 0;
|
|
91
|
+
this.#initialized = false;
|
|
92
|
+
}
|
|
93
|
+
}
|
package/src/task/parallel.ts
CHANGED
package/src/task/render.ts
CHANGED
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
* Provides renderCall and renderResult functions for displaying
|
|
5
5
|
* task execution in the terminal UI.
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
7
|
import path from "node:path";
|
|
9
|
-
import type {
|
|
10
|
-
import
|
|
8
|
+
import type { Component } from "@oh-my-pi/pi-tui";
|
|
9
|
+
import { Container, Text } from "@oh-my-pi/pi-tui";
|
|
10
|
+
import type { RenderResultOptions } from "../extensibility/custom-tools/types";
|
|
11
|
+
import type { Theme } from "../modes/theme/theme";
|
|
11
12
|
import {
|
|
12
13
|
formatBadge,
|
|
13
14
|
formatDuration,
|
|
@@ -15,16 +16,15 @@ import {
|
|
|
15
16
|
formatStatusIcon,
|
|
16
17
|
formatTokens,
|
|
17
18
|
truncate,
|
|
18
|
-
} from "
|
|
19
|
+
} from "../tools/render-utils";
|
|
19
20
|
import {
|
|
20
21
|
type FindingPriority,
|
|
21
22
|
getPriorityInfo,
|
|
22
23
|
PRIORITY_LABELS,
|
|
23
24
|
type ReportFindingDetails,
|
|
24
25
|
type SubmitReviewDetails,
|
|
25
|
-
} from "
|
|
26
|
-
import
|
|
27
|
-
import { Container, Text } from "@oh-my-pi/pi-tui";
|
|
26
|
+
} from "../tools/review";
|
|
27
|
+
import { renderStatusLine } from "../tui";
|
|
28
28
|
import { subprocessToolRegistry } from "./subprocess-tool-registry";
|
|
29
29
|
import type { AgentProgress, SingleResult, TaskParams, TaskToolDetails } from "./types";
|
|
30
30
|
|
|
@@ -78,7 +78,7 @@ function formatJsonScalar(value: unknown, theme: Theme): string {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
function buildTreePrefix(ancestors: boolean[], theme: Theme): string {
|
|
81
|
-
return ancestors.map(
|
|
81
|
+
return ancestors.map(hasNext => (hasNext ? `${theme.tree.vertical} ` : " ")).join("");
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
function renderJsonTreeLines(
|
|
@@ -229,7 +229,7 @@ function renderOutputSection(
|
|
|
229
229
|
maxExpanded = 10,
|
|
230
230
|
): string[] {
|
|
231
231
|
const lines: string[] = [];
|
|
232
|
-
const trimmedOutput = output.
|
|
232
|
+
const trimmedOutput = output.trimEnd();
|
|
233
233
|
if (!trimmedOutput) return lines;
|
|
234
234
|
|
|
235
235
|
if (trimmedOutput.startsWith("{") || trimmedOutput.startsWith("[")) {
|
|
@@ -261,7 +261,7 @@ function renderOutputSection(
|
|
|
261
261
|
|
|
262
262
|
lines.push(`${continuePrefix}${theme.fg("dim", "Output")}`);
|
|
263
263
|
|
|
264
|
-
const outputLines = output.split("\n")
|
|
264
|
+
const outputLines = output.trimEnd().split("\n");
|
|
265
265
|
const previewCount = expanded ? maxExpanded : maxCollapsed;
|
|
266
266
|
for (const line of outputLines.slice(0, previewCount)) {
|
|
267
267
|
lines.push(`${continuePrefix} ${theme.fg("dim", truncate(line, 70, theme.format.ellipsis))}`);
|
|
@@ -294,7 +294,7 @@ function formatArgsInline(args: Record<string, string>, theme: Theme): string {
|
|
|
294
294
|
|
|
295
295
|
/** Convert snake_case or kebab-case to Title Case */
|
|
296
296
|
function humanizeKey(key: string): string {
|
|
297
|
-
return key.replace(/[-_]/g, " ").replace(/\b\w/g,
|
|
297
|
+
return key.replace(/[-_]/g, " ").replace(/\b\w/g, c => c.toUpperCase());
|
|
298
298
|
}
|
|
299
299
|
|
|
300
300
|
function formatScalarInline(value: unknown, maxLen: number, theme: Theme): string {
|
|
@@ -395,13 +395,8 @@ function renderArgsSection(
|
|
|
395
395
|
* Render the tool call arguments.
|
|
396
396
|
*/
|
|
397
397
|
export function renderCall(args: TaskParams, theme: Theme): Component {
|
|
398
|
-
const label = theme.fg("toolTitle", theme.bold("Task"));
|
|
399
|
-
const agentTag = theme.italic(
|
|
400
|
-
theme.fg("dim", `${theme.format.bracketLeft}${args.agent}${theme.format.bracketRight}`),
|
|
401
|
-
);
|
|
402
|
-
|
|
403
398
|
const lines: string[] = [];
|
|
404
|
-
lines.push(
|
|
399
|
+
lines.push(renderStatusLine({ icon: "pending", title: "Task", description: args.agent }, theme));
|
|
405
400
|
|
|
406
401
|
const contextTemplate = args.context ?? "";
|
|
407
402
|
const context = contextTemplate.trim();
|
|
@@ -516,8 +511,8 @@ function renderAgentProgress(
|
|
|
516
511
|
const completeData = progress.extractedToolData.complete as Array<{ data: unknown }> | undefined;
|
|
517
512
|
const reportFindingData = progress.extractedToolData.report_finding as ReportFindingDetails[] | undefined;
|
|
518
513
|
const reviewData = completeData
|
|
519
|
-
?.map(
|
|
520
|
-
.filter(
|
|
514
|
+
?.map(c => c.data as SubmitReviewDetails)
|
|
515
|
+
.filter(d => d && typeof d === "object" && "overall_correctness" in d);
|
|
521
516
|
if (reviewData && reviewData.length > 0) {
|
|
522
517
|
const summary = reviewData[reviewData.length - 1];
|
|
523
518
|
const findings = reportFindingData ?? [];
|
|
@@ -701,8 +696,8 @@ function renderAgentResult(result: SingleResult, isLast: boolean, expanded: bool
|
|
|
701
696
|
|
|
702
697
|
// Extract review verdict from complete tool's data field if it matches SubmitReviewDetails
|
|
703
698
|
const reviewData = completeData
|
|
704
|
-
?.map(
|
|
705
|
-
.filter(
|
|
699
|
+
?.map(c => c.data as SubmitReviewDetails)
|
|
700
|
+
.filter(d => d && typeof d === "object" && "overall_correctness" in d);
|
|
706
701
|
const submitReviewData = reviewData && reviewData.length > 0 ? reviewData : undefined;
|
|
707
702
|
|
|
708
703
|
if (submitReviewData && submitReviewData.length > 0) {
|
|
@@ -734,13 +729,12 @@ function renderAgentResult(result: SingleResult, isLast: boolean, expanded: bool
|
|
|
734
729
|
if (handler?.renderFinal && (dataArray as unknown[]).length > 0) {
|
|
735
730
|
hasCustomRendering = true;
|
|
736
731
|
const component = handler.renderFinal(dataArray as unknown[], theme, expanded);
|
|
732
|
+
lines.push(`${continuePrefix}${theme.fg("dim", `Tool: ${toolName}`)}`);
|
|
737
733
|
if (component instanceof Text) {
|
|
738
734
|
// Prefix each line with continuePrefix
|
|
739
735
|
const text = component.getText();
|
|
740
736
|
for (const line of text.split("\n")) {
|
|
741
|
-
|
|
742
|
-
lines.push(`${continuePrefix}${line}`);
|
|
743
|
-
}
|
|
737
|
+
lines.push(`${continuePrefix}${line}`);
|
|
744
738
|
}
|
|
745
739
|
} else if (component instanceof Container) {
|
|
746
740
|
// For containers, render each child
|
|
@@ -780,12 +774,12 @@ export function renderResult(
|
|
|
780
774
|
theme: Theme,
|
|
781
775
|
): Component {
|
|
782
776
|
const { expanded, isPartial, spinnerFrame } = options;
|
|
783
|
-
const fallbackText = result.content.find(
|
|
777
|
+
const fallbackText = result.content.find(c => c.type === "text")?.text ?? "";
|
|
784
778
|
const details = result.details;
|
|
785
779
|
|
|
786
780
|
if (!details) {
|
|
787
781
|
// Fallback to simple text
|
|
788
|
-
const text = result.content.find(
|
|
782
|
+
const text = result.content.find(c => c.type === "text")?.text || "";
|
|
789
783
|
return new Text(theme.fg("dim", truncate(text, 100, theme.format.ellipsis)), 0, 0);
|
|
790
784
|
}
|
|
791
785
|
|
|
@@ -805,8 +799,8 @@ export function renderResult(
|
|
|
805
799
|
});
|
|
806
800
|
|
|
807
801
|
// Summary line
|
|
808
|
-
const abortedCount = details.results.filter(
|
|
809
|
-
const successCount = details.results.filter(
|
|
802
|
+
const abortedCount = details.results.filter(r => r.aborted).length;
|
|
803
|
+
const successCount = details.results.filter(r => !r.aborted && r.exitCode === 0).length;
|
|
810
804
|
const failCount = details.results.length - successCount - abortedCount;
|
|
811
805
|
let summary = `${theme.fg("dim", "Total:")} `;
|
|
812
806
|
if (abortedCount > 0) {
|
|
@@ -834,7 +828,7 @@ export function renderResult(
|
|
|
834
828
|
if (fallbackText.trim()) {
|
|
835
829
|
const summaryLines = fallbackText.split("\n");
|
|
836
830
|
const markerIndex = summaryLines.findIndex(
|
|
837
|
-
|
|
831
|
+
line => line.includes("<system-notification>") || line.startsWith("Applied patches:"),
|
|
838
832
|
);
|
|
839
833
|
if (markerIndex >= 0) {
|
|
840
834
|
const extra = summaryLines.slice(markerIndex);
|
|
@@ -845,7 +839,7 @@ export function renderResult(
|
|
|
845
839
|
}
|
|
846
840
|
}
|
|
847
841
|
|
|
848
|
-
const indented = lines.map(
|
|
842
|
+
const indented = lines.map(line => (line.length > 0 ? ` ${line}` : ""));
|
|
849
843
|
return new Text(indented.join("\n"), 0, 0);
|
|
850
844
|
}
|
|
851
845
|
|
|
@@ -6,9 +6,8 @@
|
|
|
6
6
|
* - Trigger subprocess termination on completion
|
|
7
7
|
* - Provide custom rendering for realtime/final display
|
|
8
8
|
*/
|
|
9
|
-
|
|
10
|
-
import type { Theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
|
|
11
9
|
import type { Component } from "@oh-my-pi/pi-tui";
|
|
10
|
+
import type { Theme } from "../modes/theme/theme";
|
|
12
11
|
|
|
13
12
|
/** Event from subprocess tool execution (parsed from JSONL) */
|
|
14
13
|
export interface SubprocessToolEvent {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AgentEvent, ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
2
|
-
import type { SerializedModelRegistry } from "
|
|
3
|
-
import type { Settings } from "
|
|
4
|
-
import type { SerializedAuthStorage } from "
|
|
2
|
+
import type { SerializedModelRegistry } from "../config/model-registry";
|
|
3
|
+
import type { Settings } from "../config/settings-manager";
|
|
4
|
+
import type { SerializedAuthStorage } from "../session/auth-storage";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* MCP tool metadata passed from parent to worker for proxy tool creation.
|
package/src/task/worker.ts
CHANGED
|
@@ -12,29 +12,23 @@
|
|
|
12
12
|
* 4. Worker sends { type: "done", exitCode, ... } on completion
|
|
13
13
|
* 5. Parent can send { type: "abort" } to request cancellation
|
|
14
14
|
*/
|
|
15
|
-
|
|
16
15
|
import type { AgentEvent, ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
17
16
|
import type { Api, Model } from "@oh-my-pi/pi-ai";
|
|
18
|
-
import { ModelRegistry } from "@oh-my-pi/pi-coding-agent/config/model-registry";
|
|
19
|
-
import { parseModelPattern, parseModelString } from "@oh-my-pi/pi-coding-agent/config/model-resolver";
|
|
20
|
-
import { renderPromptTemplate } from "@oh-my-pi/pi-coding-agent/config/prompt-templates";
|
|
21
|
-
import { SettingsManager } from "@oh-my-pi/pi-coding-agent/config/settings-manager";
|
|
22
|
-
import type { CustomTool } from "@oh-my-pi/pi-coding-agent/extensibility/custom-tools/types";
|
|
23
|
-
import { type LspToolDetails, lspSchema } from "@oh-my-pi/pi-coding-agent/lsp/types";
|
|
24
|
-
import lspDescription from "@oh-my-pi/pi-coding-agent/prompts/tools/lsp.md" with { type: "text" };
|
|
25
|
-
import { createAgentSession, discoverAuthStorage, discoverModels } from "@oh-my-pi/pi-coding-agent/sdk";
|
|
26
|
-
import type { AgentSessionEvent } from "@oh-my-pi/pi-coding-agent/session/agent-session";
|
|
27
|
-
import { AuthStorage } from "@oh-my-pi/pi-coding-agent/session/auth-storage";
|
|
28
|
-
import { SessionManager } from "@oh-my-pi/pi-coding-agent/session/session-manager";
|
|
29
|
-
import {
|
|
30
|
-
getPythonToolDescription,
|
|
31
|
-
type PythonToolDetails,
|
|
32
|
-
type PythonToolParams,
|
|
33
|
-
pythonSchema,
|
|
34
|
-
} from "@oh-my-pi/pi-coding-agent/tools/python";
|
|
35
|
-
import { ToolAbortError } from "@oh-my-pi/pi-coding-agent/tools/tool-errors";
|
|
36
17
|
import { logger, postmortem, untilAborted } from "@oh-my-pi/pi-utils";
|
|
37
18
|
import type { TSchema } from "@sinclair/typebox";
|
|
19
|
+
import { ModelRegistry } from "../config/model-registry";
|
|
20
|
+
import { parseModelPattern, parseModelString } from "../config/model-resolver";
|
|
21
|
+
import { renderPromptTemplate } from "../config/prompt-templates";
|
|
22
|
+
import { SettingsManager } from "../config/settings-manager";
|
|
23
|
+
import type { CustomTool } from "../extensibility/custom-tools/types";
|
|
24
|
+
import { type LspToolDetails, lspSchema } from "../lsp/types";
|
|
25
|
+
import lspDescription from "../prompts/tools/lsp.md" with { type: "text" };
|
|
26
|
+
import { createAgentSession, discoverAuthStorage, discoverModels } from "../sdk";
|
|
27
|
+
import type { AgentSessionEvent } from "../session/agent-session";
|
|
28
|
+
import { AuthStorage } from "../session/auth-storage";
|
|
29
|
+
import { SessionManager } from "../session/session-manager";
|
|
30
|
+
import { getPythonToolDescription, type PythonToolDetails, type PythonToolParams, pythonSchema } from "../tools/python";
|
|
31
|
+
import { ToolAbortError } from "../tools/tool-errors";
|
|
38
32
|
import type {
|
|
39
33
|
LspToolCallResponse,
|
|
40
34
|
MCPToolCallResponse,
|
|
@@ -47,7 +41,7 @@ import type {
|
|
|
47
41
|
|
|
48
42
|
type PostMessageFn = (message: SubagentWorkerResponse) => void;
|
|
49
43
|
|
|
50
|
-
const postMessageSafe: PostMessageFn =
|
|
44
|
+
const postMessageSafe: PostMessageFn = message => {
|
|
51
45
|
try {
|
|
52
46
|
(globalThis as typeof globalThis & { postMessage: PostMessageFn }).postMessage(message);
|
|
53
47
|
} catch {
|
|
@@ -132,11 +126,11 @@ function callMCPToolViaParent(
|
|
|
132
126
|
}
|
|
133
127
|
|
|
134
128
|
pendingMCPCalls.set(callId, {
|
|
135
|
-
resolve:
|
|
129
|
+
resolve: result => {
|
|
136
130
|
cleanup();
|
|
137
131
|
resolve(result ?? { content: [] });
|
|
138
132
|
},
|
|
139
|
-
reject:
|
|
133
|
+
reject: error => {
|
|
140
134
|
cleanup();
|
|
141
135
|
reject(error);
|
|
142
136
|
},
|
|
@@ -200,11 +194,11 @@ function callPythonToolViaParent(
|
|
|
200
194
|
}
|
|
201
195
|
|
|
202
196
|
pendingPythonCalls.set(callId, {
|
|
203
|
-
resolve:
|
|
197
|
+
resolve: result => {
|
|
204
198
|
cleanup();
|
|
205
199
|
resolve(result ?? { content: [] });
|
|
206
200
|
},
|
|
207
|
-
reject:
|
|
201
|
+
reject: error => {
|
|
208
202
|
cleanup();
|
|
209
203
|
reject(error);
|
|
210
204
|
},
|
|
@@ -260,11 +254,11 @@ function callLspToolViaParent(
|
|
|
260
254
|
}
|
|
261
255
|
|
|
262
256
|
pendingLspCalls.set(callId, {
|
|
263
|
-
resolve:
|
|
257
|
+
resolve: result => {
|
|
264
258
|
cleanup();
|
|
265
259
|
resolve(result ?? { content: [] });
|
|
266
260
|
},
|
|
267
|
-
reject:
|
|
261
|
+
reject: error => {
|
|
268
262
|
cleanup();
|
|
269
263
|
reject(error);
|
|
270
264
|
},
|
|
@@ -349,7 +343,7 @@ function createMCPProxyTool(metadata: MCPToolMetadata): CustomTool<TSchema> {
|
|
|
349
343
|
metadata.timeoutMs,
|
|
350
344
|
);
|
|
351
345
|
return {
|
|
352
|
-
content: result.content.map(
|
|
346
|
+
content: result.content.map(c =>
|
|
353
347
|
c.type === "text"
|
|
354
348
|
? { type: "text" as const, text: c.text ?? "" }
|
|
355
349
|
: { type: "text" as const, text: JSON.stringify(c) },
|
|
@@ -391,7 +385,7 @@ function createPythonProxyTool(): CustomTool<typeof pythonSchema> {
|
|
|
391
385
|
const result = await callPythonToolViaParent(params as PythonToolParams, signal, timeoutMs);
|
|
392
386
|
return {
|
|
393
387
|
content:
|
|
394
|
-
result?.content?.map(
|
|
388
|
+
result?.content?.map(c =>
|
|
395
389
|
c.type === "text"
|
|
396
390
|
? { type: "text" as const, text: c.text ?? "" }
|
|
397
391
|
: { type: "text" as const, text: JSON.stringify(c) },
|
|
@@ -424,7 +418,7 @@ function createLspProxyTool(): CustomTool<typeof lspSchema> {
|
|
|
424
418
|
const result = await callLspToolViaParent(params as Record<string, unknown>, signal);
|
|
425
419
|
return {
|
|
426
420
|
content:
|
|
427
|
-
result?.content?.map(
|
|
421
|
+
result?.content?.map(c =>
|
|
428
422
|
c.type === "text"
|
|
429
423
|
? { type: "text" as const, text: c.text ?? "" }
|
|
430
424
|
: { type: "text" as const, text: JSON.stringify(c) },
|
|
@@ -552,7 +546,7 @@ async function runTask(runState: RunState, payload: SubagentWorkerStartPayload):
|
|
|
552
546
|
let modelRegistry: ModelRegistry;
|
|
553
547
|
|
|
554
548
|
if (payload.serializedAuth && payload.serializedModels) {
|
|
555
|
-
authStorage = AuthStorage.fromSerialized(payload.serializedAuth);
|
|
549
|
+
authStorage = await AuthStorage.fromSerialized(payload.serializedAuth);
|
|
556
550
|
modelRegistry = ModelRegistry.fromSerialized(payload.serializedModels, authStorage);
|
|
557
551
|
} else {
|
|
558
552
|
authStorage = await discoverAuthStorage();
|
|
@@ -606,7 +600,7 @@ async function runTask(runState: RunState, payload: SubagentWorkerStartPayload):
|
|
|
606
600
|
outputSchema: payload.outputSchema,
|
|
607
601
|
requireCompleteTool: true,
|
|
608
602
|
// Append system prompt (equivalent to CLI's --append-system-prompt)
|
|
609
|
-
systemPrompt:
|
|
603
|
+
systemPrompt: defaultPrompt =>
|
|
610
604
|
`${defaultPrompt}\n\n${payload.systemPrompt}\n\n${worktreeNotice}\n\n${completionInstruction}`,
|
|
611
605
|
sessionManager,
|
|
612
606
|
hasUI: false,
|
|
@@ -638,14 +632,14 @@ async function runTask(runState: RunState, payload: SubagentWorkerStartPayload):
|
|
|
638
632
|
// ExtensionActions
|
|
639
633
|
{
|
|
640
634
|
sendMessage: (message, options) => {
|
|
641
|
-
session.sendCustomMessage(message, options).catch(
|
|
635
|
+
session.sendCustomMessage(message, options).catch(e => {
|
|
642
636
|
logger.error("Extension sendMessage failed", {
|
|
643
637
|
error: e instanceof Error ? e.message : String(e),
|
|
644
638
|
});
|
|
645
639
|
});
|
|
646
640
|
},
|
|
647
641
|
sendUserMessage: (content, options) => {
|
|
648
|
-
session.sendUserMessage(content, options).catch(
|
|
642
|
+
session.sendUserMessage(content, options).catch(e => {
|
|
649
643
|
logger.error("Extension sendUserMessage failed", {
|
|
650
644
|
error: e instanceof Error ? e.message : String(e),
|
|
651
645
|
});
|
|
@@ -660,14 +654,14 @@ async function runTask(runState: RunState, payload: SubagentWorkerStartPayload):
|
|
|
660
654
|
getActiveTools: () => session.getActiveToolNames(),
|
|
661
655
|
getAllTools: () => session.getAllToolNames(),
|
|
662
656
|
setActiveTools: (toolNames: string[]) => session.setActiveToolsByName(toolNames),
|
|
663
|
-
setModel: async
|
|
657
|
+
setModel: async model => {
|
|
664
658
|
const key = await session.modelRegistry.getApiKey(model);
|
|
665
659
|
if (!key) return false;
|
|
666
660
|
await session.setModel(model);
|
|
667
661
|
return true;
|
|
668
662
|
},
|
|
669
663
|
getThinkingLevel: () => session.thinkingLevel,
|
|
670
|
-
setThinkingLevel:
|
|
664
|
+
setThinkingLevel: level => session.setThinkingLevel(level),
|
|
671
665
|
},
|
|
672
666
|
// ExtensionContextActions
|
|
673
667
|
{
|
|
@@ -677,7 +671,7 @@ async function runTask(runState: RunState, payload: SubagentWorkerStartPayload):
|
|
|
677
671
|
hasPendingMessages: () => session.queuedMessageCount > 0,
|
|
678
672
|
shutdown: () => {},
|
|
679
673
|
getContextUsage: () => session.getContextUsage(),
|
|
680
|
-
compact: async
|
|
674
|
+
compact: async instructionsOrOptions => {
|
|
681
675
|
const instructions = typeof instructionsOrOptions === "string" ? instructionsOrOptions : undefined;
|
|
682
676
|
const options =
|
|
683
677
|
instructionsOrOptions && typeof instructionsOrOptions === "object"
|
|
@@ -687,7 +681,7 @@ async function runTask(runState: RunState, payload: SubagentWorkerStartPayload):
|
|
|
687
681
|
},
|
|
688
682
|
},
|
|
689
683
|
);
|
|
690
|
-
extensionRunner.onError(
|
|
684
|
+
extensionRunner.onError(err => {
|
|
691
685
|
logger.error("Extension error", { path: err.extensionPath, error: err.error });
|
|
692
686
|
});
|
|
693
687
|
await extensionRunner.emit({ type: "session_start" });
|
|
@@ -844,11 +838,11 @@ declare const self: {
|
|
|
844
838
|
addEventListener(type: "messageerror", listener: (event: MessageEvent) => void): void;
|
|
845
839
|
};
|
|
846
840
|
|
|
847
|
-
self.addEventListener("error",
|
|
841
|
+
self.addEventListener("error", event => {
|
|
848
842
|
reportFatal(`Uncaught error: ${event.message || "Unknown error"}`);
|
|
849
843
|
});
|
|
850
844
|
|
|
851
|
-
self.addEventListener("unhandledrejection",
|
|
845
|
+
self.addEventListener("unhandledrejection", event => {
|
|
852
846
|
const reason = event.reason;
|
|
853
847
|
const message = reason instanceof Error ? reason.stack || reason.message : String(reason);
|
|
854
848
|
|
package/src/task/worktree.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import * as fs from "node:fs/promises";
|
|
3
|
+
import * as os from "node:os";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { $ } from "bun";
|
|
6
6
|
|
|
@@ -30,10 +30,10 @@ export async function getRepoRoot(cwd: string): Promise<string> {
|
|
|
30
30
|
export async function ensureWorktree(baseCwd: string, id: string): Promise<string> {
|
|
31
31
|
const repoRoot = await getRepoRoot(baseCwd);
|
|
32
32
|
const encodedProject = getEncodedProjectName(repoRoot);
|
|
33
|
-
const worktreeDir = path.join(homedir(), ".omp", "wt", encodedProject, id);
|
|
34
|
-
await mkdir(path.dirname(worktreeDir), { recursive: true });
|
|
33
|
+
const worktreeDir = path.join(os.homedir(), ".omp", "wt", encodedProject, id);
|
|
34
|
+
await fs.mkdir(path.dirname(worktreeDir), { recursive: true });
|
|
35
35
|
await $`git worktree remove -f ${worktreeDir}`.cwd(repoRoot).quiet().nothrow();
|
|
36
|
-
await rm(worktreeDir, { recursive: true, force: true });
|
|
36
|
+
await fs.rm(worktreeDir, { recursive: true, force: true });
|
|
37
37
|
await $`git worktree add --detach ${worktreeDir} HEAD`.cwd(repoRoot).quiet();
|
|
38
38
|
return worktreeDir;
|
|
39
39
|
}
|
|
@@ -44,8 +44,8 @@ export async function captureBaseline(repoRoot: string): Promise<WorktreeBaselin
|
|
|
44
44
|
const untrackedRaw = await $`git ls-files --others --exclude-standard`.cwd(repoRoot).quiet().text();
|
|
45
45
|
const untracked = untrackedRaw
|
|
46
46
|
.split("\n")
|
|
47
|
-
.map(
|
|
48
|
-
.filter(
|
|
47
|
+
.map(line => line.trim())
|
|
48
|
+
.filter(line => line.length > 0);
|
|
49
49
|
|
|
50
50
|
return {
|
|
51
51
|
repoRoot,
|
|
@@ -56,7 +56,7 @@ export async function captureBaseline(repoRoot: string): Promise<WorktreeBaselin
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
async function writeTempPatchFile(patch: string): Promise<string> {
|
|
59
|
-
const tempPath = path.join(tmpdir(), `omp-task-patch-${randomUUID()}.patch`);
|
|
59
|
+
const tempPath = path.join(os.tmpdir(), `omp-task-patch-${randomUUID()}.patch`);
|
|
60
60
|
await Bun.write(tempPath, patch);
|
|
61
61
|
return tempPath;
|
|
62
62
|
}
|
|
@@ -76,7 +76,7 @@ async function applyPatch(
|
|
|
76
76
|
}
|
|
77
77
|
await runner;
|
|
78
78
|
} finally {
|
|
79
|
-
await rm(tempPath, { force: true });
|
|
79
|
+
await fs.rm(tempPath, { force: true });
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
|
|
@@ -90,8 +90,8 @@ export async function applyBaseline(worktreeDir: string, baseline: WorktreeBasel
|
|
|
90
90
|
const destination = path.join(worktreeDir, entry);
|
|
91
91
|
const exists = await Bun.file(source).exists();
|
|
92
92
|
if (!exists) continue;
|
|
93
|
-
await mkdir(path.dirname(destination), { recursive: true });
|
|
94
|
-
await cp(source, destination, { recursive: true });
|
|
93
|
+
await fs.mkdir(path.dirname(destination), { recursive: true });
|
|
94
|
+
await fs.cp(source, destination, { recursive: true });
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
|
|
@@ -106,7 +106,7 @@ async function applyPatchToIndex(cwd: string, patch: string, indexFile: string):
|
|
|
106
106
|
})
|
|
107
107
|
.quiet();
|
|
108
108
|
} finally {
|
|
109
|
-
await rm(tempPath, { force: true });
|
|
109
|
+
await fs.rm(tempPath, { force: true });
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
|
|
@@ -114,12 +114,12 @@ async function listUntracked(cwd: string): Promise<string[]> {
|
|
|
114
114
|
const raw = await $`git ls-files --others --exclude-standard`.cwd(cwd).quiet().text();
|
|
115
115
|
return raw
|
|
116
116
|
.split("\n")
|
|
117
|
-
.map(
|
|
118
|
-
.filter(
|
|
117
|
+
.map(line => line.trim())
|
|
118
|
+
.filter(line => line.length > 0);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
export async function captureDeltaPatch(worktreeDir: string, baseline: WorktreeBaseline): Promise<string> {
|
|
122
|
-
const tempIndex = path.join(tmpdir(), `omp-task-index-${randomUUID()}`);
|
|
122
|
+
const tempIndex = path.join(os.tmpdir(), `omp-task-index-${randomUUID()}`);
|
|
123
123
|
try {
|
|
124
124
|
await $`git read-tree HEAD`.cwd(worktreeDir).env({
|
|
125
125
|
GIT_INDEX_FILE: tempIndex,
|
|
@@ -136,18 +136,18 @@ export async function captureDeltaPatch(worktreeDir: string, baseline: WorktreeB
|
|
|
136
136
|
|
|
137
137
|
const currentUntracked = await listUntracked(worktreeDir);
|
|
138
138
|
const baselineUntracked = new Set(baseline.untracked);
|
|
139
|
-
const newUntracked = currentUntracked.filter(
|
|
139
|
+
const newUntracked = currentUntracked.filter(entry => !baselineUntracked.has(entry));
|
|
140
140
|
|
|
141
141
|
if (newUntracked.length === 0) return diff;
|
|
142
142
|
|
|
143
143
|
const untrackedDiffs = await Promise.all(
|
|
144
|
-
newUntracked.map(
|
|
144
|
+
newUntracked.map(entry =>
|
|
145
145
|
$`git diff --binary --no-index /dev/null ${entry}`.cwd(worktreeDir).quiet().nothrow().text(),
|
|
146
146
|
),
|
|
147
147
|
);
|
|
148
148
|
return `${diff}${diff && !diff.endsWith("\n") ? "\n" : ""}${untrackedDiffs.join("\n")}`;
|
|
149
149
|
} finally {
|
|
150
|
-
await rm(tempIndex, { force: true });
|
|
150
|
+
await fs.rm(tempIndex, { force: true });
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
|
|
@@ -161,6 +161,6 @@ export async function cleanupWorktree(dir: string): Promise<void> {
|
|
|
161
161
|
await $`git worktree remove -f ${dir}`.cwd(repoRoot).quiet().nothrow();
|
|
162
162
|
}
|
|
163
163
|
} finally {
|
|
164
|
-
await rm(dir, { recursive: true, force: true });
|
|
164
|
+
await fs.rm(dir, { recursive: true, force: true });
|
|
165
165
|
}
|
|
166
166
|
}
|