@code-yeongyu/senpi 2026.9.10 → 2026.9.12-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 +123 -0
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +5 -1
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session.d.ts +70 -9
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +183 -140
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +2 -0
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +49 -17
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/brand.d.ts +5 -0
- package/dist/core/brand.d.ts.map +1 -1
- package/dist/core/brand.js +13 -0
- package/dist/core/brand.js.map +1 -1
- package/dist/core/changelog-source.d.ts +8 -0
- package/dist/core/changelog-source.d.ts.map +1 -0
- package/dist/core/changelog-source.js +19 -0
- package/dist/core/changelog-source.js.map +1 -0
- package/dist/core/credential-accounts.d.ts +3 -0
- package/dist/core/credential-accounts.d.ts.map +1 -1
- package/dist/core/credential-accounts.js +20 -1
- package/dist/core/credential-accounts.js.map +1 -1
- package/dist/core/credential-pool/classify.d.ts.map +1 -1
- package/dist/core/credential-pool/classify.js +8 -0
- package/dist/core/credential-pool/classify.js.map +1 -1
- package/dist/core/cursor-history-admission.d.ts +50 -0
- package/dist/core/cursor-history-admission.d.ts.map +1 -0
- package/dist/core/cursor-history-admission.js +130 -0
- package/dist/core/cursor-history-admission.js.map +1 -0
- package/dist/core/extensions/builtin/account/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/account/index.js +7 -3
- package/dist/core/extensions/builtin/account/index.js.map +1 -1
- package/dist/core/extensions/builtin/account-display-name.d.ts +7 -0
- package/dist/core/extensions/builtin/account-display-name.d.ts.map +1 -0
- package/dist/core/extensions/builtin/account-display-name.js +40 -0
- package/dist/core/extensions/builtin/account-display-name.js.map +1 -0
- package/dist/core/extensions/builtin/ask-user/format.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ask-user/format.js +7 -2
- package/dist/core/extensions/builtin/ask-user/format.js.map +1 -1
- package/dist/core/extensions/builtin/ask-user/pending.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ask-user/pending.js +3 -0
- package/dist/core/extensions/builtin/ask-user/pending.js.map +1 -1
- 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 +21 -9
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-management.d.ts +1 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-management.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-management.js +11 -6
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-management.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/accounts.d.ts +9 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/accounts.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/accounts.js +10 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/accounts.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js +3 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.js +19 -10
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/settings.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/settings.js +3 -9
- package/dist/core/extensions/builtin/claude-sdk-oauth/settings.js.map +1 -1
- package/dist/core/extensions/builtin/config-reload/routine-settings.d.ts.map +1 -1
- package/dist/core/extensions/builtin/config-reload/routine-settings.js +1 -0
- package/dist/core/extensions/builtin/config-reload/routine-settings.js.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/account-command.d.ts.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/account-command.js +5 -3
- package/dist/core/extensions/builtin/cursor-cli-oauth/account-command.js.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/accounts.d.ts +1 -0
- package/dist/core/extensions/builtin/cursor-cli-oauth/accounts.d.ts.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/accounts.js.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/models.d.ts.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/models.js +2 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/models.js.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/settings.d.ts.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/settings.js +3 -9
- package/dist/core/extensions/builtin/cursor-cli-oauth/settings.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 +13 -1
- package/dist/core/extensions/builtin/goal/agent-end-continuation.js.map +1 -1
- package/dist/core/extensions/builtin/goal/prompt.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/prompt.js +11 -8
- package/dist/core/extensions/builtin/goal/prompt.js.map +1 -1
- package/dist/core/extensions/builtin/goal/terminal-provider-error.d.ts +1 -0
- package/dist/core/extensions/builtin/goal/terminal-provider-error.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/terminal-provider-error.js +28 -0
- package/dist/core/extensions/builtin/goal/terminal-provider-error.js.map +1 -1
- package/dist/core/extensions/builtin/goal/todo-gate.js +2 -2
- package/dist/core/extensions/builtin/goal/todo-gate.js.map +1 -1
- package/dist/core/extensions/builtin/goal/tool-registration.js +2 -2
- package/dist/core/extensions/builtin/goal/tool-registration.js.map +1 -1
- package/dist/core/extensions/builtin/gpt-account.d.ts.map +1 -1
- package/dist/core/extensions/builtin/gpt-account.js +19 -8
- package/dist/core/extensions/builtin/gpt-account.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-1-flash.d.ts +3 -0
- package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-1-flash.d.ts.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-1-flash.js +19 -0
- package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-1-flash.js.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.d.ts +6 -6
- 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 +26 -7
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/presets.js +29 -0
- package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.js +1 -0
- package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
- package/dist/core/high-reasoning-warning.d.ts.map +1 -1
- package/dist/core/high-reasoning-warning.js +5 -1
- package/dist/core/high-reasoning-warning.js.map +1 -1
- package/dist/core/manual-continue.d.ts +14 -0
- package/dist/core/manual-continue.d.ts.map +1 -1
- package/dist/core/manual-continue.js +13 -0
- package/dist/core/manual-continue.js.map +1 -1
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +2 -2
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/remote-catalog-merge.d.ts +16 -0
- package/dist/core/remote-catalog-merge.d.ts.map +1 -0
- package/dist/core/remote-catalog-merge.js +75 -0
- package/dist/core/remote-catalog-merge.js.map +1 -0
- package/dist/core/remote-catalog-provider.d.ts +3 -0
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +12 -40
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/session-entry-materializer.d.ts +12 -0
- package/dist/core/session-entry-materializer.d.ts.map +1 -0
- package/dist/core/session-entry-materializer.js +26 -0
- package/dist/core/session-entry-materializer.js.map +1 -0
- package/dist/core/session-manager.d.ts +38 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +60 -21
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-write-reservation.d.ts +9 -0
- package/dist/core/session-write-reservation.d.ts.map +1 -1
- package/dist/core/session-write-reservation.js +33 -0
- package/dist/core/session-write-reservation.js.map +1 -1
- package/dist/core/settings-manager.d.ts +3 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +10 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/modes/app-server/daemon/process.d.ts +6 -1
- package/dist/modes/app-server/daemon/process.d.ts.map +1 -1
- package/dist/modes/app-server/daemon/process.js +23 -4
- package/dist/modes/app-server/daemon/process.js.map +1 -1
- package/dist/modes/app-server/protocol/account.d.ts +2 -0
- package/dist/modes/app-server/protocol/account.d.ts.map +1 -1
- package/dist/modes/app-server/protocol/account.js.map +1 -1
- package/dist/modes/interactive/components/ask-user-async-widget.d.ts +2 -0
- package/dist/modes/interactive/components/ask-user-async-widget.d.ts.map +1 -1
- package/dist/modes/interactive/components/ask-user-async-widget.js +17 -1
- package/dist/modes/interactive/components/ask-user-async-widget.js.map +1 -1
- package/dist/modes/interactive/components/ask-user-question-keys.d.ts +1 -1
- package/dist/modes/interactive/components/ask-user-question-keys.d.ts.map +1 -1
- package/dist/modes/interactive/components/ask-user-question-keys.js +65 -17
- package/dist/modes/interactive/components/ask-user-question-keys.js.map +1 -1
- package/dist/modes/interactive/components/ask-user-question-render.d.ts +2 -1
- package/dist/modes/interactive/components/ask-user-question-render.d.ts.map +1 -1
- package/dist/modes/interactive/components/ask-user-question-render.js +39 -9
- package/dist/modes/interactive/components/ask-user-question-render.js.map +1 -1
- package/dist/modes/interactive/components/ask-user-question-state.d.ts +14 -4
- package/dist/modes/interactive/components/ask-user-question-state.d.ts.map +1 -1
- package/dist/modes/interactive/components/ask-user-question-state.js +63 -6
- package/dist/modes/interactive/components/ask-user-question-state.js.map +1 -1
- package/dist/modes/interactive/components/ask-user-question.d.ts +2 -0
- package/dist/modes/interactive/components/ask-user-question.d.ts.map +1 -1
- package/dist/modes/interactive/components/ask-user-question.js +27 -14
- package/dist/modes/interactive/components/ask-user-question.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +51 -19
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +11 -0
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +29 -9
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +7 -0
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/help-content.d.ts.map +1 -1
- package/dist/modes/interactive/help-content.js +4 -0
- package/dist/modes/interactive/help-content.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +13 -4
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +46 -17
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/input-tips.js +1 -1
- package/dist/modes/interactive/tips/catalog/input-tips.js.map +1 -1
- package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
- package/dist/modes/rpc/connection-handler.js +3 -1
- package/dist/modes/rpc/connection-handler.js.map +1 -1
- package/dist/modes/rpc/connection-question-bridge.js +1 -1
- package/dist/modes/rpc/connection-question-bridge.js.map +1 -1
- package/dist/modes/rpc/host-ensure.d.ts.map +1 -1
- package/dist/modes/rpc/host-ensure.js +33 -11
- package/dist/modes/rpc/host-ensure.js.map +1 -1
- package/dist/modes/rpc/host-lifecycle.d.ts +14 -0
- 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/rpc-input-validation.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-input-validation.js +2 -0
- package/dist/modes/rpc/rpc-input-validation.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +4 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js +1 -0
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/modes/rpc/session-path-reservations.d.ts +30 -0
- package/dist/modes/rpc/session-path-reservations.d.ts.map +1 -0
- package/dist/modes/rpc/session-path-reservations.js +58 -0
- package/dist/modes/rpc/session-path-reservations.js.map +1 -0
- package/dist/modes/rpc/session-registry.d.ts +3 -1
- package/dist/modes/rpc/session-registry.d.ts.map +1 -1
- package/dist/modes/rpc/session-registry.js.map +1 -1
- package/dist/modes/rpc/session-worker-client.d.ts +10 -8
- package/dist/modes/rpc/session-worker-client.d.ts.map +1 -1
- package/dist/modes/rpc/session-worker-client.js +14 -23
- package/dist/modes/rpc/session-worker-client.js.map +1 -1
- package/dist/modes/rpc/session-worker-credit.d.ts +17 -0
- package/dist/modes/rpc/session-worker-credit.d.ts.map +1 -0
- package/dist/modes/rpc/session-worker-credit.js +39 -0
- package/dist/modes/rpc/session-worker-credit.js.map +1 -0
- package/dist/modes/rpc/session-worker-protocol.d.ts +10 -0
- package/dist/modes/rpc/session-worker-protocol.d.ts.map +1 -1
- package/dist/modes/rpc/session-worker-protocol.js +2 -0
- package/dist/modes/rpc/session-worker-protocol.js.map +1 -1
- package/dist/modes/rpc/session-worker-signals.d.ts +7 -0
- package/dist/modes/rpc/session-worker-signals.d.ts.map +1 -0
- package/dist/modes/rpc/session-worker-signals.js +19 -0
- package/dist/modes/rpc/session-worker-signals.js.map +1 -0
- package/dist/modes/rpc/session-worker.js +12 -16
- package/dist/modes/rpc/session-worker.js.map +1 -1
- package/dist/modes/rpc/worker-session-registry.d.ts +12 -0
- package/dist/modes/rpc/worker-session-registry.d.ts.map +1 -1
- package/dist/modes/rpc/worker-session-registry.js +51 -24
- package/dist/modes/rpc/worker-session-registry.js.map +1 -1
- package/dist/utils/changelog.d.ts +3 -1
- package/dist/utils/changelog.d.ts.map +1 -1
- package/dist/utils/changelog.js +89 -23
- package/dist/utils/changelog.js.map +1 -1
- package/dist/utils/paths.d.ts +5 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +14 -1
- package/dist/utils/paths.js.map +1 -1
- package/docs/app-server.md +6 -0
- package/docs/extensions.md +19 -3
- package/docs/rpc.md +24 -6
- package/docs/settings.md +2 -1
- package/docs/tui.md +1 -1
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +52 -0
- package/node_modules/@code-yeongyu/senpi-codemode/README.md +5 -4
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/output/streaming-output-buffer.ts +58 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/output/streaming-output.ts +9 -64
- package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt-template.ts +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.d.ts +11 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.js +18 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts +1 -1
- 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 +5 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/discovery.d.ts +19 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/discovery.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/discovery.js +135 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/discovery.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/frames.d.ts +23 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/frames.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/frames.js +71 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/frames.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/gen/cascade_pb.d.ts +1261 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/gen/cascade_pb.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/gen/cascade_pb.js +431 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/gen/cascade_pb.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/metadata.d.ts +42 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/metadata.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/metadata.js +68 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/metadata.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/paths.d.ts +43 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/paths.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/paths.js +43 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/paths.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/request.d.ts +36 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/request.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/request.js +158 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/request.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/stream-state.d.ts +26 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/stream-state.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/stream-state.js +145 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/stream-state.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/trailer.d.ts +16 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/trailer.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/trailer.js +69 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/trailer.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/types.d.ts +12 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/types.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/types.js +3 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/types.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/unary.d.ts +26 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/unary.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/unary.js +61 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/unary.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/wire.d.ts +8 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/wire.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/wire.js +8 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/wire.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.d.ts +22 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.js +217 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.d.ts +5 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.js +23 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-callback.d.ts +25 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-callback.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-callback.js +124 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-callback.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-token.d.ts +18 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-token.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-token.js +101 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-token.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin.d.ts +19 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin.js +116 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-coding.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-coding.js +5 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-coding.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-identity.d.ts +24 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-identity.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-identity.js +86 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-identity.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.d.ts +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.js +5 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.d.ts +51 -4
- 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 +196 -7
- 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 +8 -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 +10 -0
- 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 +9 -1
- 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/bun-oauth.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/bun-oauth.js +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/bun-oauth.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/compat.d.ts +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/compat.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/compat.js +3 -0
- package/node_modules/@earendil-works/pi-ai/dist/compat.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/cursor/context-limit-store.d.ts +32 -0
- package/node_modules/@earendil-works/pi-ai/dist/cursor/context-limit-store.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/cursor/context-limit-store.js +62 -0
- package/node_modules/@earendil-works/pi-ai/dist/cursor/context-limit-store.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/cursor/store-migration.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/cursor/store-migration.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/cursor/store-migration.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +4 -4
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/model.d.ts +11 -1
- package/node_modules/@earendil-works/pi-ai/dist/model.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/model.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.d.ts +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.js +14 -5
- package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/all.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/all.js +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/all.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/cursor.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/cursor.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/cursor.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/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/fireworks.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/opencode-go.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/venice.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/devin.d.ts +12 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/devin.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/devin.js +62 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/devin.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/devin.models.d.ts +12 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/devin.models.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/devin.models.js +37 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/devin.models.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +3 -1
- 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/cursor-context-limit.d.ts +12 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/cursor-context-limit.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/cursor-context-limit.js +93 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/cursor-context-limit.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +4 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.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/dist/dollar-invocation-autocomplete.d.ts +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/dollar-invocation-autocomplete.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/dollar-invocation-autocomplete.js +55 -16
- package/node_modules/@earendil-works/pi-tui/dist/dollar-invocation-autocomplete.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-session-registry.js","sourceRoot":"","sources":["../../../src/modes/rpc/worker-session-registry.ts"],"names":[],"mappings":"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","sourcesContent":["import { isAbsolute } from \"node:path\";\nimport { ProviderScope } from \"@earendil-works/pi-ai/node/provider-scope\";\nimport type { CliRuntimeConfiguration } from \"../../main.ts\";\nimport {\n\ttype OpenRpcSession,\n\ttype RpcSessionEntry,\n\ttype RpcSessionLaunchProfile,\n\tRpcSessionRegistryError,\n} from \"./session-registry.ts\";\nimport { SessionWorkerClient } from \"./session-worker-client.ts\";\nimport { SESSION_WORKER_LIMITS } from \"./session-worker-protocol.ts\";\n\n/** Transport-side lifecycle owner. Caller paths are never inspected on this event loop. */\nexport class WorkerSessionRegistry {\n\tprivate readonly entries = new Map<string, RpcSessionEntry>();\n\tprivate readonly reservations = new Map<string, string>();\n\tprivate serial = 0;\n\treadonly closeGraceMs: number;\n\tprivate readonly now: () => number;\n\n\tprivate readonly options: { configuration: CliRuntimeConfiguration; closeGraceMs: number; now: () => number };\n\n\tconstructor(options: { configuration: CliRuntimeConfiguration; closeGraceMs: number; now: () => number }) {\n\t\tthis.options = options;\n\t\tthis.closeGraceMs = options.closeGraceMs;\n\t\tthis.now = options.now;\n\t}\n\n\tget size(): number {\n\t\treturn this.entries.size;\n\t}\n\n\tasync openSession(profile: RpcSessionLaunchProfile): Promise<OpenRpcSession> {\n\t\tif (!isAbsolute(profile.cwd) || (profile.sessionPath !== undefined && !isAbsolute(profile.sessionPath)))\n\t\t\tthrow new RpcSessionRegistryError(\"invalid_path\");\n\t\tif (profile.sessionPath) {\n\t\t\tconst key = this.knownReservationKey(profile.sessionPath);\n\t\t\tconst owner = key ? this.reservations.get(key) : undefined;\n\t\t\tif (key && owner) return this.attach(owner, key);\n\t\t}\n\t\tif (this.size >= SESSION_WORKER_LIMITS.workers) throw new Error(\"too_many_sessions\");\n\t\tconst handle = `rpc-${++this.serial}`;\n\t\tconst entry: RpcSessionEntry = {\n\t\t\tstate: \"opening\",\n\t\t\tscope: new ProviderScope(),\n\t\t\tprofile: Object.freeze({ ...profile }),\n\t\t\tcwd: profile.cwd,\n\t\t\tattachments: 1,\n\t\t\tlastCommandAt: this.now(),\n\t\t\tlifecycleMutex: Promise.resolve(),\n\t\t};\n\t\tconst worker = new SessionWorkerClient({\n\t\t\treserve: (path) => this.reserve(handle, path),\n\t\t\texit: () => {\n\t\t\t\tif (this.entries.get(handle) !== entry) return;\n\t\t\t\tentry.state = \"closed\";\n\t\t\t\tthis.entries.delete(handle);\n\t\t\t\tfor (const [path, owner] of this.reservations) if (owner === handle) this.reservations.delete(path);\n\t\t\t\tentry.closeResolve?.();\n\t\t\t},\n\t\t\tfailure: (error) => {\n\t\t\t\tentry.state = \"quarantined\";\n\t\t\t\tprocess.stderr.write(`senpi rpc session ${handle} quarantined: ${error}\\n`);\n\t\t\t},\n\t\t});\n\t\tentry.worker = worker;\n\t\tthis.entries.set(handle, entry);\n\t\ttry {\n\t\t\tconst path = await worker.prepare(this.options.configuration, profile);\n\t\t\tconst owner = this.reservations.get(path);\n\t\t\tif (owner) {\n\t\t\t\tconst attached = this.attach(owner, path);\n\t\t\t\tentry.state = \"quarantined\";\n\t\t\t\tworker.quarantine();\n\t\t\t\treturn attached;\n\t\t\t}\n\t\t\tif (!this.reserve(handle, path)) throw new RpcSessionRegistryError(\"session_path_in_use\");\n\t\t\tentry.reservationKey = path;\n\t\t\tentry.sessionPath = path;\n\t\t\tconst snapshot = await worker.commit();\n\t\t\tif (entry.state !== \"opening\") throw new RpcSessionRegistryError(\"session_closing\");\n\t\t\tentry.durableSessionId = snapshot.state.sessionId;\n\t\t\tentry.cwd = snapshot.state.cwd;\n\t\t\tentry.state = \"open\";\n\t\t\treturn this.openResult(handle, entry);\n\t\t} catch (cause) {\n\t\t\tentry.state = \"quarantined\";\n\t\t\tworker.quarantine();\n\t\t\tthrow cause;\n\t\t}\n\t}\n\n\tpeek(handle: string): RpcSessionEntry | undefined {\n\t\treturn this.entries.get(handle);\n\t}\n\n\tgetForCommand(handle: string, command: string): RpcSessionEntry {\n\t\tconst entry = this.entries.get(handle);\n\t\tif (!entry) throw new RpcSessionRegistryError(\"unknown_session\");\n\t\tif (\n\t\t\tentry.state === \"quarantined\" ||\n\t\t\t(entry.state === \"closing\" &&\n\t\t\t\t![\"abort\", \"abort_bash\", \"extension_ui_response\", \"extension_ui_progress\"].includes(command))\n\t\t)\n\t\t\tthrow new RpcSessionRegistryError(\"session_closing\");\n\t\tif (entry.state !== \"open\" && entry.state !== \"closing\") throw new RpcSessionRegistryError(\"unknown_session\");\n\t\tentry.lastCommandAt = this.now();\n\t\treturn entry;\n\t}\n\n\tbeginClose(handle: string, onRole?: (finalizer: boolean) => void): RpcSessionEntry {\n\t\tconst entry = this.entries.get(handle);\n\t\tif (!entry) throw new RpcSessionRegistryError(\"unknown_session\");\n\t\tif (entry.state === \"closing\" || entry.state === \"quarantined\") {\n\t\t\tonRole?.(false);\n\t\t\treturn entry;\n\t\t}\n\t\tif (entry.state !== \"open\" && entry.state !== \"opening\") throw new RpcSessionRegistryError(\"unknown_session\");\n\t\tentry.attachments--;\n\t\tif (entry.attachments > 0) return entry;\n\t\tentry.state = \"closing\";\n\t\tentry.closeCompletion = new Promise((resolve) => {\n\t\t\tentry.closeResolve = resolve;\n\t\t});\n\t\tonRole?.(true);\n\t\treturn entry;\n\t}\n\n\tclose(handle: string): Promise<void> {\n\t\tconst entry = this.beginClose(handle);\n\t\treturn entry.state === \"closing\" ? this.closeMarked(handle) : Promise.resolve();\n\t}\n\n\tasync closeMarked(handle: string): Promise<void> {\n\t\tconst entry = this.entries.get(handle);\n\t\tif (entry?.state !== \"closing\" || !entry.worker) throw new RpcSessionRegistryError(\"unknown_session\");\n\t\tif (entry.closeStarted) return entry.closeCompletion;\n\t\tentry.closeStarted = true;\n\t\t// Reply on a bounded deadline, but keep entry, attachments and reservations until exit.\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\t\tawait Promise.race([\n\t\t\tentry.worker.close(this.closeGraceMs),\n\t\t\tnew Promise<void>((resolve) => {\n\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\tif (entry.state !== \"closed\") entry.state = \"quarantined\";\n\t\t\t\t\tresolve();\n\t\t\t\t}, this.closeGraceMs);\n\t\t\t}),\n\t\t]);\n\t\tif (timer) clearTimeout(timer);\n\t}\n\n\tlist(): Array<{\n\t\tsessionId: string;\n\t\tdurableSessionId?: string;\n\t\tsessionPath?: string;\n\t\tcwd: string;\n\t\tname?: string;\n\t\tstatus: Exclude<RpcSessionEntry[\"state\"], \"quarantined\">;\n\t}> {\n\t\treturn [...this.entries].map(([sessionId, entry]) => {\n\t\t\tconst state = entry.worker?.snapshot?.state;\n\t\t\treturn {\n\t\t\t\tsessionId,\n\t\t\t\tdurableSessionId: state?.sessionId ?? entry.durableSessionId,\n\t\t\t\tsessionPath: state?.sessionFile ?? entry.sessionPath,\n\t\t\t\tcwd: state?.cwd ?? entry.cwd,\n\t\t\t\tname: state?.sessionName,\n\t\t\t\tstatus: entry.state === \"quarantined\" ? \"closing\" : entry.state,\n\t\t\t};\n\t\t});\n\t}\n\n\t/** Only compare spellings already tied to a granted identity; do not inspect caller paths here. */\n\tprivate knownReservationKey(path: string): string | undefined {\n\t\tif (this.reservations.has(path)) return path;\n\t\tfor (const entry of this.entries.values()) {\n\t\t\tif (entry.profile.sessionPath === path && entry.reservationKey) return entry.reservationKey;\n\t\t\tconst snapshot = entry.worker?.snapshot;\n\t\t\tif (snapshot?.state.sessionFile === path) return snapshot.sessionPath;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate attach(owner: string, path: string): OpenRpcSession {\n\t\tconst entry = this.entries.get(owner);\n\t\tif (entry?.state !== \"open\" || !entry.worker?.bindingReady || entry.worker.snapshot?.sessionPath !== path)\n\t\t\tthrow new RpcSessionRegistryError(\"session_path_in_use\");\n\t\tconst result = this.openResult(owner, entry);\n\t\tentry.attachments++;\n\t\tentry.lastCommandAt = this.now();\n\t\treturn { ...result, attached: true };\n\t}\n\n\tprivate reserve(handle: string, path: string): boolean {\n\t\tconst entry = this.entries.get(handle);\n\t\tif (!entry) return false;\n\t\tconst owner = this.reservations.get(path);\n\t\tif (owner) return owner === handle;\n\t\tif (entry.state !== \"opening\" && entry.state !== \"open\") return false;\n\t\tlet count = 0;\n\t\tfor (const current of this.reservations.values()) if (current === handle) count++;\n\t\tif (count >= SESSION_WORKER_LIMITS.reservations) return false;\n\t\tthis.reservations.set(path, handle);\n\t\treturn true;\n\t}\n\n\tprivate openResult(handle: string, entry: RpcSessionEntry): OpenRpcSession {\n\t\tconst state = entry.worker?.snapshot?.state;\n\t\tif (!state) throw new RpcSessionRegistryError(\"open_failed\");\n\t\treturn { sessionId: handle, durableSessionId: state.sessionId, sessionPath: state.sessionFile };\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"worker-session-registry.js","sourceRoot":"","sources":["../../../src/modes/rpc/worker-session-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAE1E,OAAO,EAEN,wBAAwB,EACxB,uBAAuB,GACvB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAIN,uBAAuB,GACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAA0B,MAAM,8BAA8B,CAAC;AAE7F,2FAA2F;AAC3F,MAAM,OAAO,qBAAqB;IASjC,YAAY,OAA4F;QARvF,YAAO,GAAG,IAAI,GAAG,EAA2B,CAAC;QAC7C,iBAAY,GAAG,IAAI,uBAAuB,EAAE,CAAC;QACtD,WAAM,GAAG,CAAC,CAAC;QAOlB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;QACzC,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IACxB,CAAC;IAED,IAAI,IAAI;QACP,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAAgC;QACjD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YACtG,MAAM,IAAI,uBAAuB,CAAC,cAAc,CAAC,CAAC;QACnD,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YAC1D,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAC7D,IAAI,GAAG,IAAI,KAAK;gBAAE,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAClD,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,IAAI,qBAAqB,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACrF,MAAM,MAAM,GAAG,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;QACtC,MAAM,KAAK,GAAoB;YAC9B,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,IAAI,aAAa,EAAE;YAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC;YACtC,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,WAAW,EAAE,CAAC;YACd,aAAa,EAAE,IAAI,CAAC,GAAG,EAAE;YACzB,cAAc,EAAE,OAAO,CAAC,OAAO,EAAE;SACjC,CAAC;QACF,MAAM,MAAM,GAAG,IAAI,mBAAmB,CAAC;YACtC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC;YAC7C,SAAS,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC;YAC3D,IAAI,EAAE,GAAG,EAAE;gBACV,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK;oBAAE,OAAO;gBAC/C,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC;gBACvB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC5B,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;gBACrC,KAAK,CAAC,YAAY,EAAE,EAAE,CAAC;YACxB,CAAC;YACD,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBAClB,KAAK,CAAC,KAAK,GAAG,aAAa,CAAC;gBAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,MAAM,iBAAiB,KAAK,IAAI,CAAC,CAAC;YAC7E,CAAC;SACD,CAAC,CAAC;QACH,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAChC,IAAI,CAAC;YACJ,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;YACvE,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC5C,IAAI,KAAK,EAAE,CAAC;gBACX,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;gBAC1C,KAAK,CAAC,KAAK,GAAG,aAAa,CAAC;gBAC5B,MAAM,CAAC,UAAU,EAAE,CAAC;gBACpB,OAAO,QAAQ,CAAC;YACjB,CAAC;YACD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YACzC,IAAI,KAAK,KAAK,SAAS;gBAAE,MAAM,IAAI,uBAAuB,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC,CAAC;YAC5F,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC;YAC5B,KAAK,CAAC,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;YAChE,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC;YACzB,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;YACvC,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;gBAAE,MAAM,IAAI,uBAAuB,CAAC,iBAAiB,CAAC,CAAC;YACpF,KAAK,CAAC,gBAAgB,GAAG,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC;YAClD,KAAK,CAAC,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC;YAC/B,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC;YACrB,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,KAAK,CAAC,KAAK,GAAG,aAAa,CAAC;YAC5B,MAAM,CAAC,UAAU,EAAE,CAAC;YACpB,MAAM,KAAK,CAAC;QACb,CAAC;IACF,CAAC;IAED,IAAI,CAAC,MAAc;QAClB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAED,aAAa,CAAC,MAAc,EAAE,OAAe;QAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,uBAAuB,CAAC,iBAAiB,CAAC,CAAC;QACjE,IACC,KAAK,CAAC,KAAK,KAAK,aAAa;YAC7B,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS;gBACzB,CAAC,CAAC,OAAO,EAAE,YAAY,EAAE,uBAAuB,EAAE,uBAAuB,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAE9F,MAAM,IAAI,uBAAuB,CAAC,iBAAiB,CAAC,CAAC;QACtD,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;YAAE,MAAM,IAAI,uBAAuB,CAAC,iBAAiB,CAAC,CAAC;QAC9G,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACjC,OAAO,KAAK,CAAC;IACd,CAAC;IAED,UAAU,CAAC,MAAc,EAAE,MAAqC;QAC/D,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,uBAAuB,CAAC,iBAAiB,CAAC,CAAC;QACjE,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,KAAK,aAAa,EAAE,CAAC;YAChE,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC;YAChB,OAAO,KAAK,CAAC;QACd,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;YAAE,MAAM,IAAI,uBAAuB,CAAC,iBAAiB,CAAC,CAAC;QAC9G,KAAK,CAAC,WAAW,EAAE,CAAC;QACpB,IAAI,KAAK,CAAC,WAAW,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QACxC,KAAK,CAAC,KAAK,GAAG,SAAS,CAAC;QACxB,KAAK,CAAC,eAAe,GAAG,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC/C,KAAK,CAAC,YAAY,GAAG,OAAO,CAAC;QAC9B,CAAC,CAAC,CAAC;QACH,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC;QACf,OAAO,KAAK,CAAC;IACd,CAAC;IAED,KAAK,CAAC,MAAc;QACnB,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACtC,OAAO,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACjF,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,MAAc;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,KAAK,EAAE,KAAK,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,MAAM,IAAI,uBAAuB,CAAC,iBAAiB,CAAC,CAAC;QACtG,IAAI,KAAK,CAAC,YAAY;YAAE,OAAO,KAAK,CAAC,eAAe,CAAC;QACrD,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;QAC1B,wFAAwF;QACxF,IAAI,KAAgD,CAAC;QACrD,MAAM,OAAO,CAAC,IAAI,CAAC;YAClB,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC;YACrC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBAC7B,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;oBACvB,IAAI,KAAK,CAAC,KAAK,KAAK,QAAQ;wBAAE,KAAK,CAAC,KAAK,GAAG,aAAa,CAAC;oBAC1D,OAAO,EAAE,CAAC;gBACX,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;YACvB,CAAC,CAAC;SACF,CAAC,CAAC;QACH,IAAI,KAAK;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAED,IAAI;QAQH,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,EAAE;YACnD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC;YAC5C,OAAO;gBACN,SAAS;gBACT,gBAAgB,EAAE,KAAK,EAAE,SAAS,IAAI,KAAK,CAAC,gBAAgB;gBAC5D,WAAW,EAAE,KAAK,EAAE,WAAW,IAAI,KAAK,CAAC,WAAW;gBACpD,GAAG,EAAE,KAAK,EAAE,GAAG,IAAI,KAAK,CAAC,GAAG;gBAC5B,IAAI,EAAE,KAAK,EAAE,WAAW;gBACxB,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK;aAC/D,CAAC;QACH,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,mGAAmG;IAC3F,mBAAmB,CAAC,IAAY;QACvC,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAC/C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YAC3C,8EAA8E;YAC9E,kEAAkE;YAClE,IACC,KAAK,CAAC,OAAO,CAAC,WAAW,KAAK,IAAI;gBAClC,KAAK,CAAC,gBAAgB;gBACtB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,gBAAgB,CAAC;gBAE/C,OAAO,KAAK,CAAC,gBAAgB,CAAC;YAC/B,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC;YACxC,IAAI,QAAQ,EAAE,KAAK,CAAC,WAAW,KAAK,IAAI;gBAAE,OAAO,QAAQ,CAAC,WAAW,CAAC;QACvE,CAAC;QACD,OAAO,SAAS,CAAC;IAClB,CAAC;IAEO,MAAM,CAAC,KAAa,EAAE,IAAY;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,KAAK,EAAE,KAAK,KAAK,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,YAAY,IAAI,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,WAAW,KAAK,IAAI;YACxG,MAAM,IAAI,uBAAuB,CAAC,qBAAqB,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC7C,KAAK,CAAC,WAAW,EAAE,CAAC;QACpB,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACjC,OAAO,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACtC,CAAC;IAED,wFAAwF;IACxF,gBAAgB,CAAC,MAAc;QAC9B,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IAEO,OAAO,CAAC,MAAc,EAAE,IAAY;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK;YAAE,OAAO,UAAU,CAAC;QAC9B,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,MAAM;YAAE,OAAO,SAAS,CAAC;QAC/D,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM;YAAE,OAAO,UAAU,CAAC;QAC3E,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7E,CAAC;IAED;;;;;;OAMG;IACK,SAAS,CAAC,MAAc,EAAE,SAA4B;QAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,KAAK,EAAE,KAAK,KAAK,MAAM;YAAE,OAAO;QACpC,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,WAAW,CAAC;QACxD,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,CAAC;QAChE,IAAI,CAAC,WAAW;YAAE,OAAO;QACzB,KAAK,CAAC,cAAc,GAAG,WAAW,CAAC;QACnC,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;IAED,mGAAmG;IAC3F,eAAe,CAAC,KAAsB;QAC7C,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7E,IAAI,CAAC,QAAQ;YAAE,OAAO,SAAS,CAAC;QAChC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,gBAAgB,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC;IACpF,CAAC;IAEO,UAAU,CAAC,MAAc,EAAE,KAAsB;QACxD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC;QAC5C,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,uBAAuB,CAAC,aAAa,CAAC,CAAC;QAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAK,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC;IACjG,CAAC;CACD","sourcesContent":["import { isAbsolute } from \"node:path\";\nimport { ProviderScope } from \"@earendil-works/pi-ai/node/provider-scope\";\nimport type { CliRuntimeConfiguration } from \"../../main.ts\";\nimport {\n\ttype LiveWorkerPaths,\n\tRESERVATION_DENIAL_CODES,\n\tSessionPathReservations,\n} from \"./session-path-reservations.ts\";\nimport {\n\ttype OpenRpcSession,\n\ttype RpcSessionEntry,\n\ttype RpcSessionLaunchProfile,\n\tRpcSessionRegistryError,\n} from \"./session-registry.ts\";\nimport { SessionWorkerClient } from \"./session-worker-client.ts\";\nimport { SESSION_WORKER_LIMITS, type SessionWriteGrant } from \"./session-worker-protocol.ts\";\n\n/** Transport-side lifecycle owner. Caller paths are never inspected on this event loop. */\nexport class WorkerSessionRegistry {\n\tprivate readonly entries = new Map<string, RpcSessionEntry>();\n\tprivate readonly reservations = new SessionPathReservations();\n\tprivate serial = 0;\n\treadonly closeGraceMs: number;\n\tprivate readonly now: () => number;\n\n\tprivate readonly options: { configuration: CliRuntimeConfiguration; closeGraceMs: number; now: () => number };\n\n\tconstructor(options: { configuration: CliRuntimeConfiguration; closeGraceMs: number; now: () => number }) {\n\t\tthis.options = options;\n\t\tthis.closeGraceMs = options.closeGraceMs;\n\t\tthis.now = options.now;\n\t}\n\n\tget size(): number {\n\t\treturn this.entries.size;\n\t}\n\n\tasync openSession(profile: RpcSessionLaunchProfile): Promise<OpenRpcSession> {\n\t\tif (!isAbsolute(profile.cwd) || (profile.sessionPath !== undefined && !isAbsolute(profile.sessionPath)))\n\t\t\tthrow new RpcSessionRegistryError(\"invalid_path\");\n\t\tif (profile.sessionPath) {\n\t\t\tconst key = this.knownReservationKey(profile.sessionPath);\n\t\t\tconst owner = key ? this.reservations.owner(key) : undefined;\n\t\t\tif (key && owner) return this.attach(owner, key);\n\t\t}\n\t\tif (this.size >= SESSION_WORKER_LIMITS.workers) throw new Error(\"too_many_sessions\");\n\t\tconst handle = `rpc-${++this.serial}`;\n\t\tconst entry: RpcSessionEntry = {\n\t\t\tstate: \"opening\",\n\t\t\tscope: new ProviderScope(),\n\t\t\tprofile: Object.freeze({ ...profile }),\n\t\t\tcwd: profile.cwd,\n\t\t\tattachments: 1,\n\t\t\tlastCommandAt: this.now(),\n\t\t\tlifecycleMutex: Promise.resolve(),\n\t\t};\n\t\tconst worker = new SessionWorkerClient({\n\t\t\treserve: (path) => this.reserve(handle, path),\n\t\t\treconcile: (livePaths) => this.reconcile(handle, livePaths),\n\t\t\texit: () => {\n\t\t\t\tif (this.entries.get(handle) !== entry) return;\n\t\t\t\tentry.state = \"closed\";\n\t\t\t\tthis.entries.delete(handle);\n\t\t\t\tthis.reservations.releaseAll(handle);\n\t\t\t\tentry.closeResolve?.();\n\t\t\t},\n\t\t\tfailure: (error) => {\n\t\t\t\tentry.state = \"quarantined\";\n\t\t\t\tprocess.stderr.write(`senpi rpc session ${handle} quarantined: ${error}\\n`);\n\t\t\t},\n\t\t});\n\t\tentry.worker = worker;\n\t\tthis.entries.set(handle, entry);\n\t\ttry {\n\t\t\tconst path = await worker.prepare(this.options.configuration, profile);\n\t\t\tconst owner = this.reservations.owner(path);\n\t\t\tif (owner) {\n\t\t\t\tconst attached = this.attach(owner, path);\n\t\t\t\tentry.state = \"quarantined\";\n\t\t\t\tworker.quarantine();\n\t\t\t\treturn attached;\n\t\t\t}\n\t\t\tconst grant = this.reserve(handle, path);\n\t\t\tif (grant !== \"granted\") throw new RpcSessionRegistryError(RESERVATION_DENIAL_CODES[grant]);\n\t\t\tentry.reservationKey = path;\n\t\t\tentry.requestedPathKey = profile.sessionPath ? path : undefined;\n\t\t\tentry.sessionPath = path;\n\t\t\tconst snapshot = await worker.commit();\n\t\t\tif (entry.state !== \"opening\") throw new RpcSessionRegistryError(\"session_closing\");\n\t\t\tentry.durableSessionId = snapshot.state.sessionId;\n\t\t\tentry.cwd = snapshot.state.cwd;\n\t\t\tentry.state = \"open\";\n\t\t\treturn this.openResult(handle, entry);\n\t\t} catch (cause) {\n\t\t\tentry.state = \"quarantined\";\n\t\t\tworker.quarantine();\n\t\t\tthrow cause;\n\t\t}\n\t}\n\n\tpeek(handle: string): RpcSessionEntry | undefined {\n\t\treturn this.entries.get(handle);\n\t}\n\n\tgetForCommand(handle: string, command: string): RpcSessionEntry {\n\t\tconst entry = this.entries.get(handle);\n\t\tif (!entry) throw new RpcSessionRegistryError(\"unknown_session\");\n\t\tif (\n\t\t\tentry.state === \"quarantined\" ||\n\t\t\t(entry.state === \"closing\" &&\n\t\t\t\t![\"abort\", \"abort_bash\", \"extension_ui_response\", \"extension_ui_progress\"].includes(command))\n\t\t)\n\t\t\tthrow new RpcSessionRegistryError(\"session_closing\");\n\t\tif (entry.state !== \"open\" && entry.state !== \"closing\") throw new RpcSessionRegistryError(\"unknown_session\");\n\t\tentry.lastCommandAt = this.now();\n\t\treturn entry;\n\t}\n\n\tbeginClose(handle: string, onRole?: (finalizer: boolean) => void): RpcSessionEntry {\n\t\tconst entry = this.entries.get(handle);\n\t\tif (!entry) throw new RpcSessionRegistryError(\"unknown_session\");\n\t\tif (entry.state === \"closing\" || entry.state === \"quarantined\") {\n\t\t\tonRole?.(false);\n\t\t\treturn entry;\n\t\t}\n\t\tif (entry.state !== \"open\" && entry.state !== \"opening\") throw new RpcSessionRegistryError(\"unknown_session\");\n\t\tentry.attachments--;\n\t\tif (entry.attachments > 0) return entry;\n\t\tentry.state = \"closing\";\n\t\tentry.closeCompletion = new Promise((resolve) => {\n\t\t\tentry.closeResolve = resolve;\n\t\t});\n\t\tonRole?.(true);\n\t\treturn entry;\n\t}\n\n\tclose(handle: string): Promise<void> {\n\t\tconst entry = this.beginClose(handle);\n\t\treturn entry.state === \"closing\" ? this.closeMarked(handle) : Promise.resolve();\n\t}\n\n\tasync closeMarked(handle: string): Promise<void> {\n\t\tconst entry = this.entries.get(handle);\n\t\tif (entry?.state !== \"closing\" || !entry.worker) throw new RpcSessionRegistryError(\"unknown_session\");\n\t\tif (entry.closeStarted) return entry.closeCompletion;\n\t\tentry.closeStarted = true;\n\t\t// Reply on a bounded deadline, but keep entry, attachments and reservations until exit.\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\t\tawait Promise.race([\n\t\t\tentry.worker.close(this.closeGraceMs),\n\t\t\tnew Promise<void>((resolve) => {\n\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\tif (entry.state !== \"closed\") entry.state = \"quarantined\";\n\t\t\t\t\tresolve();\n\t\t\t\t}, this.closeGraceMs);\n\t\t\t}),\n\t\t]);\n\t\tif (timer) clearTimeout(timer);\n\t}\n\n\tlist(): Array<{\n\t\tsessionId: string;\n\t\tdurableSessionId?: string;\n\t\tsessionPath?: string;\n\t\tcwd: string;\n\t\tname?: string;\n\t\tstatus: Exclude<RpcSessionEntry[\"state\"], \"quarantined\">;\n\t}> {\n\t\treturn [...this.entries].map(([sessionId, entry]) => {\n\t\t\tconst state = entry.worker?.snapshot?.state;\n\t\t\treturn {\n\t\t\t\tsessionId,\n\t\t\t\tdurableSessionId: state?.sessionId ?? entry.durableSessionId,\n\t\t\t\tsessionPath: state?.sessionFile ?? entry.sessionPath,\n\t\t\t\tcwd: state?.cwd ?? entry.cwd,\n\t\t\t\tname: state?.sessionName,\n\t\t\t\tstatus: entry.state === \"quarantined\" ? \"closing\" : entry.state,\n\t\t\t};\n\t\t});\n\t}\n\n\t/** Only compare spellings already tied to a granted identity; do not inspect caller paths here. */\n\tprivate knownReservationKey(path: string): string | undefined {\n\t\tif (this.reservations.owner(path)) return path;\n\t\tfor (const entry of this.entries.values()) {\n\t\t\t// An opening spelling maps only while the key granted for it is still held: a\n\t\t\t// superseded path belongs to nobody and must open its own worker.\n\t\t\tif (\n\t\t\t\tentry.profile.sessionPath === path &&\n\t\t\t\tentry.requestedPathKey &&\n\t\t\t\tthis.reservations.owner(entry.requestedPathKey)\n\t\t\t)\n\t\t\t\treturn entry.requestedPathKey;\n\t\t\tconst snapshot = entry.worker?.snapshot;\n\t\t\tif (snapshot?.state.sessionFile === path) return snapshot.sessionPath;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate attach(owner: string, path: string): OpenRpcSession {\n\t\tconst entry = this.entries.get(owner);\n\t\tif (entry?.state !== \"open\" || !entry.worker?.bindingReady || entry.worker.snapshot?.sessionPath !== path)\n\t\t\tthrow new RpcSessionRegistryError(\"session_path_in_use\");\n\t\tconst result = this.openResult(owner, entry);\n\t\tentry.attachments++;\n\t\tentry.lastCommandAt = this.now();\n\t\treturn { ...result, attached: true };\n\t}\n\n\t/** Granted paths currently held by a handle; the per-worker budget is bounded by it. */\n\treservationCount(handle: string): number {\n\t\treturn this.reservations.count(handle);\n\t}\n\n\tprivate reserve(handle: string, path: string): SessionWriteGrant {\n\t\tconst entry = this.entries.get(handle);\n\t\tif (!entry) return \"conflict\";\n\t\tif (this.reservations.owner(path) === handle) return \"granted\";\n\t\tif (entry.state !== \"opening\" && entry.state !== \"open\") return \"conflict\";\n\t\treturn this.reservations.reserve(handle, path, this.liveWorkerPaths(entry));\n\t}\n\n\t/**\n\t * Releases the grants a worker's latest snapshot no longer claims.\n\t *\n\t * Only a fully open entry reports live writers. An entry still opening, closing or\n\t * quarantined keeps every grant until its real exit, because a worker stuck in a\n\t * syscall can still be writing a path it can no longer report.\n\t */\n\tprivate reconcile(handle: string, livePaths: readonly string[]): void {\n\t\tconst entry = this.entries.get(handle);\n\t\tif (entry?.state !== \"open\") return;\n\t\tconst sessionPath = entry.worker?.snapshot?.sessionPath;\n\t\tthis.reservations.reconcile(handle, { livePaths, sessionPath });\n\t\tif (!sessionPath) return;\n\t\tentry.reservationKey = sessionPath;\n\t\tentry.sessionPath = sessionPath;\n\t}\n\n\t/** The live view a full budget is reconciled against; absent while the entry cannot report one. */\n\tprivate liveWorkerPaths(entry: RpcSessionEntry): LiveWorkerPaths | undefined {\n\t\tconst snapshot = entry.state === \"open\" ? entry.worker?.snapshot : undefined;\n\t\tif (!snapshot) return undefined;\n\t\treturn { livePaths: snapshot.liveSessionPaths, sessionPath: snapshot.sessionPath };\n\t}\n\n\tprivate openResult(handle: string, entry: RpcSessionEntry): OpenRpcSession {\n\t\tconst state = entry.worker?.snapshot?.state;\n\t\tif (!state) throw new RpcSessionRegistryError(\"open_failed\");\n\t\treturn { sessionId: handle, durableSessionId: state.sessionId, sessionPath: state.sessionFile };\n\t}\n}\n"]}
|
|
@@ -2,6 +2,8 @@ export interface ChangelogEntry {
|
|
|
2
2
|
major: number;
|
|
3
3
|
minor: number;
|
|
4
4
|
patch: number;
|
|
5
|
+
suffix?: string;
|
|
6
|
+
version?: string;
|
|
5
7
|
content: string;
|
|
6
8
|
}
|
|
7
9
|
export declare function normalizeChangelogLinks(markdown: string, version: string | ChangelogEntry): string;
|
|
@@ -17,6 +19,6 @@ export declare function compareVersions(v1: ChangelogEntry, v2: ChangelogEntry):
|
|
|
17
19
|
/**
|
|
18
20
|
* Get entries newer than lastVersion
|
|
19
21
|
*/
|
|
20
|
-
export declare function getNewEntries(entries: ChangelogEntry[], lastVersion: string): ChangelogEntry[];
|
|
22
|
+
export declare function getNewEntries(entries: ChangelogEntry[], lastVersion: string, currentVersion?: string): ChangelogEntry[];
|
|
21
23
|
export { getChangelogPath } from "../config.ts";
|
|
22
24
|
//# sourceMappingURL=changelog.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"changelog.d.ts","sourceRoot":"","sources":["../../src/utils/changelog.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"changelog.d.ts","sourceRoot":"","sources":["../../src/utils/changelog.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CAChB;AAuID,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,cAAc,GAAG,MAAM,CAKlG;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,cAAc,EAAE,CAgFtE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,cAAc,GAAG,MAAM,CAE9E;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC5B,OAAO,EAAE,cAAc,EAAE,EACzB,WAAW,EAAE,MAAM,EACnB,cAAc,CAAC,EAAE,MAAM,GACrB,cAAc,EAAE,CAiBlB;AAGD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/utils/changelog.js
CHANGED
|
@@ -1,12 +1,56 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { existsSync, readFileSync } from "fs";
|
|
3
|
+
import { compare, valid } from "semver";
|
|
3
4
|
const GITHUB_REPO = "earendil-works/pi";
|
|
4
5
|
const CHANGELOG_LINK_BASE_PATH = "packages/coding-agent";
|
|
5
6
|
const LEGACY_REPO_RE = /^https:\/\/github\.com\/(?:badlogic|earendil-works)\/pi-mono(?=\/|$)/;
|
|
6
7
|
const URL_SCHEME_RE = /^[a-z][a-z0-9+.-]*:/i;
|
|
7
8
|
const INLINE_MARKDOWN_LINK_RE = /(!?\[[^\]\n]+\]\()([^\s)]+)((?:\s+[^)]*)?\))/g;
|
|
8
9
|
function entryVersion(entry) {
|
|
9
|
-
return `${entry.major}.${entry.minor}.${entry.patch}`;
|
|
10
|
+
return entry.version ?? `${entry.major}.${entry.minor}.${entry.patch}${entry.suffix ? `-${entry.suffix}` : ""}`;
|
|
11
|
+
}
|
|
12
|
+
const VERSION_RE = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
13
|
+
const CALVER_RE = /^(\d{4})\.(\d{1,2})\.(\d{1,2})(?:-([2-9]\d*))?$/;
|
|
14
|
+
function isValidDate(value) {
|
|
15
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value);
|
|
16
|
+
if (!match)
|
|
17
|
+
return false;
|
|
18
|
+
const year = Number(match[1]);
|
|
19
|
+
const month = Number(match[2]);
|
|
20
|
+
const day = Number(match[3]);
|
|
21
|
+
const date = new Date(Date.UTC(year, month - 1, day));
|
|
22
|
+
return date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day;
|
|
23
|
+
}
|
|
24
|
+
function isForeignVersion(version) {
|
|
25
|
+
return version.startsWith("0.0.0-omob.") || /^\d+\.\d+\.\d+-0\.beta\./.test(version);
|
|
26
|
+
}
|
|
27
|
+
function compareVersionStrings(left, right) {
|
|
28
|
+
const leftCalver = CALVER_RE.exec(left);
|
|
29
|
+
const rightCalver = CALVER_RE.exec(right);
|
|
30
|
+
if (leftCalver && rightCalver) {
|
|
31
|
+
const leftParts = [
|
|
32
|
+
Number(leftCalver[1]),
|
|
33
|
+
Number(leftCalver[2]),
|
|
34
|
+
Number(leftCalver[3]),
|
|
35
|
+
Number(leftCalver[4] ?? 1),
|
|
36
|
+
];
|
|
37
|
+
const rightParts = [
|
|
38
|
+
Number(rightCalver[1]),
|
|
39
|
+
Number(rightCalver[2]),
|
|
40
|
+
Number(rightCalver[3]),
|
|
41
|
+
Number(rightCalver[4] ?? 1),
|
|
42
|
+
];
|
|
43
|
+
for (let index = 0; index < leftParts.length; index += 1) {
|
|
44
|
+
if (leftParts[index] !== rightParts[index])
|
|
45
|
+
return leftParts[index] < rightParts[index] ? -1 : 1;
|
|
46
|
+
}
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
const leftValid = valid(left);
|
|
50
|
+
const rightValid = valid(right);
|
|
51
|
+
if (!leftValid || !rightValid || isForeignVersion(left) !== isForeignVersion(right))
|
|
52
|
+
return undefined;
|
|
53
|
+
return Math.sign(compare(leftValid, rightValid));
|
|
10
54
|
}
|
|
11
55
|
function normalizeTag(version) {
|
|
12
56
|
const versionString = typeof version === "string" ? version : entryVersion(version);
|
|
@@ -91,9 +135,21 @@ export function parseChangelog(changelogPath) {
|
|
|
91
135
|
const entries = [];
|
|
92
136
|
let currentLines = [];
|
|
93
137
|
let currentVersion = null;
|
|
138
|
+
let fence = null;
|
|
94
139
|
for (const line of lines) {
|
|
95
|
-
|
|
96
|
-
if (
|
|
140
|
+
const fenceMatch = /^ {0,3}(`{3,}|~{3,})/.exec(line);
|
|
141
|
+
if (fenceMatch) {
|
|
142
|
+
const character = fenceMatch[1][0] === "`" ? "`" : "~";
|
|
143
|
+
if (!fence)
|
|
144
|
+
fence = { character, length: fenceMatch[1].length };
|
|
145
|
+
else if (fence.character === character && fenceMatch[1].length >= fence.length)
|
|
146
|
+
fence = null;
|
|
147
|
+
}
|
|
148
|
+
const headerMatch = fence === null
|
|
149
|
+
? /^##[ \t]+(?:\[([0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?)\]|([0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)))(?:[ \t]+-[ \t]+(\d{4}-\d{2}-\d{2}))?[ \t]*$/.exec(line)
|
|
150
|
+
: null;
|
|
151
|
+
if (headerMatch ||
|
|
152
|
+
(fence === null && /^##[ \t]+\[?Unreleased\]?[ \t]*(?:-[ \t]+\d{4}-\d{2}-\d{2})?[ \t]*$/.test(line))) {
|
|
97
153
|
// Save previous entry if exists
|
|
98
154
|
if (currentVersion && currentLines.length > 0) {
|
|
99
155
|
entries.push({
|
|
@@ -102,14 +158,21 @@ export function parseChangelog(changelogPath) {
|
|
|
102
158
|
});
|
|
103
159
|
}
|
|
104
160
|
// Try to parse version from this line
|
|
105
|
-
|
|
106
|
-
|
|
161
|
+
if (headerMatch && isValidDate(headerMatch[3] ?? "2026-01-01")) {
|
|
162
|
+
const parts = /^(\d+)\.(\d+)\.(\d+)(?:-(.*))?$/.exec(headerMatch[1] ?? headerMatch[2]);
|
|
163
|
+
if (!parts) {
|
|
164
|
+
currentVersion = null;
|
|
165
|
+
currentLines = [];
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
107
168
|
currentVersion = {
|
|
108
|
-
major: Number
|
|
109
|
-
minor: Number
|
|
110
|
-
patch: Number
|
|
169
|
+
major: Number(parts[1]),
|
|
170
|
+
minor: Number(parts[2]),
|
|
171
|
+
patch: Number(parts[3]),
|
|
172
|
+
suffix: parts[4],
|
|
173
|
+
version: `${parts[1]}.${parts[2]}.${parts[3]}${parts[4] ? `-${parts[4]}` : ""}`,
|
|
111
174
|
};
|
|
112
|
-
currentLines = [
|
|
175
|
+
currentLines = [];
|
|
113
176
|
}
|
|
114
177
|
else {
|
|
115
178
|
// Reset if we can't parse version
|
|
@@ -140,25 +203,28 @@ export function parseChangelog(changelogPath) {
|
|
|
140
203
|
* Compare versions. Returns: -1 if v1 < v2, 0 if v1 === v2, 1 if v1 > v2
|
|
141
204
|
*/
|
|
142
205
|
export function compareVersions(v1, v2) {
|
|
143
|
-
|
|
144
|
-
return v1.major - v2.major;
|
|
145
|
-
if (v1.minor !== v2.minor)
|
|
146
|
-
return v1.minor - v2.minor;
|
|
147
|
-
return v1.patch - v2.patch;
|
|
206
|
+
return compareVersionStrings(entryVersion(v1), entryVersion(v2)) ?? 0;
|
|
148
207
|
}
|
|
149
208
|
/**
|
|
150
209
|
* Get entries newer than lastVersion
|
|
151
210
|
*/
|
|
152
|
-
export function getNewEntries(entries, lastVersion) {
|
|
211
|
+
export function getNewEntries(entries, lastVersion, currentVersion) {
|
|
153
212
|
// Parse lastVersion
|
|
154
|
-
const parts = lastVersion.
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
213
|
+
const parts = lastVersion.match(/^(\d+)\.(\d+)\.(\d+)(?:-(.*))?$/);
|
|
214
|
+
if (!parts || isForeignVersion(lastVersion))
|
|
215
|
+
return [];
|
|
216
|
+
const current = currentVersion && VERSION_RE.test(currentVersion) ? currentVersion : undefined;
|
|
217
|
+
if (current && (isForeignVersion(current) || compareVersionStrings(lastVersion, current) === undefined))
|
|
218
|
+
return [];
|
|
219
|
+
return entries.filter((entry, index, all) => {
|
|
220
|
+
const version = entryVersion(entry);
|
|
221
|
+
const lower = compareVersionStrings(version, lastVersion);
|
|
222
|
+
const upper = current ? compareVersionStrings(version, current) : 0;
|
|
223
|
+
return (lower !== undefined &&
|
|
224
|
+
lower > 0 &&
|
|
225
|
+
(upper === undefined || upper <= 0) &&
|
|
226
|
+
all.findIndex((candidate) => entryVersion(candidate) === version) === index);
|
|
227
|
+
});
|
|
162
228
|
}
|
|
163
229
|
// Re-export getChangelogPath from paths.ts for convenience
|
|
164
230
|
export { getChangelogPath } from "../config.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"changelog.js","sourceRoot":"","sources":["../../src/utils/changelog.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\nimport { existsSync, readFileSync } from \"fs\";\n\nexport interface ChangelogEntry {\n\tmajor: number;\n\tminor: number;\n\tpatch: number;\n\tcontent: string;\n}\n\nconst GITHUB_REPO = \"earendil-works/pi\";\nconst CHANGELOG_LINK_BASE_PATH = \"packages/coding-agent\";\nconst LEGACY_REPO_RE = /^https:\\/\\/github\\.com\\/(?:badlogic|earendil-works)\\/pi-mono(?=\\/|$)/;\nconst URL_SCHEME_RE = /^[a-z][a-z0-9+.-]*:/i;\nconst INLINE_MARKDOWN_LINK_RE = /(!?\\[[^\\]\\n]+\\]\\()([^\\s)]+)((?:\\s+[^)]*)?\\))/g;\n\nfunction entryVersion(entry: ChangelogEntry): string {\n\treturn `${entry.major}.${entry.minor}.${entry.patch}`;\n}\n\nfunction normalizeTag(version: string | ChangelogEntry): string {\n\tconst versionString = typeof version === \"string\" ? version : entryVersion(version);\n\treturn versionString.startsWith(\"v\") ? versionString : `v${versionString}`;\n}\n\nfunction splitLocalTarget(target: string): { fragment: string; pathPart: string; query: string } {\n\tconst hashIndex = target.indexOf(\"#\");\n\tconst beforeHash = hashIndex === -1 ? target : target.slice(0, hashIndex);\n\tconst fragment = hashIndex === -1 ? \"\" : target.slice(hashIndex);\n\tconst queryIndex = beforeHash.indexOf(\"?\");\n\n\tif (queryIndex === -1) {\n\t\treturn { fragment, pathPart: beforeHash, query: \"\" };\n\t}\n\n\treturn {\n\t\tfragment,\n\t\tpathPart: beforeHash.slice(0, queryIndex),\n\t\tquery: beforeHash.slice(queryIndex),\n\t};\n}\n\nfunction normalizePathPart(value: string): string {\n\treturn value.replaceAll(\"\\\\\", \"/\");\n}\n\nfunction resolveRepositoryPath(targetPath: string): string | undefined {\n\tconst normalizedTarget = normalizePathPart(targetPath);\n\tconst joined = normalizedTarget.startsWith(\"/\")\n\t\t? path.posix.normalize(normalizedTarget.replace(/^\\/+/, \"\"))\n\t\t: path.posix.normalize(path.posix.join(CHANGELOG_LINK_BASE_PATH, normalizedTarget));\n\n\tif (joined === \".\" || joined.startsWith(\"../\") || joined === \"..\") {\n\t\treturn undefined;\n\t}\n\n\treturn joined;\n}\n\nfunction isDirectoryTarget(originalPath: string, repositoryPath: string): boolean {\n\tif (originalPath.endsWith(\"/\")) {\n\t\treturn true;\n\t}\n\n\tconst basename = path.posix.basename(repositoryPath);\n\treturn !basename.includes(\".\");\n}\n\nfunction normalizeChangelogLinkTarget(target: string, tag: string): string {\n\tlet canonicalTarget = target.replace(LEGACY_REPO_RE, `https://github.com/${GITHUB_REPO}`);\n\tconst repoUrl = `https://github.com/${GITHUB_REPO}`;\n\n\tfor (const route of [\"blob\", \"tree\"]) {\n\t\tfor (const branch of [\"main\", \"master\"]) {\n\t\t\tconst floatingRefPrefix = `${repoUrl}/${route}/${branch}/`;\n\t\t\tif (canonicalTarget.startsWith(floatingRefPrefix)) {\n\t\t\t\tcanonicalTarget = `${repoUrl}/${route}/${tag}/${canonicalTarget.slice(floatingRefPrefix.length)}`;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (canonicalTarget.startsWith(\"#\") || canonicalTarget.startsWith(\"//\") || URL_SCHEME_RE.test(canonicalTarget)) {\n\t\treturn canonicalTarget;\n\t}\n\n\tconst { fragment, pathPart, query } = splitLocalTarget(canonicalTarget);\n\tif (!pathPart) {\n\t\treturn canonicalTarget;\n\t}\n\n\tconst repositoryPath = resolveRepositoryPath(pathPart);\n\tif (!repositoryPath) {\n\t\treturn canonicalTarget;\n\t}\n\n\tconst route = isDirectoryTarget(pathPart, repositoryPath) ? \"tree\" : \"blob\";\n\treturn `https://github.com/${GITHUB_REPO}/${route}/${tag}/${encodeURI(repositoryPath)}${query}${fragment}`;\n}\n\nexport function normalizeChangelogLinks(markdown: string, version: string | ChangelogEntry): string {\n\tconst tag = normalizeTag(version);\n\treturn markdown.replace(INLINE_MARKDOWN_LINK_RE, (_match, prefix, target, suffix) => {\n\t\treturn `${prefix}${normalizeChangelogLinkTarget(target, tag)}${suffix}`;\n\t});\n}\n\n/**\n * Parse changelog entries from CHANGELOG.md\n * Scans for ## lines and collects content until next ## or EOF\n */\nexport function parseChangelog(changelogPath: string): ChangelogEntry[] {\n\tif (!existsSync(changelogPath)) {\n\t\treturn [];\n\t}\n\n\ttry {\n\t\tconst content = readFileSync(changelogPath, \"utf-8\");\n\t\tconst lines = content.split(\"\\n\");\n\t\tconst entries: ChangelogEntry[] = [];\n\n\t\tlet currentLines: string[] = [];\n\t\tlet currentVersion: { major: number; minor: number; patch: number } | null = null;\n\n\t\tfor (const line of lines) {\n\t\t\t// Check if this is a version header (## [x.y.z] ...)\n\t\t\tif (line.startsWith(\"## \")) {\n\t\t\t\t// Save previous entry if exists\n\t\t\t\tif (currentVersion && currentLines.length > 0) {\n\t\t\t\t\tentries.push({\n\t\t\t\t\t\t...currentVersion,\n\t\t\t\t\t\tcontent: currentLines.join(\"\\n\").trim(),\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Try to parse version from this line\n\t\t\t\tconst versionMatch = line.match(/##\\s+\\[?(\\d+)\\.(\\d+)\\.(\\d+)\\]?/);\n\t\t\t\tif (versionMatch) {\n\t\t\t\t\tcurrentVersion = {\n\t\t\t\t\t\tmajor: Number.parseInt(versionMatch[1], 10),\n\t\t\t\t\t\tminor: Number.parseInt(versionMatch[2], 10),\n\t\t\t\t\t\tpatch: Number.parseInt(versionMatch[3], 10),\n\t\t\t\t\t};\n\t\t\t\t\tcurrentLines = [line];\n\t\t\t\t} else {\n\t\t\t\t\t// Reset if we can't parse version\n\t\t\t\t\tcurrentVersion = null;\n\t\t\t\t\tcurrentLines = [];\n\t\t\t\t}\n\t\t\t} else if (currentVersion) {\n\t\t\t\t// Collect lines for current version\n\t\t\t\tcurrentLines.push(line);\n\t\t\t}\n\t\t}\n\n\t\t// Save last entry\n\t\tif (currentVersion && currentLines.length > 0) {\n\t\t\tentries.push({\n\t\t\t\t...currentVersion,\n\t\t\t\tcontent: currentLines.join(\"\\n\").trim(),\n\t\t\t});\n\t\t}\n\n\t\treturn entries;\n\t} catch (error) {\n\t\tconsole.error(`Warning: Could not parse changelog: ${error}`);\n\t\treturn [];\n\t}\n}\n\n/**\n * Compare versions. Returns: -1 if v1 < v2, 0 if v1 === v2, 1 if v1 > v2\n */\nexport function compareVersions(v1: ChangelogEntry, v2: ChangelogEntry): number {\n\tif (v1.major !== v2.major) return v1.major - v2.major;\n\tif (v1.minor !== v2.minor) return v1.minor - v2.minor;\n\treturn v1.patch - v2.patch;\n}\n\n/**\n * Get entries newer than lastVersion\n */\nexport function getNewEntries(entries: ChangelogEntry[], lastVersion: string): ChangelogEntry[] {\n\t// Parse lastVersion\n\tconst parts = lastVersion.split(\".\").map(Number);\n\tconst last: ChangelogEntry = {\n\t\tmajor: parts[0] || 0,\n\t\tminor: parts[1] || 0,\n\t\tpatch: parts[2] || 0,\n\t\tcontent: \"\",\n\t};\n\n\treturn entries.filter((entry) => compareVersions(entry, last) > 0);\n}\n\n// Re-export getChangelogPath from paths.ts for convenience\nexport { getChangelogPath } from \"../config.ts\";\n"]}
|
|
1
|
+
{"version":3,"file":"changelog.js","sourceRoot":"","sources":["../../src/utils/changelog.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\nimport { existsSync, readFileSync } from \"fs\";\nimport { compare, valid } from \"semver\";\n\nexport interface ChangelogEntry {\n\tmajor: number;\n\tminor: number;\n\tpatch: number;\n\tsuffix?: string;\n\tversion?: string;\n\tcontent: string;\n}\n\nconst GITHUB_REPO = \"earendil-works/pi\";\nconst CHANGELOG_LINK_BASE_PATH = \"packages/coding-agent\";\nconst LEGACY_REPO_RE = /^https:\\/\\/github\\.com\\/(?:badlogic|earendil-works)\\/pi-mono(?=\\/|$)/;\nconst URL_SCHEME_RE = /^[a-z][a-z0-9+.-]*:/i;\nconst INLINE_MARKDOWN_LINK_RE = /(!?\\[[^\\]\\n]+\\]\\()([^\\s)]+)((?:\\s+[^)]*)?\\))/g;\n\nfunction entryVersion(entry: ChangelogEntry): string {\n\treturn entry.version ?? `${entry.major}.${entry.minor}.${entry.patch}${entry.suffix ? `-${entry.suffix}` : \"\"}`;\n}\n\nconst VERSION_RE = /^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$/;\nconst CALVER_RE = /^(\\d{4})\\.(\\d{1,2})\\.(\\d{1,2})(?:-([2-9]\\d*))?$/;\n\nfunction isValidDate(value: string): boolean {\n\tconst match = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(value);\n\tif (!match) return false;\n\tconst year = Number(match[1]);\n\tconst month = Number(match[2]);\n\tconst day = Number(match[3]);\n\tconst date = new Date(Date.UTC(year, month - 1, day));\n\treturn date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day;\n}\n\nfunction isForeignVersion(version: string): boolean {\n\treturn version.startsWith(\"0.0.0-omob.\") || /^\\d+\\.\\d+\\.\\d+-0\\.beta\\./.test(version);\n}\n\nfunction compareVersionStrings(left: string, right: string): number | undefined {\n\tconst leftCalver = CALVER_RE.exec(left);\n\tconst rightCalver = CALVER_RE.exec(right);\n\tif (leftCalver && rightCalver) {\n\t\tconst leftParts = [\n\t\t\tNumber(leftCalver[1]),\n\t\t\tNumber(leftCalver[2]),\n\t\t\tNumber(leftCalver[3]),\n\t\t\tNumber(leftCalver[4] ?? 1),\n\t\t];\n\t\tconst rightParts = [\n\t\t\tNumber(rightCalver[1]),\n\t\t\tNumber(rightCalver[2]),\n\t\t\tNumber(rightCalver[3]),\n\t\t\tNumber(rightCalver[4] ?? 1),\n\t\t];\n\t\tfor (let index = 0; index < leftParts.length; index += 1) {\n\t\t\tif (leftParts[index] !== rightParts[index]) return leftParts[index] < rightParts[index] ? -1 : 1;\n\t\t}\n\t\treturn 0;\n\t}\n\tconst leftValid = valid(left);\n\tconst rightValid = valid(right);\n\tif (!leftValid || !rightValid || isForeignVersion(left) !== isForeignVersion(right)) return undefined;\n\treturn Math.sign(compare(leftValid, rightValid));\n}\n\nfunction normalizeTag(version: string | ChangelogEntry): string {\n\tconst versionString = typeof version === \"string\" ? version : entryVersion(version);\n\treturn versionString.startsWith(\"v\") ? versionString : `v${versionString}`;\n}\n\nfunction splitLocalTarget(target: string): { fragment: string; pathPart: string; query: string } {\n\tconst hashIndex = target.indexOf(\"#\");\n\tconst beforeHash = hashIndex === -1 ? target : target.slice(0, hashIndex);\n\tconst fragment = hashIndex === -1 ? \"\" : target.slice(hashIndex);\n\tconst queryIndex = beforeHash.indexOf(\"?\");\n\n\tif (queryIndex === -1) {\n\t\treturn { fragment, pathPart: beforeHash, query: \"\" };\n\t}\n\n\treturn {\n\t\tfragment,\n\t\tpathPart: beforeHash.slice(0, queryIndex),\n\t\tquery: beforeHash.slice(queryIndex),\n\t};\n}\n\nfunction normalizePathPart(value: string): string {\n\treturn value.replaceAll(\"\\\\\", \"/\");\n}\n\nfunction resolveRepositoryPath(targetPath: string): string | undefined {\n\tconst normalizedTarget = normalizePathPart(targetPath);\n\tconst joined = normalizedTarget.startsWith(\"/\")\n\t\t? path.posix.normalize(normalizedTarget.replace(/^\\/+/, \"\"))\n\t\t: path.posix.normalize(path.posix.join(CHANGELOG_LINK_BASE_PATH, normalizedTarget));\n\n\tif (joined === \".\" || joined.startsWith(\"../\") || joined === \"..\") {\n\t\treturn undefined;\n\t}\n\n\treturn joined;\n}\n\nfunction isDirectoryTarget(originalPath: string, repositoryPath: string): boolean {\n\tif (originalPath.endsWith(\"/\")) {\n\t\treturn true;\n\t}\n\n\tconst basename = path.posix.basename(repositoryPath);\n\treturn !basename.includes(\".\");\n}\n\nfunction normalizeChangelogLinkTarget(target: string, tag: string): string {\n\tlet canonicalTarget = target.replace(LEGACY_REPO_RE, `https://github.com/${GITHUB_REPO}`);\n\tconst repoUrl = `https://github.com/${GITHUB_REPO}`;\n\n\tfor (const route of [\"blob\", \"tree\"]) {\n\t\tfor (const branch of [\"main\", \"master\"]) {\n\t\t\tconst floatingRefPrefix = `${repoUrl}/${route}/${branch}/`;\n\t\t\tif (canonicalTarget.startsWith(floatingRefPrefix)) {\n\t\t\t\tcanonicalTarget = `${repoUrl}/${route}/${tag}/${canonicalTarget.slice(floatingRefPrefix.length)}`;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (canonicalTarget.startsWith(\"#\") || canonicalTarget.startsWith(\"//\") || URL_SCHEME_RE.test(canonicalTarget)) {\n\t\treturn canonicalTarget;\n\t}\n\n\tconst { fragment, pathPart, query } = splitLocalTarget(canonicalTarget);\n\tif (!pathPart) {\n\t\treturn canonicalTarget;\n\t}\n\n\tconst repositoryPath = resolveRepositoryPath(pathPart);\n\tif (!repositoryPath) {\n\t\treturn canonicalTarget;\n\t}\n\n\tconst route = isDirectoryTarget(pathPart, repositoryPath) ? \"tree\" : \"blob\";\n\treturn `https://github.com/${GITHUB_REPO}/${route}/${tag}/${encodeURI(repositoryPath)}${query}${fragment}`;\n}\n\nexport function normalizeChangelogLinks(markdown: string, version: string | ChangelogEntry): string {\n\tconst tag = normalizeTag(version);\n\treturn markdown.replace(INLINE_MARKDOWN_LINK_RE, (_match, prefix, target, suffix) => {\n\t\treturn `${prefix}${normalizeChangelogLinkTarget(target, tag)}${suffix}`;\n\t});\n}\n\n/**\n * Parse changelog entries from CHANGELOG.md\n * Scans for ## lines and collects content until next ## or EOF\n */\nexport function parseChangelog(changelogPath: string): ChangelogEntry[] {\n\tif (!existsSync(changelogPath)) {\n\t\treturn [];\n\t}\n\n\ttry {\n\t\tconst content = readFileSync(changelogPath, \"utf-8\");\n\t\tconst lines = content.split(\"\\n\");\n\t\tconst entries: ChangelogEntry[] = [];\n\n\t\tlet currentLines: string[] = [];\n\t\tlet currentVersion: { major: number; minor: number; patch: number; suffix?: string; version: string } | null =\n\t\t\tnull;\n\t\tlet fence: { character: \"`\" | \"~\"; length: number } | null = null;\n\n\t\tfor (const line of lines) {\n\t\t\tconst fenceMatch = /^ {0,3}(`{3,}|~{3,})/.exec(line);\n\t\t\tif (fenceMatch) {\n\t\t\t\tconst character = fenceMatch[1][0] === \"`\" ? \"`\" : \"~\";\n\t\t\t\tif (!fence) fence = { character, length: fenceMatch[1].length };\n\t\t\t\telse if (fence.character === character && fenceMatch[1].length >= fence.length) fence = null;\n\t\t\t}\n\t\t\tconst headerMatch =\n\t\t\t\tfence === null\n\t\t\t\t\t? /^##[ \\t]+(?:\\[([0-9]+\\.[0-9]+\\.[0-9]+(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?)\\]|([0-9]+\\.[0-9]+\\.[0-9]+(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)))(?:[ \\t]+-[ \\t]+(\\d{4}-\\d{2}-\\d{2}))?[ \\t]*$/.exec(\n\t\t\t\t\t\t\tline,\n\t\t\t\t\t\t)\n\t\t\t\t\t: null;\n\t\t\tif (\n\t\t\t\theaderMatch ||\n\t\t\t\t(fence === null && /^##[ \\t]+\\[?Unreleased\\]?[ \\t]*(?:-[ \\t]+\\d{4}-\\d{2}-\\d{2})?[ \\t]*$/.test(line))\n\t\t\t) {\n\t\t\t\t// Save previous entry if exists\n\t\t\t\tif (currentVersion && currentLines.length > 0) {\n\t\t\t\t\tentries.push({\n\t\t\t\t\t\t...currentVersion,\n\t\t\t\t\t\tcontent: currentLines.join(\"\\n\").trim(),\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Try to parse version from this line\n\t\t\t\tif (headerMatch && isValidDate(headerMatch[3] ?? \"2026-01-01\")) {\n\t\t\t\t\tconst parts = /^(\\d+)\\.(\\d+)\\.(\\d+)(?:-(.*))?$/.exec(headerMatch[1] ?? headerMatch[2]);\n\t\t\t\t\tif (!parts) {\n\t\t\t\t\t\tcurrentVersion = null;\n\t\t\t\t\t\tcurrentLines = [];\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tcurrentVersion = {\n\t\t\t\t\t\tmajor: Number(parts[1]),\n\t\t\t\t\t\tminor: Number(parts[2]),\n\t\t\t\t\t\tpatch: Number(parts[3]),\n\t\t\t\t\t\tsuffix: parts[4],\n\t\t\t\t\t\tversion: `${parts[1]}.${parts[2]}.${parts[3]}${parts[4] ? `-${parts[4]}` : \"\"}`,\n\t\t\t\t\t};\n\t\t\t\t\tcurrentLines = [];\n\t\t\t\t} else {\n\t\t\t\t\t// Reset if we can't parse version\n\t\t\t\t\tcurrentVersion = null;\n\t\t\t\t\tcurrentLines = [];\n\t\t\t\t}\n\t\t\t} else if (currentVersion) {\n\t\t\t\t// Collect lines for current version\n\t\t\t\tcurrentLines.push(line);\n\t\t\t}\n\t\t}\n\n\t\t// Save last entry\n\t\tif (currentVersion && currentLines.length > 0) {\n\t\t\tentries.push({\n\t\t\t\t...currentVersion,\n\t\t\t\tcontent: currentLines.join(\"\\n\").trim(),\n\t\t\t});\n\t\t}\n\n\t\treturn entries;\n\t} catch (error) {\n\t\tconsole.error(`Warning: Could not parse changelog: ${error}`);\n\t\treturn [];\n\t}\n}\n\n/**\n * Compare versions. Returns: -1 if v1 < v2, 0 if v1 === v2, 1 if v1 > v2\n */\nexport function compareVersions(v1: ChangelogEntry, v2: ChangelogEntry): number {\n\treturn compareVersionStrings(entryVersion(v1), entryVersion(v2)) ?? 0;\n}\n\n/**\n * Get entries newer than lastVersion\n */\nexport function getNewEntries(\n\tentries: ChangelogEntry[],\n\tlastVersion: string,\n\tcurrentVersion?: string,\n): ChangelogEntry[] {\n\t// Parse lastVersion\n\tconst parts = lastVersion.match(/^(\\d+)\\.(\\d+)\\.(\\d+)(?:-(.*))?$/);\n\tif (!parts || isForeignVersion(lastVersion)) return [];\n\tconst current = currentVersion && VERSION_RE.test(currentVersion) ? currentVersion : undefined;\n\tif (current && (isForeignVersion(current) || compareVersionStrings(lastVersion, current) === undefined)) return [];\n\treturn entries.filter((entry, index, all) => {\n\t\tconst version = entryVersion(entry);\n\t\tconst lower = compareVersionStrings(version, lastVersion);\n\t\tconst upper = current ? compareVersionStrings(version, current) : 0;\n\t\treturn (\n\t\t\tlower !== undefined &&\n\t\t\tlower > 0 &&\n\t\t\t(upper === undefined || upper <= 0) &&\n\t\t\tall.findIndex((candidate) => entryVersion(candidate) === version) === index\n\t\t);\n\t});\n}\n\n// Re-export getChangelogPath from paths.ts for convenience\nexport { getChangelogPath } from \"../config.ts\";\n"]}
|
package/dist/utils/paths.d.ts
CHANGED
|
@@ -51,6 +51,11 @@ export declare function realpathWithoutOpen(inputPath: string): string;
|
|
|
51
51
|
*/
|
|
52
52
|
export declare function realpathWithoutOpenStrict(inputPath: string): string;
|
|
53
53
|
export declare function getFileRevision(path: string): string | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* Returns a revision derived from file contents rather than filesystem timestamps.
|
|
56
|
+
* Use this when a same-tick rewrite must invalidate an in-memory snapshot.
|
|
57
|
+
*/
|
|
58
|
+
export declare function getFileContentRevision(path: string): string | undefined;
|
|
54
59
|
/**
|
|
55
60
|
* Returns true if the value is NOT a package source (npm:, git:, etc.)
|
|
56
61
|
* or a remote URL protocol. Bare names, relative paths, and file: URLs
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,gBAAgB;IAChC,6DAA6D;IAC7D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gEAAgE;IAChE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,0DAA0D;IAC1D,sBAAsB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMrD;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3D;AAoED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CASnE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAOhE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAMvE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAclD;AAED,gGAAgG;AAChG,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMlE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM,CAyBnF;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,MAAsB,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM,CAIlH;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CASpF;AAED,wBAAgB,iCAAiC,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAGvF;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKhD;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAe7D"}
|
package/dist/utils/paths.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { lstatSync, readFileSync, readlinkSync, realpathSync, statSync } from "node:fs";
|
|
2
3
|
import { homedir } from "node:os";
|
|
3
4
|
import { isAbsolute, join, resolve as nodeResolvePath, parse, relative, sep } from "node:path";
|
|
4
5
|
import { fileURLToPath } from "node:url";
|
|
@@ -133,6 +134,18 @@ export function getFileRevision(path) {
|
|
|
133
134
|
return undefined;
|
|
134
135
|
}
|
|
135
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* Returns a revision derived from file contents rather than filesystem timestamps.
|
|
139
|
+
* Use this when a same-tick rewrite must invalidate an in-memory snapshot.
|
|
140
|
+
*/
|
|
141
|
+
export function getFileContentRevision(path) {
|
|
142
|
+
try {
|
|
143
|
+
return createHash("sha256").update(readFileSync(path)).digest("hex");
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
136
149
|
/**
|
|
137
150
|
* Returns true if the value is NOT a package source (npm:, git:, etc.)
|
|
138
151
|
* or a remote URL protocol. Bare names, relative paths, and file: URLs
|
package/dist/utils/paths.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"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","sourcesContent":["import { lstatSync, readlinkSync, realpathSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { isAbsolute, join, resolve as nodeResolvePath, parse, relative, sep } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { spawnProcessSync } from \"./child-process.ts\";\n\nconst UNICODE_SPACES = /[\\u00A0\\u2000-\\u200A\\u202F\\u205F\\u3000]/g;\n\nexport interface PathInputOptions {\n\t/** Trim leading/trailing whitespace before normalization. */\n\ttrim?: boolean;\n\t/** Expand leading `~` to a home directory. Defaults to true. */\n\texpandTilde?: boolean;\n\t/** Home directory used for `~` expansion. Defaults to `os.homedir()`. */\n\thomeDir?: string;\n\t/** Strip a leading `@`, used for CLI @file paths. */\n\tstripAtPrefix?: boolean;\n\t/** Normalize unicode space variants to regular spaces. */\n\tnormalizeUnicodeSpaces?: boolean;\n}\n\n/**\n * Resolve a path to its canonical (real) form, following symlinks.\n * Falls back to the raw path if resolution fails (e.g. the target does\n * not exist yet), so that callers never crash on missing filesystem\n * entries.\n */\nexport function canonicalizePath(path: string): string {\n\ttry {\n\t\treturn realpathSync.native(path);\n\t} catch {\n\t\treturn path;\n\t}\n}\n\n/**\n * {@link canonicalizePath} that refuses to guess.\n *\n * The convenience form hands back its input when resolution fails, which is what most callers\n * want: they compare two canonical spellings and an unresolvable path simply compares unequal.\n * A security decision cannot use that, because the raw input is indistinguishable from a\n * canonical answer - so a path that could not be resolved would be keyed, compared, or trusted\n * under a spelling the filesystem never confirmed. This form throws instead, leaving the caller\n * to decide what an unresolvable path means.\n */\nexport function canonicalizePathStrict(path: string): string {\n\treturn realpathSync.native(path);\n}\n\n/** Symlink hops allowed while resolving one path; realpath(3) reports ELOOP past this. */\nconst MAX_SYMLINK_HOPS = 40;\n\n/** Error codes that mean \"this component does not exist\", which resolution tolerates. */\nconst MISSING_PATH_CODES = new Set([\"ENOENT\", \"ENOTDIR\"]);\n\nfunction splitParts(pathSegment: string): string[] {\n\treturn pathSegment.split(sep).filter((part) => part.length > 0);\n}\n\ninterface OpenFreeResolution {\n\t/** The resolved path; components from an unresolvable one onward are kept verbatim. */\n\treadonly path: string;\n\t/** Set when resolution stopped early: the fs error code, or ELOOP for hop exhaustion. */\n\treadonly errorCode?: string;\n}\n\n/**\n * realpath(3) semantics with one lstat/readlink per component and no open(2) anywhere.\n *\n * `..` is applied to the already-resolved prefix rather than collapsed lexically, because the two\n * differ whenever a link target reaches back through a symlink: for `entry -> jump/../secret` with\n * `jump -> /elsewhere/dir`, POSIX resolves `jump` first and lands in `/elsewhere/secret`, while a\n * lexical collapse would answer `secret` next to `entry`. Handing a lexical answer to a\n * containment decision would approve one directory while the I/O reached another, so neither the\n * input nor a link target is normalized before traversal.\n */\nfunction resolveWithoutOpen(inputPath: string): OpenFreeResolution {\n\tconst absolutePath = isAbsolute(inputPath) ? inputPath : nodeResolvePath(inputPath);\n\tconst { root } = parse(absolutePath);\n\tconst pending = splitParts(absolutePath.slice(root.length));\n\tconst resolved: string[] = [];\n\tlet hops = 0;\n\twhile (pending.length > 0) {\n\t\tconst part = pending.shift();\n\t\tif (part === undefined) break;\n\t\tif (part === \".\") continue;\n\t\tif (part === \"..\") {\n\t\t\t// At the root `..` is the root itself, which an empty stack already represents.\n\t\t\tresolved.pop();\n\t\t\tcontinue;\n\t\t}\n\t\tconst candidate = join(root, ...resolved, part);\n\t\tlet link: string;\n\t\ttry {\n\t\t\tif (!lstatSync(candidate).isSymbolicLink()) {\n\t\t\t\tresolved.push(part);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\thops += 1;\n\t\t\tif (hops > MAX_SYMLINK_HOPS) return { path: join(candidate, ...pending), errorCode: \"ELOOP\" };\n\t\t\tlink = readlinkSync(candidate);\n\t\t} catch (error) {\n\t\t\tconst code = (error as NodeJS.ErrnoException)?.code ?? \"UNKNOWN\";\n\t\t\treturn { path: join(candidate, ...pending), errorCode: code };\n\t\t}\n\t\tif (isAbsolute(link)) {\n\t\t\tresolved.length = 0;\n\t\t\tpending.unshift(...splitParts(link.slice(parse(link).root.length)));\n\t\t} else {\n\t\t\tpending.unshift(...splitParts(link));\n\t\t}\n\t}\n\treturn { path: join(root, ...resolved) };\n}\n\n/**\n * Resolve symlinks without ever open(2)-ing a component, tolerating every error.\n *\n * Bun's `fs.realpath*` opens every directory it resolves, so an autofs trigger such as macOS\n * `/home` blocks the calling thread (on the host main thread that freezes the TUI) and an\n * execute-only directory fails with EACCES; lstat needs only search permission and never mounts\n * anything. Components from the first unresolvable one onward are kept verbatim, so a file that\n * does not exist yet still lands where its symlinked parent points.\n *\n * Never throws, so the resolved path may be incomplete. Use it where an approximate answer is\n * better than a blocked thread — the external-path classifier and the monitor parent identity —\n * and use {@link realpathWithoutOpenStrict} where an incomplete answer must not be trusted.\n */\nexport function realpathWithoutOpen(inputPath: string): string {\n\treturn resolveWithoutOpen(inputPath).path;\n}\n\n/**\n * {@link realpathWithoutOpen} that refuses to answer with a guess: a missing component is still\n * tolerated (its name is appended verbatim, which is what a not-yet-created target needs), but\n * EACCES, EIO, ELOOP and hop exhaustion throw instead of returning an unresolved path. Callers\n * that feed a canonical path into a containment or identity decision need this contract, because\n * an unresolved path can name a different file than the one the I/O will reach.\n */\nexport function realpathWithoutOpenStrict(inputPath: string): string {\n\tconst resolution = resolveWithoutOpen(inputPath);\n\tif (resolution.errorCode !== undefined && !MISSING_PATH_CODES.has(resolution.errorCode)) {\n\t\tthrow Object.assign(new Error(`${resolution.errorCode}: cannot resolve path '${inputPath}' without opening it`), {\n\t\t\tcode: resolution.errorCode,\n\t\t\tpath: inputPath,\n\t\t});\n\t}\n\treturn resolution.path;\n}\n\nexport function getFileRevision(path: string): string | undefined {\n\ttry {\n\t\tconst stats = statSync(path, { bigint: true });\n\t\treturn `${stats.dev}:${stats.ino}:${stats.size}:${stats.mtimeNs}:${stats.ctimeNs}`;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Returns true if the value is NOT a package source (npm:, git:, etc.)\n * or a remote URL protocol. Bare names, relative paths, and file: URLs\n * are considered local.\n */\nexport function isLocalPath(value: string): boolean {\n\tconst trimmed = value.trim();\n\t// Known non-local prefixes. file: URLs are local paths and are intentionally resolved by resolvePath().\n\tif (\n\t\ttrimmed.startsWith(\"npm:\") ||\n\t\ttrimmed.startsWith(\"git:\") ||\n\t\ttrimmed.startsWith(\"github:\") ||\n\t\ttrimmed.startsWith(\"http:\") ||\n\t\ttrimmed.startsWith(\"https:\") ||\n\t\ttrimmed.startsWith(\"ssh:\")\n\t) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\n/** Convert Git Bash, MSYS, Cygwin, and WSL drive paths to a form native Windows APIs accept. */\nexport function normalizeWindowsShellPath(filePath: string): string {\n\tif (!filePath.startsWith(\"/\") || filePath.startsWith(\"//\") || filePath.includes(\"\\\\\")) return filePath;\n\tconst match = filePath.match(/^\\/(?:mnt\\/|cygdrive\\/)?([a-z])(?:\\/(.*))?$/i);\n\tif (!match) return filePath;\n\tconst suffix = match[2]?.replaceAll(\"/\", \"\\\\\");\n\treturn `${match[1].toUpperCase()}:\\\\${suffix ?? \"\"}`;\n}\n\nexport function normalizePath(input: string, options: PathInputOptions = {}): string {\n\tlet normalized = options.trim ? input.trim() : input;\n\tif (options.normalizeUnicodeSpaces) {\n\t\tnormalized = normalized.replace(UNICODE_SPACES, \" \");\n\t}\n\tif (options.stripAtPrefix && normalized.startsWith(\"@\")) {\n\t\tnormalized = normalized.slice(1);\n\t}\n\tif (process.platform === \"win32\") {\n\t\tnormalized = normalizeWindowsShellPath(normalized);\n\t}\n\n\tif (options.expandTilde ?? true) {\n\t\tconst home = options.homeDir ?? homedir();\n\t\tif (normalized === \"~\") return home;\n\t\tif (normalized.startsWith(\"~/\") || (process.platform === \"win32\" && normalized.startsWith(\"~\\\\\"))) {\n\t\t\treturn join(home, normalized.slice(2));\n\t\t}\n\t}\n\n\tif (/^file:\\/\\//.test(normalized)) {\n\t\treturn fileURLToPath(normalized);\n\t}\n\n\treturn normalized;\n}\n\nexport function resolvePath(input: string, baseDir: string = process.cwd(), options: PathInputOptions = {}): string {\n\tconst normalized = normalizePath(input, options);\n\tconst normalizedBaseDir = normalizePath(baseDir);\n\treturn isAbsolute(normalized) ? nodeResolvePath(normalized) : nodeResolvePath(normalizedBaseDir, normalized);\n}\n\nexport function getCwdRelativePath(filePath: string, cwd: string): string | undefined {\n\tconst resolvedCwd = resolvePath(cwd);\n\tconst resolvedPath = resolvePath(filePath, resolvedCwd);\n\tconst relativePath = relative(resolvedCwd, resolvedPath);\n\tconst isInsideCwd =\n\t\trelativePath === \"\" ||\n\t\t(relativePath !== \"..\" && !relativePath.startsWith(`..${sep}`) && !isAbsolute(relativePath));\n\n\treturn isInsideCwd ? relativePath || \".\" : undefined;\n}\n\nexport function formatPathRelativeToCwdOrAbsolute(filePath: string, cwd: string): string {\n\tconst absolutePath = resolvePath(filePath, cwd);\n\treturn (getCwdRelativePath(absolutePath, cwd) ?? absolutePath).split(sep).join(\"/\");\n}\n\nexport function shortenPath(path: string): string {\n\tif (!path) return path;\n\tconst home = homedir();\n\tif (path.startsWith(home)) return `~${path.slice(home.length)}`;\n\treturn path;\n}\n\nexport function markPathIgnoredByCloudSync(path: string): void {\n\tconst attrs =\n\t\tprocess.platform === \"darwin\"\n\t\t\t? [\"com.dropbox.ignored\", \"com.apple.fileprovider.ignore#P\"]\n\t\t\t: process.platform === \"linux\"\n\t\t\t\t? [\"user.com.dropbox.ignored\"]\n\t\t\t\t: [];\n\n\tfor (const attr of attrs) {\n\t\tif (process.platform === \"darwin\") {\n\t\t\tspawnProcessSync(\"xattr\", [\"-w\", attr, \"1\", path], { encoding: \"utf-8\", stdio: \"ignore\" });\n\t\t} else {\n\t\t\tspawnProcessSync(\"setfattr\", [\"-n\", attr, \"-v\", \"1\", path], { encoding: \"utf-8\", stdio: \"ignore\" });\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { lstatSync, readFileSync, readlinkSync, realpathSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { isAbsolute, join, resolve as nodeResolvePath, parse, relative, sep } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { spawnProcessSync } from \"./child-process.ts\";\n\nconst UNICODE_SPACES = /[\\u00A0\\u2000-\\u200A\\u202F\\u205F\\u3000]/g;\n\nexport interface PathInputOptions {\n\t/** Trim leading/trailing whitespace before normalization. */\n\ttrim?: boolean;\n\t/** Expand leading `~` to a home directory. Defaults to true. */\n\texpandTilde?: boolean;\n\t/** Home directory used for `~` expansion. Defaults to `os.homedir()`. */\n\thomeDir?: string;\n\t/** Strip a leading `@`, used for CLI @file paths. */\n\tstripAtPrefix?: boolean;\n\t/** Normalize unicode space variants to regular spaces. */\n\tnormalizeUnicodeSpaces?: boolean;\n}\n\n/**\n * Resolve a path to its canonical (real) form, following symlinks.\n * Falls back to the raw path if resolution fails (e.g. the target does\n * not exist yet), so that callers never crash on missing filesystem\n * entries.\n */\nexport function canonicalizePath(path: string): string {\n\ttry {\n\t\treturn realpathSync.native(path);\n\t} catch {\n\t\treturn path;\n\t}\n}\n\n/**\n * {@link canonicalizePath} that refuses to guess.\n *\n * The convenience form hands back its input when resolution fails, which is what most callers\n * want: they compare two canonical spellings and an unresolvable path simply compares unequal.\n * A security decision cannot use that, because the raw input is indistinguishable from a\n * canonical answer - so a path that could not be resolved would be keyed, compared, or trusted\n * under a spelling the filesystem never confirmed. This form throws instead, leaving the caller\n * to decide what an unresolvable path means.\n */\nexport function canonicalizePathStrict(path: string): string {\n\treturn realpathSync.native(path);\n}\n\n/** Symlink hops allowed while resolving one path; realpath(3) reports ELOOP past this. */\nconst MAX_SYMLINK_HOPS = 40;\n\n/** Error codes that mean \"this component does not exist\", which resolution tolerates. */\nconst MISSING_PATH_CODES = new Set([\"ENOENT\", \"ENOTDIR\"]);\n\nfunction splitParts(pathSegment: string): string[] {\n\treturn pathSegment.split(sep).filter((part) => part.length > 0);\n}\n\ninterface OpenFreeResolution {\n\t/** The resolved path; components from an unresolvable one onward are kept verbatim. */\n\treadonly path: string;\n\t/** Set when resolution stopped early: the fs error code, or ELOOP for hop exhaustion. */\n\treadonly errorCode?: string;\n}\n\n/**\n * realpath(3) semantics with one lstat/readlink per component and no open(2) anywhere.\n *\n * `..` is applied to the already-resolved prefix rather than collapsed lexically, because the two\n * differ whenever a link target reaches back through a symlink: for `entry -> jump/../secret` with\n * `jump -> /elsewhere/dir`, POSIX resolves `jump` first and lands in `/elsewhere/secret`, while a\n * lexical collapse would answer `secret` next to `entry`. Handing a lexical answer to a\n * containment decision would approve one directory while the I/O reached another, so neither the\n * input nor a link target is normalized before traversal.\n */\nfunction resolveWithoutOpen(inputPath: string): OpenFreeResolution {\n\tconst absolutePath = isAbsolute(inputPath) ? inputPath : nodeResolvePath(inputPath);\n\tconst { root } = parse(absolutePath);\n\tconst pending = splitParts(absolutePath.slice(root.length));\n\tconst resolved: string[] = [];\n\tlet hops = 0;\n\twhile (pending.length > 0) {\n\t\tconst part = pending.shift();\n\t\tif (part === undefined) break;\n\t\tif (part === \".\") continue;\n\t\tif (part === \"..\") {\n\t\t\t// At the root `..` is the root itself, which an empty stack already represents.\n\t\t\tresolved.pop();\n\t\t\tcontinue;\n\t\t}\n\t\tconst candidate = join(root, ...resolved, part);\n\t\tlet link: string;\n\t\ttry {\n\t\t\tif (!lstatSync(candidate).isSymbolicLink()) {\n\t\t\t\tresolved.push(part);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\thops += 1;\n\t\t\tif (hops > MAX_SYMLINK_HOPS) return { path: join(candidate, ...pending), errorCode: \"ELOOP\" };\n\t\t\tlink = readlinkSync(candidate);\n\t\t} catch (error) {\n\t\t\tconst code = (error as NodeJS.ErrnoException)?.code ?? \"UNKNOWN\";\n\t\t\treturn { path: join(candidate, ...pending), errorCode: code };\n\t\t}\n\t\tif (isAbsolute(link)) {\n\t\t\tresolved.length = 0;\n\t\t\tpending.unshift(...splitParts(link.slice(parse(link).root.length)));\n\t\t} else {\n\t\t\tpending.unshift(...splitParts(link));\n\t\t}\n\t}\n\treturn { path: join(root, ...resolved) };\n}\n\n/**\n * Resolve symlinks without ever open(2)-ing a component, tolerating every error.\n *\n * Bun's `fs.realpath*` opens every directory it resolves, so an autofs trigger such as macOS\n * `/home` blocks the calling thread (on the host main thread that freezes the TUI) and an\n * execute-only directory fails with EACCES; lstat needs only search permission and never mounts\n * anything. Components from the first unresolvable one onward are kept verbatim, so a file that\n * does not exist yet still lands where its symlinked parent points.\n *\n * Never throws, so the resolved path may be incomplete. Use it where an approximate answer is\n * better than a blocked thread — the external-path classifier and the monitor parent identity —\n * and use {@link realpathWithoutOpenStrict} where an incomplete answer must not be trusted.\n */\nexport function realpathWithoutOpen(inputPath: string): string {\n\treturn resolveWithoutOpen(inputPath).path;\n}\n\n/**\n * {@link realpathWithoutOpen} that refuses to answer with a guess: a missing component is still\n * tolerated (its name is appended verbatim, which is what a not-yet-created target needs), but\n * EACCES, EIO, ELOOP and hop exhaustion throw instead of returning an unresolved path. Callers\n * that feed a canonical path into a containment or identity decision need this contract, because\n * an unresolved path can name a different file than the one the I/O will reach.\n */\nexport function realpathWithoutOpenStrict(inputPath: string): string {\n\tconst resolution = resolveWithoutOpen(inputPath);\n\tif (resolution.errorCode !== undefined && !MISSING_PATH_CODES.has(resolution.errorCode)) {\n\t\tthrow Object.assign(new Error(`${resolution.errorCode}: cannot resolve path '${inputPath}' without opening it`), {\n\t\t\tcode: resolution.errorCode,\n\t\t\tpath: inputPath,\n\t\t});\n\t}\n\treturn resolution.path;\n}\n\nexport function getFileRevision(path: string): string | undefined {\n\ttry {\n\t\tconst stats = statSync(path, { bigint: true });\n\t\treturn `${stats.dev}:${stats.ino}:${stats.size}:${stats.mtimeNs}:${stats.ctimeNs}`;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Returns a revision derived from file contents rather than filesystem timestamps.\n * Use this when a same-tick rewrite must invalidate an in-memory snapshot.\n */\nexport function getFileContentRevision(path: string): string | undefined {\n\ttry {\n\t\treturn createHash(\"sha256\").update(readFileSync(path)).digest(\"hex\");\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Returns true if the value is NOT a package source (npm:, git:, etc.)\n * or a remote URL protocol. Bare names, relative paths, and file: URLs\n * are considered local.\n */\nexport function isLocalPath(value: string): boolean {\n\tconst trimmed = value.trim();\n\t// Known non-local prefixes. file: URLs are local paths and are intentionally resolved by resolvePath().\n\tif (\n\t\ttrimmed.startsWith(\"npm:\") ||\n\t\ttrimmed.startsWith(\"git:\") ||\n\t\ttrimmed.startsWith(\"github:\") ||\n\t\ttrimmed.startsWith(\"http:\") ||\n\t\ttrimmed.startsWith(\"https:\") ||\n\t\ttrimmed.startsWith(\"ssh:\")\n\t) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\n/** Convert Git Bash, MSYS, Cygwin, and WSL drive paths to a form native Windows APIs accept. */\nexport function normalizeWindowsShellPath(filePath: string): string {\n\tif (!filePath.startsWith(\"/\") || filePath.startsWith(\"//\") || filePath.includes(\"\\\\\")) return filePath;\n\tconst match = filePath.match(/^\\/(?:mnt\\/|cygdrive\\/)?([a-z])(?:\\/(.*))?$/i);\n\tif (!match) return filePath;\n\tconst suffix = match[2]?.replaceAll(\"/\", \"\\\\\");\n\treturn `${match[1].toUpperCase()}:\\\\${suffix ?? \"\"}`;\n}\n\nexport function normalizePath(input: string, options: PathInputOptions = {}): string {\n\tlet normalized = options.trim ? input.trim() : input;\n\tif (options.normalizeUnicodeSpaces) {\n\t\tnormalized = normalized.replace(UNICODE_SPACES, \" \");\n\t}\n\tif (options.stripAtPrefix && normalized.startsWith(\"@\")) {\n\t\tnormalized = normalized.slice(1);\n\t}\n\tif (process.platform === \"win32\") {\n\t\tnormalized = normalizeWindowsShellPath(normalized);\n\t}\n\n\tif (options.expandTilde ?? true) {\n\t\tconst home = options.homeDir ?? homedir();\n\t\tif (normalized === \"~\") return home;\n\t\tif (normalized.startsWith(\"~/\") || (process.platform === \"win32\" && normalized.startsWith(\"~\\\\\"))) {\n\t\t\treturn join(home, normalized.slice(2));\n\t\t}\n\t}\n\n\tif (/^file:\\/\\//.test(normalized)) {\n\t\treturn fileURLToPath(normalized);\n\t}\n\n\treturn normalized;\n}\n\nexport function resolvePath(input: string, baseDir: string = process.cwd(), options: PathInputOptions = {}): string {\n\tconst normalized = normalizePath(input, options);\n\tconst normalizedBaseDir = normalizePath(baseDir);\n\treturn isAbsolute(normalized) ? nodeResolvePath(normalized) : nodeResolvePath(normalizedBaseDir, normalized);\n}\n\nexport function getCwdRelativePath(filePath: string, cwd: string): string | undefined {\n\tconst resolvedCwd = resolvePath(cwd);\n\tconst resolvedPath = resolvePath(filePath, resolvedCwd);\n\tconst relativePath = relative(resolvedCwd, resolvedPath);\n\tconst isInsideCwd =\n\t\trelativePath === \"\" ||\n\t\t(relativePath !== \"..\" && !relativePath.startsWith(`..${sep}`) && !isAbsolute(relativePath));\n\n\treturn isInsideCwd ? relativePath || \".\" : undefined;\n}\n\nexport function formatPathRelativeToCwdOrAbsolute(filePath: string, cwd: string): string {\n\tconst absolutePath = resolvePath(filePath, cwd);\n\treturn (getCwdRelativePath(absolutePath, cwd) ?? absolutePath).split(sep).join(\"/\");\n}\n\nexport function shortenPath(path: string): string {\n\tif (!path) return path;\n\tconst home = homedir();\n\tif (path.startsWith(home)) return `~${path.slice(home.length)}`;\n\treturn path;\n}\n\nexport function markPathIgnoredByCloudSync(path: string): void {\n\tconst attrs =\n\t\tprocess.platform === \"darwin\"\n\t\t\t? [\"com.dropbox.ignored\", \"com.apple.fileprovider.ignore#P\"]\n\t\t\t: process.platform === \"linux\"\n\t\t\t\t? [\"user.com.dropbox.ignored\"]\n\t\t\t\t: [];\n\n\tfor (const attr of attrs) {\n\t\tif (process.platform === \"darwin\") {\n\t\t\tspawnProcessSync(\"xattr\", [\"-w\", attr, \"1\", path], { encoding: \"utf-8\", stdio: \"ignore\" });\n\t\t} else {\n\t\t\tspawnProcessSync(\"setfattr\", [\"-n\", attr, \"-v\", \"1\", path], { encoding: \"utf-8\", stdio: \"ignore\" });\n\t\t}\n\t}\n}\n"]}
|
package/docs/app-server.md
CHANGED
|
@@ -50,6 +50,12 @@ All server notifications use the current Codex envelope and include `emittedAtMs
|
|
|
50
50
|
before, between, and after correlated responses, except where a method explicitly guarantees response-before-notification
|
|
51
51
|
ordering below.
|
|
52
52
|
|
|
53
|
+
## Provider account display names
|
|
54
|
+
|
|
55
|
+
`account/providerAccounts/read` returns secret-free account descriptors with `name`, `source`, `blocked`, `pinned`, and optional `displayName`. Clients should render `displayName (name)` when present and the ID alone otherwise. Pins, removal, and comparisons must continue using immutable `name`, not the display label. Rename/clear operations are available through Senpi's account slash commands; no new app-server mutation method is introduced.
|
|
56
|
+
|
|
57
|
+
`displayName` is stored NFC-normalized with internal whitespace collapsed and is at most 32 terminal columns wide, so a client can render it inline without measuring; it is unique per provider under a fold of case, Unicode compatibility forms, invisible code points, and Cyrillic lookalikes.
|
|
58
|
+
|
|
53
59
|
## Protocol Provenance
|
|
54
60
|
|
|
55
61
|
The raw TypeScript fixture is pinned to Codex git
|
package/docs/extensions.md
CHANGED
|
@@ -2340,18 +2340,34 @@ pi.registerTool({
|
|
|
2340
2340
|
|
|
2341
2341
|
**Usage accounting:** If a tool makes nested LLM calls, return their combined `Usage` as `usage`. Senpi persists it on the tool result and includes it in footer, `/session`, and RPC session totals. `tool_result` handlers can inspect or replace this value.
|
|
2342
2342
|
|
|
2343
|
-
**Signaling errors:**
|
|
2343
|
+
**Signaling errors:** There are two ways to mark a tool execution as failed (sets `isError: true` on the result, the `tool_execution_end` event, and the `toolResult` message the LLM sees):
|
|
2344
|
+
|
|
2345
|
+
- Throw an error from `execute`. The thrown message becomes the result text and `details` is empty.
|
|
2346
|
+
- Return a normal result with `isError: true`. `content` and `details` are delivered unchanged, so the LLM can still branch on your typed `details` while every error surface (TUI row background, RPC `isError`, `tool_result` handlers) treats the call as a failure. Omitting `isError` or setting it to `false` is a success.
|
|
2344
2347
|
|
|
2345
2348
|
**Early termination:** Return `terminate: true` from `execute()` to hint that the automatic follow-up LLM call should be skipped after the current tool batch. This only takes effect when every finalized tool result in that batch is terminating. See [examples/extensions/structured-output.ts](../examples/extensions/structured-output.ts) for a minimal example where the agent ends on a final structured-output tool call.
|
|
2346
2349
|
|
|
2347
2350
|
```typescript
|
|
2348
|
-
//
|
|
2351
|
+
// Throw when there is nothing structured to report
|
|
2349
2352
|
async execute(toolCallId, params) {
|
|
2350
2353
|
if (!isValid(params.input)) {
|
|
2351
2354
|
throw new Error(`Invalid input: ${params.input}`);
|
|
2352
2355
|
}
|
|
2353
2356
|
return { content: [{ type: "text", text: "OK" }], details: {} };
|
|
2354
2357
|
}
|
|
2358
|
+
|
|
2359
|
+
// Return isError: true when the LLM should still see typed details
|
|
2360
|
+
async execute(toolCallId, params) {
|
|
2361
|
+
const outcome = await createTeam(params);
|
|
2362
|
+
if (outcome.kind === "member_start_rejected") {
|
|
2363
|
+
return {
|
|
2364
|
+
content: [{ type: "text", text: outcome.reason }],
|
|
2365
|
+
details: { kind: "runtime_error", code: outcome.kind },
|
|
2366
|
+
isError: true,
|
|
2367
|
+
};
|
|
2368
|
+
}
|
|
2369
|
+
return { content: [{ type: "text", text: "Created" }], details: { kind: "created" } };
|
|
2370
|
+
}
|
|
2355
2371
|
```
|
|
2356
2372
|
|
|
2357
2373
|
**Important:** Use `StringEnum` from `@earendil-works/pi-ai` for string enums. `Type.Union`/`Type.Literal` doesn't work with Google's API.
|
|
@@ -3270,7 +3286,7 @@ const highlighted = highlightCode(code, lang, theme);
|
|
|
3270
3286
|
|
|
3271
3287
|
- Extension errors are logged, agent continues
|
|
3272
3288
|
- `tool_call` errors block the tool (fail-safe)
|
|
3273
|
-
- Tool `execute` errors
|
|
3289
|
+
- Tool `execute` errors are signaled by throwing or by returning a result with `isError: true`; either way the result reaches the LLM with `isError: true` and execution continues (a returned result keeps its `content` and `details`)
|
|
3274
3290
|
|
|
3275
3291
|
## Mode Behavior
|
|
3276
3292
|
|