@oh-my-pi/pi-coding-agent 7.0.0 → 8.0.1
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 +87 -0
- package/README.md +1 -1
- package/docs/hooks.md +2 -2
- package/docs/sdk.md +1 -1
- package/package.json +12 -11
- package/scripts/format-prompts.ts +143 -0
- package/scripts/generate-template.ts +1 -1
- package/src/cli/args.ts +3 -3
- package/src/cli/config-cli.ts +4 -4
- package/src/cli/file-processor.ts +3 -3
- package/src/cli/list-models.ts +2 -2
- package/src/cli/plugin-cli.ts +3 -3
- package/src/cli/session-picker.ts +2 -2
- package/src/cli/setup-cli.ts +2 -2
- package/src/cli/stats-cli.ts +1 -1
- package/src/cli/update-cli.ts +2 -2
- package/src/{core → config}/keybindings.ts +1 -1
- package/src/{core → config}/model-registry.ts +1 -1
- package/src/{core → config}/model-resolver.ts +3 -3
- package/src/{core → config}/prompt-templates.ts +2 -2
- package/src/{core → config}/settings-manager.ts +6 -6
- package/src/{core/cursor/exec-bridge.ts → cursor.ts} +4 -4
- package/src/discovery/agents-md.ts +4 -4
- package/src/discovery/builtin.ts +17 -17
- package/src/discovery/claude.ts +12 -12
- package/src/discovery/cline.ts +6 -6
- package/src/discovery/codex.ts +21 -21
- package/src/discovery/cursor.ts +9 -9
- package/src/discovery/gemini.ts +9 -9
- package/src/discovery/github.ts +6 -6
- package/src/discovery/helpers.ts +4 -4
- package/src/discovery/index.ts +16 -16
- package/src/discovery/mcp-json.ts +4 -4
- package/src/discovery/ssh.ts +4 -4
- package/src/discovery/vscode.ts +4 -4
- package/src/discovery/windsurf.ts +6 -6
- package/src/{core/tools/exa → exa}/company.ts +2 -3
- package/src/{core/tools/exa → exa}/index.ts +2 -2
- package/src/{core/tools/exa → exa}/linkedin.ts +2 -3
- package/src/{core/tools/exa → exa}/mcp-client.ts +2 -2
- package/src/{core/tools/exa → exa}/render.ts +3 -3
- package/src/{core/tools/exa → exa}/researcher.ts +1 -1
- package/src/{core/tools/exa → exa}/search.ts +2 -10
- package/src/{core/tools/exa → exa}/websets.ts +1 -1
- package/src/{core → exec}/bash-executor.ts +22 -6
- package/src/{core → export}/custom-share.ts +1 -1
- package/src/{core/export-html → export/html}/index.ts +3 -3
- package/src/{core → export}/ttsr.ts +2 -2
- package/src/{core → extensibility}/custom-commands/bundled/review/index.ts +4 -4
- package/src/{core → extensibility}/custom-commands/loader.ts +3 -3
- package/src/{core → extensibility}/custom-commands/types.ts +1 -1
- package/src/{core → extensibility}/custom-tools/loader.ts +9 -9
- package/src/{core → extensibility}/custom-tools/types.ts +6 -6
- package/src/{core → extensibility}/custom-tools/wrapper.ts +1 -1
- package/src/{core → extensibility}/extensions/loader.ts +8 -8
- package/src/{core → extensibility}/extensions/runner.ts +3 -3
- package/src/{core → extensibility}/extensions/types.ts +15 -15
- package/src/{core → extensibility}/extensions/wrapper.ts +1 -1
- package/src/{core → extensibility}/hooks/index.ts +1 -1
- package/src/{core → extensibility}/hooks/loader.ts +7 -7
- package/src/{core → extensibility}/hooks/runner.ts +4 -4
- package/src/{core → extensibility}/hooks/types.ts +9 -9
- package/src/{core → extensibility}/plugins/doctor.ts +1 -1
- package/src/{core → extensibility}/plugins/installer.ts +2 -3
- package/src/{core → extensibility}/plugins/paths.ts +1 -1
- package/src/{core → extensibility}/skills.ts +8 -48
- package/src/{core → extensibility}/slash-commands.ts +6 -6
- package/src/index.ts +127 -128
- package/src/internal-urls/agent-protocol.ts +126 -0
- package/src/internal-urls/artifact-protocol.ts +93 -0
- package/src/internal-urls/index.ts +28 -0
- package/src/internal-urls/json-query.ts +126 -0
- package/src/internal-urls/router.ts +69 -0
- package/src/internal-urls/rule-protocol.ts +56 -0
- package/src/internal-urls/skill-protocol.ts +112 -0
- package/src/internal-urls/types.ts +48 -0
- package/src/{core/python-executor.ts → ipy/executor.ts} +51 -11
- package/src/{core/python-gateway-coordinator.ts → ipy/gateway-coordinator.ts} +41 -325
- package/src/{core/python-kernel.ts → ipy/kernel.ts} +38 -10
- package/src/ipy/prelude.ts +3 -0
- package/src/{core/tools/lsp → lsp}/client.ts +7 -6
- package/src/{core/tools/lsp → lsp}/clients/biome-client.ts +1 -1
- package/src/{core/tools/lsp → lsp}/clients/index.ts +1 -1
- package/src/{core/tools/lsp → lsp}/clients/lsp-linter-client.ts +4 -4
- package/src/{core/tools/lsp → lsp}/config.ts +1 -1
- package/src/{core/tools/lsp → lsp}/index.ts +16 -15
- package/src/{core/tools/lsp → lsp}/render.ts +2 -2
- package/src/{core/tools/lsp → lsp}/types.ts +14 -16
- package/src/{core/tools/lsp → lsp}/utils.ts +1 -1
- package/src/main.ts +12 -12
- package/src/{core/mcp → mcp}/config.ts +8 -8
- package/src/{core/mcp → mcp}/loader.ts +5 -6
- package/src/{core/mcp → mcp}/manager.ts +2 -2
- package/src/{core/mcp → mcp}/tool-bridge.ts +35 -6
- package/src/{core/mcp → mcp}/tool-cache.ts +1 -1
- package/src/{core/mcp → mcp}/transports/http.ts +7 -1
- package/src/{core/mcp → mcp}/transports/stdio.ts +1 -1
- package/src/{core/mcp → mcp}/types.ts +1 -1
- package/src/migrations.ts +2 -2
- package/src/modes/{interactive/components → components}/armin.ts +1 -1
- package/src/modes/{interactive/components → components}/assistant-message.ts +1 -1
- package/src/modes/{interactive/components → components}/bash-execution.ts +37 -29
- package/src/modes/{interactive/components → components}/bordered-loader.ts +1 -1
- package/src/modes/{interactive/components → components}/branch-summary-message.ts +2 -2
- package/src/modes/{interactive/components → components}/compaction-summary-message.ts +2 -2
- package/src/modes/{interactive/components → components}/custom-message.ts +3 -3
- package/src/modes/{interactive/components → components}/diff.ts +1 -1
- package/src/modes/{interactive/components → components}/dynamic-border.ts +1 -1
- package/src/modes/{interactive/components → components}/extensions/extension-dashboard.ts +3 -3
- package/src/modes/{interactive/components → components}/extensions/extension-list.ts +2 -2
- package/src/modes/{interactive/components → components}/extensions/inspector-panel.ts +1 -1
- package/src/modes/{interactive/components → components}/extensions/state-manager.ts +11 -17
- package/src/modes/{interactive/components → components}/extensions/types.ts +1 -1
- package/src/modes/{interactive/components → components}/footer.ts +3 -3
- package/src/modes/{interactive/components → components}/history-search.ts +2 -2
- package/src/modes/{interactive/components → components}/hook-editor.ts +1 -1
- package/src/modes/{interactive/components → components}/hook-input.ts +1 -1
- package/src/modes/{interactive/components → components}/hook-message.ts +3 -3
- package/src/modes/{interactive/components → components}/hook-selector.ts +1 -1
- package/src/modes/{interactive/components → components}/keybinding-hints.ts +2 -2
- package/src/modes/{interactive/components → components}/login-dialog.ts +1 -1
- package/src/modes/{interactive/components → components}/model-selector.ts +5 -5
- package/src/modes/{interactive/components → components}/oauth-selector.ts +2 -2
- package/src/modes/{interactive/components → components}/plugin-settings.ts +3 -3
- package/src/modes/{interactive/components → components}/python-execution.ts +35 -24
- package/src/modes/{interactive/components → components}/queue-mode-selector.ts +1 -1
- package/src/modes/{interactive/components → components}/read-tool-group.ts +2 -2
- package/src/modes/{interactive/components → components}/session-selector.ts +3 -3
- package/src/modes/{interactive/components → components}/settings-defs.ts +2 -2
- package/src/modes/{interactive/components → components}/settings-selector.ts +2 -2
- package/src/modes/{interactive/components → components}/show-images-selector.ts +1 -1
- package/src/modes/{interactive/components → components}/status-line/segments.ts +2 -2
- package/src/modes/{interactive/components → components}/status-line/separators.ts +1 -1
- package/src/modes/{interactive/components → components}/status-line/types.ts +2 -2
- package/src/modes/{interactive/components → components}/status-line-segment-editor.ts +2 -2
- package/src/modes/{interactive/components → components}/status-line.ts +3 -3
- package/src/modes/{interactive/components → components}/theme-selector.ts +1 -1
- package/src/modes/{interactive/components → components}/thinking-selector.ts +1 -1
- package/src/modes/{interactive/components → components}/todo-display.ts +3 -4
- package/src/modes/{interactive/components → components}/todo-reminder.ts +2 -2
- package/src/modes/{interactive/components → components}/tool-execution.ts +8 -8
- package/src/modes/{interactive/components → components}/tree-selector.ts +3 -3
- package/src/modes/{interactive/components → components}/ttsr-notification.ts +2 -2
- package/src/modes/{interactive/components → components}/user-message-selector.ts +1 -1
- package/src/modes/{interactive/components → components}/user-message.ts +1 -1
- package/src/modes/{interactive/components → components}/welcome.ts +2 -2
- package/src/modes/{interactive/controllers → controllers}/command-controller.ts +32 -30
- package/src/modes/{interactive/controllers → controllers}/event-controller.ts +9 -9
- package/src/modes/{interactive/controllers → controllers}/extension-ui-controller.ts +8 -8
- package/src/modes/{interactive/controllers → controllers}/input-controller.ts +6 -6
- package/src/modes/{interactive/controllers → controllers}/selector-controller.ts +16 -16
- package/src/modes/index.ts +1 -1
- package/src/modes/{interactive/interactive-mode.ts → interactive-mode.ts} +14 -14
- package/src/modes/print-mode.ts +1 -1
- package/src/modes/rpc/rpc-client.ts +3 -3
- package/src/modes/rpc/rpc-mode.ts +3 -3
- package/src/modes/rpc/rpc-types.ts +3 -3
- package/src/modes/{interactive/theme → theme}/theme.ts +1 -1
- package/src/modes/{interactive/types.ts → types.ts} +8 -9
- package/src/modes/{interactive/utils → utils}/ui-helpers.ts +20 -27
- package/src/{core/tools/patch → patch}/applicator.ts +1 -1
- package/src/{core/tools/patch → patch}/diff.ts +1 -1
- package/src/{core/tools/patch → patch}/index.ts +31 -36
- package/src/{core/tools/patch → patch}/shared.ts +9 -6
- package/src/prompts/agents/explore.md +83 -46
- package/src/prompts/agents/init.md +9 -4
- package/src/prompts/agents/plan.md +8 -7
- package/src/prompts/agents/reviewer.md +36 -18
- package/src/prompts/agents/task.md +4 -4
- package/src/prompts/compaction/branch-summary-preamble.md +0 -1
- package/src/prompts/review-request.md +0 -1
- package/src/prompts/system/custom-system-prompt.md +2 -14
- package/src/prompts/system/file-operations.md +0 -2
- package/src/prompts/system/system-prompt.md +147 -138
- package/src/prompts/system/web-search.md +26 -0
- package/src/prompts/tools/ask.md +31 -24
- package/src/prompts/tools/bash.md +20 -17
- package/src/prompts/tools/calculator.md +9 -5
- package/src/prompts/tools/fetch.md +16 -0
- package/src/prompts/tools/find.md +15 -5
- package/src/prompts/tools/gemini-image.md +21 -6
- package/src/prompts/tools/grep.md +28 -12
- package/src/prompts/tools/lsp.md +35 -14
- package/src/prompts/tools/patch.md +39 -41
- package/src/prompts/tools/python.md +59 -76
- package/src/prompts/tools/read.md +23 -22
- package/src/prompts/tools/replace.md +19 -12
- package/src/prompts/tools/ssh.md +21 -28
- package/src/prompts/tools/task.md +54 -44
- package/src/prompts/tools/todo-write.md +52 -163
- package/src/prompts/tools/web-search.md +16 -9
- package/src/prompts/tools/write.md +13 -2
- package/src/{core/sdk.ts → sdk.ts} +65 -34
- package/src/{core → session}/agent-session.ts +45 -37
- package/src/{core → session}/agent-storage.ts +2 -2
- package/src/session/artifacts.ts +110 -0
- package/src/{core → session}/auth-storage.ts +1 -1
- package/src/{core → session}/compaction/branch-summarization.ts +5 -5
- package/src/{core → session}/compaction/compaction.ts +6 -6
- package/src/{core → session}/compaction/utils.ts +3 -3
- package/src/{core → session}/history-storage.ts +1 -1
- package/src/{core → session}/messages.ts +6 -8
- package/src/{core → session}/session-manager.ts +2 -2
- package/src/{core → session}/storage-migration.ts +2 -2
- package/src/session/streaming-output.ts +177 -0
- package/src/{core/ssh → ssh}/connection-manager.ts +1 -1
- package/src/{core/ssh → ssh}/ssh-executor.ts +19 -4
- package/src/{core/ssh → ssh}/sshfs-mount.ts +1 -1
- package/src/{core/system-prompt.ts → system-prompt.ts} +8 -37
- package/src/{core/tools/task → task}/agents.ts +8 -8
- package/src/{core/tools/task → task}/commands.ts +5 -6
- package/src/{core/tools/task → task}/discovery.ts +3 -3
- package/src/{core/tools/task → task}/executor.ts +34 -44
- package/src/{core/tools/task → task}/index.ts +206 -50
- package/src/{core/tools/task → task}/render.ts +80 -23
- package/src/{core/tools/task → task}/subprocess-tool-registry.ts +1 -1
- package/src/task/template.ts +47 -0
- package/src/{core/tools/task → task}/types.ts +19 -27
- package/src/{core/tools/task → task}/worker-protocol.ts +8 -4
- package/src/{core/tools/task → task}/worker.ts +34 -29
- package/src/task/worktree.ts +166 -0
- package/src/{core/tools → tools}/ask.ts +13 -21
- package/src/{core/tools → tools}/bash-interceptor.ts +1 -1
- package/src/{core/tools → tools}/bash.ts +61 -63
- package/src/{core/tools → tools}/calculator.ts +4 -4
- package/src/{core/tools → tools}/complete.ts +1 -1
- package/src/{core/tools → tools}/context.ts +2 -2
- package/src/{core/tools/web-fetch.ts → tools/fetch.ts} +97 -76
- package/src/{core/tools → tools}/find.ts +80 -104
- package/src/{core/tools → tools}/gemini-image.ts +420 -29
- package/src/{core/tools → tools}/grep.ts +155 -164
- package/src/{core/tools → tools}/index.ts +63 -56
- package/src/tools/list-limit.ts +40 -0
- package/src/{core/tools → tools}/ls.ts +44 -35
- package/src/{core/tools → tools}/notebook.ts +3 -3
- package/src/tools/output-meta.ts +443 -0
- package/src/tools/output-utils.ts +63 -0
- package/src/{core/tools → tools}/python.ts +105 -89
- package/src/tools/read.ts +882 -0
- package/src/{core/tools → tools}/render-utils.ts +1 -1
- package/src/{core/tools → tools}/renderers.ts +8 -10
- package/src/{core/tools → tools}/review.ts +2 -2
- package/src/{core/tools → tools}/ssh.ts +56 -59
- package/src/{core/tools → tools}/todo-write.ts +12 -23
- package/src/tools/tool-errors.ts +95 -0
- package/src/tools/tool-result.ts +92 -0
- package/src/{core/tools → tools}/truncate.ts +2 -2
- package/src/{core/tools → tools}/write.ts +15 -13
- package/src/utils/changelog.ts +1 -1
- package/src/{core → utils}/file-mentions.ts +4 -4
- package/src/utils/image-convert.ts +1 -1
- package/src/utils/image-resize.ts +1 -1
- package/src/utils/shell.ts +1 -1
- package/src/{core → utils}/title-generator.ts +4 -4
- package/src/utils/tools-manager.ts +1 -1
- package/src/{core/tools/web-scrapers → web/scrapers}/choosealicense.ts +1 -1
- package/src/{core/tools/web-scrapers → web/scrapers}/twitter.ts +3 -2
- package/src/{core/tools/web-scrapers → web/scrapers}/types.ts +4 -2
- package/src/{core/tools/web-scrapers → web/scrapers}/utils.ts +1 -1
- package/src/{core/tools/web-scrapers → web/scrapers}/youtube.ts +14 -13
- package/src/{core/tools/web-search → web/search}/auth.ts +4 -4
- package/src/{core/tools/web-search → web/search}/index.ts +22 -71
- package/src/{core/tools/web-search → web/search}/providers/anthropic.ts +7 -10
- package/src/{core/tools/web-search → web/search}/providers/exa.ts +2 -2
- package/src/{core/tools/web-search → web/search}/providers/perplexity.ts +4 -16
- package/src/{core/tools/web-search → web/search}/render.ts +3 -3
- package/tsconfig.json +25 -0
- package/scripts/migrate-sessions.sh +0 -93
- package/src/core/index.ts +0 -56
- package/src/core/python-prelude.ts +0 -3
- package/src/core/ssh-executor.ts +0 -5
- package/src/core/streaming-output.ts +0 -115
- package/src/core/tools/output.ts +0 -519
- package/src/core/tools/read.ts +0 -717
- package/src/core/tools/task/template.ts +0 -37
- package/src/prompts/tools/output.md +0 -47
- package/src/prompts/tools/web-fetch.md +0 -9
- package/src/vendor/photon/photon_rs_bg.wasm.b64.js +0 -1
- /package/src/{core/tools/exa → exa}/types.ts +0 -0
- /package/src/{core → exec}/exec.ts +0 -0
- /package/src/{core/export-html → export/html}/template.css +0 -0
- /package/src/{core/export-html → export/html}/template.generated.ts +0 -0
- /package/src/{core/export-html → export/html}/template.html +0 -0
- /package/src/{core/export-html → export/html}/template.js +0 -0
- /package/src/{core/export-html → export/html}/template.macro.ts +0 -0
- /package/src/{core/export-html → export/html}/vendor/highlight.min.js +0 -0
- /package/src/{core/export-html → export/html}/vendor/marked.min.js +0 -0
- /package/src/{core → extensibility}/custom-commands/index.ts +0 -0
- /package/src/{core → extensibility}/custom-tools/index.ts +0 -0
- /package/src/{core → extensibility}/extensions/index.ts +0 -0
- /package/src/{core → extensibility}/hooks/tool-wrapper.ts +0 -0
- /package/src/{core → extensibility}/plugins/index.ts +0 -0
- /package/src/{core → extensibility}/plugins/loader.ts +0 -0
- /package/src/{core → extensibility}/plugins/manager.ts +0 -0
- /package/src/{core → extensibility}/plugins/parser.ts +0 -0
- /package/src/{core → extensibility}/plugins/types.ts +0 -0
- /package/src/{core/python-modules.ts → ipy/modules.ts} +0 -0
- /package/src/{core/python-prelude.py → ipy/prelude.py} +0 -0
- /package/src/{core/tools/lsp → lsp}/defaults.json +0 -0
- /package/src/{core/tools/lsp → lsp}/edits.ts +0 -0
- /package/src/{core/tools/lsp → lsp}/lspmux.ts +0 -0
- /package/src/{core/tools/lsp → lsp}/rust-analyzer.ts +0 -0
- /package/src/{core/mcp → mcp}/client.ts +0 -0
- /package/src/{core/mcp → mcp}/index.ts +0 -0
- /package/src/{core/mcp → mcp}/json-rpc.ts +0 -0
- /package/src/{core/mcp → mcp}/transports/index.ts +0 -0
- /package/src/modes/{interactive/components → components}/countdown-timer.ts +0 -0
- /package/src/modes/{interactive/components → components}/custom-editor.ts +0 -0
- /package/src/modes/{interactive/components → components}/extensions/index.ts +0 -0
- /package/src/modes/{interactive/components → components}/index.ts +0 -0
- /package/src/modes/{interactive/components → components}/status-line/index.ts +0 -0
- /package/src/modes/{interactive/components → components}/status-line/presets.ts +0 -0
- /package/src/modes/{interactive/components → components}/visual-truncate.ts +0 -0
- /package/src/modes/{interactive/theme → theme}/dark.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/alabaster.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/amethyst.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/anthracite.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/basalt.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/birch.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-abyss.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-arctic.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-aurora.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-catppuccin.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-cavern.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-copper.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-cosmos.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-cyberpunk.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-dracula.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-eclipse.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-ember.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-equinox.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-forest.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-github.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-gruvbox.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-lavender.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-lunar.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-midnight.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-monochrome.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-monokai.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-nebula.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-nord.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-ocean.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-one.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-rainforest.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-reef.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-retro.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-rose-pine.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-sakura.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-slate.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-solarized.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-solstice.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-starfall.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-sunset.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-swamp.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-synthwave.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-taiga.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-terminal.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-tokyo-night.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-tundra.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-twilight.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/dark-volcanic.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/graphite.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/index.ts +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-arctic.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-aurora-day.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-canyon.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-catppuccin.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-cirrus.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-coral.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-cyberpunk.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-dawn.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-dunes.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-eucalyptus.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-forest.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-frost.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-github.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-glacier.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-gruvbox.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-haze.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-honeycomb.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-lagoon.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-lavender.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-meadow.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-mint.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-monochrome.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-ocean.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-one.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-opal.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-orchard.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-paper.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-prism.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-retro.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-sand.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-savanna.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-solarized.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-soleil.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-sunset.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-synthwave.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-tokyo-night.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-wetland.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/light-zenith.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/limestone.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/mahogany.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/marble.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/obsidian.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/onyx.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/pearl.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/porcelain.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/quartz.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/sandstone.json +0 -0
- /package/src/modes/{interactive/theme → theme}/defaults/titanium.json +0 -0
- /package/src/modes/{interactive/theme → theme}/light.json +0 -0
- /package/src/modes/{interactive/theme → theme}/theme-schema.json +0 -0
- /package/src/{core/tools/patch → patch}/fuzzy.ts +0 -0
- /package/src/{core/tools/patch → patch}/normalize.ts +0 -0
- /package/src/{core/tools/patch → patch}/normative.ts +0 -0
- /package/src/{core/tools/patch → patch}/parser.ts +0 -0
- /package/src/{core/tools/patch → patch}/types.ts +0 -0
- /package/src/{core → session}/compaction/index.ts +0 -0
- /package/src/{core → session}/session-storage.ts +0 -0
- /package/src/{core/tools/task → task}/name-generator.ts +0 -0
- /package/src/{core/tools/task → task}/omp-command.ts +0 -0
- /package/src/{core/tools/task → task}/parallel.ts +0 -0
- /package/src/{core/tools → tools}/jtd-to-json-schema.ts +0 -0
- /package/src/{core/tools → tools}/path-utils.ts +0 -0
- /package/src/{core → utils}/event-bus.ts +0 -0
- /package/src/{core → utils}/frontmatter.ts +0 -0
- /package/src/{core → utils}/terminal-notify.ts +0 -0
- /package/src/{core → utils}/timings.ts +0 -0
- /package/src/{core → utils}/utils.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/artifacthub.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/arxiv.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/aur.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/biorxiv.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/bluesky.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/brew.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/cheatsh.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/chocolatey.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/cisa-kev.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/clojars.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/coingecko.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/crates-io.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/crossref.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/devto.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/discogs.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/discourse.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/dockerhub.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/fdroid.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/firefox-addons.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/flathub.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/github-gist.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/github.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/gitlab.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/go-pkg.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/hackage.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/hackernews.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/hex.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/huggingface.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/iacr.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/index.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/jetbrains-marketplace.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/lemmy.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/lobsters.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/mastodon.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/maven.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/mdn.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/metacpan.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/musicbrainz.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/npm.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/nuget.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/nvd.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/ollama.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/open-vsx.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/opencorporates.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/openlibrary.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/orcid.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/osv.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/packagist.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/pub-dev.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/pubmed.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/pypi.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/rawg.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/readthedocs.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/reddit.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/repology.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/rfc.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/rubygems.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/searchcode.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/sec-edgar.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/semantic-scholar.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/snapcraft.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/sourcegraph.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/spdx.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/spotify.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/stackoverflow.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/terraform.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/tldr.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/vimeo.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/vscode-marketplace.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/w3c.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/wikidata.ts +0 -0
- /package/src/{core/tools/web-scrapers → web/scrapers}/wikipedia.ts +0 -0
- /package/src/{core/tools/web-search → web/search}/types.ts +0 -0
|
@@ -28,23 +28,21 @@ import type {
|
|
|
28
28
|
import { isContextOverflow, modelsAreEqual, supportsXhigh } from "@oh-my-pi/pi-ai";
|
|
29
29
|
import { abortableSleep, logger } from "@oh-my-pi/pi-utils";
|
|
30
30
|
import { YAML } from "bun";
|
|
31
|
-
import type { Rule } from "
|
|
32
|
-
import { getAgentDbPath } from "
|
|
33
|
-
import {
|
|
34
|
-
import
|
|
35
|
-
import { type BashResult, executeBash as executeBashCommand } from "./bash-executor";
|
|
31
|
+
import type { Rule } from "$c/capability/rule";
|
|
32
|
+
import { getAgentDbPath } from "$c/config";
|
|
33
|
+
import type { ModelRegistry } from "$c/config/model-registry";
|
|
34
|
+
import { parseModelString } from "$c/config/model-resolver";
|
|
36
35
|
import {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
} from "
|
|
46
|
-
import type { LoadedCustomCommand } from "
|
|
47
|
-
import { exportSessionToHtml } from "./export-html/index";
|
|
36
|
+
expandPromptTemplate,
|
|
37
|
+
type PromptTemplate,
|
|
38
|
+
parseCommandArgs,
|
|
39
|
+
renderPromptTemplate,
|
|
40
|
+
} from "$c/config/prompt-templates";
|
|
41
|
+
import type { SettingsManager, SkillsSettings } from "$c/config/settings-manager";
|
|
42
|
+
import { type BashResult, executeBash as executeBashCommand } from "$c/exec/bash-executor";
|
|
43
|
+
import { exportSessionToHtml } from "$c/export/html/index";
|
|
44
|
+
import type { TtsrManager } from "$c/export/ttsr";
|
|
45
|
+
import type { LoadedCustomCommand } from "$c/extensibility/custom-commands/index";
|
|
48
46
|
import type {
|
|
49
47
|
ExtensionCommandContext,
|
|
50
48
|
ExtensionRunner,
|
|
@@ -56,10 +54,31 @@ import type {
|
|
|
56
54
|
TreePreparation,
|
|
57
55
|
TurnEndEvent,
|
|
58
56
|
TurnStartEvent,
|
|
59
|
-
} from "
|
|
60
|
-
import type { CompactOptions, ContextUsage } from "
|
|
61
|
-
import {
|
|
62
|
-
import type {
|
|
57
|
+
} from "$c/extensibility/extensions";
|
|
58
|
+
import type { CompactOptions, ContextUsage } from "$c/extensibility/extensions/types";
|
|
59
|
+
import type { HookCommandContext } from "$c/extensibility/hooks/types";
|
|
60
|
+
import type { Skill, SkillWarning } from "$c/extensibility/skills";
|
|
61
|
+
import { expandSlashCommand, type FileSlashCommand } from "$c/extensibility/slash-commands";
|
|
62
|
+
import { executePython as executePythonCommand, type PythonResult } from "$c/ipy/executor";
|
|
63
|
+
import { theme } from "$c/modes/theme/theme";
|
|
64
|
+
import { normalizeDiff, normalizeToLF, ParseError, previewPatch, stripBom } from "$c/patch";
|
|
65
|
+
import ttsrInterruptTemplate from "$c/prompts/system/ttsr-interrupt.md" with { type: "text" };
|
|
66
|
+
import { closeAllConnections } from "$c/ssh/connection-manager";
|
|
67
|
+
import { unmountAll } from "$c/ssh/sshfs-mount";
|
|
68
|
+
import { outputMeta } from "$c/tools/output-meta";
|
|
69
|
+
import { resolveToCwd } from "$c/tools/path-utils";
|
|
70
|
+
import type { TodoItem } from "$c/tools/todo-write";
|
|
71
|
+
import { extractFileMentions, generateFileMentionMessages } from "$c/utils/file-mentions";
|
|
72
|
+
import {
|
|
73
|
+
type CompactionResult,
|
|
74
|
+
calculateContextTokens,
|
|
75
|
+
collectEntriesForBranchSummary,
|
|
76
|
+
compact,
|
|
77
|
+
estimateTokens,
|
|
78
|
+
generateBranchSummary,
|
|
79
|
+
prepareCompaction,
|
|
80
|
+
shouldCompact,
|
|
81
|
+
} from "./compaction/index";
|
|
63
82
|
import {
|
|
64
83
|
type BashExecutionMessage,
|
|
65
84
|
type BranchSummaryMessage,
|
|
@@ -71,20 +90,7 @@ import {
|
|
|
71
90
|
type PythonExecutionMessage,
|
|
72
91
|
pythonExecutionToText,
|
|
73
92
|
} from "./messages";
|
|
74
|
-
import type { ModelRegistry } from "./model-registry";
|
|
75
|
-
import { parseModelString } from "./model-resolver";
|
|
76
|
-
import { expandPromptTemplate, type PromptTemplate, parseCommandArgs, renderPromptTemplate } from "./prompt-templates";
|
|
77
|
-
import { executePython as executePythonCommand, type PythonResult } from "./python-executor";
|
|
78
93
|
import type { BranchSummaryEntry, CompactionEntry, NewSessionOptions, SessionManager } from "./session-manager";
|
|
79
|
-
import type { SettingsManager, SkillsSettings } from "./settings-manager";
|
|
80
|
-
import type { Skill, SkillWarning } from "./skills";
|
|
81
|
-
import { expandSlashCommand, type FileSlashCommand } from "./slash-commands";
|
|
82
|
-
import { closeAllConnections } from "./ssh/connection-manager";
|
|
83
|
-
import { unmountAll } from "./ssh/sshfs-mount";
|
|
84
|
-
import { normalizeDiff, normalizeToLF, ParseError, previewPatch, stripBom } from "./tools/patch";
|
|
85
|
-
import { resolveToCwd } from "./tools/path-utils";
|
|
86
|
-
import type { TodoItem } from "./tools/todo-write";
|
|
87
|
-
import type { TtsrManager } from "./ttsr";
|
|
88
94
|
|
|
89
95
|
/** Session-specific events that extend the core AgentEvent */
|
|
90
96
|
export type AgentSessionEvent =
|
|
@@ -587,7 +593,7 @@ export class AgentSession {
|
|
|
587
593
|
|
|
588
594
|
const args = toolCall.arguments;
|
|
589
595
|
if (!args || typeof args !== "object" || Array.isArray(args)) return;
|
|
590
|
-
if ("
|
|
596
|
+
if ("old_text" in args || "new_text" in args) return;
|
|
591
597
|
|
|
592
598
|
const path = typeof args.path === "string" ? args.path : undefined;
|
|
593
599
|
if (!path) return;
|
|
@@ -632,7 +638,7 @@ export class AgentSession {
|
|
|
632
638
|
|
|
633
639
|
const args = toolCall.arguments;
|
|
634
640
|
if (!args || typeof args !== "object" || Array.isArray(args)) return;
|
|
635
|
-
if ("
|
|
641
|
+
if ("old_text" in args || "new_text" in args) return;
|
|
636
642
|
|
|
637
643
|
const path = typeof args.path === "string" ? args.path : undefined;
|
|
638
644
|
const diff = typeof args.diff === "string" ? args.diff : undefined;
|
|
@@ -2597,6 +2603,7 @@ export class AgentSession {
|
|
|
2597
2603
|
* Used by executeBash and by extensions that handle bash execution themselves.
|
|
2598
2604
|
*/
|
|
2599
2605
|
recordBashResult(command: string, result: BashResult, options?: { excludeFromContext?: boolean }): void {
|
|
2606
|
+
const meta = outputMeta().truncationFromSummary(result, { direction: "tail" }).get();
|
|
2600
2607
|
const bashMessage: BashExecutionMessage = {
|
|
2601
2608
|
role: "bashExecution",
|
|
2602
2609
|
command,
|
|
@@ -2604,7 +2611,7 @@ export class AgentSession {
|
|
|
2604
2611
|
exitCode: result.exitCode,
|
|
2605
2612
|
cancelled: result.cancelled,
|
|
2606
2613
|
truncated: result.truncated,
|
|
2607
|
-
|
|
2614
|
+
meta,
|
|
2608
2615
|
timestamp: Date.now(),
|
|
2609
2616
|
excludeFromContext: options?.excludeFromContext,
|
|
2610
2617
|
};
|
|
@@ -2701,6 +2708,7 @@ export class AgentSession {
|
|
|
2701
2708
|
* Record a Python execution result in session history.
|
|
2702
2709
|
*/
|
|
2703
2710
|
recordPythonResult(code: string, result: PythonResult, options?: { excludeFromContext?: boolean }): void {
|
|
2711
|
+
const meta = outputMeta().truncationFromSummary(result, { direction: "tail" }).get();
|
|
2704
2712
|
const pythonMessage: PythonExecutionMessage = {
|
|
2705
2713
|
role: "pythonExecution",
|
|
2706
2714
|
code,
|
|
@@ -2708,7 +2716,7 @@ export class AgentSession {
|
|
|
2708
2716
|
exitCode: result.exitCode,
|
|
2709
2717
|
cancelled: result.cancelled,
|
|
2710
2718
|
truncated: result.truncated,
|
|
2711
|
-
|
|
2719
|
+
meta,
|
|
2712
2720
|
timestamp: Date.now(),
|
|
2713
2721
|
excludeFromContext: options?.excludeFromContext,
|
|
2714
2722
|
};
|
|
@@ -2,9 +2,9 @@ import { Database } from "bun:sqlite";
|
|
|
2
2
|
import { chmodSync, existsSync, mkdirSync } from "node:fs";
|
|
3
3
|
import { dirname } from "node:path";
|
|
4
4
|
import { logger } from "@oh-my-pi/pi-utils";
|
|
5
|
-
import { getAgentDbPath } from "
|
|
5
|
+
import { getAgentDbPath } from "$c/config";
|
|
6
|
+
import type { Settings } from "$c/config/settings-manager";
|
|
6
7
|
import type { AuthCredential } from "./auth-storage";
|
|
7
|
-
import type { Settings } from "./settings-manager";
|
|
8
8
|
|
|
9
9
|
/** Prepared SQLite statement type from bun:sqlite */
|
|
10
10
|
type Statement = ReturnType<Database["prepare"]>;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session-scoped artifact storage for truncated tool outputs.
|
|
3
|
+
*
|
|
4
|
+
* Artifacts are stored in a directory alongside the session file,
|
|
5
|
+
* accessible via artifact:// URLs or the $ARTIFACTS environment variable.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { mkdir, readdir } from "node:fs/promises";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Manages artifact storage for a session.
|
|
13
|
+
*
|
|
14
|
+
* Artifacts are stored with sequential IDs in the session's artifact directory.
|
|
15
|
+
* The directory is created lazily on first write.
|
|
16
|
+
*/
|
|
17
|
+
export class ArtifactManager {
|
|
18
|
+
#nextId = 0;
|
|
19
|
+
readonly #dir: string;
|
|
20
|
+
#dirCreated = false;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @param sessionFile Path to the session .jsonl file
|
|
24
|
+
*/
|
|
25
|
+
constructor(sessionFile: string) {
|
|
26
|
+
// Artifact directory is session file path without .jsonl extension
|
|
27
|
+
this.#dir = sessionFile.slice(0, -6);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Artifact directory path.
|
|
32
|
+
* Directory may not exist until first artifact is saved.
|
|
33
|
+
*/
|
|
34
|
+
get dir(): string {
|
|
35
|
+
return this.#dir;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async #ensureDir(): Promise<void> {
|
|
39
|
+
if (!this.#dirCreated) {
|
|
40
|
+
await mkdir(this.#dir, { recursive: true });
|
|
41
|
+
this.#dirCreated = true;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Atomically allocate next artifact ID.
|
|
47
|
+
* IDs are sequential within the session.
|
|
48
|
+
*/
|
|
49
|
+
allocateId(): number {
|
|
50
|
+
return this.#nextId++;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Allocate a new artifact path and ID without writing content.
|
|
55
|
+
*
|
|
56
|
+
* @param toolType Tool name for file extension (e.g., "bash", "fetch")
|
|
57
|
+
*/
|
|
58
|
+
async allocatePath(toolType: string): Promise<{ id: string; path: string }> {
|
|
59
|
+
await this.#ensureDir();
|
|
60
|
+
const id = String(this.allocateId());
|
|
61
|
+
const filename = `${id}.${toolType}.txt`;
|
|
62
|
+
return { id, path: join(this.#dir, filename) };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Save content as an artifact and return the artifact ID.
|
|
67
|
+
*
|
|
68
|
+
* @param content Full content to save
|
|
69
|
+
* @param toolType Tool name for file extension (e.g., "bash", "fetch")
|
|
70
|
+
* @returns Artifact ID (numeric string)
|
|
71
|
+
*/
|
|
72
|
+
async save(content: string, toolType: string): Promise<string> {
|
|
73
|
+
const { id, path } = await this.allocatePath(toolType);
|
|
74
|
+
await Bun.write(path, content);
|
|
75
|
+
return id;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Check if an artifact exists.
|
|
80
|
+
* @param id Artifact ID (numeric string)
|
|
81
|
+
*/
|
|
82
|
+
async exists(id: string): Promise<boolean> {
|
|
83
|
+
const files = await this.listFiles();
|
|
84
|
+
return files.some((f) => f.startsWith(`${id}.`));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* List all artifact files in the directory.
|
|
89
|
+
* Returns empty array if directory doesn't exist.
|
|
90
|
+
*/
|
|
91
|
+
async listFiles(): Promise<string[]> {
|
|
92
|
+
try {
|
|
93
|
+
return await readdir(this.#dir);
|
|
94
|
+
} catch {
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Get the full path to an artifact file.
|
|
101
|
+
* Returns null if artifact doesn't exist.
|
|
102
|
+
*
|
|
103
|
+
* @param id Artifact ID (numeric string)
|
|
104
|
+
*/
|
|
105
|
+
async getPath(id: string): Promise<string | null> {
|
|
106
|
+
const files = await this.listFiles();
|
|
107
|
+
const match = files.find((f) => f.startsWith(`${id}.`));
|
|
108
|
+
return match ? join(this.#dir, match) : null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
zaiUsageProvider,
|
|
34
34
|
} from "@oh-my-pi/pi-ai";
|
|
35
35
|
import { logger } from "@oh-my-pi/pi-utils";
|
|
36
|
-
import { getAgentDbPath, getAuthPath } from "
|
|
36
|
+
import { getAgentDbPath, getAuthPath } from "$c/config";
|
|
37
37
|
import { AgentStorage } from "./agent-storage";
|
|
38
38
|
import { migrateJsonStorage } from "./storage-migration";
|
|
39
39
|
|
|
@@ -8,16 +8,16 @@
|
|
|
8
8
|
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
9
9
|
import type { Model } from "@oh-my-pi/pi-ai";
|
|
10
10
|
import { completeSimple } from "@oh-my-pi/pi-ai";
|
|
11
|
-
import
|
|
12
|
-
import
|
|
11
|
+
import { renderPromptTemplate } from "$c/config/prompt-templates";
|
|
12
|
+
import branchSummaryPrompt from "$c/prompts/compaction/branch-summary.md" with { type: "text" };
|
|
13
|
+
import branchSummaryPreamble from "$c/prompts/compaction/branch-summary-preamble.md" with { type: "text" };
|
|
13
14
|
import {
|
|
14
15
|
convertToLlm,
|
|
15
16
|
createBranchSummaryMessage,
|
|
16
17
|
createCompactionSummaryMessage,
|
|
17
18
|
createCustomMessage,
|
|
18
|
-
} from "
|
|
19
|
-
import {
|
|
20
|
-
import type { ReadonlySessionManager, SessionEntry } from "../session-manager";
|
|
19
|
+
} from "$c/session/messages";
|
|
20
|
+
import type { ReadonlySessionManager, SessionEntry } from "$c/session/session-manager";
|
|
21
21
|
import { estimateTokens } from "./compaction";
|
|
22
22
|
import {
|
|
23
23
|
computeFileLists,
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
9
9
|
import type { AssistantMessage, Model, Usage } from "@oh-my-pi/pi-ai";
|
|
10
10
|
import { completeSimple } from "@oh-my-pi/pi-ai";
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import {
|
|
16
|
-
import type { CompactionEntry, SessionEntry } from "
|
|
11
|
+
import { renderPromptTemplate } from "$c/config/prompt-templates";
|
|
12
|
+
import compactionSummaryPrompt from "$c/prompts/compaction/compaction-summary.md" with { type: "text" };
|
|
13
|
+
import compactionTurnPrefixPrompt from "$c/prompts/compaction/compaction-turn-prefix.md" with { type: "text" };
|
|
14
|
+
import compactionUpdateSummaryPrompt from "$c/prompts/compaction/compaction-update-summary.md" with { type: "text" };
|
|
15
|
+
import { convertToLlm, createBranchSummaryMessage, createCustomMessage } from "$c/session/messages";
|
|
16
|
+
import type { CompactionEntry, SessionEntry } from "$c/session/session-manager";
|
|
17
17
|
import {
|
|
18
18
|
computeFileLists,
|
|
19
19
|
createFileOps,
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
6
6
|
import type { Message } from "@oh-my-pi/pi-ai";
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
7
|
+
import { renderPromptTemplate } from "$c/config/prompt-templates";
|
|
8
|
+
import fileOperationsTemplate from "$c/prompts/system/file-operations.md" with { type: "text" };
|
|
9
|
+
import summarizationSystemPrompt from "$c/prompts/system/summarization-system.md" with { type: "text" };
|
|
10
10
|
|
|
11
11
|
// ============================================================================
|
|
12
12
|
// File Operation Tracking
|
|
@@ -2,7 +2,7 @@ import { Database } from "bun:sqlite";
|
|
|
2
2
|
import { mkdirSync } from "node:fs";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
import { logger } from "@oh-my-pi/pi-utils";
|
|
5
|
-
import { getAgentDir } from "
|
|
5
|
+
import { getAgentDir } from "$c/config";
|
|
6
6
|
|
|
7
7
|
export interface HistoryEntry {
|
|
8
8
|
id: number;
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
9
9
|
import type { ImageContent, Message, TextContent } from "@oh-my-pi/pi-ai";
|
|
10
|
+
import type { OutputMeta } from "$c/tools/output-meta";
|
|
11
|
+
import { formatOutputNotice } from "$c/tools/output-meta";
|
|
10
12
|
|
|
11
13
|
export const COMPACTION_SUMMARY_PREFIX = `The conversation history before this point was compacted into the following summary:
|
|
12
14
|
|
|
@@ -33,7 +35,7 @@ export interface BashExecutionMessage {
|
|
|
33
35
|
exitCode: number | undefined;
|
|
34
36
|
cancelled: boolean;
|
|
35
37
|
truncated: boolean;
|
|
36
|
-
|
|
38
|
+
meta?: OutputMeta;
|
|
37
39
|
timestamp: number;
|
|
38
40
|
/** If true, this message is excluded from LLM context (!! prefix) */
|
|
39
41
|
excludeFromContext?: boolean;
|
|
@@ -50,7 +52,7 @@ export interface PythonExecutionMessage {
|
|
|
50
52
|
exitCode: number | undefined;
|
|
51
53
|
cancelled: boolean;
|
|
52
54
|
truncated: boolean;
|
|
53
|
-
|
|
55
|
+
meta?: OutputMeta;
|
|
54
56
|
timestamp: number;
|
|
55
57
|
/** If true, this message is excluded from LLM context ($$ prefix) */
|
|
56
58
|
excludeFromContext?: boolean;
|
|
@@ -136,9 +138,7 @@ export function bashExecutionToText(msg: BashExecutionMessage): string {
|
|
|
136
138
|
} else if (msg.exitCode !== null && msg.exitCode !== undefined && msg.exitCode !== 0) {
|
|
137
139
|
text += `\n\nCommand exited with code ${msg.exitCode}`;
|
|
138
140
|
}
|
|
139
|
-
|
|
140
|
-
text += `\n\n[Output truncated. Full output: ${msg.fullOutputPath}]`;
|
|
141
|
-
}
|
|
141
|
+
text += formatOutputNotice(msg.meta);
|
|
142
142
|
return text;
|
|
143
143
|
}
|
|
144
144
|
|
|
@@ -157,9 +157,7 @@ export function pythonExecutionToText(msg: PythonExecutionMessage): string {
|
|
|
157
157
|
} else if (msg.exitCode !== null && msg.exitCode !== undefined && msg.exitCode !== 0) {
|
|
158
158
|
text += `\n\nExecution failed with code ${msg.exitCode}`;
|
|
159
159
|
}
|
|
160
|
-
|
|
161
|
-
text += `\n\n[Output truncated. Full output: ${msg.fullOutputPath}]`;
|
|
162
|
-
}
|
|
160
|
+
text += formatOutputNotice(msg.meta);
|
|
163
161
|
return text;
|
|
164
162
|
}
|
|
165
163
|
|
|
@@ -3,8 +3,8 @@ import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
|
3
3
|
import type { ImageContent, Message, TextContent, Usage } from "@oh-my-pi/pi-ai";
|
|
4
4
|
import { logger } from "@oh-my-pi/pi-utils";
|
|
5
5
|
import { nanoid } from "nanoid";
|
|
6
|
-
import { getAgentDir as getDefaultAgentDir } from "
|
|
7
|
-
import { resizeImage } from "
|
|
6
|
+
import { getAgentDir as getDefaultAgentDir } from "$c/config";
|
|
7
|
+
import { resizeImage } from "$c/utils/image-resize";
|
|
8
8
|
import {
|
|
9
9
|
type BashExecutionMessage,
|
|
10
10
|
type CustomMessage,
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { logger } from "@oh-my-pi/pi-utils";
|
|
8
|
-
import { getAgentDbPath } from "
|
|
8
|
+
import { getAgentDbPath } from "$c/config";
|
|
9
|
+
import type { Settings } from "$c/config/settings-manager";
|
|
9
10
|
import { AgentStorage } from "./agent-storage";
|
|
10
11
|
import type { AuthCredential, AuthCredentialEntry, AuthStorageData } from "./auth-storage";
|
|
11
|
-
import type { Settings } from "./settings-manager";
|
|
12
12
|
|
|
13
13
|
/** Paths configuration for the storage migration process. */
|
|
14
14
|
type MigrationPaths = {
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { sanitizeText } from "@oh-my-pi/pi-utils";
|
|
2
|
+
import { DEFAULT_MAX_BYTES } from "$c/tools/truncate";
|
|
3
|
+
|
|
4
|
+
export interface OutputSummary {
|
|
5
|
+
output: string;
|
|
6
|
+
truncated: boolean;
|
|
7
|
+
totalLines: number;
|
|
8
|
+
totalBytes: number;
|
|
9
|
+
outputLines: number;
|
|
10
|
+
outputBytes: number;
|
|
11
|
+
/** Artifact ID for internal URL access (artifact://<id>) when truncated */
|
|
12
|
+
artifactId?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface OutputSinkOptions {
|
|
16
|
+
artifactPath?: string;
|
|
17
|
+
artifactId?: string;
|
|
18
|
+
spillThreshold?: number;
|
|
19
|
+
onChunk?: (chunk: string) => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function countNewlines(text: string): number {
|
|
23
|
+
let count = 0;
|
|
24
|
+
for (let i = 0; i < text.length; i++) {
|
|
25
|
+
if (text.charCodeAt(i) === 10) count += 1;
|
|
26
|
+
}
|
|
27
|
+
return count;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function countLines(text: string): number {
|
|
31
|
+
if (text.length === 0) return 0;
|
|
32
|
+
return countNewlines(text) + 1;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function truncateStringToBytesFromEnd(text: string, maxBytes: number): { text: string; bytes: number } {
|
|
36
|
+
const buf = Buffer.from(text, "utf-8");
|
|
37
|
+
if (buf.length <= maxBytes) {
|
|
38
|
+
return { text, bytes: buf.length };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let start = buf.length - maxBytes;
|
|
42
|
+
while (start < buf.length && (buf[start] & 0xc0) === 0x80) {
|
|
43
|
+
start++;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const sliced = buf.subarray(start).toString("utf-8");
|
|
47
|
+
return { text: sliced, bytes: Buffer.byteLength(sliced, "utf-8") };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Line-buffered output sink with file spill support.
|
|
52
|
+
*
|
|
53
|
+
* Uses a single string buffer with line position tracking.
|
|
54
|
+
* When memory limit exceeded, spills ~half to file in one batch operation.
|
|
55
|
+
*/
|
|
56
|
+
export class OutputSink {
|
|
57
|
+
#buffer = "";
|
|
58
|
+
#bufferBytes = 0;
|
|
59
|
+
#totalLines = 0;
|
|
60
|
+
#totalBytes = 0;
|
|
61
|
+
#sawData = false;
|
|
62
|
+
#truncated = false;
|
|
63
|
+
#file?: {
|
|
64
|
+
path: string;
|
|
65
|
+
artifactId?: string;
|
|
66
|
+
sink: Bun.FileSink;
|
|
67
|
+
};
|
|
68
|
+
readonly #artifactPath?: string;
|
|
69
|
+
readonly #artifactId?: string;
|
|
70
|
+
readonly #spillThreshold: number;
|
|
71
|
+
readonly #onChunk?: (chunk: string) => void;
|
|
72
|
+
|
|
73
|
+
constructor(options?: OutputSinkOptions) {
|
|
74
|
+
const { artifactPath, artifactId, spillThreshold = DEFAULT_MAX_BYTES, onChunk } = options ?? {};
|
|
75
|
+
|
|
76
|
+
this.#artifactPath = artifactPath;
|
|
77
|
+
this.#artifactId = artifactId;
|
|
78
|
+
this.#spillThreshold = spillThreshold;
|
|
79
|
+
this.#onChunk = onChunk;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async #pushSanitized(data: string): Promise<void> {
|
|
83
|
+
this.#onChunk?.(data);
|
|
84
|
+
|
|
85
|
+
const dataBytes = Buffer.byteLength(data, "utf-8");
|
|
86
|
+
this.#totalBytes += dataBytes;
|
|
87
|
+
if (data.length > 0) {
|
|
88
|
+
this.#sawData = true;
|
|
89
|
+
this.#totalLines += countNewlines(data);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const bufferOverflow = this.#bufferBytes + dataBytes > this.#spillThreshold;
|
|
93
|
+
const overflow = this.#file || bufferOverflow;
|
|
94
|
+
const sink = overflow ? await this.#fileSink() : null;
|
|
95
|
+
|
|
96
|
+
this.#buffer += data;
|
|
97
|
+
this.#bufferBytes += dataBytes;
|
|
98
|
+
await sink?.write(data);
|
|
99
|
+
|
|
100
|
+
if (bufferOverflow) {
|
|
101
|
+
this.#truncated = true;
|
|
102
|
+
const trimmed = truncateStringToBytesFromEnd(this.#buffer, this.#spillThreshold);
|
|
103
|
+
this.#buffer = trimmed.text;
|
|
104
|
+
this.#bufferBytes = trimmed.bytes;
|
|
105
|
+
}
|
|
106
|
+
if (this.#file) {
|
|
107
|
+
this.#truncated = true;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async #fileSink(): Promise<Bun.FileSink | null> {
|
|
112
|
+
if (!this.#artifactPath) return null;
|
|
113
|
+
if (!this.#file) {
|
|
114
|
+
try {
|
|
115
|
+
this.#file = {
|
|
116
|
+
path: this.#artifactPath,
|
|
117
|
+
artifactId: this.#artifactId,
|
|
118
|
+
sink: Bun.file(this.#artifactPath).writer(),
|
|
119
|
+
};
|
|
120
|
+
await this.#file.sink.write(this.#buffer);
|
|
121
|
+
} catch {
|
|
122
|
+
try {
|
|
123
|
+
await this.#file?.sink?.end();
|
|
124
|
+
} catch {}
|
|
125
|
+
this.#file = undefined;
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return this.#file.sink;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async push(chunk: string): Promise<void> {
|
|
133
|
+
chunk = sanitizeText(chunk);
|
|
134
|
+
await this.#pushSanitized(chunk);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
createInput(): WritableStream<Uint8Array | string> {
|
|
138
|
+
const dec = new TextDecoder("utf-8", { ignoreBOM: true });
|
|
139
|
+
const finalize = async () => {
|
|
140
|
+
await this.push(dec.decode());
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
return new WritableStream<Uint8Array | string>({
|
|
144
|
+
write: async (chunk) => {
|
|
145
|
+
if (typeof chunk === "string") {
|
|
146
|
+
await this.push(chunk);
|
|
147
|
+
} else {
|
|
148
|
+
await this.push(dec.decode(chunk, { stream: true }));
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
close: finalize,
|
|
152
|
+
abort: finalize,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async dump(notice?: string): Promise<OutputSummary> {
|
|
157
|
+
const noticeLine = notice ? `[${notice}]\n` : "";
|
|
158
|
+
const outputLines = countLines(this.#buffer);
|
|
159
|
+
const outputBytes = this.#bufferBytes;
|
|
160
|
+
const totalLines = this.#sawData ? this.#totalLines + 1 : 0;
|
|
161
|
+
const totalBytes = this.#totalBytes;
|
|
162
|
+
|
|
163
|
+
if (this.#file) {
|
|
164
|
+
await this.#file.sink.end();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return {
|
|
168
|
+
output: `${noticeLine}${this.#buffer}`,
|
|
169
|
+
truncated: this.#truncated,
|
|
170
|
+
totalLines,
|
|
171
|
+
totalBytes,
|
|
172
|
+
outputLines,
|
|
173
|
+
outputBytes,
|
|
174
|
+
artifactId: this.#file?.artifactId,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
}
|
|
@@ -3,7 +3,7 @@ import { homedir } from "node:os";
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { logger } from "@oh-my-pi/pi-utils";
|
|
5
5
|
import { $ } from "bun";
|
|
6
|
-
import { CONFIG_DIR_NAME } from "
|
|
6
|
+
import { CONFIG_DIR_NAME } from "$c/config";
|
|
7
7
|
|
|
8
8
|
export interface SSHConnectionTarget {
|
|
9
9
|
name: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { cspawn, logger, ptree } from "@oh-my-pi/pi-utils";
|
|
2
|
-
import { OutputSink } from "
|
|
2
|
+
import { OutputSink } from "$c/session/streaming-output";
|
|
3
3
|
import { buildRemoteCommand, ensureConnection, ensureHostInfo, type SSHConnectionTarget } from "./connection-manager";
|
|
4
4
|
import { hasSshfs, mountRemote } from "./sshfs-mount";
|
|
5
5
|
|
|
@@ -14,6 +14,9 @@ export interface SSHExecutorOptions {
|
|
|
14
14
|
remotePath?: string;
|
|
15
15
|
/** Wrap commands in a POSIX shell for compat mode */
|
|
16
16
|
compatEnabled?: boolean;
|
|
17
|
+
/** Artifact path/id for full output storage */
|
|
18
|
+
artifactPath?: string;
|
|
19
|
+
artifactId?: string;
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
export interface SSHResult {
|
|
@@ -25,8 +28,16 @@ export interface SSHResult {
|
|
|
25
28
|
cancelled: boolean;
|
|
26
29
|
/** Whether the output was truncated */
|
|
27
30
|
truncated: boolean;
|
|
28
|
-
/**
|
|
29
|
-
|
|
31
|
+
/** Total number of lines in the output stream */
|
|
32
|
+
totalLines: number;
|
|
33
|
+
/** Total number of bytes in the output stream */
|
|
34
|
+
totalBytes: number;
|
|
35
|
+
/** Number of lines included in the output text */
|
|
36
|
+
outputLines: number;
|
|
37
|
+
/** Number of bytes included in the output text */
|
|
38
|
+
outputBytes: number;
|
|
39
|
+
/** Artifact ID if full output was saved to artifact storage */
|
|
40
|
+
artifactId?: string;
|
|
30
41
|
}
|
|
31
42
|
|
|
32
43
|
function quoteForCompatShell(command: string): string {
|
|
@@ -70,7 +81,11 @@ export async function executeSSH(
|
|
|
70
81
|
timeout: options?.timeout,
|
|
71
82
|
});
|
|
72
83
|
|
|
73
|
-
const sink = new OutputSink({
|
|
84
|
+
const sink = new OutputSink({
|
|
85
|
+
onChunk: options?.onChunk,
|
|
86
|
+
artifactPath: options?.artifactPath,
|
|
87
|
+
artifactId: options?.artifactId,
|
|
88
|
+
});
|
|
74
89
|
|
|
75
90
|
await Promise.allSettled([child.stdout.pipeTo(sink.createInput()), child.stderr.pipeTo(sink.createInput())]).catch(
|
|
76
91
|
() => {},
|
|
@@ -3,7 +3,7 @@ import { homedir } from "node:os";
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { logger } from "@oh-my-pi/pi-utils";
|
|
5
5
|
import { $ } from "bun";
|
|
6
|
-
import { CONFIG_DIR_NAME } from "
|
|
6
|
+
import { CONFIG_DIR_NAME } from "$c/config";
|
|
7
7
|
import { getControlDir, getControlPathTemplate, type SSHConnectionTarget } from "./connection-manager";
|
|
8
8
|
|
|
9
9
|
const REMOTE_DIR = join(homedir(), CONFIG_DIR_NAME, "remote");
|