@sheason/pi-coding-agent 0.74.1-sheason.0 → 0.78.0-sheason.0.6.0-alpha.2
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 +256 -4
- package/README.md +16 -8
- package/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/cli.js.map +1 -1
- package/dist/cli/args.d.ts +7 -2
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +49 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/config-selector.d.ts +2 -2
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js +1 -1
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +2 -3
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/cli/initial-message.d.ts +1 -1
- package/dist/cli/initial-message.d.ts.map +1 -1
- package/dist/cli/initial-message.js.map +1 -1
- package/dist/cli/list-models.d.ts +1 -1
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js.map +1 -1
- package/dist/cli/session-picker.d.ts +1 -1
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +4 -6
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +61 -32
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-proxy.d.ts +268 -0
- package/dist/core/agent-session-proxy.d.ts.map +1 -0
- package/dist/core/agent-session-proxy.js +2 -0
- package/dist/core/agent-session-proxy.js.map +1 -0
- package/dist/core/agent-session-runtime.d.ts +10 -10
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +14 -14
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +8 -7
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +4 -2
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +60 -27
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +303 -177
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-guidance.d.ts.map +1 -1
- package/dist/core/auth-guidance.js.map +1 -1
- package/dist/core/auth-storage.d.ts +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +3 -2
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/bash-executor.d.ts +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +3 -3
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +5 -5
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +41 -37
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/index.d.ts +3 -3
- package/dist/core/compaction/index.d.ts.map +1 -1
- package/dist/core/compaction/index.js.map +1 -1
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js.map +1 -1
- package/dist/core/export-html/index.d.ts +1 -1
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js +8 -6
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/export-html/template.js +23 -6
- package/dist/core/export-html/tool-renderer.d.ts +2 -2
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
- package/dist/core/export-html/tool-renderer.js.map +1 -1
- package/dist/core/extensions/index.d.ts +8 -8
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +2 -2
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +17 -34
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +12 -7
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +36 -2
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +26 -24
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/wrapper.d.ts +2 -2
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +3 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +4 -0
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts +21 -0
- package/dist/core/http-dispatcher.d.ts.map +1 -0
- package/dist/core/http-dispatcher.js +48 -0
- package/dist/core/http-dispatcher.js.map +1 -0
- package/dist/core/index.d.ts +8 -8
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/local-agent-session-proxy.d.ts +82 -0
- package/dist/core/local-agent-session-proxy.d.ts.map +1 -0
- package/dist/core/local-agent-session-proxy.js +531 -0
- package/dist/core/local-agent-session-proxy.js.map +1 -0
- package/dist/core/messages.d.ts +0 -9
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +0 -10
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-registry.d.ts +4 -4
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +72 -16
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +1 -1
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/output-guard.d.ts +1 -0
- package/dist/core/output-guard.d.ts.map +1 -1
- package/dist/core/output-guard.js +52 -22
- package/dist/core/output-guard.js.map +1 -1
- package/dist/core/package-manager.d.ts +7 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +129 -64
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/prompt-templates.d.ts +1 -1
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js +12 -24
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/provider-display-names.d.ts.map +1 -1
- package/dist/core/provider-display-names.js +0 -1
- package/dist/core/provider-display-names.js.map +1 -1
- package/dist/core/resolve-config-value.d.ts +9 -1
- package/dist/core/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.js +134 -11
- package/dist/core/resolve-config-value.js.map +1 -1
- package/dist/core/resource-loader.d.ts +13 -10
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +41 -33
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +15 -13
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +24 -17
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +20 -10
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +201 -106
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +5 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +31 -13
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts +2 -2
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +10 -27
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/source-info.d.ts +1 -1
- package/dist/core/source-info.d.ts.map +1 -1
- package/dist/core/source-info.js.map +1 -1
- package/dist/core/system-prompt.d.ts +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +16 -9
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/telemetry.d.ts +1 -1
- package/dist/core/telemetry.d.ts.map +1 -1
- package/dist/core/telemetry.js.map +1 -1
- package/dist/core/tools/bash.d.ts +2 -2
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +55 -54
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +3 -1
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +8 -1
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts +5 -3
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +51 -91
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js +27 -12
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/find.d.ts +2 -2
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +2 -3
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +2 -2
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +3 -3
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +17 -17
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts +2 -2
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +10 -12
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts +3 -1
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +9 -3
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/path-utils.d.ts +2 -0
- package/dist/core/tools/path-utils.d.ts.map +1 -1
- package/dist/core/tools/path-utils.js +39 -21
- package/dist/core/tools/path-utils.js.map +1 -1
- package/dist/core/tools/read.d.ts +2 -2
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +15 -15
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +5 -2
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +17 -1
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/core/tools/truncate.d.ts.map +1 -1
- package/dist/core/tools/truncate.js +12 -2
- package/dist/core/tools/truncate.js.map +1 -1
- package/dist/core/tools/write.d.ts +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +25 -41
- package/dist/core/tools/write.js.map +1 -1
- package/dist/d-pi-worker.d.ts +12 -0
- package/dist/d-pi-worker.d.ts.map +1 -0
- package/dist/d-pi-worker.js +9 -0
- package/dist/d-pi-worker.js.map +1 -0
- package/dist/index.d.ts +30 -28
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +100 -39
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +118 -1
- package/dist/migrations.js.map +1 -1
- package/dist/modes/connect/auth-headers.d.ts +2 -0
- package/dist/modes/connect/auth-headers.d.ts.map +1 -0
- package/dist/modes/connect/auth-headers.js +2 -0
- package/dist/modes/connect/auth-headers.js.map +1 -0
- package/dist/modes/connect/client-extension-sync.d.ts +13 -0
- package/dist/modes/connect/client-extension-sync.d.ts.map +1 -0
- package/dist/modes/connect/client-extension-sync.js +51 -0
- package/dist/modes/connect/client-extension-sync.js.map +1 -0
- package/dist/modes/connect/connect-mode.d.ts +6 -0
- package/dist/modes/connect/connect-mode.d.ts.map +1 -0
- package/dist/modes/connect/connect-mode.js +29 -0
- package/dist/modes/connect/connect-mode.js.map +1 -0
- package/dist/modes/connect/remote-agent-session-proxy.d.ts +81 -0
- package/dist/modes/connect/remote-agent-session-proxy.d.ts.map +1 -0
- package/dist/modes/connect/remote-agent-session-proxy.js +326 -0
- package/dist/modes/connect/remote-agent-session-proxy.js.map +1 -0
- package/dist/modes/connect/sse-client.d.ts +18 -0
- package/dist/modes/connect/sse-client.d.ts.map +1 -0
- package/dist/modes/connect/sse-client.js +90 -0
- package/dist/modes/connect/sse-client.js.map +1 -0
- package/dist/modes/index.d.ts +5 -5
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/components/armin.d.ts.map +1 -1
- package/dist/modes/interactive/components/armin.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts +4 -4
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +8 -5
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.d.ts +2 -2
- package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.js +2 -2
- package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts +2 -2
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +0 -1
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
- package/dist/modes/interactive/components/daxnuts.js.map +1 -1
- package/dist/modes/interactive/components/diff.d.ts.map +1 -1
- package/dist/modes/interactive/components/diff.js.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +14 -6
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +15 -4
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +126 -8
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +31 -31
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +7 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +28 -5
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +2 -2
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts +3 -3
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +15 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/theme-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +53 -7
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +1247 -205
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/dark.json +5 -4
- package/dist/modes/interactive/theme/light.json +5 -4
- package/dist/modes/interactive/theme/theme.d.ts +22 -3
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +130 -69
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/print-mode.d.ts +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +8 -5
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +65 -8
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts +2 -2
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +18 -4
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +5 -4
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/modes/serve/api-handlers.d.ts +4 -0
- package/dist/modes/serve/api-handlers.d.ts.map +1 -0
- package/dist/modes/serve/api-handlers.js +324 -0
- package/dist/modes/serve/api-handlers.js.map +1 -0
- package/dist/modes/serve/http-server.d.ts +14 -0
- package/dist/modes/serve/http-server.d.ts.map +1 -0
- package/dist/modes/serve/http-server.js +94 -0
- package/dist/modes/serve/http-server.js.map +1 -0
- package/dist/modes/serve/serve-mode.d.ts +10 -0
- package/dist/modes/serve/serve-mode.d.ts.map +1 -0
- package/dist/modes/serve/serve-mode.js +217 -0
- package/dist/modes/serve/serve-mode.js.map +1 -0
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +62 -7
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/ansi.d.ts.map +1 -1
- package/dist/utils/ansi.js +47 -72
- package/dist/utils/ansi.js.map +1 -1
- package/dist/utils/changelog.d.ts +1 -1
- package/dist/utils/changelog.d.ts.map +1 -1
- package/dist/utils/changelog.js.map +1 -1
- package/dist/utils/child-process.d.ts +5 -2
- package/dist/utils/child-process.d.ts.map +1 -1
- package/dist/utils/child-process.js +9 -7
- package/dist/utils/child-process.js.map +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/clipboard-native.d.ts +3 -1
- package/dist/utils/clipboard-native.d.ts.map +1 -1
- package/dist/utils/clipboard-native.js +14 -8
- package/dist/utils/clipboard-native.js.map +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/deprecation.d.ts +4 -0
- package/dist/utils/deprecation.d.ts.map +1 -0
- package/dist/utils/deprecation.js +13 -0
- package/dist/utils/deprecation.js.map +1 -0
- package/dist/utils/exif-orientation.d.ts +1 -1
- package/dist/utils/exif-orientation.d.ts.map +1 -1
- package/dist/utils/exif-orientation.js.map +1 -1
- package/dist/utils/html.d.ts +7 -0
- package/dist/utils/html.d.ts.map +1 -0
- package/dist/utils/html.js +40 -0
- package/dist/utils/html.js.map +1 -0
- package/dist/utils/image-convert.d.ts.map +1 -1
- package/dist/utils/image-convert.js.map +1 -1
- package/dist/utils/image-resize-core.d.ts +30 -0
- package/dist/utils/image-resize-core.d.ts.map +1 -0
- package/dist/utils/image-resize-core.js +124 -0
- package/dist/utils/image-resize-core.js.map +1 -0
- package/dist/utils/image-resize-worker.d.ts +2 -0
- package/dist/utils/image-resize-worker.d.ts.map +1 -0
- package/dist/utils/image-resize-worker.js +31 -0
- package/dist/utils/image-resize-worker.js.map +1 -0
- package/dist/utils/image-resize.d.ts +7 -27
- package/dist/utils/image-resize.d.ts.map +1 -1
- package/dist/utils/image-resize.js +75 -131
- package/dist/utils/image-resize.js.map +1 -1
- package/dist/utils/json.d.ts +3 -0
- package/dist/utils/json.d.ts.map +1 -0
- package/dist/utils/json.js +7 -0
- package/dist/utils/json.js.map +1 -0
- package/dist/utils/paths.d.ts +16 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +49 -7
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +6 -1
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts +12 -0
- package/dist/utils/syntax-highlight.d.ts.map +1 -0
- package/dist/utils/syntax-highlight.js +118 -0
- package/dist/utils/syntax-highlight.js.map +1 -0
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +4 -1
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts +2 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +9 -4
- package/dist/utils/version-check.js.map +1 -1
- package/dist/utils/windows-self-update.d.ts +3 -0
- package/dist/utils/windows-self-update.d.ts.map +1 -0
- package/dist/utils/windows-self-update.js +77 -0
- package/dist/utils/windows-self-update.js.map +1 -0
- package/docs/custom-provider.md +111 -21
- package/docs/development.md +1 -1
- package/docs/extensions.md +13 -7
- package/docs/index.md +13 -3
- package/docs/models.md +32 -13
- package/docs/packages.md +9 -6
- package/docs/providers.md +13 -5
- package/docs/quickstart.md +24 -1
- package/docs/rpc.md +2 -1
- package/docs/sdk.md +8 -0
- package/docs/session-format.md +1 -1
- package/docs/sessions.md +8 -0
- package/docs/settings.md +8 -6
- package/docs/skills.md +3 -4
- package/docs/terminal-setup.md +8 -0
- package/docs/termux.md +3 -3
- package/docs/tui.md +2 -2
- package/docs/usage.md +13 -2
- package/examples/extensions/README.md +1 -0
- package/examples/extensions/custom-provider-anthropic/index.ts +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +2 -2
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +54 -3
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/test.ts +1 -1
- package/examples/extensions/doom-overlay/doom-component.ts +2 -2
- package/examples/extensions/doom-overlay/index.ts +3 -3
- package/examples/extensions/git-merge-and-resolve.ts +115 -0
- package/examples/extensions/input-transform-streaming.ts +39 -0
- package/examples/extensions/overlay-qa-tests.ts +97 -66
- package/examples/extensions/overlay-test.ts +7 -4
- package/examples/extensions/plan-mode/index.ts +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +2 -2
- package/examples/extensions/subagent/README.md +3 -0
- package/examples/extensions/subagent/index.ts +42 -20
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +3 -3
- package/npm-shrinkwrap.json +1790 -0
- package/package.json +39 -32
- package/dist/utils/uuid.d.ts +0 -2
- package/dist/utils/uuid.d.ts.map +0 -1
- package/dist/utils/uuid.js +0 -40
- package/dist/utils/uuid.js.map +0 -1
|
@@ -1,14 +1,20 @@
|
|
|
1
|
+
import { uuidv7 } from "@sheason/pi-agent-core";
|
|
1
2
|
import { randomUUID } from "crypto";
|
|
2
|
-
import { appendFileSync, closeSync, existsSync, mkdirSync, openSync, readdirSync, readFileSync, readSync, statSync, writeFileSync, } from "fs";
|
|
3
|
+
import { appendFileSync, closeSync, existsSync, mkdirSync, openSync, readdirSync, readFileSync, readSync, renameSync, statSync, writeFileSync, } from "fs";
|
|
3
4
|
import { readdir, readFile, stat } from "fs/promises";
|
|
4
5
|
import { join, resolve } from "path";
|
|
5
6
|
import { getAgentDir as getDefaultAgentDir, getSessionsDir } from "../config.js";
|
|
6
|
-
import {
|
|
7
|
+
import { canonicalizePath, normalizePath, resolvePath } from "../utils/paths.js";
|
|
7
8
|
import { createBranchSummaryMessage, createCompactionSummaryMessage, createCustomMessage, } from "./messages.js";
|
|
8
9
|
export const CURRENT_SESSION_VERSION = 3;
|
|
9
10
|
function createSessionId() {
|
|
10
11
|
return uuidv7();
|
|
11
12
|
}
|
|
13
|
+
export function assertValidSessionId(id) {
|
|
14
|
+
if (!/^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/.test(id)) {
|
|
15
|
+
throw new Error("Session id must be non-empty, contain only alphanumeric characters, '-', '_', and '.', and start and end with an alphanumeric character");
|
|
16
|
+
}
|
|
17
|
+
}
|
|
12
18
|
/** Generate a unique short ID (8 hex chars, collision-checked) */
|
|
13
19
|
function generateId(byId) {
|
|
14
20
|
for (let i = 0; i < 100; i++) {
|
|
@@ -137,10 +143,9 @@ export function buildSessionContext(entries, leafId, byId) {
|
|
|
137
143
|
const path = [];
|
|
138
144
|
let current = leaf;
|
|
139
145
|
while (current) {
|
|
140
|
-
path.
|
|
146
|
+
path.unshift(current);
|
|
141
147
|
current = current.parentId ? byId.get(current.parentId) : undefined;
|
|
142
148
|
}
|
|
143
|
-
path.reverse();
|
|
144
149
|
// Extract settings and find compaction
|
|
145
150
|
let thinkingLevel = "off";
|
|
146
151
|
let model = null;
|
|
@@ -210,9 +215,14 @@ export function buildSessionContext(entries, leafId, byId) {
|
|
|
210
215
|
* Compute the default session directory for a cwd.
|
|
211
216
|
* Encodes cwd into a safe directory name under ~/.pi/agent/sessions/.
|
|
212
217
|
*/
|
|
218
|
+
function getDefaultSessionDirPath(cwd, agentDir = getDefaultAgentDir()) {
|
|
219
|
+
const resolvedCwd = resolvePath(cwd);
|
|
220
|
+
const resolvedAgentDir = resolvePath(agentDir);
|
|
221
|
+
const safePath = `--${resolvedCwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
|
|
222
|
+
return join(resolvedAgentDir, "sessions", safePath);
|
|
223
|
+
}
|
|
213
224
|
export function getDefaultSessionDir(cwd, agentDir = getDefaultAgentDir()) {
|
|
214
|
-
const
|
|
215
|
-
const sessionDir = join(agentDir, "sessions", safePath);
|
|
225
|
+
const sessionDir = getDefaultSessionDirPath(cwd, agentDir);
|
|
216
226
|
if (!existsSync(sessionDir)) {
|
|
217
227
|
mkdirSync(sessionDir, { recursive: true });
|
|
218
228
|
}
|
|
@@ -220,9 +230,10 @@ export function getDefaultSessionDir(cwd, agentDir = getDefaultAgentDir()) {
|
|
|
220
230
|
}
|
|
221
231
|
/** Exported for testing */
|
|
222
232
|
export function loadEntriesFromFile(filePath) {
|
|
223
|
-
|
|
233
|
+
const resolvedFilePath = normalizePath(filePath);
|
|
234
|
+
if (!existsSync(resolvedFilePath))
|
|
224
235
|
return [];
|
|
225
|
-
const content = readFileSync(
|
|
236
|
+
const content = readFileSync(resolvedFilePath, "utf8");
|
|
226
237
|
const entries = [];
|
|
227
238
|
const lines = content.trim().split("\n");
|
|
228
239
|
for (const line of lines) {
|
|
@@ -245,45 +256,7 @@ export function loadEntriesFromFile(filePath) {
|
|
|
245
256
|
}
|
|
246
257
|
return entries;
|
|
247
258
|
}
|
|
248
|
-
function
|
|
249
|
-
if (!existsSync(filePath))
|
|
250
|
-
return undefined;
|
|
251
|
-
try {
|
|
252
|
-
const fd = openSync(filePath, "r");
|
|
253
|
-
try {
|
|
254
|
-
let offset = 0;
|
|
255
|
-
let firstLine = "";
|
|
256
|
-
const buffer = Buffer.alloc(4096);
|
|
257
|
-
while (firstLine.length < 1024 * 1024) {
|
|
258
|
-
const bytesRead = readSync(fd, buffer, 0, buffer.length, offset);
|
|
259
|
-
if (bytesRead === 0)
|
|
260
|
-
break;
|
|
261
|
-
offset += bytesRead;
|
|
262
|
-
const chunk = buffer.toString("utf8", 0, bytesRead);
|
|
263
|
-
const newline = chunk.indexOf("\n");
|
|
264
|
-
if (newline >= 0) {
|
|
265
|
-
firstLine += chunk.slice(0, newline);
|
|
266
|
-
break;
|
|
267
|
-
}
|
|
268
|
-
firstLine += chunk;
|
|
269
|
-
}
|
|
270
|
-
if (!firstLine.trim())
|
|
271
|
-
return undefined;
|
|
272
|
-
const header = JSON.parse(firstLine);
|
|
273
|
-
if (header.type !== "session" || typeof header.id !== "string") {
|
|
274
|
-
return undefined;
|
|
275
|
-
}
|
|
276
|
-
return header;
|
|
277
|
-
}
|
|
278
|
-
finally {
|
|
279
|
-
closeSync(fd);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
catch {
|
|
283
|
-
return undefined;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
function isValidSessionFile(filePath) {
|
|
259
|
+
function readSessionHeader(filePath) {
|
|
287
260
|
try {
|
|
288
261
|
const fd = openSync(filePath, "r");
|
|
289
262
|
const buffer = Buffer.alloc(512);
|
|
@@ -291,22 +264,39 @@ function isValidSessionFile(filePath) {
|
|
|
291
264
|
closeSync(fd);
|
|
292
265
|
const firstLine = buffer.toString("utf8", 0, bytesRead).split("\n")[0];
|
|
293
266
|
if (!firstLine)
|
|
294
|
-
return
|
|
267
|
+
return null;
|
|
295
268
|
const header = JSON.parse(firstLine);
|
|
296
|
-
|
|
269
|
+
if (header.type !== "session" || typeof header.id !== "string") {
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
return header;
|
|
297
273
|
}
|
|
298
274
|
catch {
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
function getSessionHeaderCwd(header) {
|
|
279
|
+
const cwd = header.cwd;
|
|
280
|
+
return typeof cwd === "string" ? cwd : undefined;
|
|
281
|
+
}
|
|
282
|
+
function sessionCwdMatches(cwd, resolvedCwd) {
|
|
283
|
+
if (cwd === undefined || cwd === "") {
|
|
299
284
|
return false;
|
|
300
285
|
}
|
|
286
|
+
return canonicalizePath(resolvePath(cwd)) === canonicalizePath(resolvedCwd);
|
|
301
287
|
}
|
|
302
288
|
/** Exported for testing */
|
|
303
|
-
export function findMostRecentSession(sessionDir) {
|
|
289
|
+
export function findMostRecentSession(sessionDir, cwd) {
|
|
290
|
+
const resolvedSessionDir = normalizePath(sessionDir);
|
|
291
|
+
const resolvedCwd = cwd ? resolvePath(cwd) : undefined;
|
|
304
292
|
try {
|
|
305
|
-
const files = readdirSync(
|
|
293
|
+
const files = readdirSync(resolvedSessionDir)
|
|
306
294
|
.filter((f) => f.endsWith(".jsonl"))
|
|
307
|
-
.map((f) => join(
|
|
308
|
-
.
|
|
309
|
-
.
|
|
295
|
+
.map((f) => join(resolvedSessionDir, f))
|
|
296
|
+
.map((path) => ({ path, header: readSessionHeader(path) }))
|
|
297
|
+
.filter((file) => file.header !== null &&
|
|
298
|
+
(!resolvedCwd || sessionCwdMatches(getSessionHeaderCwd(file.header), resolvedCwd)))
|
|
299
|
+
.map(({ path }) => ({ path, mtime: statSync(path).mtime }))
|
|
310
300
|
.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
|
|
311
301
|
return files[0]?.path || null;
|
|
312
302
|
}
|
|
@@ -427,6 +417,40 @@ async function buildSessionInfo(filePath) {
|
|
|
427
417
|
return null;
|
|
428
418
|
}
|
|
429
419
|
}
|
|
420
|
+
const MAX_CONCURRENT_SESSION_INFO_LOADS = 10;
|
|
421
|
+
async function buildSessionInfosWithConcurrency(files, onLoaded) {
|
|
422
|
+
const results = new Array(files.length).fill(null);
|
|
423
|
+
const inFlight = new Set();
|
|
424
|
+
let nextIndex = 0;
|
|
425
|
+
const startNext = () => {
|
|
426
|
+
const index = nextIndex++;
|
|
427
|
+
const file = files[index];
|
|
428
|
+
if (!file)
|
|
429
|
+
return;
|
|
430
|
+
let task;
|
|
431
|
+
task = buildSessionInfo(file)
|
|
432
|
+
.then((info) => {
|
|
433
|
+
results[index] = info;
|
|
434
|
+
})
|
|
435
|
+
.catch(() => {
|
|
436
|
+
results[index] = null;
|
|
437
|
+
})
|
|
438
|
+
.finally(() => {
|
|
439
|
+
inFlight.delete(task);
|
|
440
|
+
onLoaded();
|
|
441
|
+
});
|
|
442
|
+
inFlight.add(task);
|
|
443
|
+
};
|
|
444
|
+
while (nextIndex < files.length || inFlight.size > 0) {
|
|
445
|
+
while (nextIndex < files.length && inFlight.size < MAX_CONCURRENT_SESSION_INFO_LOADS) {
|
|
446
|
+
startNext();
|
|
447
|
+
}
|
|
448
|
+
if (inFlight.size > 0) {
|
|
449
|
+
await Promise.race(inFlight);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
return results;
|
|
453
|
+
}
|
|
430
454
|
async function listSessionsFromDir(dir, onProgress, progressOffset = 0, progressTotal) {
|
|
431
455
|
const sessions = [];
|
|
432
456
|
if (!existsSync(dir)) {
|
|
@@ -437,12 +461,10 @@ async function listSessionsFromDir(dir, onProgress, progressOffset = 0, progress
|
|
|
437
461
|
const files = dirEntries.filter((f) => f.endsWith(".jsonl")).map((f) => join(dir, f));
|
|
438
462
|
const total = progressTotal ?? files.length;
|
|
439
463
|
let loaded = 0;
|
|
440
|
-
const results = await
|
|
441
|
-
const info = await buildSessionInfo(file);
|
|
464
|
+
const results = await buildSessionInfosWithConcurrency(files, () => {
|
|
442
465
|
loaded++;
|
|
443
466
|
onProgress?.(progressOffset + loaded, total);
|
|
444
|
-
|
|
445
|
-
}));
|
|
467
|
+
});
|
|
446
468
|
for (const info of results) {
|
|
447
469
|
if (info) {
|
|
448
470
|
sessions.push(info);
|
|
@@ -477,23 +499,23 @@ export class SessionManager {
|
|
|
477
499
|
labelsById = new Map();
|
|
478
500
|
labelTimestampsById = new Map();
|
|
479
501
|
leafId = null;
|
|
480
|
-
constructor(cwd, sessionDir, sessionFile, persist) {
|
|
481
|
-
this.cwd = cwd;
|
|
482
|
-
this.sessionDir = sessionDir;
|
|
502
|
+
constructor(cwd, sessionDir, sessionFile, persist, newSessionOptions) {
|
|
503
|
+
this.cwd = resolvePath(cwd);
|
|
504
|
+
this.sessionDir = normalizePath(sessionDir);
|
|
483
505
|
this.persist = persist;
|
|
484
|
-
if (persist && sessionDir && !existsSync(sessionDir)) {
|
|
485
|
-
mkdirSync(sessionDir, { recursive: true });
|
|
506
|
+
if (persist && this.sessionDir && !existsSync(this.sessionDir)) {
|
|
507
|
+
mkdirSync(this.sessionDir, { recursive: true });
|
|
486
508
|
}
|
|
487
509
|
if (sessionFile) {
|
|
488
510
|
this.setSessionFile(sessionFile);
|
|
489
511
|
}
|
|
490
512
|
else {
|
|
491
|
-
this.newSession();
|
|
513
|
+
this.newSession(newSessionOptions);
|
|
492
514
|
}
|
|
493
515
|
}
|
|
494
516
|
/** Switch to a different session file (used for resume and branching) */
|
|
495
517
|
setSessionFile(sessionFile) {
|
|
496
|
-
this.sessionFile =
|
|
518
|
+
this.sessionFile = resolvePath(sessionFile);
|
|
497
519
|
if (existsSync(this.sessionFile)) {
|
|
498
520
|
this.fileEntries = loadEntriesFromFile(this.sessionFile);
|
|
499
521
|
// If file was empty or corrupted (no valid header), truncate and start fresh
|
|
@@ -521,6 +543,9 @@ export class SessionManager {
|
|
|
521
543
|
}
|
|
522
544
|
}
|
|
523
545
|
newSession(options) {
|
|
546
|
+
if (options?.id !== undefined) {
|
|
547
|
+
assertValidSessionId(options.id);
|
|
548
|
+
}
|
|
524
549
|
this.sessionId = options?.id ?? createSessionId();
|
|
525
550
|
const timestamp = new Date().toISOString();
|
|
526
551
|
const header = {
|
|
@@ -570,14 +595,56 @@ export class SessionManager {
|
|
|
570
595
|
const content = `${this.fileEntries.map((e) => JSON.stringify(e)).join("\n")}\n`;
|
|
571
596
|
writeFileSync(this.sessionFile, content);
|
|
572
597
|
}
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
}
|
|
576
|
-
flushPendingEntries() {
|
|
598
|
+
/** Rewrite the session file atomically (write to temp + rename). */
|
|
599
|
+
_rewriteFileAtomic() {
|
|
577
600
|
if (!this.persist || !this.sessionFile)
|
|
578
601
|
return;
|
|
579
|
-
this.
|
|
580
|
-
|
|
602
|
+
const content = `${this.fileEntries.map((e) => JSON.stringify(e)).join("\n")}\n`;
|
|
603
|
+
const tmpFile = `${this.sessionFile}.tmp`;
|
|
604
|
+
writeFileSync(tmpFile, content);
|
|
605
|
+
renameSync(tmpFile, this.sessionFile);
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* After compaction, prune entries before firstKeptEntryId from the current branch.
|
|
609
|
+
* Rewrites the JSONL file with only the kept entries.
|
|
610
|
+
* This releases memory and prevents unbounded file growth.
|
|
611
|
+
*
|
|
612
|
+
* Only the current branch (leaf → root) is preserved. Branches that diverge
|
|
613
|
+
* from entries before firstKeptEntryId are discarded — this matches the
|
|
614
|
+
* semantics of compaction (old context is summarized away and no longer needed).
|
|
615
|
+
*/
|
|
616
|
+
pruneAfterCompaction() {
|
|
617
|
+
// 1. Get current branch (leaf → root, chronological order)
|
|
618
|
+
const branch = this.getBranch();
|
|
619
|
+
if (branch.length === 0)
|
|
620
|
+
return;
|
|
621
|
+
// 2. Find the latest compaction entry on the branch
|
|
622
|
+
const compactionIdx = branch.findIndex((e) => e.type === "compaction");
|
|
623
|
+
if (compactionIdx === -1)
|
|
624
|
+
return; // No compaction, nothing to prune
|
|
625
|
+
const compaction = branch[compactionIdx];
|
|
626
|
+
// 3. Find firstKeptEntryId in the branch
|
|
627
|
+
const firstKeptIdx = branch.findIndex((e) => e.id === compaction.firstKeptEntryId);
|
|
628
|
+
if (firstKeptIdx === -1)
|
|
629
|
+
return; // Can't find kept entry, don't prune
|
|
630
|
+
// Nothing to prune if firstKeptEntryId is the first entry
|
|
631
|
+
if (firstKeptIdx === 0)
|
|
632
|
+
return;
|
|
633
|
+
// 4. Collect entries to keep: header + entries from firstKeptIdx onward
|
|
634
|
+
const header = this.fileEntries.find((e) => e.type === "session");
|
|
635
|
+
const keptEntries = branch.slice(firstKeptIdx);
|
|
636
|
+
// 5. Fix parent chain: first kept entry becomes root (parentId = null)
|
|
637
|
+
if (keptEntries.length > 0 && keptEntries[0].parentId !== null) {
|
|
638
|
+
keptEntries[0].parentId = null;
|
|
639
|
+
}
|
|
640
|
+
// 6. Replace fileEntries and rebuild index
|
|
641
|
+
this.fileEntries = header ? [header, ...keptEntries] : [...keptEntries];
|
|
642
|
+
this._buildIndex();
|
|
643
|
+
// 7. Rewrite file atomically
|
|
644
|
+
this._rewriteFileAtomic();
|
|
645
|
+
}
|
|
646
|
+
isPersisted() {
|
|
647
|
+
return this.persist;
|
|
581
648
|
}
|
|
582
649
|
getCwd() {
|
|
583
650
|
return this.cwd;
|
|
@@ -585,6 +652,9 @@ export class SessionManager {
|
|
|
585
652
|
getSessionDir() {
|
|
586
653
|
return this.sessionDir;
|
|
587
654
|
}
|
|
655
|
+
usesDefaultSessionDir() {
|
|
656
|
+
return this.sessionDir === getDefaultSessionDirPath(this.cwd);
|
|
657
|
+
}
|
|
588
658
|
getSessionId() {
|
|
589
659
|
return this.sessionId;
|
|
590
660
|
}
|
|
@@ -596,12 +666,26 @@ export class SessionManager {
|
|
|
596
666
|
return;
|
|
597
667
|
const hasAssistant = this.fileEntries.some((e) => e.type === "message" && e.message.role === "assistant");
|
|
598
668
|
if (!hasAssistant) {
|
|
599
|
-
|
|
600
|
-
|
|
669
|
+
if (this.flushed) {
|
|
670
|
+
appendFileSync(this.sessionFile, `${JSON.stringify(entry)}\n`);
|
|
671
|
+
}
|
|
672
|
+
else {
|
|
673
|
+
// Mark as not flushed so when assistant arrives, all entries get written
|
|
674
|
+
this.flushed = false;
|
|
675
|
+
}
|
|
601
676
|
return;
|
|
602
677
|
}
|
|
603
678
|
if (!this.flushed) {
|
|
604
|
-
this.
|
|
679
|
+
const fd = openSync(this.sessionFile, "wx");
|
|
680
|
+
try {
|
|
681
|
+
for (const e of this.fileEntries) {
|
|
682
|
+
writeFileSync(fd, `${JSON.stringify(e)}\n`);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
finally {
|
|
686
|
+
closeSync(fd);
|
|
687
|
+
}
|
|
688
|
+
this.flushed = true;
|
|
605
689
|
}
|
|
606
690
|
else {
|
|
607
691
|
appendFileSync(this.sessionFile, `${JSON.stringify(entry)}\n`);
|
|
@@ -799,10 +883,10 @@ export class SessionManager {
|
|
|
799
883
|
const startId = fromId ?? this.leafId;
|
|
800
884
|
let current = startId ? this.byId.get(startId) : undefined;
|
|
801
885
|
while (current) {
|
|
802
|
-
path.
|
|
886
|
+
path.unshift(current);
|
|
803
887
|
current = current.parentId ? this.byId.get(current.parentId) : undefined;
|
|
804
888
|
}
|
|
805
|
-
return path
|
|
889
|
+
return path;
|
|
806
890
|
}
|
|
807
891
|
/**
|
|
808
892
|
* Build the session context (what gets sent to the LLM).
|
|
@@ -1009,9 +1093,9 @@ export class SessionManager {
|
|
|
1009
1093
|
* @param cwd Working directory (stored in session header)
|
|
1010
1094
|
* @param sessionDir Optional session directory. If omitted, uses default (~/.pi/agent/sessions/<encoded-cwd>/).
|
|
1011
1095
|
*/
|
|
1012
|
-
static create(cwd, sessionDir) {
|
|
1013
|
-
const dir = sessionDir
|
|
1014
|
-
return new SessionManager(cwd, dir, undefined, true);
|
|
1096
|
+
static create(cwd, sessionDir, options) {
|
|
1097
|
+
const dir = sessionDir ? normalizePath(sessionDir) : getDefaultSessionDir(cwd);
|
|
1098
|
+
return new SessionManager(cwd, dir, undefined, true, options);
|
|
1015
1099
|
}
|
|
1016
1100
|
/**
|
|
1017
1101
|
* Open a specific session file.
|
|
@@ -1020,12 +1104,14 @@ export class SessionManager {
|
|
|
1020
1104
|
* @param cwdOverride Optional cwd override instead of the session header cwd.
|
|
1021
1105
|
*/
|
|
1022
1106
|
static open(path, sessionDir, cwdOverride) {
|
|
1107
|
+
const resolvedPath = resolvePath(path);
|
|
1023
1108
|
// Extract cwd from session header if possible, otherwise use process.cwd()
|
|
1024
|
-
const
|
|
1109
|
+
const entries = loadEntriesFromFile(resolvedPath);
|
|
1110
|
+
const header = entries.find((e) => e.type === "session");
|
|
1025
1111
|
const cwd = cwdOverride ?? header?.cwd ?? process.cwd();
|
|
1026
1112
|
// If no sessionDir provided, derive from file's parent directory
|
|
1027
|
-
const dir = sessionDir
|
|
1028
|
-
return new SessionManager(cwd, dir,
|
|
1113
|
+
const dir = sessionDir ? normalizePath(sessionDir) : resolve(resolvedPath, "..");
|
|
1114
|
+
return new SessionManager(cwd, dir, resolvedPath, true);
|
|
1029
1115
|
}
|
|
1030
1116
|
/**
|
|
1031
1117
|
* Continue the most recent session, or create new if none.
|
|
@@ -1033,8 +1119,9 @@ export class SessionManager {
|
|
|
1033
1119
|
* @param sessionDir Optional session directory. If omitted, uses default (~/.pi/agent/sessions/<encoded-cwd>/).
|
|
1034
1120
|
*/
|
|
1035
1121
|
static continueRecent(cwd, sessionDir) {
|
|
1036
|
-
const dir = sessionDir
|
|
1037
|
-
const
|
|
1122
|
+
const dir = sessionDir ? normalizePath(sessionDir) : getDefaultSessionDir(cwd);
|
|
1123
|
+
const filterCwd = sessionDir !== undefined && dir !== getDefaultSessionDirPath(cwd);
|
|
1124
|
+
const mostRecent = findMostRecentSession(dir, filterCwd ? cwd : undefined);
|
|
1038
1125
|
if (mostRecent) {
|
|
1039
1126
|
return new SessionManager(cwd, dir, mostRecent, true);
|
|
1040
1127
|
}
|
|
@@ -1051,21 +1138,26 @@ export class SessionManager {
|
|
|
1051
1138
|
* @param targetCwd Target working directory (where the new session will be stored)
|
|
1052
1139
|
* @param sessionDir Optional session directory. If omitted, uses default for targetCwd.
|
|
1053
1140
|
*/
|
|
1054
|
-
static forkFrom(sourcePath, targetCwd, sessionDir) {
|
|
1055
|
-
const
|
|
1141
|
+
static forkFrom(sourcePath, targetCwd, sessionDir, options) {
|
|
1142
|
+
const resolvedSourcePath = resolvePath(sourcePath);
|
|
1143
|
+
const resolvedTargetCwd = resolvePath(targetCwd);
|
|
1144
|
+
const sourceEntries = loadEntriesFromFile(resolvedSourcePath);
|
|
1056
1145
|
if (sourceEntries.length === 0) {
|
|
1057
|
-
throw new Error(`Cannot fork: source session file is empty or invalid: ${
|
|
1146
|
+
throw new Error(`Cannot fork: source session file is empty or invalid: ${resolvedSourcePath}`);
|
|
1058
1147
|
}
|
|
1059
1148
|
const sourceHeader = sourceEntries.find((e) => e.type === "session");
|
|
1060
1149
|
if (!sourceHeader) {
|
|
1061
|
-
throw new Error(`Cannot fork: source session has no header: ${
|
|
1150
|
+
throw new Error(`Cannot fork: source session has no header: ${resolvedSourcePath}`);
|
|
1062
1151
|
}
|
|
1063
|
-
const dir = sessionDir
|
|
1152
|
+
const dir = sessionDir ? normalizePath(sessionDir) : getDefaultSessionDir(resolvedTargetCwd);
|
|
1064
1153
|
if (!existsSync(dir)) {
|
|
1065
1154
|
mkdirSync(dir, { recursive: true });
|
|
1066
1155
|
}
|
|
1067
1156
|
// Create new session file with new ID but forked content
|
|
1068
|
-
|
|
1157
|
+
if (options?.id !== undefined) {
|
|
1158
|
+
assertValidSessionId(options.id);
|
|
1159
|
+
}
|
|
1160
|
+
const newSessionId = options?.id ?? createSessionId();
|
|
1069
1161
|
const timestamp = new Date().toISOString();
|
|
1070
1162
|
const fileTimestamp = timestamp.replace(/[:.]/g, "-");
|
|
1071
1163
|
const newSessionFile = join(dir, `${fileTimestamp}_${newSessionId}.jsonl`);
|
|
@@ -1075,17 +1167,17 @@ export class SessionManager {
|
|
|
1075
1167
|
version: CURRENT_SESSION_VERSION,
|
|
1076
1168
|
id: newSessionId,
|
|
1077
1169
|
timestamp,
|
|
1078
|
-
cwd:
|
|
1079
|
-
parentSession:
|
|
1170
|
+
cwd: resolvedTargetCwd,
|
|
1171
|
+
parentSession: resolvedSourcePath,
|
|
1080
1172
|
};
|
|
1081
|
-
|
|
1173
|
+
writeFileSync(newSessionFile, `${JSON.stringify(newHeader)}\n`, { flag: "wx" });
|
|
1082
1174
|
// Copy all non-header entries from source
|
|
1083
1175
|
for (const entry of sourceEntries) {
|
|
1084
1176
|
if (entry.type !== "session") {
|
|
1085
1177
|
appendFileSync(newSessionFile, `${JSON.stringify(entry)}\n`);
|
|
1086
1178
|
}
|
|
1087
1179
|
}
|
|
1088
|
-
return new SessionManager(
|
|
1180
|
+
return new SessionManager(resolvedTargetCwd, dir, newSessionFile, true);
|
|
1089
1181
|
}
|
|
1090
1182
|
/**
|
|
1091
1183
|
* List all sessions for a directory.
|
|
@@ -1094,16 +1186,21 @@ export class SessionManager {
|
|
|
1094
1186
|
* @param onProgress Optional callback for progress updates (loaded, total)
|
|
1095
1187
|
*/
|
|
1096
1188
|
static async list(cwd, sessionDir, onProgress) {
|
|
1097
|
-
const dir = sessionDir
|
|
1098
|
-
const
|
|
1189
|
+
const dir = sessionDir ? normalizePath(sessionDir) : getDefaultSessionDir(cwd);
|
|
1190
|
+
const filterCwd = sessionDir !== undefined && dir !== getDefaultSessionDirPath(cwd);
|
|
1191
|
+
const resolvedCwd = resolvePath(cwd);
|
|
1192
|
+
const sessions = (await listSessionsFromDir(dir, onProgress)).filter((session) => !filterCwd || sessionCwdMatches(session.cwd, resolvedCwd));
|
|
1099
1193
|
sessions.sort((a, b) => b.modified.getTime() - a.modified.getTime());
|
|
1100
1194
|
return sessions;
|
|
1101
1195
|
}
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1196
|
+
static async listAll(sessionDirOrOnProgress, onProgress) {
|
|
1197
|
+
const customSessionDir = typeof sessionDirOrOnProgress === "string" ? normalizePath(sessionDirOrOnProgress) : undefined;
|
|
1198
|
+
const progress = typeof sessionDirOrOnProgress === "function" ? sessionDirOrOnProgress : onProgress;
|
|
1199
|
+
if (customSessionDir) {
|
|
1200
|
+
const sessions = await listSessionsFromDir(customSessionDir, progress);
|
|
1201
|
+
sessions.sort((a, b) => b.modified.getTime() - a.modified.getTime());
|
|
1202
|
+
return sessions;
|
|
1203
|
+
}
|
|
1107
1204
|
const sessionsDir = getSessionsDir();
|
|
1108
1205
|
try {
|
|
1109
1206
|
if (!existsSync(sessionsDir)) {
|
|
@@ -1128,12 +1225,10 @@ export class SessionManager {
|
|
|
1128
1225
|
let loaded = 0;
|
|
1129
1226
|
const sessions = [];
|
|
1130
1227
|
const allFiles = dirFiles.flat();
|
|
1131
|
-
const results = await
|
|
1132
|
-
const info = await buildSessionInfo(file);
|
|
1228
|
+
const results = await buildSessionInfosWithConcurrency(allFiles, () => {
|
|
1133
1229
|
loaded++;
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
}));
|
|
1230
|
+
progress?.(loaded, totalFiles);
|
|
1231
|
+
});
|
|
1137
1232
|
for (const info of results) {
|
|
1138
1233
|
if (info) {
|
|
1139
1234
|
sessions.push(info);
|