@code-yeongyu/senpi 2026.8.26 → 2026.8.28-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 +138 -0
- package/README.md +3 -3
- package/dist/cli/args.d.ts +5 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +18 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +2 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +5 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +11 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +1 -0
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +3 -0
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +67 -29
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/credential-accounts.d.ts +31 -0
- package/dist/core/credential-accounts.d.ts.map +1 -0
- package/dist/core/credential-accounts.js +135 -0
- package/dist/core/credential-accounts.js.map +1 -0
- package/dist/core/credential-pool/classify.d.ts +47 -0
- package/dist/core/credential-pool/classify.d.ts.map +1 -0
- package/dist/core/credential-pool/classify.js +92 -0
- package/dist/core/credential-pool/classify.js.map +1 -0
- package/dist/core/credential-pool/env-slots.d.ts +22 -0
- package/dist/core/credential-pool/env-slots.d.ts.map +1 -0
- package/dist/core/credential-pool/env-slots.js +37 -0
- package/dist/core/credential-pool/env-slots.js.map +1 -0
- package/dist/core/credential-pool/failover.d.ts +62 -0
- package/dist/core/credential-pool/failover.d.ts.map +1 -0
- package/dist/core/credential-pool/failover.js +124 -0
- package/dist/core/credential-pool/failover.js.map +1 -0
- package/dist/core/credential-pool/rotation-stream.d.ts +54 -0
- package/dist/core/credential-pool/rotation-stream.d.ts.map +1 -0
- package/dist/core/credential-pool/rotation-stream.js +183 -0
- package/dist/core/credential-pool/rotation-stream.js.map +1 -0
- package/dist/core/credential-pool/state-store.d.ts +89 -0
- package/dist/core/credential-pool/state-store.d.ts.map +1 -0
- package/dist/core/credential-pool/state-store.js +166 -0
- package/dist/core/credential-pool/state-store.js.map +1 -0
- package/dist/core/extensions/builtin/account/index.d.ts +9 -0
- package/dist/core/extensions/builtin/account/index.d.ts.map +1 -0
- package/dist/core/extensions/builtin/account/index.js +69 -0
- package/dist/core/extensions/builtin/account/index.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.js +67 -0
- package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/log.d.ts +1 -1
- package/dist/core/extensions/builtin/compaction/log.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/log.js +1 -0
- package/dist/core/extensions/builtin/compaction/log.js.map +1 -1
- package/dist/core/extensions/builtin/config-reload/index.js +14 -22
- package/dist/core/extensions/builtin/config-reload/index.js.map +1 -1
- package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts +1 -0
- package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/continuation-recovery.js +2 -0
- package/dist/core/extensions/builtin/goal/continuation-recovery.js.map +1 -1
- package/dist/core/extensions/builtin/goal/continuation.d.ts +8 -1
- package/dist/core/extensions/builtin/goal/continuation.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/continuation.js +15 -0
- package/dist/core/extensions/builtin/goal/continuation.js.map +1 -1
- package/dist/core/extensions/builtin/goal/direct-input-lifecycle.js +2 -2
- package/dist/core/extensions/builtin/goal/direct-input-lifecycle.js.map +1 -1
- package/dist/core/extensions/builtin/goal/format.d.ts +6 -1
- package/dist/core/extensions/builtin/goal/format.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/format.js +6 -0
- package/dist/core/extensions/builtin/goal/format.js.map +1 -1
- package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/index.js +7 -0
- package/dist/core/extensions/builtin/goal/index.js.map +1 -1
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +5 -2
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -1
- package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/monitor-continuation.js +31 -7
- package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
- package/dist/core/extensions/builtin/goal/persistence.js +2 -0
- package/dist/core/extensions/builtin/goal/persistence.js.map +1 -1
- package/dist/core/extensions/builtin/goal/renderers.d.ts +14 -0
- package/dist/core/extensions/builtin/goal/renderers.d.ts.map +1 -0
- package/dist/core/extensions/builtin/goal/renderers.js +153 -0
- package/dist/core/extensions/builtin/goal/renderers.js.map +1 -0
- package/dist/core/extensions/builtin/goal/store.d.ts +6 -2
- package/dist/core/extensions/builtin/goal/store.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/store.js +8 -2
- package/dist/core/extensions/builtin/goal/store.js.map +1 -1
- package/dist/core/extensions/builtin/goal/tool-registration.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/tool-registration.js +16 -6
- package/dist/core/extensions/builtin/goal/tool-registration.js.map +1 -1
- package/dist/core/extensions/builtin/goal/types.d.ts +1 -0
- package/dist/core/extensions/builtin/goal/types.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/types.js.map +1 -1
- package/dist/core/extensions/builtin/imagegen/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/imagegen/index.js +10 -3
- package/dist/core/extensions/builtin/imagegen/index.js.map +1 -1
- package/dist/core/extensions/builtin/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/index.js +4 -0
- package/dist/core/extensions/builtin/index.js.map +1 -1
- package/dist/core/extensions/builtin/service-tier.d.ts.map +1 -1
- package/dist/core/extensions/builtin/service-tier.js +13 -0
- package/dist/core/extensions/builtin/service-tier.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/extension.js +4 -2
- package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/index.js +1 -1
- package/dist/core/extensions/builtin/todotools/index.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/native-todo-mirror.d.ts +1 -1
- package/dist/core/extensions/builtin/todotools/native-todo-mirror.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/native-todo-mirror.js +1 -1
- package/dist/core/extensions/builtin/todotools/native-todo-mirror.js.map +1 -1
- package/dist/core/hidden-stdout-log.d.ts +10 -0
- package/dist/core/hidden-stdout-log.d.ts.map +1 -1
- package/dist/core/hidden-stdout-log.js +36 -5
- package/dist/core/hidden-stdout-log.js.map +1 -1
- package/dist/core/model-config-schema.d.ts +85 -12
- package/dist/core/model-config-schema.d.ts.map +1 -1
- package/dist/core/model-config-schema.js +25 -0
- package/dist/core/model-config-schema.js.map +1 -1
- package/dist/core/model-runtime.d.ts +36 -1
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +142 -12
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/retry-fallback/chains.d.ts +23 -1
- package/dist/core/retry-fallback/chains.d.ts.map +1 -1
- package/dist/core/retry-fallback/chains.js +59 -3
- package/dist/core/retry-fallback/chains.js.map +1 -1
- package/dist/core/retry-fallback/controller.d.ts.map +1 -1
- package/dist/core/retry-fallback/controller.js +9 -2
- package/dist/core/retry-fallback/controller.js.map +1 -1
- package/dist/core/retry-fallback/settings.d.ts.map +1 -1
- package/dist/core/retry-fallback/settings.js +9 -0
- package/dist/core/retry-fallback/settings.js.map +1 -1
- package/dist/core/retry-fallback/validate.js +1 -1
- package/dist/core/retry-fallback/validate.js.map +1 -1
- package/dist/core/sdk.js +1 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +9 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +31 -0
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts +2 -0
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +32 -7
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +7 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +48 -4
- package/dist/main.js.map +1 -1
- package/dist/modes/app-server/server/account.d.ts.map +1 -1
- package/dist/modes/app-server/server/account.js +5 -5
- package/dist/modes/app-server/server/account.js.map +1 -1
- package/dist/modes/index.d.ts +1 -0
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js +1 -0
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +11 -3
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +31 -1
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution-fallback.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution-fallback.js +82 -1
- package/dist/modes/interactive/components/tool-execution-fallback.js.map +1 -1
- package/dist/modes/interactive/grok/chrome.d.ts +4 -4
- package/dist/modes/interactive/grok/chrome.d.ts.map +1 -1
- package/dist/modes/interactive/grok/chrome.js.map +1 -1
- package/dist/modes/interactive/grok/footer.d.ts +3 -3
- package/dist/modes/interactive/grok/footer.d.ts.map +1 -1
- package/dist/modes/interactive/grok/footer.js.map +1 -1
- package/dist/modes/interactive/interactive-host-runtime.d.ts +44 -0
- package/dist/modes/interactive/interactive-host-runtime.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-host-runtime.js +529 -0
- package/dist/modes/interactive/interactive-host-runtime.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +340 -257
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
- package/dist/modes/rpc/connection-handler.js +151 -30
- package/dist/modes/rpc/connection-handler.js.map +1 -1
- package/dist/modes/rpc/host-ensure.d.ts +41 -0
- package/dist/modes/rpc/host-ensure.d.ts.map +1 -0
- package/dist/modes/rpc/host-ensure.js +245 -0
- package/dist/modes/rpc/host-ensure.js.map +1 -0
- package/dist/modes/rpc/host-lifecycle.d.ts +57 -0
- package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -0
- package/dist/modes/rpc/host-lifecycle.js +491 -0
- package/dist/modes/rpc/host-lifecycle.js.map +1 -0
- package/dist/modes/rpc/host-watchdog.d.ts +33 -0
- package/dist/modes/rpc/host-watchdog.d.ts.map +1 -0
- package/dist/modes/rpc/host-watchdog.js +142 -0
- package/dist/modes/rpc/host-watchdog.js.map +1 -0
- package/dist/modes/rpc/multi-session-host.d.ts +7 -1
- package/dist/modes/rpc/multi-session-host.d.ts.map +1 -1
- package/dist/modes/rpc/multi-session-host.js +216 -32
- package/dist/modes/rpc/multi-session-host.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +115 -8
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +200 -32
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts +4 -2
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +4 -2
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +166 -3
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/modes/rpc/session-command-router.d.ts +22 -0
- package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
- package/dist/modes/rpc/session-command-router.js +165 -16
- package/dist/modes/rpc/session-command-router.js.map +1 -1
- package/dist/modes/rpc/session-event-writer.d.ts +15 -2
- package/dist/modes/rpc/session-event-writer.d.ts.map +1 -1
- package/dist/modes/rpc/session-event-writer.js +69 -25
- package/dist/modes/rpc/session-event-writer.js.map +1 -1
- package/dist/modes/rpc/session-registry.d.ts +16 -0
- package/dist/modes/rpc/session-registry.d.ts.map +1 -1
- package/dist/modes/rpc/session-registry.js +40 -3
- package/dist/modes/rpc/session-registry.js.map +1 -1
- package/docs/providers.md +48 -0
- package/docs/rpc.md +96 -5
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +56 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/context-manager.ts +13 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/inline-worker.ts +15 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-indirect-eval.js +711 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/transport.ts +14 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +10 -10
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-eval-result.ts +9 -3
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +6 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/edit.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/edit.js +20 -4
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/edit.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/index.d.ts +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/post-mutate.d.ts +21 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/post-mutate.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/post-mutate.js +27 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/post-mutate.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/tool-context.d.ts +24 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/tool-context.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/tool-context.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/write.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/write.js +7 -2
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/write.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-pairs.d.ts +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-pairs.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-pairs.js +46 -14
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-pairs.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts +11 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js +30 -16
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.d.ts +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/classify.d.ts +16 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/classify.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/classify.js +75 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/classify.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.d.ts +45 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.js +81 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/select.d.ts +31 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/select.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/select.js +65 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/select.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.d.ts +12 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.js +37 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.d.ts +6 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js +32 -6
- package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts +3 -2
- package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.d.ts +6 -0
- package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js +6 -1
- package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts +75 -0
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +75 -0
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/alibaba-token-plan.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/baseten.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-workers-ai.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/github-copilot.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/minimax-cn.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/minimax.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/mistral.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai-codex.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opengateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan-cn.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/together.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai-coding-cn.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +4 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +5 -5
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +5 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js +90 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui.js +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
|
@@ -17,7 +17,7 @@ import { envValue } from "../../core/brand.js";
|
|
|
17
17
|
import { CACHE_TTL_MS, collectCacheMisses, computeCacheWaste, detectCacheMiss, } from "../../core/cache-stats.js";
|
|
18
18
|
import { buildNoticeBox } from "../../core/extensions/notice/index.js";
|
|
19
19
|
import { FooterDataProvider } from "../../core/footer-data-provider.js";
|
|
20
|
-
import { appendHiddenTuiStdout } from "../../core/hidden-stdout-log.js";
|
|
20
|
+
import { appendHiddenTuiStdout, appendUncaughtCrashLog } from "../../core/hidden-stdout-log.js";
|
|
21
21
|
import { buildHighReasoningWarning } from "../../core/high-reasoning-warning.js";
|
|
22
22
|
import { configureHttpDispatcher, formatHttpIdleTimeoutMs } from "../../core/http-dispatcher.js";
|
|
23
23
|
import { KeybindingsManager } from "../../core/keybindings.js";
|
|
@@ -143,6 +143,8 @@ function isCompactionCostNotice(item) {
|
|
|
143
143
|
return "type" in item && item.type === "compaction_cost";
|
|
144
144
|
}
|
|
145
145
|
const DEAD_TERMINAL_ERROR_CODES = new Set(["EIO", "EPIPE", "ENOTCONN"]);
|
|
146
|
+
// Bun's macOS tty shim can report a dead terminal as raw positive errno 5 without a string code.
|
|
147
|
+
const EIO_ERRNO = 5;
|
|
146
148
|
const DEFAULT_RETRY_STATUS_REFRESH_INTERVAL_MS = 80;
|
|
147
149
|
const LARGE_SESSION_RETRY_STATUS_REFRESH_INTERVAL_MS = 60_000;
|
|
148
150
|
const DEFAULT_WORKING_STATUS_REFRESH_INTERVAL_MS = 600;
|
|
@@ -207,11 +209,33 @@ function formatWorkingStatusShimmerText(text, intensity) {
|
|
|
207
209
|
return `\x1b[1m\x1b[38;2;${color.r};${color.g};${color.b}m${text}\x1b[39m\x1b[22m`;
|
|
208
210
|
}
|
|
209
211
|
function isDeadTerminalError(error) {
|
|
210
|
-
if (!error || typeof error !== "object"
|
|
212
|
+
if (!error || typeof error !== "object") {
|
|
211
213
|
return false;
|
|
212
214
|
}
|
|
215
|
+
if ("code" in error) {
|
|
216
|
+
const code = error.code;
|
|
217
|
+
if (code !== undefined && DEAD_TERMINAL_ERROR_CODES.has(code)) {
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if ("errno" in error) {
|
|
222
|
+
const errno = error.errno;
|
|
223
|
+
return errno === EIO_ERRNO || errno === -EIO_ERRNO;
|
|
224
|
+
}
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
function storageWriteCrashMessage(error) {
|
|
228
|
+
if (!error || typeof error !== "object" || !("code" in error)) {
|
|
229
|
+
return undefined;
|
|
230
|
+
}
|
|
213
231
|
const code = error.code;
|
|
214
|
-
|
|
232
|
+
if (code === "EDQUOT") {
|
|
233
|
+
return "Disk quota exceeded (EDQUOT). Free space or quota on the filesystem, then retry.";
|
|
234
|
+
}
|
|
235
|
+
if (code === "ENOSPC") {
|
|
236
|
+
return "Disk full (ENOSPC). Free space on the filesystem, then retry.";
|
|
237
|
+
}
|
|
238
|
+
return undefined;
|
|
215
239
|
}
|
|
216
240
|
const ANTHROPIC_SUBSCRIPTION_AUTH_WARNING = "Anthropic subscription auth is active. Third-party harness usage draws from extra usage and is billed per token, not your Claude plan limits. Manage extra usage at https://claude.ai/settings/usage. Disable this warning in /settings.";
|
|
217
241
|
function isAnthropicSubscriptionAuthKey(apiKey) {
|
|
@@ -479,6 +503,8 @@ export class InteractiveMode {
|
|
|
479
503
|
this.ui.setMaxRenderFps(fps);
|
|
480
504
|
}
|
|
481
505
|
// Convenience accessors
|
|
506
|
+
// The session may be the local AgentSession or the shared-host RPC proxy; the
|
|
507
|
+
// four reads widened on InteractiveSession must be awaited at every call site.
|
|
482
508
|
get session() {
|
|
483
509
|
return this.runtimeHost.session;
|
|
484
510
|
}
|
|
@@ -2974,7 +3000,7 @@ export class InteractiveMode {
|
|
|
2974
3000
|
this.showTreeSelector();
|
|
2975
3001
|
}
|
|
2976
3002
|
else {
|
|
2977
|
-
this.showUserMessageSelector();
|
|
3003
|
+
void this.showUserMessageSelector().catch((error) => this.showError(error instanceof Error ? error.message : String(error)));
|
|
2978
3004
|
}
|
|
2979
3005
|
this.lastEscapeTime = 0;
|
|
2980
3006
|
}
|
|
@@ -2988,7 +3014,9 @@ export class InteractiveMode {
|
|
|
2988
3014
|
this.defaultEditor.onAction("app.clear", () => this.handleCtrlC());
|
|
2989
3015
|
this.defaultEditor.onCtrlD = () => this.handleCtrlD();
|
|
2990
3016
|
this.defaultEditor.onAction("app.suspend", () => this.handleCtrlZ());
|
|
2991
|
-
this.defaultEditor.onAction("app.thinking.cycle", () =>
|
|
3017
|
+
this.defaultEditor.onAction("app.thinking.cycle", () => {
|
|
3018
|
+
void this.cycleThinkingLevel().catch((error) => this.showError(error instanceof Error ? error.message : String(error)));
|
|
3019
|
+
});
|
|
2992
3020
|
this.defaultEditor.onAction("app.model.cycleForward", () => this.cycleModel("forward"));
|
|
2993
3021
|
this.defaultEditor.onAction("app.model.cycleBackward", () => this.cycleModel("backward"));
|
|
2994
3022
|
// Global debug handler on TUI (works regardless of focus)
|
|
@@ -3010,7 +3038,7 @@ export class InteractiveMode {
|
|
|
3010
3038
|
this.defaultEditor.onAction("app.message.dequeue", () => this.handleDequeue());
|
|
3011
3039
|
this.defaultEditor.onAction("app.session.new", () => this.handleClearCommand());
|
|
3012
3040
|
this.defaultEditor.onAction("app.session.tree", () => this.showTreeSelector());
|
|
3013
|
-
this.defaultEditor.onAction("app.session.fork", () => this.showUserMessageSelector());
|
|
3041
|
+
this.defaultEditor.onAction("app.session.fork", () => void this.showUserMessageSelector().catch((error) => this.showError(error instanceof Error ? error.message : String(error))));
|
|
3014
3042
|
this.defaultEditor.onAction("app.session.resume", () => this.showSessionSelector());
|
|
3015
3043
|
this.defaultEditor.onChange = (text) => {
|
|
3016
3044
|
const wasBashMode = this.isBashMode;
|
|
@@ -3166,197 +3194,158 @@ export class InteractiveMode {
|
|
|
3166
3194
|
}
|
|
3167
3195
|
setupEditorSubmitHandler() {
|
|
3168
3196
|
this.defaultEditor.onSubmit = async (text) => {
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
if (text === "/favorite-models") {
|
|
3188
|
-
this.editor.setText("");
|
|
3189
|
-
await this.showFavoriteModelsSelector();
|
|
3190
|
-
return;
|
|
3191
|
-
}
|
|
3192
|
-
if (text === "/scoped-models") {
|
|
3193
|
-
this.editor.setText("");
|
|
3194
|
-
this.showScopedModelsSelector();
|
|
3195
|
-
return;
|
|
3196
|
-
}
|
|
3197
|
-
if (text === "/model" || text.startsWith("/model ")) {
|
|
3198
|
-
const searchTerm = text.startsWith("/model ") ? text.slice(7).trim() : undefined;
|
|
3199
|
-
this.editor.setText("");
|
|
3200
|
-
await this.handleModelCommand(searchTerm);
|
|
3201
|
-
return;
|
|
3202
|
-
}
|
|
3203
|
-
if (text === "/export" || text.startsWith("/export ")) {
|
|
3204
|
-
await this.handleExportCommand(text);
|
|
3205
|
-
this.editor.setText("");
|
|
3206
|
-
return;
|
|
3207
|
-
}
|
|
3208
|
-
if (text === "/import" || text.startsWith("/import ")) {
|
|
3209
|
-
await this.handleImportCommand(text);
|
|
3210
|
-
this.editor.setText("");
|
|
3211
|
-
return;
|
|
3212
|
-
}
|
|
3213
|
-
if (text === "/share") {
|
|
3214
|
-
await this.handleShareCommand();
|
|
3215
|
-
this.editor.setText("");
|
|
3216
|
-
return;
|
|
3217
|
-
}
|
|
3218
|
-
if (text === "/copy") {
|
|
3219
|
-
await this.handleCopyCommand();
|
|
3220
|
-
this.editor.setText("");
|
|
3221
|
-
return;
|
|
3222
|
-
}
|
|
3223
|
-
if (text === "/name" || text.startsWith("/name ")) {
|
|
3224
|
-
this.handleNameCommand(text);
|
|
3225
|
-
this.editor.setText("");
|
|
3226
|
-
return;
|
|
3227
|
-
}
|
|
3228
|
-
if (text === "/session") {
|
|
3229
|
-
this.handleSessionCommand();
|
|
3230
|
-
this.editor.setText("");
|
|
3231
|
-
return;
|
|
3232
|
-
}
|
|
3233
|
-
if (text === "/changelog") {
|
|
3234
|
-
this.handleChangelogCommand();
|
|
3235
|
-
this.editor.setText("");
|
|
3236
|
-
return;
|
|
3237
|
-
}
|
|
3238
|
-
if (text === "/keybindings") {
|
|
3239
|
-
this.editor.setText("");
|
|
3240
|
-
await this.handleKeybindingsCommand();
|
|
3241
|
-
return;
|
|
3242
|
-
}
|
|
3243
|
-
if (text === "/hotkeys") {
|
|
3244
|
-
this.handleHotkeysCommand();
|
|
3245
|
-
this.editor.setText("");
|
|
3246
|
-
return;
|
|
3247
|
-
}
|
|
3248
|
-
if (text === "/fork") {
|
|
3249
|
-
this.showUserMessageSelector();
|
|
3250
|
-
this.editor.setText("");
|
|
3251
|
-
return;
|
|
3252
|
-
}
|
|
3253
|
-
if (text === "/clone") {
|
|
3254
|
-
this.editor.setText("");
|
|
3255
|
-
await this.handleCloneCommand();
|
|
3256
|
-
return;
|
|
3257
|
-
}
|
|
3258
|
-
if (text === "/tree") {
|
|
3259
|
-
this.showTreeSelector();
|
|
3260
|
-
this.editor.setText("");
|
|
3261
|
-
return;
|
|
3262
|
-
}
|
|
3263
|
-
if (text === "/trust") {
|
|
3264
|
-
this.showTrustSelector();
|
|
3265
|
-
this.editor.setText("");
|
|
3266
|
-
return;
|
|
3267
|
-
}
|
|
3268
|
-
if (text === "/login" || text.startsWith("/login ")) {
|
|
3269
|
-
const providerRef = text.startsWith("/login ") ? text.slice(7).trim() : undefined;
|
|
3270
|
-
this.editor.setText("");
|
|
3271
|
-
await this.handleLoginCommand(providerRef);
|
|
3272
|
-
return;
|
|
3273
|
-
}
|
|
3274
|
-
if (text === "/logout") {
|
|
3275
|
-
this.showOAuthSelector("logout");
|
|
3276
|
-
this.editor.setText("");
|
|
3277
|
-
return;
|
|
3278
|
-
}
|
|
3279
|
-
if (text === "/new") {
|
|
3280
|
-
this.editor.setText("");
|
|
3281
|
-
await this.handleClearCommand();
|
|
3282
|
-
return;
|
|
3283
|
-
}
|
|
3284
|
-
if (text === "/compact" || text.startsWith("/compact ")) {
|
|
3285
|
-
const customInstructions = text.startsWith("/compact ") ? text.slice(9).trim() : undefined;
|
|
3286
|
-
this.editor.setText("");
|
|
3287
|
-
await this.handleCompactCommand(customInstructions);
|
|
3288
|
-
return;
|
|
3289
|
-
}
|
|
3290
|
-
if (text === "/reload") {
|
|
3291
|
-
this.editor.setText("");
|
|
3292
|
-
await this.handleReloadCommand();
|
|
3293
|
-
return;
|
|
3294
|
-
}
|
|
3295
|
-
if (text === "/debug") {
|
|
3296
|
-
this.handleDebugCommand();
|
|
3297
|
-
this.editor.setText("");
|
|
3298
|
-
return;
|
|
3299
|
-
}
|
|
3300
|
-
if (text === "/arminsayshi") {
|
|
3301
|
-
this.handleArminSaysHi();
|
|
3302
|
-
this.editor.setText("");
|
|
3303
|
-
return;
|
|
3304
|
-
}
|
|
3305
|
-
if (text === "/dementedelves") {
|
|
3306
|
-
this.handleDementedDelves();
|
|
3307
|
-
this.editor.setText("");
|
|
3308
|
-
return;
|
|
3309
|
-
}
|
|
3310
|
-
if (text === "/resume") {
|
|
3311
|
-
this.showSessionSelector();
|
|
3312
|
-
this.editor.setText("");
|
|
3313
|
-
return;
|
|
3314
|
-
}
|
|
3315
|
-
if (text === "/quit" || text === "/exit") {
|
|
3316
|
-
this.editor.setText("");
|
|
3317
|
-
await this.shutdown();
|
|
3318
|
-
return;
|
|
3319
|
-
}
|
|
3320
|
-
if (this.isExtensionCommand(text)) {
|
|
3321
|
-
this.editor.addToHistory?.(text);
|
|
3322
|
-
this.editor.setText("");
|
|
3323
|
-
const pendingEchoId = this.optimisticUserEchoes.begin(text);
|
|
3324
|
-
try {
|
|
3325
|
-
await this.session.prompt(text, this.optimisticUserEchoes.promptOptions(pendingEchoId));
|
|
3197
|
+
try {
|
|
3198
|
+
// Capture-then-clear BEFORE any branch: handleFollowUp's non-streaming
|
|
3199
|
+
// path pre-resolves images and hands off here, but slash / extension /
|
|
3200
|
+
// bash submissions return before the consuming branches below. Clearing
|
|
3201
|
+
// only after use would leak a stale array into a later ordinary
|
|
3202
|
+
// submission whose text never references it.
|
|
3203
|
+
const preResolvedImages = this.preResolvedSubmissionImages;
|
|
3204
|
+
this.preResolvedSubmissionImages = undefined;
|
|
3205
|
+
this.hideShortcutOverlay();
|
|
3206
|
+
this.lastEditorText = "";
|
|
3207
|
+
text = text.trim();
|
|
3208
|
+
if (!text)
|
|
3209
|
+
return;
|
|
3210
|
+
// Handle commands
|
|
3211
|
+
if (text === "/settings") {
|
|
3212
|
+
await this.showSettingsSelector();
|
|
3213
|
+
this.editor.setText("");
|
|
3214
|
+
return;
|
|
3326
3215
|
}
|
|
3327
|
-
|
|
3328
|
-
this.
|
|
3329
|
-
|
|
3216
|
+
if (text === "/favorite-models") {
|
|
3217
|
+
this.editor.setText("");
|
|
3218
|
+
await this.showFavoriteModelsSelector();
|
|
3219
|
+
return;
|
|
3330
3220
|
}
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
this.
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3221
|
+
if (text === "/scoped-models") {
|
|
3222
|
+
this.editor.setText("");
|
|
3223
|
+
this.showScopedModelsSelector();
|
|
3224
|
+
return;
|
|
3225
|
+
}
|
|
3226
|
+
if (text === "/model" || text.startsWith("/model ")) {
|
|
3227
|
+
const searchTerm = text.startsWith("/model ") ? text.slice(7).trim() : undefined;
|
|
3228
|
+
this.editor.setText("");
|
|
3229
|
+
await this.handleModelCommand(searchTerm);
|
|
3230
|
+
return;
|
|
3231
|
+
}
|
|
3232
|
+
if (text === "/export" || text.startsWith("/export ")) {
|
|
3233
|
+
await this.handleExportCommand(text);
|
|
3234
|
+
this.editor.setText("");
|
|
3235
|
+
return;
|
|
3236
|
+
}
|
|
3237
|
+
if (text === "/import" || text.startsWith("/import ")) {
|
|
3238
|
+
await this.handleImportCommand(text);
|
|
3239
|
+
this.editor.setText("");
|
|
3240
|
+
return;
|
|
3241
|
+
}
|
|
3242
|
+
if (text === "/share") {
|
|
3243
|
+
await this.handleShareCommand();
|
|
3244
|
+
this.editor.setText("");
|
|
3245
|
+
return;
|
|
3246
|
+
}
|
|
3247
|
+
if (text === "/copy") {
|
|
3248
|
+
await this.handleCopyCommand();
|
|
3249
|
+
this.editor.setText("");
|
|
3250
|
+
return;
|
|
3251
|
+
}
|
|
3252
|
+
if (text === "/name" || text.startsWith("/name ")) {
|
|
3253
|
+
await this.handleNameCommand(text);
|
|
3254
|
+
this.editor.setText("");
|
|
3255
|
+
return;
|
|
3256
|
+
}
|
|
3257
|
+
if (text === "/session") {
|
|
3258
|
+
await this.handleSessionCommand();
|
|
3259
|
+
this.editor.setText("");
|
|
3260
|
+
return;
|
|
3261
|
+
}
|
|
3262
|
+
if (text === "/changelog") {
|
|
3263
|
+
this.handleChangelogCommand();
|
|
3264
|
+
this.editor.setText("");
|
|
3265
|
+
return;
|
|
3266
|
+
}
|
|
3267
|
+
if (text === "/keybindings") {
|
|
3268
|
+
this.editor.setText("");
|
|
3269
|
+
await this.handleKeybindingsCommand();
|
|
3270
|
+
return;
|
|
3271
|
+
}
|
|
3272
|
+
if (text === "/hotkeys") {
|
|
3273
|
+
this.handleHotkeysCommand();
|
|
3274
|
+
this.editor.setText("");
|
|
3275
|
+
return;
|
|
3276
|
+
}
|
|
3277
|
+
if (text === "/fork") {
|
|
3278
|
+
await this.showUserMessageSelector();
|
|
3279
|
+
this.editor.setText("");
|
|
3280
|
+
return;
|
|
3281
|
+
}
|
|
3282
|
+
if (text === "/clone") {
|
|
3283
|
+
this.editor.setText("");
|
|
3284
|
+
await this.handleCloneCommand();
|
|
3285
|
+
return;
|
|
3286
|
+
}
|
|
3287
|
+
if (text === "/tree") {
|
|
3288
|
+
this.showTreeSelector();
|
|
3289
|
+
this.editor.setText("");
|
|
3290
|
+
return;
|
|
3291
|
+
}
|
|
3292
|
+
if (text === "/trust") {
|
|
3293
|
+
this.showTrustSelector();
|
|
3294
|
+
this.editor.setText("");
|
|
3295
|
+
return;
|
|
3296
|
+
}
|
|
3297
|
+
if (text === "/login" || text.startsWith("/login ")) {
|
|
3298
|
+
const providerRef = text.startsWith("/login ") ? text.slice(7).trim() : undefined;
|
|
3299
|
+
this.editor.setText("");
|
|
3300
|
+
await this.handleLoginCommand(providerRef);
|
|
3301
|
+
return;
|
|
3302
|
+
}
|
|
3303
|
+
if (text === "/logout") {
|
|
3304
|
+
this.showOAuthSelector("logout");
|
|
3305
|
+
this.editor.setText("");
|
|
3306
|
+
return;
|
|
3307
|
+
}
|
|
3308
|
+
if (text === "/new") {
|
|
3309
|
+
this.editor.setText("");
|
|
3310
|
+
await this.handleClearCommand();
|
|
3311
|
+
return;
|
|
3312
|
+
}
|
|
3313
|
+
if (text === "/compact" || text.startsWith("/compact ")) {
|
|
3314
|
+
const customInstructions = text.startsWith("/compact ") ? text.slice(9).trim() : undefined;
|
|
3315
|
+
this.editor.setText("");
|
|
3316
|
+
await this.handleCompactCommand(customInstructions);
|
|
3317
|
+
return;
|
|
3318
|
+
}
|
|
3319
|
+
if (text === "/reload") {
|
|
3320
|
+
this.editor.setText("");
|
|
3321
|
+
await this.handleReloadCommand();
|
|
3322
|
+
return;
|
|
3323
|
+
}
|
|
3324
|
+
if (text === "/debug") {
|
|
3325
|
+
this.handleDebugCommand();
|
|
3326
|
+
this.editor.setText("");
|
|
3327
|
+
return;
|
|
3328
|
+
}
|
|
3329
|
+
if (text === "/arminsayshi") {
|
|
3330
|
+
this.handleArminSaysHi();
|
|
3331
|
+
this.editor.setText("");
|
|
3332
|
+
return;
|
|
3333
|
+
}
|
|
3334
|
+
if (text === "/dementedelves") {
|
|
3335
|
+
this.handleDementedDelves();
|
|
3336
|
+
this.editor.setText("");
|
|
3337
|
+
return;
|
|
3338
|
+
}
|
|
3339
|
+
if (text === "/resume") {
|
|
3340
|
+
this.showSessionSelector();
|
|
3341
|
+
this.editor.setText("");
|
|
3342
|
+
return;
|
|
3343
|
+
}
|
|
3344
|
+
if (text === "/quit" || text === "/exit") {
|
|
3345
|
+
this.editor.setText("");
|
|
3346
|
+
await this.shutdown();
|
|
3347
3347
|
return;
|
|
3348
3348
|
}
|
|
3349
|
-
}
|
|
3350
|
-
// Queue non-command input during compaction.
|
|
3351
|
-
// Extension commands short-circuit at the isExtensionCommand branch above and
|
|
3352
|
-
// dispatch immediately inside AgentSession.prompt(), so the only text that
|
|
3353
|
-
// reaches this compaction branch is non-command user input, which is queued
|
|
3354
|
-
// for delivery after compaction settles.
|
|
3355
|
-
//
|
|
3356
|
-
// Note: the isExtensionCommand re-check below is already unreachable today
|
|
3357
|
-
// (the branch above returns first) and stays harmless after the
|
|
3358
|
-
// immediate-dispatch hoist in prompt().
|
|
3359
|
-
if (this.session.isCompacting) {
|
|
3360
3349
|
if (this.isExtensionCommand(text)) {
|
|
3361
3350
|
this.editor.addToHistory?.(text);
|
|
3362
3351
|
this.editor.setText("");
|
|
@@ -3368,52 +3357,96 @@ export class InteractiveMode {
|
|
|
3368
3357
|
this.optimisticUserEchoes.reject(pendingEchoId);
|
|
3369
3358
|
throw error;
|
|
3370
3359
|
}
|
|
3360
|
+
return;
|
|
3371
3361
|
}
|
|
3372
|
-
|
|
3373
|
-
|
|
3362
|
+
// Handle bash command (! for normal, !! for excluded from context)
|
|
3363
|
+
if (text.startsWith("!")) {
|
|
3364
|
+
const isExcluded = text.startsWith("!!");
|
|
3365
|
+
const command = isExcluded ? text.slice(2).trim() : text.slice(1).trim();
|
|
3366
|
+
if (command) {
|
|
3367
|
+
if (this.session.isBashRunning) {
|
|
3368
|
+
this.showWarning("A bash command is already running. Press Esc to cancel it first.");
|
|
3369
|
+
this.editor.setText(text);
|
|
3370
|
+
return;
|
|
3371
|
+
}
|
|
3372
|
+
this.editor.addToHistory?.(text);
|
|
3373
|
+
await this.handleBashCommand(command, isExcluded);
|
|
3374
|
+
this.isBashMode = false;
|
|
3375
|
+
this.updateEditorBorderColor();
|
|
3376
|
+
return;
|
|
3377
|
+
}
|
|
3374
3378
|
}
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
//
|
|
3384
|
-
|
|
3379
|
+
// Queue non-command input during compaction.
|
|
3380
|
+
// Extension commands short-circuit at the isExtensionCommand branch above and
|
|
3381
|
+
// dispatch immediately inside AgentSession.prompt(), so the only text that
|
|
3382
|
+
// reaches this compaction branch is non-command user input, which is queued
|
|
3383
|
+
// for delivery after compaction settles.
|
|
3384
|
+
//
|
|
3385
|
+
// Note: the isExtensionCommand re-check below is already unreachable today
|
|
3386
|
+
// (the branch above returns first) and stays harmless after the
|
|
3387
|
+
// immediate-dispatch hoist in prompt().
|
|
3388
|
+
if (this.session.isCompacting) {
|
|
3389
|
+
if (this.isExtensionCommand(text)) {
|
|
3390
|
+
this.editor.addToHistory?.(text);
|
|
3391
|
+
this.editor.setText("");
|
|
3392
|
+
const pendingEchoId = this.optimisticUserEchoes.begin(text);
|
|
3393
|
+
try {
|
|
3394
|
+
await this.session.prompt(text, this.optimisticUserEchoes.promptOptions(pendingEchoId));
|
|
3395
|
+
}
|
|
3396
|
+
catch (error) {
|
|
3397
|
+
this.optimisticUserEchoes.reject(pendingEchoId);
|
|
3398
|
+
throw error;
|
|
3399
|
+
}
|
|
3400
|
+
}
|
|
3401
|
+
else {
|
|
3402
|
+
this.queueCompactionSubmission(text, "steer");
|
|
3403
|
+
}
|
|
3404
|
+
return;
|
|
3405
|
+
}
|
|
3406
|
+
// If streaming, use prompt() with steer behavior.
|
|
3407
|
+
// Extension commands are dispatched immediately by AgentSession.prompt()
|
|
3408
|
+
// (short-circuited at the isExtensionCommand branch above); the steer
|
|
3409
|
+
// behavior here applies only to ordinary text, prompt template expansion,
|
|
3410
|
+
// and queueing.
|
|
3411
|
+
if (this.session.isStreaming) {
|
|
3412
|
+
// Resolve BEFORE setText(""): the editor's prune chain fires
|
|
3413
|
+
// onImageMarkersChanged([]) and destroys pendingImages.
|
|
3414
|
+
const images = preResolvedImages ?? this.takeSubmissionImages(text);
|
|
3415
|
+
this.editor.addToHistory?.(text);
|
|
3416
|
+
this.editor.setText("");
|
|
3417
|
+
const pendingEchoId = this.optimisticUserEchoes.begin(text);
|
|
3418
|
+
try {
|
|
3419
|
+
await this.session.prompt(text, {
|
|
3420
|
+
streamingBehavior: "steer",
|
|
3421
|
+
...(images.length > 0 ? { images } : {}),
|
|
3422
|
+
...this.optimisticUserEchoes.promptOptions(pendingEchoId),
|
|
3423
|
+
});
|
|
3424
|
+
}
|
|
3425
|
+
catch (error) {
|
|
3426
|
+
this.optimisticUserEchoes.reject(pendingEchoId);
|
|
3427
|
+
throw error;
|
|
3428
|
+
}
|
|
3429
|
+
this.updatePendingMessagesDisplay();
|
|
3430
|
+
this.ui.requestRender();
|
|
3431
|
+
return;
|
|
3432
|
+
}
|
|
3433
|
+
// Normal message submission
|
|
3434
|
+
// First, move any pending bash components to chat
|
|
3435
|
+
this.flushPendingBashComponents();
|
|
3385
3436
|
const images = preResolvedImages ?? this.takeSubmissionImages(text);
|
|
3386
|
-
this.editor.addToHistory?.(text);
|
|
3387
|
-
this.editor.setText("");
|
|
3388
3437
|
const pendingEchoId = this.optimisticUserEchoes.begin(text);
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
...(images.length > 0 ? { images } : {}),
|
|
3393
|
-
...this.optimisticUserEchoes.promptOptions(pendingEchoId),
|
|
3394
|
-
});
|
|
3438
|
+
const submission = images.length > 0 ? { text, images, pendingEchoId } : { text, pendingEchoId };
|
|
3439
|
+
if (this.onInputCallback) {
|
|
3440
|
+
this.onInputCallback(submission);
|
|
3395
3441
|
}
|
|
3396
|
-
|
|
3397
|
-
this.
|
|
3398
|
-
throw error;
|
|
3442
|
+
else {
|
|
3443
|
+
this.pendingUserInputs.push(submission);
|
|
3399
3444
|
}
|
|
3400
|
-
this.
|
|
3401
|
-
this.ui.requestRender();
|
|
3402
|
-
return;
|
|
3403
|
-
}
|
|
3404
|
-
// Normal message submission
|
|
3405
|
-
// First, move any pending bash components to chat
|
|
3406
|
-
this.flushPendingBashComponents();
|
|
3407
|
-
const images = preResolvedImages ?? this.takeSubmissionImages(text);
|
|
3408
|
-
const pendingEchoId = this.optimisticUserEchoes.begin(text);
|
|
3409
|
-
const submission = images.length > 0 ? { text, images, pendingEchoId } : { text, pendingEchoId };
|
|
3410
|
-
if (this.onInputCallback) {
|
|
3411
|
-
this.onInputCallback(submission);
|
|
3445
|
+
this.editor.addToHistory?.(text);
|
|
3412
3446
|
}
|
|
3413
|
-
|
|
3414
|
-
this.
|
|
3447
|
+
catch (error) {
|
|
3448
|
+
this.showError(error instanceof Error ? error.message : String(error));
|
|
3415
3449
|
}
|
|
3416
|
-
this.editor.addToHistory?.(text);
|
|
3417
3450
|
};
|
|
3418
3451
|
}
|
|
3419
3452
|
subscribeToAgent() {
|
|
@@ -3474,6 +3507,7 @@ export class InteractiveMode {
|
|
|
3474
3507
|
case "thinking_level_changed":
|
|
3475
3508
|
this.footer.invalidate();
|
|
3476
3509
|
this.updateEditorBorderColor();
|
|
3510
|
+
this.showStatus(`Thinking level: ${event.level}`);
|
|
3477
3511
|
break;
|
|
3478
3512
|
case "high_reasoning_warning":
|
|
3479
3513
|
this.showHighReasoningWarning(event);
|
|
@@ -3724,15 +3758,24 @@ export class InteractiveMode {
|
|
|
3724
3758
|
// Keep the structural fallback for focused handler consumers while using
|
|
3725
3759
|
// the session-owned manager on the real TUI path.
|
|
3726
3760
|
const sessionManager = this.session.sessionManager ?? this.sessionManager;
|
|
3727
|
-
|
|
3761
|
+
let entries = sessionManager?.buildContextEntries?.() ?? [];
|
|
3728
3762
|
if (entries[0]?.type !== "compaction") {
|
|
3729
|
-
|
|
3763
|
+
try {
|
|
3764
|
+
sessionManager?.reloadFromDisk?.();
|
|
3765
|
+
entries = sessionManager?.buildContextEntries?.() ?? entries;
|
|
3766
|
+
}
|
|
3767
|
+
catch {
|
|
3768
|
+
// Retain existing entries on reload error
|
|
3769
|
+
}
|
|
3730
3770
|
}
|
|
3731
3771
|
this.chatContainer.clear();
|
|
3732
3772
|
const summaryMessage = createCompactionSummaryMessage(sanitizeTerminalLabel(event.result.summary), event.result.tokensBefore, new Date().toISOString(), event.result.details);
|
|
3733
3773
|
if (typeof this.renderSessionEntries === "function") {
|
|
3734
3774
|
// The latest compaction is prepended for model context; append it below at its chronological position.
|
|
3735
|
-
|
|
3775
|
+
const entriesToRender = entries[0]?.type === "compaction"
|
|
3776
|
+
? entries.slice(1)
|
|
3777
|
+
: entries.filter((e) => e.type !== "compaction");
|
|
3778
|
+
this.renderSessionEntries(entriesToRender);
|
|
3736
3779
|
this.addMessageToChat(summaryMessage);
|
|
3737
3780
|
if (event.result.usage) {
|
|
3738
3781
|
this.addCompactionCostNotice({
|
|
@@ -4032,8 +4075,12 @@ export class InteractiveMode {
|
|
|
4032
4075
|
this.ui.requestRender();
|
|
4033
4076
|
const removePending = () => {
|
|
4034
4077
|
const componentIndex = this.chatContainer.children.indexOf(component);
|
|
4035
|
-
|
|
4036
|
-
|
|
4078
|
+
if (componentIndex === -1) {
|
|
4079
|
+
return this.chatContainer.children.length;
|
|
4080
|
+
}
|
|
4081
|
+
const spacerIndex = spacer ? this.chatContainer.children.indexOf(spacer) : -1;
|
|
4082
|
+
const insertionIndex = spacerIndex >= 0 ? spacerIndex : componentIndex;
|
|
4083
|
+
if (spacerIndex >= 0 && spacer)
|
|
4037
4084
|
this.chatContainer.removeChild(spacer);
|
|
4038
4085
|
this.chatContainer.removeChild(component);
|
|
4039
4086
|
return insertionIndex;
|
|
@@ -4423,6 +4470,12 @@ export class InteractiveMode {
|
|
|
4423
4470
|
};
|
|
4424
4471
|
}
|
|
4425
4472
|
rebuildChatFromMessages() {
|
|
4473
|
+
try {
|
|
4474
|
+
this.sessionManager?.reloadFromDisk?.();
|
|
4475
|
+
}
|
|
4476
|
+
catch {
|
|
4477
|
+
// Keep in-memory entries if file reload is unavailable
|
|
4478
|
+
}
|
|
4426
4479
|
this.chatContainer.clear();
|
|
4427
4480
|
this.renderSessionEntries(this.sessionManager.buildContextEntries());
|
|
4428
4481
|
}
|
|
@@ -4479,8 +4532,17 @@ export class InteractiveMode {
|
|
|
4479
4532
|
}
|
|
4480
4533
|
process.exit(0);
|
|
4481
4534
|
}
|
|
4482
|
-
emergencyTerminalExit() {
|
|
4535
|
+
emergencyTerminalExit(crash) {
|
|
4483
4536
|
this.isShuttingDown = true;
|
|
4537
|
+
// This exit is silent by design (the terminal is gone, so a banner would go
|
|
4538
|
+
// nowhere), which makes the debug log the ONLY surface that can record this
|
|
4539
|
+
// crash class — exactly the EIO case that left the 2026-08-26 diagnosis with no
|
|
4540
|
+
// evidence. Write before the cleanup below, which is unguarded and could throw.
|
|
4541
|
+
// A logging failure must never alter the exit path.
|
|
4542
|
+
try {
|
|
4543
|
+
appendUncaughtCrashLog(crash.origin, crash.error);
|
|
4544
|
+
}
|
|
4545
|
+
catch { }
|
|
4484
4546
|
this.unregisterSignalHandlers();
|
|
4485
4547
|
killTrackedDetachedChildren();
|
|
4486
4548
|
// The terminal is gone. Do not run normal shutdown because TUI and
|
|
@@ -4502,6 +4564,13 @@ export class InteractiveMode {
|
|
|
4502
4564
|
if (this.isShuttingDown) {
|
|
4503
4565
|
process.exit(1);
|
|
4504
4566
|
}
|
|
4567
|
+
if (isDeadTerminalError(error)) {
|
|
4568
|
+
// The terminal died under the session (e.g. an stdin read EIO after
|
|
4569
|
+
// the controlling terminal vanished or this pgrp lost the tty
|
|
4570
|
+
// foreground). Same handling as terminal write errors: exit silently
|
|
4571
|
+
// instead of printing a crash banner to a terminal that is gone.
|
|
4572
|
+
this.emergencyTerminalExit({ origin: `dead-terminal ${origin}`, error });
|
|
4573
|
+
}
|
|
4505
4574
|
if (isRecoverableInspectorVmImportError(error, origin)) {
|
|
4506
4575
|
this.showWarning(INSPECTOR_VM_IMPORT_WARNING);
|
|
4507
4576
|
return;
|
|
@@ -4519,7 +4588,18 @@ export class InteractiveMode {
|
|
|
4519
4588
|
this.ui.stop();
|
|
4520
4589
|
}
|
|
4521
4590
|
catch { }
|
|
4591
|
+
// Record the crash before the terminal handoff: the banner below only reaches
|
|
4592
|
+
// terminal scrollback, which is gone when the terminal is closed or is itself
|
|
4593
|
+
// the thing that failed. A logging failure must never alter the crash path.
|
|
4594
|
+
try {
|
|
4595
|
+
appendUncaughtCrashLog(origin, error);
|
|
4596
|
+
}
|
|
4597
|
+
catch { }
|
|
4522
4598
|
restoreInteractiveStderr();
|
|
4599
|
+
const storageMessage = storageWriteCrashMessage(error);
|
|
4600
|
+
if (storageMessage !== undefined) {
|
|
4601
|
+
console.error(storageMessage);
|
|
4602
|
+
}
|
|
4523
4603
|
console.error(`${APP_NAME} exiting due to uncaughtException:`);
|
|
4524
4604
|
console.error(error);
|
|
4525
4605
|
process.exit(1);
|
|
@@ -4552,7 +4632,7 @@ export class InteractiveMode {
|
|
|
4552
4632
|
}
|
|
4553
4633
|
const terminalErrorHandler = (error) => {
|
|
4554
4634
|
if (isDeadTerminalError(error)) {
|
|
4555
|
-
this.emergencyTerminalExit();
|
|
4635
|
+
this.emergencyTerminalExit({ origin: "dead-terminal stdio error", error });
|
|
4556
4636
|
}
|
|
4557
4637
|
throw error;
|
|
4558
4638
|
};
|
|
@@ -4700,16 +4780,15 @@ export class InteractiveMode {
|
|
|
4700
4780
|
}
|
|
4701
4781
|
this.ui.requestRender();
|
|
4702
4782
|
}
|
|
4703
|
-
cycleThinkingLevel() {
|
|
4704
|
-
|
|
4783
|
+
async cycleThinkingLevel() {
|
|
4784
|
+
// The shared-host proxy answers this over RPC. The level itself is rendered
|
|
4785
|
+
// from the thinking_level_changed event (single path for local and remote,
|
|
4786
|
+
// and for changes made by OTHER attached clients); the awaited value only
|
|
4787
|
+
// distinguishes "model does not support thinking".
|
|
4788
|
+
const newLevel = await this.session.cycleThinkingLevel();
|
|
4705
4789
|
if (newLevel === undefined) {
|
|
4706
4790
|
this.showStatus("Current model does not support thinking");
|
|
4707
4791
|
}
|
|
4708
|
-
else {
|
|
4709
|
-
this.footer.invalidate();
|
|
4710
|
-
this.updateEditorBorderColor();
|
|
4711
|
-
this.showStatus(`Thinking level: ${newLevel}`);
|
|
4712
|
-
}
|
|
4713
4792
|
}
|
|
4714
4793
|
async cycleModel(direction) {
|
|
4715
4794
|
try {
|
|
@@ -5191,7 +5270,9 @@ export class InteractiveMode {
|
|
|
5191
5270
|
this.ui.setFocus(created.focus);
|
|
5192
5271
|
this.ui.requestRender();
|
|
5193
5272
|
}
|
|
5194
|
-
showSettingsSelector() {
|
|
5273
|
+
async showSettingsSelector() {
|
|
5274
|
+
// Awaited at the boundary: the shared-host proxy answers this over RPC.
|
|
5275
|
+
const availableThinkingLevels = await this.session.getAvailableThinkingLevels();
|
|
5195
5276
|
this.showSelector((done) => {
|
|
5196
5277
|
let selector;
|
|
5197
5278
|
selector = new SettingsSelectorComponent({
|
|
@@ -5206,7 +5287,7 @@ export class InteractiveMode {
|
|
|
5206
5287
|
transport: this.settingsManager.getTransport(),
|
|
5207
5288
|
httpIdleTimeoutMs: this.settingsManager.getHttpIdleTimeoutMs(),
|
|
5208
5289
|
thinkingLevel: this.session.thinkingLevel,
|
|
5209
|
-
availableThinkingLevels
|
|
5290
|
+
availableThinkingLevels,
|
|
5210
5291
|
currentTheme: this.themeController.getThemeSelection() || "dark",
|
|
5211
5292
|
terminalTheme: this.themeController.getTerminalTheme(),
|
|
5212
5293
|
availableThemes: getAvailableThemes(),
|
|
@@ -5794,8 +5875,9 @@ export class InteractiveMode {
|
|
|
5794
5875
|
};
|
|
5795
5876
|
});
|
|
5796
5877
|
}
|
|
5797
|
-
showUserMessageSelector() {
|
|
5798
|
-
|
|
5878
|
+
async showUserMessageSelector() {
|
|
5879
|
+
// Awaited at the boundary: the shared-host proxy answers this over RPC.
|
|
5880
|
+
const userMessages = await this.session.getUserMessagesForForking();
|
|
5799
5881
|
if (userMessages.length === 0) {
|
|
5800
5882
|
this.showStatus("No messages to fork from");
|
|
5801
5883
|
return;
|
|
@@ -6574,7 +6656,7 @@ export class InteractiveMode {
|
|
|
6574
6656
|
const outputPath = this.getPathCommandArgument(text, "/export");
|
|
6575
6657
|
try {
|
|
6576
6658
|
if (outputPath?.endsWith(".jsonl")) {
|
|
6577
|
-
const filePath = this.session.exportToJsonl(outputPath);
|
|
6659
|
+
const filePath = await this.session.exportToJsonl(outputPath);
|
|
6578
6660
|
this.showStatus(`Session exported to: ${filePath}`);
|
|
6579
6661
|
}
|
|
6580
6662
|
else {
|
|
@@ -6763,7 +6845,7 @@ export class InteractiveMode {
|
|
|
6763
6845
|
this.showError(error instanceof Error ? error.message : String(error));
|
|
6764
6846
|
}
|
|
6765
6847
|
}
|
|
6766
|
-
handleNameCommand(text) {
|
|
6848
|
+
async handleNameCommand(text) {
|
|
6767
6849
|
const name = text.replace(/^\/name\s*/, "").trim();
|
|
6768
6850
|
if (!name) {
|
|
6769
6851
|
const currentName = this.sessionManager.getSessionName();
|
|
@@ -6777,8 +6859,8 @@ export class InteractiveMode {
|
|
|
6777
6859
|
this.ui.requestRender();
|
|
6778
6860
|
return;
|
|
6779
6861
|
}
|
|
6780
|
-
this.session.setSessionName(name);
|
|
6781
|
-
const sessionName = this.
|
|
6862
|
+
await this.session.setSessionName(name);
|
|
6863
|
+
const sessionName = this.session.sessionName;
|
|
6782
6864
|
if (sessionName !== name) {
|
|
6783
6865
|
this.showWarning(`Session name was normalized from ${JSON.stringify(name)} to ${JSON.stringify(sessionName)}`);
|
|
6784
6866
|
}
|
|
@@ -6786,9 +6868,10 @@ export class InteractiveMode {
|
|
|
6786
6868
|
this.chatContainer.addChild(new Text(theme.fg("dim", `Session name set: ${sessionName ?? name}`), 1, 0));
|
|
6787
6869
|
this.ui.requestRender();
|
|
6788
6870
|
}
|
|
6789
|
-
handleSessionCommand() {
|
|
6790
|
-
|
|
6791
|
-
const
|
|
6871
|
+
async handleSessionCommand() {
|
|
6872
|
+
// Awaited at the boundary: the shared-host proxy answers this over RPC.
|
|
6873
|
+
const stats = await this.session.getSessionStats();
|
|
6874
|
+
const sessionName = this.session.sessionName;
|
|
6792
6875
|
const entries = this.sessionManager.getEntries();
|
|
6793
6876
|
const cacheWaste = computeCacheWaste(entries, this.session.modelRuntime);
|
|
6794
6877
|
// Cost/token totals per provider/model actually used (e.g. OpenRouter `auto`
|
|
@@ -7070,7 +7153,7 @@ export class InteractiveMode {
|
|
|
7070
7153
|
}
|
|
7071
7154
|
this.bashComponent.setComplete(result.exitCode, result.cancelled, result.truncated ? { truncated: true, content: result.output } : undefined, result.fullOutputPath);
|
|
7072
7155
|
// Record the result in session
|
|
7073
|
-
this.session.recordBashResult(command, result, { excludeFromContext });
|
|
7156
|
+
void this.session.recordBashResult(command, result, { excludeFromContext });
|
|
7074
7157
|
this.bashComponent = undefined;
|
|
7075
7158
|
this.ui.requestRender();
|
|
7076
7159
|
return;
|