@code-yeongyu/senpi 2026.9.7 → 2026.9.8
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 +79 -0
- package/dist/core/agent-session.d.ts +40 -3
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +159 -40
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +2 -1
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/dynamic-prompt/working-task.js +1 -1
- package/dist/core/dynamic-prompt/working-task.js.map +1 -1
- package/dist/core/extensions/builtin/cache-keepalive/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/cache-keepalive/index.js +4 -21
- package/dist/core/extensions/builtin/cache-keepalive/index.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.d.ts +2 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.js +10 -25
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js +36 -19
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-commit-boundary.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-commit-boundary.js +21 -10
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-commit-boundary.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.d.ts +4 -17
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.js +23 -33
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js +1 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.js +5 -3
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.js +8 -3
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/tools.d.ts +6 -5
- package/dist/core/extensions/builtin/claude-sdk-oauth/tools.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/tools.js +6 -5
- package/dist/core/extensions/builtin/claude-sdk-oauth/tools.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/circuit-breaker.d.ts +8 -0
- package/dist/core/extensions/builtin/compaction/circuit-breaker.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/circuit-breaker.js +8 -0
- package/dist/core/extensions/builtin/compaction/circuit-breaker.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +8 -0
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +125 -20
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/fallback-failed-turn-normalization.d.ts +18 -0
- package/dist/core/extensions/builtin/compaction/fallback-failed-turn-normalization.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/fallback-failed-turn-normalization.js +20 -0
- package/dist/core/extensions/builtin/compaction/fallback-failed-turn-normalization.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.js +54 -11
- package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/lane-policy.d.ts +3 -0
- package/dist/core/extensions/builtin/compaction/lane-policy.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/lane-policy.js +47 -23
- package/dist/core/extensions/builtin/compaction/lane-policy.js.map +1 -1
- package/dist/core/extensions/builtin/goal/agent-end-continuation.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/agent-end-continuation.js +11 -0
- package/dist/core/extensions/builtin/goal/agent-end-continuation.js.map +1 -1
- package/dist/core/extensions/builtin/goal/cache-warm-renderer.js +6 -4
- package/dist/core/extensions/builtin/goal/cache-warm-renderer.js.map +1 -1
- package/dist/core/extensions/builtin/goal/cache-warm.d.ts +25 -1
- package/dist/core/extensions/builtin/goal/cache-warm.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/cache-warm.js +29 -10
- package/dist/core/extensions/builtin/goal/cache-warm.js.map +1 -1
- package/dist/core/extensions/builtin/goal/continuation.d.ts +3 -1
- package/dist/core/extensions/builtin/goal/continuation.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/continuation.js +17 -2
- package/dist/core/extensions/builtin/goal/continuation.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 +1 -0
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -1
- package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts +1 -1
- package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/monitor-continuation.js +8 -3
- package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
- package/dist/core/extensions/builtin/gpt-account.d.ts +5 -1
- package/dist/core/extensions/builtin/gpt-account.d.ts.map +1 -1
- package/dist/core/extensions/builtin/gpt-account.js +9 -26
- package/dist/core/extensions/builtin/gpt-account.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/plugin-manifest.js +2 -2
- package/dist/core/extensions/builtin/hooks/plugin-manifest.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/safety.js +2 -2
- package/dist/core/extensions/builtin/hooks/safety.js.map +1 -1
- package/dist/core/extensions/builtin/monitor-state-event.d.ts +18 -0
- package/dist/core/extensions/builtin/monitor-state-event.d.ts.map +1 -1
- package/dist/core/extensions/builtin/monitor-state-event.js +23 -0
- package/dist/core/extensions/builtin/monitor-state-event.js.map +1 -1
- package/dist/core/extensions/builtin/oauth-login-interaction.d.ts +24 -0
- package/dist/core/extensions/builtin/oauth-login-interaction.d.ts.map +1 -0
- package/dist/core/extensions/builtin/oauth-login-interaction.js +77 -0
- package/dist/core/extensions/builtin/oauth-login-interaction.js.map +1 -0
- package/dist/core/extensions/builtin/permission-system/external-dir.d.ts.map +1 -1
- package/dist/core/extensions/builtin/permission-system/external-dir.js +5 -51
- package/dist/core/extensions/builtin/permission-system/external-dir.js.map +1 -1
- package/dist/core/extensions/builtin/permission-system/parsers.d.ts.map +1 -1
- package/dist/core/extensions/builtin/permission-system/parsers.js +5 -7
- package/dist/core/extensions/builtin/permission-system/parsers.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/execution-tooling.d.ts +14 -7
- package/dist/core/extensions/builtin/prompt-preset/execution-tooling.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/execution-tooling.js +34 -13
- package/dist/core/extensions/builtin/prompt-preset/execution-tooling.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts +6 -10
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +14 -9
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.d.ts +15 -15
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.js +49 -21
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js.map +1 -1
- package/dist/core/extensions/builtin/service-tier.d.ts +2 -0
- package/dist/core/extensions/builtin/service-tier.d.ts.map +1 -1
- package/dist/core/extensions/builtin/service-tier.js +17 -1
- package/dist/core/extensions/builtin/service-tier.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/durable-command.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/durable-command.js +3 -0
- package/dist/core/extensions/builtin/terminal/durable-command.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/durable-file.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/durable-file.js +2 -0
- package/dist/core/extensions/builtin/terminal/durable-file.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/extension.js +14 -2
- package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-notify.js +27 -5
- package/dist/core/extensions/builtin/terminal/monitor-notify.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts +17 -0
- package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-registry.js +76 -14
- package/dist/core/extensions/builtin/terminal/monitor-registry.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/notify.d.ts +2 -0
- package/dist/core/extensions/builtin/terminal/notify.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/notify.js +6 -1
- package/dist/core/extensions/builtin/terminal/notify.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/session-bundle.d.ts +3 -1
- package/dist/core/extensions/builtin/terminal/session-bundle.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/session-bundle.js +13 -0
- package/dist/core/extensions/builtin/terminal/session-bundle.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/shared.d.ts +13 -2
- package/dist/core/extensions/builtin/terminal/shared.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/shared.js +15 -2
- package/dist/core/extensions/builtin/terminal/shared.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/monitor.js +8 -1
- package/dist/core/extensions/builtin/terminal/tools/monitor.js.map +1 -1
- package/dist/core/extensions/builtin/tool-search/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/tool-search/index.js +1 -0
- package/dist/core/extensions/builtin/tool-search/index.js.map +1 -1
- package/dist/core/extensions/builtin/tool-search/service.d.ts +4 -0
- package/dist/core/extensions/builtin/tool-search/service.d.ts.map +1 -1
- package/dist/core/extensions/builtin/tool-search/service.js +11 -0
- package/dist/core/extensions/builtin/tool-search/service.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +1 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +8 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +9 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/high-reasoning-warning.d.ts.map +1 -1
- package/dist/core/high-reasoning-warning.js +4 -6
- package/dist/core/high-reasoning-warning.js.map +1 -1
- package/dist/core/sdk.d.ts +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +25 -6
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/settings-manager.js +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/settings-shapes.js.map +1 -1
- package/dist/core/tools/bounded-realpath.d.ts +28 -0
- package/dist/core/tools/bounded-realpath.d.ts.map +1 -0
- package/dist/core/tools/bounded-realpath.js +53 -0
- package/dist/core/tools/bounded-realpath.js.map +1 -0
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js +15 -13
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/filesystem-policy.d.ts +7 -0
- package/dist/core/tools/filesystem-policy.d.ts.map +1 -1
- package/dist/core/tools/filesystem-policy.js +25 -15
- package/dist/core/tools/filesystem-policy.js.map +1 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +13 -2
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +1 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/memory-tips.d.ts.map +1 -1
- package/dist/modes/interactive/tips/catalog/memory-tips.js +6 -0
- package/dist/modes/interactive/tips/catalog/memory-tips.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/subagent-tips.d.ts.map +1 -1
- package/dist/modes/interactive/tips/catalog/subagent-tips.js +6 -0
- package/dist/modes/interactive/tips/catalog/subagent-tips.js.map +1 -1
- package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -1
- package/dist/modes/rpc/host-lifecycle.js +31 -5
- package/dist/modes/rpc/host-lifecycle.js.map +1 -1
- package/dist/modes/rpc/host-watchdog.d.ts +11 -0
- package/dist/modes/rpc/host-watchdog.d.ts.map +1 -1
- package/dist/modes/rpc/host-watchdog.js +16 -2
- package/dist/modes/rpc/host-watchdog.js.map +1 -1
- package/dist/modes/rpc/multi-session-host.d.ts.map +1 -1
- package/dist/modes/rpc/multi-session-host.js +54 -16
- package/dist/modes/rpc/multi-session-host.js.map +1 -1
- package/dist/modes/rpc/socket-ownership.d.ts +46 -0
- package/dist/modes/rpc/socket-ownership.d.ts.map +1 -0
- package/dist/modes/rpc/socket-ownership.js +178 -0
- package/dist/modes/rpc/socket-ownership.js.map +1 -0
- package/dist/utils/fs-watch.d.ts +17 -0
- package/dist/utils/fs-watch.d.ts.map +1 -1
- package/dist/utils/fs-watch.js +38 -10
- package/dist/utils/fs-watch.js.map +1 -1
- package/dist/utils/paths.d.ts +33 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +109 -3
- package/dist/utils/paths.js.map +1 -1
- package/docs/development.md +3 -2
- package/docs/providers.md +5 -1
- package/docs/settings.md +1 -0
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +31 -0
- package/node_modules/@code-yeongyu/senpi-codemode/README.md +14 -1
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/protocol.ts +1 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/extension/runtime-factory.ts +3 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/extension/session-manager.ts +7 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/AGENTS.md +7 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/jl/kernel.ts +4 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-contract.ts +3 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-core.js +29 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-indirect-eval.js +10 -6
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-shell-capture.d.ts +16 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-shell-capture.js +44 -8
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-startup.ts +1 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel-contract.ts +3 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/transport.ts +9 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/rb/kernel.ts +4 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/session-env.ts +56 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-contract.ts +3 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-kernel.ts +9 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/output/output-meta.ts +26 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +17 -24
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/image.ts +12 -3
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +2 -2
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts +7 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js +19 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.js +24 -16
- package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/index.js +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/index.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-messages.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +47 -178
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.d.ts +3 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.js +260 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic-callback-listener.d.ts +40 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic-callback-listener.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic-callback-listener.js +138 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic-callback-listener.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.d.ts +2 -3
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.js +42 -139
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/authorization-input.d.ts +6 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/authorization-input.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/authorization-input.js +29 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/authorization-input.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/error-details.d.ts +3 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/error-details.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/error-details.js +20 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/error-details.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.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/azure-openai-responses.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/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.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/vercel-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/recovery-stream-terminal.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/recovery-stream-terminal.js +16 -1
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/recovery-stream-terminal.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +7 -0
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts +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 +14 -3
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.d.ts +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.js +16 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- 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/package.json +1 -1
- package/package.json +7 -7
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { createExtensionLoginInteraction, LOGIN_CANCELLED_MESSAGE } from "../oauth-login-interaction.js";
|
|
1
2
|
import { emitProviderAccountsChanged } from "./account-events.js";
|
|
2
3
|
import { CLAUDE_SDK_OAUTH_PROVIDER_ID, pinProviderAccount, removeProviderAccount } from "./account-management.js";
|
|
3
4
|
import { emptyCredential, listAccounts } from "./accounts.js";
|
|
4
5
|
import { selectAccount } from "./affinity.js";
|
|
5
6
|
import { loadClaudeSdkOauthProviderSettingsFromDisk } from "./settings.js";
|
|
6
7
|
const cliPinsBySession = new Map();
|
|
8
|
+
const CLAUDE_SDK_OAUTH_PROVIDER_LABEL = "Claude SDK OAuth";
|
|
7
9
|
function asCredential(value) {
|
|
8
10
|
return value?.type === "oauth" ? value : undefined;
|
|
9
11
|
}
|
|
@@ -28,18 +30,6 @@ function accountError(ctx, name) {
|
|
|
28
30
|
function parseArgs(rawArgs) {
|
|
29
31
|
return rawArgs.trim().split(/\s+/).filter(Boolean);
|
|
30
32
|
}
|
|
31
|
-
function authEventMessage(event) {
|
|
32
|
-
if (event === null || typeof event !== "object")
|
|
33
|
-
return "Claude SDK OAuth authentication update.";
|
|
34
|
-
const value = event;
|
|
35
|
-
if (value.type === "auth_url" && typeof value.url === "string") {
|
|
36
|
-
return `Open this URL to authorize Claude SDK OAuth:\n${value.url}`;
|
|
37
|
-
}
|
|
38
|
-
if (value.type === "device_code" && typeof value.verificationUri === "string") {
|
|
39
|
-
return `Open this URL to authorize Claude SDK OAuth:\n${value.verificationUri}`;
|
|
40
|
-
}
|
|
41
|
-
return typeof value.message === "string" ? value.message : "Claude SDK OAuth authentication update.";
|
|
42
|
-
}
|
|
43
33
|
export function getSessionClaudeAccountPin(sessionId) {
|
|
44
34
|
return sessionId === undefined ? undefined : cliPinsBySession.get(sessionId);
|
|
45
35
|
}
|
|
@@ -76,7 +66,7 @@ export function registerClaudeAccountCommand(pi, deps = {}) {
|
|
|
76
66
|
return;
|
|
77
67
|
}
|
|
78
68
|
if (action === "add") {
|
|
79
|
-
await addAccount(ctx);
|
|
69
|
+
await addAccount(ctx, deps);
|
|
80
70
|
return;
|
|
81
71
|
}
|
|
82
72
|
if (action === "remove") {
|
|
@@ -128,29 +118,24 @@ function showAccounts(ctx, settings, environment) {
|
|
|
128
118
|
lines.push(`Affinity pick: ${affinityPick ?? (affinityError ? `unavailable - ${affinityError}` : "none")}`);
|
|
129
119
|
ctx.ui.notify(lines.join("\n"), "info");
|
|
130
120
|
}
|
|
131
|
-
async function addAccount(ctx) {
|
|
121
|
+
async function addAccount(ctx, deps) {
|
|
132
122
|
if (!ctx.hasUI) {
|
|
133
123
|
ctx.ui.notify("/claude-account add requires an interactive UI.", "error");
|
|
134
124
|
return;
|
|
135
125
|
}
|
|
136
126
|
try {
|
|
137
|
-
await ctx.modelRegistry.modelRuntime.login(CLAUDE_SDK_OAUTH_PROVIDER_ID, "oauth", {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
if (answer === undefined)
|
|
142
|
-
throw new Error("Login cancelled");
|
|
143
|
-
return answer;
|
|
144
|
-
},
|
|
145
|
-
notify: (event) => ctx.ui.notify(authEventMessage(event), "info"),
|
|
146
|
-
});
|
|
127
|
+
await ctx.modelRegistry.modelRuntime.login(CLAUDE_SDK_OAUTH_PROVIDER_ID, "oauth", createExtensionLoginInteraction(ctx, {
|
|
128
|
+
providerLabel: CLAUDE_SDK_OAUTH_PROVIDER_LABEL,
|
|
129
|
+
openBrowser: deps.openBrowser,
|
|
130
|
+
}));
|
|
147
131
|
emitProviderAccountsChanged(CLAUDE_SDK_OAUTH_PROVIDER_ID);
|
|
148
132
|
ctx.ui.notify("Claude SDK OAuth account added.", "info");
|
|
149
133
|
}
|
|
150
134
|
catch (error) {
|
|
151
135
|
const message = error instanceof Error ? error.message : String(error);
|
|
152
|
-
if (message !==
|
|
136
|
+
if (message !== LOGIN_CANCELLED_MESSAGE) {
|
|
153
137
|
ctx.ui.notify(`Failed to add Claude SDK OAuth account: ${message}`, "error");
|
|
138
|
+
}
|
|
154
139
|
}
|
|
155
140
|
}
|
|
156
141
|
async function removeNamedAccount(ctx, name, environment) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-command.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/account-command.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Credential } from \"@earendil-works/pi-ai\";\nimport type { ExtensionAPI, ExtensionCommandContext } from \"../../types.ts\";\nimport { emitProviderAccountsChanged } from \"./account-events.ts\";\nimport { CLAUDE_SDK_OAUTH_PROVIDER_ID, pinProviderAccount, removeProviderAccount } from \"./account-management.ts\";\nimport { type AccountSlot, type ClaudeSdkOauthCredential, emptyCredential, listAccounts } from \"./accounts.ts\";\nimport { selectAccount } from \"./affinity.ts\";\nimport { type ClaudeSdkOauthProviderSettings, loadClaudeSdkOauthProviderSettingsFromDisk } from \"./settings.ts\";\n\nconst cliPinsBySession = new Map<string, string>();\n\ntype CommandEnvironment = (name: string) => string | undefined;\n\nexport interface ClaudeAccountCommandDeps {\n\tloadSettings?: (cwd: string) => ClaudeSdkOauthProviderSettings;\n\tenvironment?: CommandEnvironment;\n}\n\nfunction asCredential(value: Credential | undefined): ClaudeSdkOauthCredential | undefined {\n\treturn value?.type === \"oauth\" ? (value as ClaudeSdkOauthCredential) : undefined;\n}\n\nfunction slotStatus(slot: AccountSlot): string {\n\tif (slot.blockReason === \"auth_error\") return \"blocked until re-login\";\n\tif (slot.blockedUntil !== undefined && slot.blockedUntil > Date.now()) {\n\t\treturn `blocked until ${new Date(slot.blockedUntil).toISOString()}`;\n\t}\n\treturn \"available\";\n}\n\nfunction readAccounts(\n\tctx: ExtensionCommandContext,\n\tenvironment: CommandEnvironment,\n): {\n\tcredential: ClaudeSdkOauthCredential | undefined;\n\taccounts: AccountSlot[];\n} {\n\tconst credential = asCredential(ctx.modelRegistry.authStorage.get(CLAUDE_SDK_OAUTH_PROVIDER_ID));\n\treturn {\n\t\tcredential,\n\t\taccounts: listAccounts(credential ?? emptyCredential(), environment),\n\t};\n}\n\nfunction accountError(ctx: ExtensionCommandContext, name: string): void {\n\tctx.ui.notify(`Claude SDK OAuth account '${name}' does not exist.`, \"error\");\n}\n\nfunction parseArgs(rawArgs: string): string[] {\n\treturn rawArgs.trim().split(/\\s+/).filter(Boolean);\n}\n\nfunction authEventMessage(event: unknown): string {\n\tif (event === null || typeof event !== \"object\") return \"Claude SDK OAuth authentication update.\";\n\tconst value = event as Record<string, unknown>;\n\tif (value.type === \"auth_url\" && typeof value.url === \"string\") {\n\t\treturn `Open this URL to authorize Claude SDK OAuth:\\n${value.url}`;\n\t}\n\tif (value.type === \"device_code\" && typeof value.verificationUri === \"string\") {\n\t\treturn `Open this URL to authorize Claude SDK OAuth:\\n${value.verificationUri}`;\n\t}\n\treturn typeof value.message === \"string\" ? value.message : \"Claude SDK OAuth authentication update.\";\n}\n\nexport function getSessionClaudeAccountPin(sessionId: string | undefined): string | undefined {\n\treturn sessionId === undefined ? undefined : cliPinsBySession.get(sessionId);\n}\n\n/** CLI pins are request-local overrides; settings and stored pins remain fallback choices. */\nexport function resolveClaudeAccountPin(\n\tcliPinnedAccount: string | undefined,\n\tsettingsPinnedAccount: string | undefined,\n\tstoredPinnedAccount: string | undefined,\n): string | undefined {\n\treturn cliPinnedAccount ?? settingsPinnedAccount ?? storedPinnedAccount;\n}\n\nexport function registerClaudeAccountCommand(pi: ExtensionAPI, deps: ClaudeAccountCommandDeps = {}): void {\n\tconst loadSettings = deps.loadSettings ?? loadClaudeSdkOauthProviderSettingsFromDisk;\n\tconst environment = deps.environment ?? ((name: string) => process.env[name]);\n\n\tpi.registerFlag(\"claude-account\", {\n\t\ttype: \"string\",\n\t\tdescription: \"Pin Claude SDK OAuth account for this session.\",\n\t});\n\tpi.on(\"session_start\", (_event, ctx) => {\n\t\tconst flag = pi.getFlag(\"claude-account\");\n\t\tconst sessionId = ctx.sessionManager.getSessionId();\n\t\tif (typeof flag === \"string\" && flag.length > 0) cliPinsBySession.set(sessionId, flag);\n\t\telse cliPinsBySession.delete(sessionId);\n\t});\n\tpi.on(\"session_shutdown\", (_event, ctx) => {\n\t\tcliPinsBySession.delete(ctx.sessionManager.getSessionId());\n\t});\n\tpi.registerCommand(\"claude-account\", {\n\t\tdescription: \"List and manage Claude SDK OAuth accounts.\",\n\t\targumentHint: \"[add | remove <name> | pin <name> | unpin]\",\n\t\thandler: async (rawArgs, ctx) => {\n\t\t\tconst args = parseArgs(rawArgs);\n\t\t\tconst action = args[0] ?? \"list\";\n\t\t\tif (action === \"list\") {\n\t\t\t\tshowAccounts(ctx, loadSettings(ctx.cwd), environment);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (action === \"add\") {\n\t\t\t\tawait addAccount(ctx);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (action === \"remove\") {\n\t\t\t\tawait removeNamedAccount(ctx, args[1], environment);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (action === \"pin\" && args[1] !== \"unpin\") {\n\t\t\t\tawait pinNamedAccount(ctx, args[1], environment);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (action === \"unpin\" || (action === \"pin\" && args[1] === \"unpin\")) {\n\t\t\t\tawait unpinAccount(ctx);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tctx.ui.notify(\"Usage: /claude-account [add | remove <name> | pin <name> | unpin]\", \"error\");\n\t\t},\n\t});\n}\n\nfunction showAccounts(\n\tctx: ExtensionCommandContext,\n\tsettings: ClaudeSdkOauthProviderSettings,\n\tenvironment: CommandEnvironment,\n): void {\n\tconst { credential, accounts } = readAccounts(ctx, environment);\n\tconst cliPin = getSessionClaudeAccountPin(ctx.sessionManager.getSessionId());\n\tconst pinned = resolveClaudeAccountPin(cliPin, settings.pinnedAccount, credential?.pinned);\n\tconst pinSource = cliPin !== undefined ? \"CLI\" : settings.pinnedAccount !== undefined ? \"settings\" : \"stored\";\n\tlet affinityPick: string | undefined;\n\tlet affinityError: string | undefined;\n\tif (accounts.length > 0) {\n\t\ttry {\n\t\t\taffinityPick = selectAccount(accounts, {\n\t\t\t\tsessionId: ctx.sessionManager.getSessionId(),\n\t\t\t\tpinnedAccount: pinned,\n\t\t\t}).name;\n\t\t} catch (error) {\n\t\t\taffinityError = error instanceof Error ? error.message : String(error);\n\t\t}\n\t}\n\tconst lines = [\"Claude SDK OAuth accounts:\"];\n\tif (accounts.length === 0) lines.push(\" (none)\");\n\tfor (const account of accounts) {\n\t\tconst states = [account.name, account.source, slotStatus(account)];\n\t\tif (account.name === pinned) states.push(\"pinned\");\n\t\tif (account.name === affinityPick) states.push(\"affinity pick\");\n\t\tlines.push(` ${states.join(\" | \")}`);\n\t}\n\tlines.push(`Pinned account: ${pinned === undefined ? \"none\" : `${pinned} (${pinSource.toLowerCase()})`}`);\n\tlines.push(`Affinity pick: ${affinityPick ?? (affinityError ? `unavailable - ${affinityError}` : \"none\")}`);\n\tctx.ui.notify(lines.join(\"\\n\"), \"info\");\n}\n\nasync function addAccount(ctx: ExtensionCommandContext): Promise<void> {\n\tif (!ctx.hasUI) {\n\t\tctx.ui.notify(\"/claude-account add requires an interactive UI.\", \"error\");\n\t\treturn;\n\t}\n\ttry {\n\t\tawait ctx.modelRegistry.modelRuntime.login(CLAUDE_SDK_OAUTH_PROVIDER_ID, \"oauth\", {\n\t\t\tsignal: ctx.signal,\n\t\t\tprompt: async (prompt) => {\n\t\t\t\tconst answer = await ctx.ui.input(prompt.message);\n\t\t\t\tif (answer === undefined) throw new Error(\"Login cancelled\");\n\t\t\t\treturn answer;\n\t\t\t},\n\t\t\tnotify: (event) => ctx.ui.notify(authEventMessage(event), \"info\"),\n\t\t});\n\t\temitProviderAccountsChanged(CLAUDE_SDK_OAUTH_PROVIDER_ID);\n\t\tctx.ui.notify(\"Claude SDK OAuth account added.\", \"info\");\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tif (message !== \"Login cancelled\") ctx.ui.notify(`Failed to add Claude SDK OAuth account: ${message}`, \"error\");\n\t}\n}\n\nasync function removeNamedAccount(\n\tctx: ExtensionCommandContext,\n\tname: string | undefined,\n\tenvironment: CommandEnvironment,\n): Promise<void> {\n\tif (!name) {\n\t\tctx.ui.notify(\"Usage: /claude-account remove <name>\", \"error\");\n\t\treturn;\n\t}\n\tconst { accounts } = readAccounts(ctx, environment);\n\tconst target = accounts.find((account) => account.name === name);\n\tif (!target) return accountError(ctx, name);\n\tif (target.source === \"env\") {\n\t\tctx.ui.notify(`Claude SDK OAuth account '${name}' comes from the environment and cannot be removed.`, \"error\");\n\t\treturn;\n\t}\n\ttry {\n\t\tawait removeProviderAccount(ctx.modelRegistry.authStorage, CLAUDE_SDK_OAUTH_PROVIDER_ID, name);\n\t\tctx.ui.notify(`Removed Claude SDK OAuth account: ${name}.`, \"info\");\n\t} catch (error) {\n\t\tctx.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t}\n}\n\nasync function pinNamedAccount(\n\tctx: ExtensionCommandContext,\n\tname: string | undefined,\n\tenvironment: CommandEnvironment,\n): Promise<void> {\n\tif (!name) {\n\t\tctx.ui.notify(\"Usage: /claude-account pin <name>\", \"error\");\n\t\treturn;\n\t}\n\tif (!readAccounts(ctx, environment).accounts.some((account) => account.name === name)) {\n\t\treturn accountError(ctx, name);\n\t}\n\ttry {\n\t\tawait pinProviderAccount(ctx.modelRegistry.authStorage, CLAUDE_SDK_OAUTH_PROVIDER_ID, name);\n\t\tctx.ui.notify(`Pinned Claude SDK OAuth account: ${name}.`, \"info\");\n\t} catch (error) {\n\t\tctx.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t}\n}\n\nasync function unpinAccount(ctx: ExtensionCommandContext): Promise<void> {\n\tconst credential = asCredential(ctx.modelRegistry.authStorage.get(CLAUDE_SDK_OAUTH_PROVIDER_ID));\n\tif (!credential?.pinned) {\n\t\tctx.ui.notify(\"No stored Claude SDK OAuth account pin is set.\", \"info\");\n\t\treturn;\n\t}\n\tawait pinProviderAccount(ctx.modelRegistry.authStorage, CLAUDE_SDK_OAUTH_PROVIDER_ID, null);\n\tctx.ui.notify(\"Unpinned Claude SDK OAuth account.\", \"info\");\n}\n"]}
|
|
1
|
+
{"version":3,"file":"account-command.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/account-command.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Credential } from \"@earendil-works/pi-ai\";\nimport type { ExtensionAPI, ExtensionCommandContext } from \"../../types.ts\";\nimport { createExtensionLoginInteraction, LOGIN_CANCELLED_MESSAGE } from \"../oauth-login-interaction.ts\";\nimport { emitProviderAccountsChanged } from \"./account-events.ts\";\nimport { CLAUDE_SDK_OAUTH_PROVIDER_ID, pinProviderAccount, removeProviderAccount } from \"./account-management.ts\";\nimport { type AccountSlot, type ClaudeSdkOauthCredential, emptyCredential, listAccounts } from \"./accounts.ts\";\nimport { selectAccount } from \"./affinity.ts\";\nimport { type ClaudeSdkOauthProviderSettings, loadClaudeSdkOauthProviderSettingsFromDisk } from \"./settings.ts\";\n\nconst cliPinsBySession = new Map<string, string>();\n\ntype CommandEnvironment = (name: string) => string | undefined;\n\nexport interface ClaudeAccountCommandDeps {\n\tloadSettings?: (cwd: string) => ClaudeSdkOauthProviderSettings;\n\tenvironment?: CommandEnvironment;\n\t/** Browser launcher for the OAuth authorize URL; tests inject a recorder. */\n\topenBrowser?: ((url: string) => void) | undefined;\n}\n\nconst CLAUDE_SDK_OAUTH_PROVIDER_LABEL = \"Claude SDK OAuth\";\n\nfunction asCredential(value: Credential | undefined): ClaudeSdkOauthCredential | undefined {\n\treturn value?.type === \"oauth\" ? (value as ClaudeSdkOauthCredential) : undefined;\n}\n\nfunction slotStatus(slot: AccountSlot): string {\n\tif (slot.blockReason === \"auth_error\") return \"blocked until re-login\";\n\tif (slot.blockedUntil !== undefined && slot.blockedUntil > Date.now()) {\n\t\treturn `blocked until ${new Date(slot.blockedUntil).toISOString()}`;\n\t}\n\treturn \"available\";\n}\n\nfunction readAccounts(\n\tctx: ExtensionCommandContext,\n\tenvironment: CommandEnvironment,\n): {\n\tcredential: ClaudeSdkOauthCredential | undefined;\n\taccounts: AccountSlot[];\n} {\n\tconst credential = asCredential(ctx.modelRegistry.authStorage.get(CLAUDE_SDK_OAUTH_PROVIDER_ID));\n\treturn {\n\t\tcredential,\n\t\taccounts: listAccounts(credential ?? emptyCredential(), environment),\n\t};\n}\n\nfunction accountError(ctx: ExtensionCommandContext, name: string): void {\n\tctx.ui.notify(`Claude SDK OAuth account '${name}' does not exist.`, \"error\");\n}\n\nfunction parseArgs(rawArgs: string): string[] {\n\treturn rawArgs.trim().split(/\\s+/).filter(Boolean);\n}\n\nexport function getSessionClaudeAccountPin(sessionId: string | undefined): string | undefined {\n\treturn sessionId === undefined ? undefined : cliPinsBySession.get(sessionId);\n}\n\n/** CLI pins are request-local overrides; settings and stored pins remain fallback choices. */\nexport function resolveClaudeAccountPin(\n\tcliPinnedAccount: string | undefined,\n\tsettingsPinnedAccount: string | undefined,\n\tstoredPinnedAccount: string | undefined,\n): string | undefined {\n\treturn cliPinnedAccount ?? settingsPinnedAccount ?? storedPinnedAccount;\n}\n\nexport function registerClaudeAccountCommand(pi: ExtensionAPI, deps: ClaudeAccountCommandDeps = {}): void {\n\tconst loadSettings = deps.loadSettings ?? loadClaudeSdkOauthProviderSettingsFromDisk;\n\tconst environment = deps.environment ?? ((name: string) => process.env[name]);\n\n\tpi.registerFlag(\"claude-account\", {\n\t\ttype: \"string\",\n\t\tdescription: \"Pin Claude SDK OAuth account for this session.\",\n\t});\n\tpi.on(\"session_start\", (_event, ctx) => {\n\t\tconst flag = pi.getFlag(\"claude-account\");\n\t\tconst sessionId = ctx.sessionManager.getSessionId();\n\t\tif (typeof flag === \"string\" && flag.length > 0) cliPinsBySession.set(sessionId, flag);\n\t\telse cliPinsBySession.delete(sessionId);\n\t});\n\tpi.on(\"session_shutdown\", (_event, ctx) => {\n\t\tcliPinsBySession.delete(ctx.sessionManager.getSessionId());\n\t});\n\tpi.registerCommand(\"claude-account\", {\n\t\tdescription: \"List and manage Claude SDK OAuth accounts.\",\n\t\targumentHint: \"[add | remove <name> | pin <name> | unpin]\",\n\t\thandler: async (rawArgs, ctx) => {\n\t\t\tconst args = parseArgs(rawArgs);\n\t\t\tconst action = args[0] ?? \"list\";\n\t\t\tif (action === \"list\") {\n\t\t\t\tshowAccounts(ctx, loadSettings(ctx.cwd), environment);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (action === \"add\") {\n\t\t\t\tawait addAccount(ctx, deps);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (action === \"remove\") {\n\t\t\t\tawait removeNamedAccount(ctx, args[1], environment);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (action === \"pin\" && args[1] !== \"unpin\") {\n\t\t\t\tawait pinNamedAccount(ctx, args[1], environment);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (action === \"unpin\" || (action === \"pin\" && args[1] === \"unpin\")) {\n\t\t\t\tawait unpinAccount(ctx);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tctx.ui.notify(\"Usage: /claude-account [add | remove <name> | pin <name> | unpin]\", \"error\");\n\t\t},\n\t});\n}\n\nfunction showAccounts(\n\tctx: ExtensionCommandContext,\n\tsettings: ClaudeSdkOauthProviderSettings,\n\tenvironment: CommandEnvironment,\n): void {\n\tconst { credential, accounts } = readAccounts(ctx, environment);\n\tconst cliPin = getSessionClaudeAccountPin(ctx.sessionManager.getSessionId());\n\tconst pinned = resolveClaudeAccountPin(cliPin, settings.pinnedAccount, credential?.pinned);\n\tconst pinSource = cliPin !== undefined ? \"CLI\" : settings.pinnedAccount !== undefined ? \"settings\" : \"stored\";\n\tlet affinityPick: string | undefined;\n\tlet affinityError: string | undefined;\n\tif (accounts.length > 0) {\n\t\ttry {\n\t\t\taffinityPick = selectAccount(accounts, {\n\t\t\t\tsessionId: ctx.sessionManager.getSessionId(),\n\t\t\t\tpinnedAccount: pinned,\n\t\t\t}).name;\n\t\t} catch (error) {\n\t\t\taffinityError = error instanceof Error ? error.message : String(error);\n\t\t}\n\t}\n\tconst lines = [\"Claude SDK OAuth accounts:\"];\n\tif (accounts.length === 0) lines.push(\" (none)\");\n\tfor (const account of accounts) {\n\t\tconst states = [account.name, account.source, slotStatus(account)];\n\t\tif (account.name === pinned) states.push(\"pinned\");\n\t\tif (account.name === affinityPick) states.push(\"affinity pick\");\n\t\tlines.push(` ${states.join(\" | \")}`);\n\t}\n\tlines.push(`Pinned account: ${pinned === undefined ? \"none\" : `${pinned} (${pinSource.toLowerCase()})`}`);\n\tlines.push(`Affinity pick: ${affinityPick ?? (affinityError ? `unavailable - ${affinityError}` : \"none\")}`);\n\tctx.ui.notify(lines.join(\"\\n\"), \"info\");\n}\n\nasync function addAccount(ctx: ExtensionCommandContext, deps: ClaudeAccountCommandDeps): Promise<void> {\n\tif (!ctx.hasUI) {\n\t\tctx.ui.notify(\"/claude-account add requires an interactive UI.\", \"error\");\n\t\treturn;\n\t}\n\ttry {\n\t\tawait ctx.modelRegistry.modelRuntime.login(\n\t\t\tCLAUDE_SDK_OAUTH_PROVIDER_ID,\n\t\t\t\"oauth\",\n\t\t\tcreateExtensionLoginInteraction(ctx, {\n\t\t\t\tproviderLabel: CLAUDE_SDK_OAUTH_PROVIDER_LABEL,\n\t\t\t\topenBrowser: deps.openBrowser,\n\t\t\t}),\n\t\t);\n\t\temitProviderAccountsChanged(CLAUDE_SDK_OAUTH_PROVIDER_ID);\n\t\tctx.ui.notify(\"Claude SDK OAuth account added.\", \"info\");\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tif (message !== LOGIN_CANCELLED_MESSAGE) {\n\t\t\tctx.ui.notify(`Failed to add Claude SDK OAuth account: ${message}`, \"error\");\n\t\t}\n\t}\n}\n\nasync function removeNamedAccount(\n\tctx: ExtensionCommandContext,\n\tname: string | undefined,\n\tenvironment: CommandEnvironment,\n): Promise<void> {\n\tif (!name) {\n\t\tctx.ui.notify(\"Usage: /claude-account remove <name>\", \"error\");\n\t\treturn;\n\t}\n\tconst { accounts } = readAccounts(ctx, environment);\n\tconst target = accounts.find((account) => account.name === name);\n\tif (!target) return accountError(ctx, name);\n\tif (target.source === \"env\") {\n\t\tctx.ui.notify(`Claude SDK OAuth account '${name}' comes from the environment and cannot be removed.`, \"error\");\n\t\treturn;\n\t}\n\ttry {\n\t\tawait removeProviderAccount(ctx.modelRegistry.authStorage, CLAUDE_SDK_OAUTH_PROVIDER_ID, name);\n\t\tctx.ui.notify(`Removed Claude SDK OAuth account: ${name}.`, \"info\");\n\t} catch (error) {\n\t\tctx.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t}\n}\n\nasync function pinNamedAccount(\n\tctx: ExtensionCommandContext,\n\tname: string | undefined,\n\tenvironment: CommandEnvironment,\n): Promise<void> {\n\tif (!name) {\n\t\tctx.ui.notify(\"Usage: /claude-account pin <name>\", \"error\");\n\t\treturn;\n\t}\n\tif (!readAccounts(ctx, environment).accounts.some((account) => account.name === name)) {\n\t\treturn accountError(ctx, name);\n\t}\n\ttry {\n\t\tawait pinProviderAccount(ctx.modelRegistry.authStorage, CLAUDE_SDK_OAUTH_PROVIDER_ID, name);\n\t\tctx.ui.notify(`Pinned Claude SDK OAuth account: ${name}.`, \"info\");\n\t} catch (error) {\n\t\tctx.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t}\n}\n\nasync function unpinAccount(ctx: ExtensionCommandContext): Promise<void> {\n\tconst credential = asCredential(ctx.modelRegistry.authStorage.get(CLAUDE_SDK_OAUTH_PROVIDER_ID));\n\tif (!credential?.pinned) {\n\t\tctx.ui.notify(\"No stored Claude SDK OAuth account pin is set.\", \"info\");\n\t\treturn;\n\t}\n\tawait pinProviderAccount(ctx.modelRegistry.authStorage, CLAUDE_SDK_OAUTH_PROVIDER_ID, null);\n\tctx.ui.notify(\"Unpinned Claude SDK OAuth account.\", \"info\");\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-binding.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/session-binding.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAG/D,eAAO,MAAM,kBAAkB,6BAA6B,CAAC;AAC7D,eAAO,MAAM,cAAc;;;CAA8C,CAAC;AAE1E,MAAM,MAAM,mBAAmB,GAAG;IACjC,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,KAAK,WAAW,GAAG;IAClB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,oBAAoB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3D,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACrC,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,MAAM,EAAE,mBAAmB,GACzB,aAAa,CAgBf;AAED,0FAA0F;AAC1F,wBAAgB,wBAAwB,CACvC,OAAO,EAAE,iBAAiB,EAC1B,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,MAAM,EAAE,mBAAmB,GACzB,aAAa,GAAG,SAAS,CAsB3B;AAED,wBAAgB,uBAAuB,CACtC,MAAM,EAAE,SAAS,WAAW,EAAE,EAC9B,MAAM,EAAE,aAAa,GACnB,iBAAiB,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"session-binding.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/session-binding.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAG/D,eAAO,MAAM,kBAAkB,6BAA6B,CAAC;AAC7D,eAAO,MAAM,cAAc;;;CAA8C,CAAC;AAE1E,MAAM,MAAM,mBAAmB,GAAG;IACjC,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,KAAK,WAAW,GAAG;IAClB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,oBAAoB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3D,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACrC,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,MAAM,EAAE,mBAAmB,GACzB,aAAa,CAgBf;AAED,0FAA0F;AAC1F,wBAAgB,wBAAwB,CACvC,OAAO,EAAE,iBAAiB,EAC1B,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,MAAM,EAAE,mBAAmB,GACzB,aAAa,GAAG,SAAS,CAsB3B;AAED,wBAAgB,uBAAuB,CACtC,MAAM,EAAE,SAAS,WAAW,EAAE,EAC9B,MAAM,EAAE,aAAa,GACnB,iBAAiB,GAAG,SAAS,CAW/B"}
|
|
@@ -58,12 +58,12 @@ export function bindingFromStoredBranch(branch, stored) {
|
|
|
58
58
|
if (markerIndex < 0)
|
|
59
59
|
return undefined;
|
|
60
60
|
const marker = branch[markerIndex];
|
|
61
|
-
if (marker?.id !== stored.markerEntryId ||
|
|
62
|
-
!isBindingMarker(marker.data) ||
|
|
63
|
-
!branch.slice(markerIndex + 2).every(isSafeBindingSuffix)) {
|
|
61
|
+
if (marker?.id !== stored.markerEntryId || !isBindingMarker(marker.data))
|
|
64
62
|
return undefined;
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
const assistantIndex = committedAssistantIndex(branch, markerIndex + 1);
|
|
64
|
+
if (assistantIndex < 0 || !branch.slice(assistantIndex + 1).every(isLedgerOnlyEntry))
|
|
65
|
+
return undefined;
|
|
66
|
+
const committedAssistant = branch[assistantIndex]?.message;
|
|
67
67
|
if (!isAssistantMessage(committedAssistant))
|
|
68
68
|
return undefined;
|
|
69
69
|
if (assistantContentHash(committedAssistant) !== stored.assistantContentHash)
|
|
@@ -71,24 +71,41 @@ export function bindingFromStoredBranch(branch, stored) {
|
|
|
71
71
|
return bindingFromStored(stored);
|
|
72
72
|
}
|
|
73
73
|
/**
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
74
|
+
* The marker is appended inside `message_end`, so handlers that run after this
|
|
75
|
+
* builtin (and extensions loaded later) can append ledger entries before the
|
|
76
|
+
* assistant itself persists. The committed assistant is the first message after
|
|
77
|
+
* the marker; anything that reaches the model in between fails closed.
|
|
78
|
+
*/
|
|
79
|
+
function committedAssistantIndex(branch, from) {
|
|
80
|
+
for (let index = from; index < branch.length; index += 1) {
|
|
81
|
+
const entry = branch[index];
|
|
82
|
+
if (entry?.type === "message")
|
|
83
|
+
return index;
|
|
84
|
+
if (!entry || !isLedgerOnlyEntry(entry))
|
|
85
|
+
return -1;
|
|
86
|
+
}
|
|
87
|
+
return -1;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Entry types the session-manager never projects into the LLM context. They
|
|
91
|
+
* cannot shift the sent-stream digest the binding is verified against, so any
|
|
92
|
+
* `custom` ledger record (hook state, rule scans, memory bookkeeping, ...) is
|
|
93
|
+
* admitted regardless of who wrote it. Everything the model can see - messages,
|
|
94
|
+
* custom messages other than the goal continuation, compaction and branch
|
|
95
|
+
* summaries - keeps failing closed (oh-my-openagent#7925).
|
|
77
96
|
*/
|
|
78
|
-
const
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
"
|
|
84
|
-
"
|
|
97
|
+
const LEDGER_ONLY_ENTRY_TYPES = new Set([
|
|
98
|
+
"custom",
|
|
99
|
+
"label",
|
|
100
|
+
"session_info",
|
|
101
|
+
"thinking_level_change",
|
|
102
|
+
"model_change",
|
|
103
|
+
"configuration_update",
|
|
85
104
|
]);
|
|
86
|
-
function
|
|
87
|
-
if (entry.type === "label")
|
|
88
|
-
return true;
|
|
105
|
+
function isLedgerOnlyEntry(entry) {
|
|
89
106
|
if (entry.type === "custom_message")
|
|
90
107
|
return entry.customType === GOAL_CONTINUATION_MESSAGE_TYPE;
|
|
91
|
-
return
|
|
108
|
+
return LEDGER_ONLY_ENTRY_TYPES.has(entry.type);
|
|
92
109
|
}
|
|
93
110
|
function newestBindingEntryIndex(branch) {
|
|
94
111
|
for (let index = branch.length - 1; index >= 0; index -= 1) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-binding.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/session-binding.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AssistantMessage } from \"@earendil-works/pi-ai\";\nimport { GOAL_CONTINUATION_MESSAGE_TYPE } from \"../../../messages.ts\";\nimport type { StoredBinding } from \"./session-binding-store.ts\";\nimport { assistantContentHash } from \"./session-commit-boundary.ts\";\nimport type { ContinuityBinding } from \"./session-reattach.ts\";\nimport { sentHashPrefixDigest } from \"./session-sync.ts\";\n\nexport const BINDING_ENTRY_TYPE = \"claude-sdk-oauth-binding\";\nexport const BINDING_MARKER = { schemaVersion: 2, marker: true } as const;\n\nexport type BindingInvalidation = {\n\treadonly schemaVersion: 1;\n\treadonly invalidated: true;\n\treadonly reason: string;\n};\n\ntype BranchEntry = {\n\treadonly id?: string;\n\treadonly type: string;\n\treadonly customType?: string;\n\treadonly data?: unknown;\n\treadonly message?: unknown;\n};\n\nexport type StoredBindingAnchor = {\n\treadonly sessionPath: string;\n\treadonly sessionId: string;\n\treadonly markerEntryId: string;\n\treadonly assistantContentHash: string;\n};\n\nexport type BindingEntryState = {\n\treadonly sdkSessionId: string;\n\treadonly accountName: string;\n\treadonly modelId: string;\n\treadonly systemPromptHash: string;\n\treadonly toolsetHash: string;\n\treadonly assistantUuidByIndex: ReadonlyMap<number, string>;\n};\n\n/**\n * The record is derived from the registry entry plus the hashes the branch\n * actually carries, never from the process binding map: that map holds the\n * previous turn's state while `message_end` runs (and only a prefix digest right\n * after a restart), so reading it would anchor this turn's marker to a stale or\n * absent sent-stream.\n */\nexport function storedBindingFromEntry(\n\tentry: BindingEntryState,\n\thashes: readonly string[],\n\tanchor: StoredBindingAnchor,\n): StoredBinding {\n\treturn {\n\t\tschemaVersion: 1,\n\t\tsessionPath: anchor.sessionPath,\n\t\tsessionId: anchor.sessionId,\n\t\tmarkerEntryId: anchor.markerEntryId,\n\t\tsdkSessionId: entry.sdkSessionId,\n\t\tsentCount: hashes.length,\n\t\tsentPrefixHash: sentHashPrefixDigest(hashes),\n\t\tassistantContentHash: anchor.assistantContentHash,\n\t\tlastAssistantUuid: entry.assistantUuidByIndex.get(hashes.length) ?? null,\n\t\taccountName: entry.accountName,\n\t\tmodelId: entry.modelId,\n\t\tsystemPromptHash: entry.systemPromptHash,\n\t\ttoolsetHash: entry.toolsetHash,\n\t};\n}\n\n/** Persist a completed turn whose resident registry entry closed before `message_end`. */\nexport function storedBindingFromBinding(\n\tbinding: ContinuityBinding,\n\thashes: readonly string[],\n\tanchor: StoredBindingAnchor,\n): StoredBinding | undefined {\n\tif (binding.sdkSessionIdConfirmed === false) return undefined;\n\tif (binding.sentCount !== hashes.length) return undefined;\n\tconst expectedDigest = sentHashPrefixDigest(hashes);\n\tconst bindingDigest =\n\t\tbinding.sentPrefixHash ?? (binding.sentHashes.length > 0 ? sentHashPrefixDigest(binding.sentHashes) : undefined);\n\tif (bindingDigest === undefined || bindingDigest !== expectedDigest) return undefined;\n\treturn {\n\t\tschemaVersion: 1,\n\t\tsessionPath: anchor.sessionPath,\n\t\tsessionId: anchor.sessionId,\n\t\tmarkerEntryId: anchor.markerEntryId,\n\t\tsdkSessionId: binding.sdkSessionId,\n\t\tsentCount: hashes.length,\n\t\tsentPrefixHash: sentHashPrefixDigest(hashes),\n\t\tassistantContentHash: anchor.assistantContentHash,\n\t\tlastAssistantUuid: binding.lastAssistantUuid,\n\t\taccountName: binding.accountName,\n\t\tmodelId: binding.modelId,\n\t\tsystemPromptHash: binding.systemPromptHash,\n\t\ttoolsetHash: binding.toolsetHash,\n\t};\n}\n\nexport function bindingFromStoredBranch(\n\tbranch: readonly BranchEntry[],\n\tstored: StoredBinding,\n): ContinuityBinding | undefined {\n\tconst markerIndex = newestBindingEntryIndex(branch);\n\tif (markerIndex < 0) return undefined;\n\tconst marker = branch[markerIndex];\n\tif (\n\t\tmarker?.id !== stored.markerEntryId ||\n\t\t!isBindingMarker(marker.data) ||\n\t\t!branch.slice(markerIndex + 2).every(isSafeBindingSuffix)\n\t) {\n\t\treturn undefined;\n\t}\n\tconst committedAssistant = branch[markerIndex + 1]?.message;\n\tif (!isAssistantMessage(committedAssistant)) return undefined;\n\tif (assistantContentHash(committedAssistant) !== stored.assistantContentHash) return undefined;\n\treturn bindingFromStored(stored);\n}\n\n/**\n * Display-only metadata the co-resident builtins append after the committed\n * assistant (stop-hook state/diagnostics/output, rule activations, rule scans).\n * None participates in the sent stream, so none can shift the prefix digest.\n */\nconst SAFE_BINDING_SUFFIX_TYPES: ReadonlySet<string> = new Set([\n\t\"senpi.hooks.stop-state\",\n\t\"senpi.hooks.stop-diagnostics\",\n\t\"senpi.hooks.stop-output\",\n\t\"pi-rules.scan\",\n\t\"rule-activation\",\n\t\"goal-cache-warmup\",\n]);\n\nfunction isSafeBindingSuffix(entry: BranchEntry): boolean {\n\tif (entry.type === \"label\") return true;\n\tif (entry.type === \"custom_message\") return entry.customType === GOAL_CONTINUATION_MESSAGE_TYPE;\n\treturn entry.type === \"custom\" && entry.customType !== undefined && SAFE_BINDING_SUFFIX_TYPES.has(entry.customType);\n}\n\nfunction newestBindingEntryIndex(branch: readonly BranchEntry[]): number {\n\tfor (let index = branch.length - 1; index >= 0; index -= 1) {\n\t\tconst entry = branch[index];\n\t\tif (entry?.type === \"custom\" && entry.customType === BINDING_ENTRY_TYPE) return index;\n\t}\n\treturn -1;\n}\n\nfunction isBindingMarker(value: unknown): boolean {\n\tif (typeof value !== \"object\" || value === null) return false;\n\treturn \"schemaVersion\" in value && value.schemaVersion === 2 && \"marker\" in value && value.marker === true;\n}\n\nfunction isAssistantMessage(value: unknown): value is AssistantMessage {\n\tif (typeof value !== \"object\" || value === null) return false;\n\treturn (\n\t\t\"role\" in value &&\n\t\tvalue.role === \"assistant\" &&\n\t\t\"api\" in value &&\n\t\ttypeof value.api === \"string\" &&\n\t\t\"provider\" in value &&\n\t\ttypeof value.provider === \"string\" &&\n\t\t\"model\" in value &&\n\t\ttypeof value.model === \"string\" &&\n\t\t\"content\" in value &&\n\t\tArray.isArray(value.content)\n\t);\n}\n\nfunction bindingFromStored(stored: StoredBinding): ContinuityBinding {\n\treturn {\n\t\tsenpiSessionId: stored.sessionId,\n\t\tsdkSessionId: stored.sdkSessionId,\n\t\tsentCount: stored.sentCount,\n\t\tsentHashes: [],\n\t\tsentPrefixHash: stored.sentPrefixHash,\n\t\tlastAssistantUuid: stored.lastAssistantUuid,\n\t\tassistantUuidByIndex: stored.lastAssistantUuid === null ? [] : [[stored.sentCount, stored.lastAssistantUuid]],\n\t\taccountName: stored.accountName,\n\t\tmodelId: stored.modelId,\n\t\tsystemPromptHash: stored.systemPromptHash,\n\t\ttoolsetHash: stored.toolsetHash,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"session-binding.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/session-binding.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AssistantMessage } from \"@earendil-works/pi-ai\";\nimport { GOAL_CONTINUATION_MESSAGE_TYPE } from \"../../../messages.ts\";\nimport type { StoredBinding } from \"./session-binding-store.ts\";\nimport { assistantContentHash } from \"./session-commit-boundary.ts\";\nimport type { ContinuityBinding } from \"./session-reattach.ts\";\nimport { sentHashPrefixDigest } from \"./session-sync.ts\";\n\nexport const BINDING_ENTRY_TYPE = \"claude-sdk-oauth-binding\";\nexport const BINDING_MARKER = { schemaVersion: 2, marker: true } as const;\n\nexport type BindingInvalidation = {\n\treadonly schemaVersion: 1;\n\treadonly invalidated: true;\n\treadonly reason: string;\n};\n\ntype BranchEntry = {\n\treadonly id?: string;\n\treadonly type: string;\n\treadonly customType?: string;\n\treadonly data?: unknown;\n\treadonly message?: unknown;\n};\n\nexport type StoredBindingAnchor = {\n\treadonly sessionPath: string;\n\treadonly sessionId: string;\n\treadonly markerEntryId: string;\n\treadonly assistantContentHash: string;\n};\n\nexport type BindingEntryState = {\n\treadonly sdkSessionId: string;\n\treadonly accountName: string;\n\treadonly modelId: string;\n\treadonly systemPromptHash: string;\n\treadonly toolsetHash: string;\n\treadonly assistantUuidByIndex: ReadonlyMap<number, string>;\n};\n\n/**\n * The record is derived from the registry entry plus the hashes the branch\n * actually carries, never from the process binding map: that map holds the\n * previous turn's state while `message_end` runs (and only a prefix digest right\n * after a restart), so reading it would anchor this turn's marker to a stale or\n * absent sent-stream.\n */\nexport function storedBindingFromEntry(\n\tentry: BindingEntryState,\n\thashes: readonly string[],\n\tanchor: StoredBindingAnchor,\n): StoredBinding {\n\treturn {\n\t\tschemaVersion: 1,\n\t\tsessionPath: anchor.sessionPath,\n\t\tsessionId: anchor.sessionId,\n\t\tmarkerEntryId: anchor.markerEntryId,\n\t\tsdkSessionId: entry.sdkSessionId,\n\t\tsentCount: hashes.length,\n\t\tsentPrefixHash: sentHashPrefixDigest(hashes),\n\t\tassistantContentHash: anchor.assistantContentHash,\n\t\tlastAssistantUuid: entry.assistantUuidByIndex.get(hashes.length) ?? null,\n\t\taccountName: entry.accountName,\n\t\tmodelId: entry.modelId,\n\t\tsystemPromptHash: entry.systemPromptHash,\n\t\ttoolsetHash: entry.toolsetHash,\n\t};\n}\n\n/** Persist a completed turn whose resident registry entry closed before `message_end`. */\nexport function storedBindingFromBinding(\n\tbinding: ContinuityBinding,\n\thashes: readonly string[],\n\tanchor: StoredBindingAnchor,\n): StoredBinding | undefined {\n\tif (binding.sdkSessionIdConfirmed === false) return undefined;\n\tif (binding.sentCount !== hashes.length) return undefined;\n\tconst expectedDigest = sentHashPrefixDigest(hashes);\n\tconst bindingDigest =\n\t\tbinding.sentPrefixHash ?? (binding.sentHashes.length > 0 ? sentHashPrefixDigest(binding.sentHashes) : undefined);\n\tif (bindingDigest === undefined || bindingDigest !== expectedDigest) return undefined;\n\treturn {\n\t\tschemaVersion: 1,\n\t\tsessionPath: anchor.sessionPath,\n\t\tsessionId: anchor.sessionId,\n\t\tmarkerEntryId: anchor.markerEntryId,\n\t\tsdkSessionId: binding.sdkSessionId,\n\t\tsentCount: hashes.length,\n\t\tsentPrefixHash: sentHashPrefixDigest(hashes),\n\t\tassistantContentHash: anchor.assistantContentHash,\n\t\tlastAssistantUuid: binding.lastAssistantUuid,\n\t\taccountName: binding.accountName,\n\t\tmodelId: binding.modelId,\n\t\tsystemPromptHash: binding.systemPromptHash,\n\t\ttoolsetHash: binding.toolsetHash,\n\t};\n}\n\nexport function bindingFromStoredBranch(\n\tbranch: readonly BranchEntry[],\n\tstored: StoredBinding,\n): ContinuityBinding | undefined {\n\tconst markerIndex = newestBindingEntryIndex(branch);\n\tif (markerIndex < 0) return undefined;\n\tconst marker = branch[markerIndex];\n\tif (marker?.id !== stored.markerEntryId || !isBindingMarker(marker.data)) return undefined;\n\tconst assistantIndex = committedAssistantIndex(branch, markerIndex + 1);\n\tif (assistantIndex < 0 || !branch.slice(assistantIndex + 1).every(isLedgerOnlyEntry)) return undefined;\n\tconst committedAssistant = branch[assistantIndex]?.message;\n\tif (!isAssistantMessage(committedAssistant)) return undefined;\n\tif (assistantContentHash(committedAssistant) !== stored.assistantContentHash) return undefined;\n\treturn bindingFromStored(stored);\n}\n\n/**\n * The marker is appended inside `message_end`, so handlers that run after this\n * builtin (and extensions loaded later) can append ledger entries before the\n * assistant itself persists. The committed assistant is the first message after\n * the marker; anything that reaches the model in between fails closed.\n */\nfunction committedAssistantIndex(branch: readonly BranchEntry[], from: number): number {\n\tfor (let index = from; index < branch.length; index += 1) {\n\t\tconst entry = branch[index];\n\t\tif (entry?.type === \"message\") return index;\n\t\tif (!entry || !isLedgerOnlyEntry(entry)) return -1;\n\t}\n\treturn -1;\n}\n\n/**\n * Entry types the session-manager never projects into the LLM context. They\n * cannot shift the sent-stream digest the binding is verified against, so any\n * `custom` ledger record (hook state, rule scans, memory bookkeeping, ...) is\n * admitted regardless of who wrote it. Everything the model can see - messages,\n * custom messages other than the goal continuation, compaction and branch\n * summaries - keeps failing closed (oh-my-openagent#7925).\n */\nconst LEDGER_ONLY_ENTRY_TYPES: ReadonlySet<string> = new Set([\n\t\"custom\",\n\t\"label\",\n\t\"session_info\",\n\t\"thinking_level_change\",\n\t\"model_change\",\n\t\"configuration_update\",\n]);\n\nfunction isLedgerOnlyEntry(entry: BranchEntry): boolean {\n\tif (entry.type === \"custom_message\") return entry.customType === GOAL_CONTINUATION_MESSAGE_TYPE;\n\treturn LEDGER_ONLY_ENTRY_TYPES.has(entry.type);\n}\n\nfunction newestBindingEntryIndex(branch: readonly BranchEntry[]): number {\n\tfor (let index = branch.length - 1; index >= 0; index -= 1) {\n\t\tconst entry = branch[index];\n\t\tif (entry?.type === \"custom\" && entry.customType === BINDING_ENTRY_TYPE) return index;\n\t}\n\treturn -1;\n}\n\nfunction isBindingMarker(value: unknown): boolean {\n\tif (typeof value !== \"object\" || value === null) return false;\n\treturn \"schemaVersion\" in value && value.schemaVersion === 2 && \"marker\" in value && value.marker === true;\n}\n\nfunction isAssistantMessage(value: unknown): value is AssistantMessage {\n\tif (typeof value !== \"object\" || value === null) return false;\n\treturn (\n\t\t\"role\" in value &&\n\t\tvalue.role === \"assistant\" &&\n\t\t\"api\" in value &&\n\t\ttypeof value.api === \"string\" &&\n\t\t\"provider\" in value &&\n\t\ttypeof value.provider === \"string\" &&\n\t\t\"model\" in value &&\n\t\ttypeof value.model === \"string\" &&\n\t\t\"content\" in value &&\n\t\tArray.isArray(value.content)\n\t);\n}\n\nfunction bindingFromStored(stored: StoredBinding): ContinuityBinding {\n\treturn {\n\t\tsenpiSessionId: stored.sessionId,\n\t\tsdkSessionId: stored.sdkSessionId,\n\t\tsentCount: stored.sentCount,\n\t\tsentHashes: [],\n\t\tsentPrefixHash: stored.sentPrefixHash,\n\t\tlastAssistantUuid: stored.lastAssistantUuid,\n\t\tassistantUuidByIndex: stored.lastAssistantUuid === null ? [] : [[stored.sentCount, stored.lastAssistantUuid]],\n\t\taccountName: stored.accountName,\n\t\tmodelId: stored.modelId,\n\t\tsystemPromptHash: stored.systemPromptHash,\n\t\ttoolsetHash: stored.toolsetHash,\n\t};\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-commit-boundary.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/session-commit-boundary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAI9D,MAAM,MAAM,sBAAsB,GAAG,OAAO,GAAG,WAAW,GAAG,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"session-commit-boundary.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/session-commit-boundary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAI9D,MAAM,MAAM,sBAAsB,GAAG,OAAO,GAAG,WAAW,GAAG,cAAc,CAAC;AAyB5E,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAQtE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAMvF;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAEpE;AAED;;;;;GAKG;AACH,qBAAa,uBAAuB;IACnC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA6B;IAEhE,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI;IAIlE,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,GAAG,sBAAsB;IAQvF,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAGzB"}
|
|
@@ -1,21 +1,32 @@
|
|
|
1
1
|
import { CLAUDE_SDK_OAUTH_PROVIDER_ID } from "./account-management.js";
|
|
2
2
|
import { sessionSyncDigest } from "./session-sync.js";
|
|
3
|
+
/**
|
|
4
|
+
* Only the payload the model produced is fingerprinted. Everything the stream
|
|
5
|
+
* pipeline stamps around it (thinking timing, content-block indices, partial
|
|
6
|
+
* JSON) can legitimately differ between the last `message_update` and `message_end`
|
|
7
|
+
* without any extension rewriting the answer; hashing such fields marked plain
|
|
8
|
+
* turns `assistant_rewritten` and forced a full re-send on the next turn
|
|
9
|
+
* (senpi#691, oh-my-openagent#7925). An unknown block shape stays fail-closed.
|
|
10
|
+
*/
|
|
11
|
+
function semanticContentBlock(block) {
|
|
12
|
+
switch (block.type) {
|
|
13
|
+
case "text":
|
|
14
|
+
return { type: block.type, text: block.text };
|
|
15
|
+
case "thinking":
|
|
16
|
+
return { type: block.type, thinking: block.thinking, thinkingSignature: block.thinkingSignature };
|
|
17
|
+
case "toolCall":
|
|
18
|
+
return { type: block.type, id: block.id, name: block.name, arguments: block.arguments };
|
|
19
|
+
default:
|
|
20
|
+
return block;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
3
23
|
export function assistantContentHash(message) {
|
|
4
24
|
return sessionSyncDigest({
|
|
5
25
|
role: message.role,
|
|
6
26
|
api: message.api,
|
|
7
27
|
provider: message.provider,
|
|
8
28
|
model: message.model,
|
|
9
|
-
content: message.content.map(
|
|
10
|
-
if (block.type !== "thinking")
|
|
11
|
-
return block;
|
|
12
|
-
// Agent-core stamps these display-only fields after the final
|
|
13
|
-
// message_update; every semantic thinking field stays fail-closed.
|
|
14
|
-
const stableBlock = { ...block };
|
|
15
|
-
delete stableBlock.startedAt;
|
|
16
|
-
delete stableBlock.endedAt;
|
|
17
|
-
return stableBlock;
|
|
18
|
-
}),
|
|
29
|
+
content: message.content.map(semanticContentBlock),
|
|
19
30
|
});
|
|
20
31
|
}
|
|
21
32
|
export function isResidentAssistant(message, modelId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-commit-boundary.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/session-commit-boundary.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"session-commit-boundary.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/session-commit-boundary.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAMtD;;;;;;;GAOG;AACH,SAAS,oBAAoB,CAAC,KAAmB;IAChD,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,MAAM;YACV,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;QAC/C,KAAK,UAAU;YACd,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,EAAE,CAAC;QACnG,KAAK,UAAU;YACd,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC;QACzF;YACC,OAAO,KAAK,CAAC;IACf,CAAC;AACF,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAAyB;IAC7D,OAAO,iBAAiB,CAAC;QACxB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;KAClD,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAyB,EAAE,OAAe;IAC7E,OAAO,CACN,OAAO,CAAC,GAAG,KAAK,4BAA4B;QAC5C,OAAO,CAAC,QAAQ,KAAK,4BAA4B;QACjD,OAAO,CAAC,KAAK,KAAK,OAAO,CACzB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,OAAyB;IAC1D,OAAO,OAAO,CAAC,UAAU,KAAK,OAAO,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC;AAC3E,CAAC;AAED;;;;;GAKG;AACH,MAAM,OAAO,uBAAuB;IAApC;QACkB,uBAAkB,GAAG,IAAI,GAAG,EAAkB,CAAC;IAiBjE,CAAC;IAfA,oBAAoB,CAAC,GAAW,EAAE,OAAyB;QAC1D,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,GAAG,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,CAAC,GAAW,EAAE,OAAyB,EAAE,OAAe;QAC7D,MAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACvD,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC;YAAE,OAAO,cAAc,CAAC;QAClE,IAAI,aAAa,KAAK,SAAS;YAAE,OAAO,OAAO,CAAC;QAChD,OAAO,aAAa,KAAK,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC;IAChF,CAAC;IAED,MAAM,CAAC,GAAW;QACjB,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC;CACD","sourcesContent":["import type { AssistantMessage } from \"@earendil-works/pi-ai\";\nimport { CLAUDE_SDK_OAUTH_PROVIDER_ID } from \"./account-management.ts\";\nimport { sessionSyncDigest } from \"./session-sync.ts\";\n\nexport type AssistantCommitOutcome = \"clean\" | \"rewritten\" | \"not-resident\";\n\ntype ContentBlock = AssistantMessage[\"content\"][number];\n\n/**\n * Only the payload the model produced is fingerprinted. Everything the stream\n * pipeline stamps around it (thinking timing, content-block indices, partial\n * JSON) can legitimately differ between the last `message_update` and `message_end`\n * without any extension rewriting the answer; hashing such fields marked plain\n * turns `assistant_rewritten` and forced a full re-send on the next turn\n * (senpi#691, oh-my-openagent#7925). An unknown block shape stays fail-closed.\n */\nfunction semanticContentBlock(block: ContentBlock): unknown {\n\tswitch (block.type) {\n\t\tcase \"text\":\n\t\t\treturn { type: block.type, text: block.text };\n\t\tcase \"thinking\":\n\t\t\treturn { type: block.type, thinking: block.thinking, thinkingSignature: block.thinkingSignature };\n\t\tcase \"toolCall\":\n\t\t\treturn { type: block.type, id: block.id, name: block.name, arguments: block.arguments };\n\t\tdefault:\n\t\t\treturn block;\n\t}\n}\n\nexport function assistantContentHash(message: AssistantMessage): string {\n\treturn sessionSyncDigest({\n\t\trole: message.role,\n\t\tapi: message.api,\n\t\tprovider: message.provider,\n\t\tmodel: message.model,\n\t\tcontent: message.content.map(semanticContentBlock),\n\t});\n}\n\nexport function isResidentAssistant(message: AssistantMessage, modelId: string): boolean {\n\treturn (\n\t\tmessage.api === CLAUDE_SDK_OAUTH_PROVIDER_ID &&\n\t\tmessage.provider === CLAUDE_SDK_OAUTH_PROVIDER_ID &&\n\t\tmessage.model === modelId\n\t);\n}\n\nexport function isTerminalFailure(message: AssistantMessage): boolean {\n\treturn message.stopReason === \"error\" || message.stopReason === \"aborted\";\n}\n\n/**\n * Divergence is decided by comparing what the provider streamed against what the\n * session ledger committed, never by in-flight staging: a result-only turn fills\n * its content at the terminal message with no preceding delta, so a staged-hash\n * comparison reports false divergence on a perfectly valid SDK response shape.\n */\nexport class AssistantCommitBoundary {\n\tprivate readonly providerFinalByKey = new Map<string, string>();\n\n\tcaptureProviderFinal(key: string, message: AssistantMessage): void {\n\t\tthis.providerFinalByKey.set(key, assistantContentHash(message));\n\t}\n\n\tcommit(key: string, message: AssistantMessage, modelId: string): AssistantCommitOutcome {\n\t\tconst providerFinal = this.providerFinalByKey.get(key);\n\t\tthis.providerFinalByKey.delete(key);\n\t\tif (!isResidentAssistant(message, modelId)) return \"not-resident\";\n\t\tif (providerFinal === undefined) return \"clean\";\n\t\treturn providerFinal === assistantContentHash(message) ? \"clean\" : \"rewritten\";\n\t}\n\n\tforget(key: string): void {\n\t\tthis.providerFinalByKey.delete(key);\n\t}\n}\n"]}
|
|
@@ -38,6 +38,8 @@ export type ContinuityDecisionInput = {
|
|
|
38
38
|
toolsetHash: string;
|
|
39
39
|
};
|
|
40
40
|
transcriptAvailable: boolean;
|
|
41
|
+
/** false only on the config-dir lane, whose per-account credential roots cannot share a transcript root, so cross-account resume is impossible there. */
|
|
42
|
+
crossAccountResumeSupported: boolean;
|
|
41
43
|
idleExpired?: boolean;
|
|
42
44
|
};
|
|
43
45
|
export type ContinuityDecision = {
|
|
@@ -60,25 +62,10 @@ export type ContinuityDecision = {
|
|
|
60
62
|
kind: "flatten";
|
|
61
63
|
reason: ContinuityReason;
|
|
62
64
|
};
|
|
63
|
-
export type FailoverLane = "oauth-slots" | "ambient" | "config-dir";
|
|
64
|
-
export type FailoverContinuityInput = {
|
|
65
|
-
authLane: FailoverLane;
|
|
66
|
-
crossAccountResumeSupported: boolean;
|
|
67
|
-
entry: {
|
|
68
|
-
sdkSessionId: string;
|
|
69
|
-
sentCount: number;
|
|
70
|
-
lastAssistantUuid: string | null;
|
|
71
|
-
};
|
|
72
|
-
};
|
|
73
|
-
/**
|
|
74
|
-
* The config-dir lane keeps each account's credentials inside its own
|
|
75
|
-
* CLAUDE_CONFIG_DIR, and no official SDK API moves a transcript across roots, so
|
|
76
|
-
* its failover is the one declared residual that must still flatten.
|
|
77
|
-
*/
|
|
78
|
-
export declare function decideFailoverContinuity(input: FailoverContinuityInput): ContinuityDecision;
|
|
79
65
|
/**
|
|
80
66
|
* Resume-first: a live session is never abandoned for a flattened re-send. Only a
|
|
81
|
-
* missing transcript
|
|
67
|
+
* missing transcript, an unrecoverable boundary, a model identity drift, or account
|
|
68
|
+
* drift on the config-dir lane on a persisted binding reaches `flatten`; every other
|
|
82
69
|
* divergence resolves to `fork` (same lineage, new branch) or `reattach` (same
|
|
83
70
|
* session, new query).
|
|
84
71
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-continuity.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/session-continuity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAGnE,MAAM,MAAM,uBAAuB,GAAG;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,oBAAoB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,0FAA0F;IAC1F,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,sGAAsG;IACtG,qBAAqB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACrC,KAAK,EAAE,uBAAuB,GAAG,SAAS,CAAC;IAC3C,OAAO,EAAE,yBAAyB,GAAG,SAAS,CAAC;IAC/C,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE;QAAE,gBAAgB,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/D,mBAAmB,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAC3B;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,GAClF;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,GAC9F;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"session-continuity.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/session-continuity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAGnE,MAAM,MAAM,uBAAuB,GAAG;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,oBAAoB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,0FAA0F;IAC1F,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,sGAAsG;IACtG,qBAAqB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACrC,KAAK,EAAE,uBAAuB,GAAG,SAAS,CAAC;IAC3C,OAAO,EAAE,yBAAyB,GAAG,SAAS,CAAC;IAC/C,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE;QAAE,gBAAgB,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/D,mBAAmB,EAAE,OAAO,CAAC;IAC7B,yJAAyJ;IACzJ,2BAA2B,EAAE,OAAO,CAAC;IACrC,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAC3B;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,GAClF;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,GAC9F;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,CAAC;AA6JjD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,uBAAuB,GAAG,kBAAkB,CA8BzF"}
|
|
@@ -41,9 +41,9 @@ function identityDrift(input, entry) {
|
|
|
41
41
|
if (entry.modelId !== input.modelId)
|
|
42
42
|
return "model_changed";
|
|
43
43
|
if (entry.systemPromptHash !== input.fingerprint.systemPromptHash)
|
|
44
|
-
return "
|
|
44
|
+
return "system_prompt_changed";
|
|
45
45
|
if (entry.toolsetHash !== input.fingerprint.toolsetHash)
|
|
46
|
-
return "
|
|
46
|
+
return "toolset_changed";
|
|
47
47
|
return null;
|
|
48
48
|
}
|
|
49
49
|
/**
|
|
@@ -96,8 +96,19 @@ function decideFromBinding(input, binding) {
|
|
|
96
96
|
if (!input.transcriptAvailable)
|
|
97
97
|
return { kind: "flatten", reason: "transcript_missing" };
|
|
98
98
|
const drift = identityDrift(input, binding);
|
|
99
|
-
|
|
99
|
+
// Model identity drift fails closed: the persisted identity no longer matches the turn.
|
|
100
|
+
// Account drift flattens only on the config-dir lane, whose per-account roots cannot
|
|
101
|
+
// share a transcript; on shared-root lanes it falls through like prompt/toolset drift
|
|
102
|
+
// (senpi#1432), so the retry checkpoint forks a same-turn failover at the pre-turn
|
|
103
|
+
// boundary and a matching prefix reattaches with reason account_changed.
|
|
104
|
+
if (drift === "model_changed")
|
|
100
105
|
return { kind: "flatten", reason: drift };
|
|
106
|
+
if (drift === "account_changed" && !input.crossAccountResumeSupported)
|
|
107
|
+
return { kind: "flatten", reason: "cross_root_unsupported" };
|
|
108
|
+
// Prompt/toolset drift instead reattaches like the live path
|
|
109
|
+
// (oh-my-openagent#7884) - a restart has no live query, so the resume builds a
|
|
110
|
+
// fresh query carrying the CURRENT options and hooks, and flattening would
|
|
111
|
+
// re-send the whole conversation for drift the SDK applies per-query anyway.
|
|
101
112
|
const retry = retryCheckpointDecision(input, binding);
|
|
102
113
|
if (retry)
|
|
103
114
|
return retry;
|
|
@@ -109,7 +120,7 @@ function decideFromBinding(input, binding) {
|
|
|
109
120
|
kind: "reattach",
|
|
110
121
|
sdkSessionId: binding.sdkSessionId,
|
|
111
122
|
from: binding.sentCount,
|
|
112
|
-
reason: "registry_miss",
|
|
123
|
+
reason: drift ?? "registry_miss",
|
|
113
124
|
};
|
|
114
125
|
}
|
|
115
126
|
return {
|
|
@@ -119,7 +130,12 @@ function decideFromBinding(input, binding) {
|
|
|
119
130
|
}
|
|
120
131
|
const shared = commonPrefixLength(binding.sentHashes, input.currentHashes);
|
|
121
132
|
if (shared === binding.sentCount) {
|
|
122
|
-
return {
|
|
133
|
+
return {
|
|
134
|
+
kind: "reattach",
|
|
135
|
+
sdkSessionId: binding.sdkSessionId,
|
|
136
|
+
from: binding.sentCount,
|
|
137
|
+
reason: drift ?? "registry_miss",
|
|
138
|
+
};
|
|
123
139
|
}
|
|
124
140
|
if (!binding.lastAssistantUuid)
|
|
125
141
|
return { kind: "flatten", reason: "registry_miss" };
|
|
@@ -131,36 +147,10 @@ function decideFromBinding(input, binding) {
|
|
|
131
147
|
reason: shared < binding.sentCount ? "history_rolled_back" : "sent_stream_diverged",
|
|
132
148
|
};
|
|
133
149
|
}
|
|
134
|
-
/**
|
|
135
|
-
* The config-dir lane keeps each account's credentials inside its own
|
|
136
|
-
* CLAUDE_CONFIG_DIR, and no official SDK API moves a transcript across roots, so
|
|
137
|
-
* its failover is the one declared residual that must still flatten.
|
|
138
|
-
*/
|
|
139
|
-
export function decideFailoverContinuity(input) {
|
|
140
|
-
const { entry } = input;
|
|
141
|
-
if (input.authLane === "config-dir")
|
|
142
|
-
return { kind: "flatten", reason: "cross_root_unsupported" };
|
|
143
|
-
if (input.crossAccountResumeSupported) {
|
|
144
|
-
return {
|
|
145
|
-
kind: "reattach",
|
|
146
|
-
sdkSessionId: entry.sdkSessionId,
|
|
147
|
-
from: entry.sentCount,
|
|
148
|
-
reason: "account_changed",
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
if (!entry.lastAssistantUuid)
|
|
152
|
-
return { kind: "flatten", reason: "branch_boundary_unavailable" };
|
|
153
|
-
return {
|
|
154
|
-
kind: "fork",
|
|
155
|
-
sdkSessionId: entry.sdkSessionId,
|
|
156
|
-
atUuid: entry.lastAssistantUuid,
|
|
157
|
-
from: entry.sentCount,
|
|
158
|
-
reason: "account_changed",
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
150
|
/**
|
|
162
151
|
* Resume-first: a live session is never abandoned for a flattened re-send. Only a
|
|
163
|
-
* missing transcript
|
|
152
|
+
* missing transcript, an unrecoverable boundary, a model identity drift, or account
|
|
153
|
+
* drift on the config-dir lane on a persisted binding reaches `flatten`; every other
|
|
164
154
|
* divergence resolves to `fork` (same lineage, new branch) or `reattach` (same
|
|
165
155
|
* session, new query).
|
|
166
156
|
*/
|