@code-yeongyu/senpi 2026.9.7 → 2026.9.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +79 -0
- package/dist/core/agent-session.d.ts +40 -3
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +159 -40
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +2 -1
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/dynamic-prompt/working-task.js +1 -1
- package/dist/core/dynamic-prompt/working-task.js.map +1 -1
- package/dist/core/extensions/builtin/cache-keepalive/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/cache-keepalive/index.js +4 -21
- package/dist/core/extensions/builtin/cache-keepalive/index.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.d.ts +2 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.js +10 -25
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js +36 -19
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-commit-boundary.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-commit-boundary.js +21 -10
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-commit-boundary.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.d.ts +4 -17
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.js +23 -33
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js +1 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.js +5 -3
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.js +8 -3
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/tools.d.ts +6 -5
- package/dist/core/extensions/builtin/claude-sdk-oauth/tools.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/tools.js +6 -5
- package/dist/core/extensions/builtin/claude-sdk-oauth/tools.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/circuit-breaker.d.ts +8 -0
- package/dist/core/extensions/builtin/compaction/circuit-breaker.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/circuit-breaker.js +8 -0
- package/dist/core/extensions/builtin/compaction/circuit-breaker.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +8 -0
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +125 -20
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/fallback-failed-turn-normalization.d.ts +18 -0
- package/dist/core/extensions/builtin/compaction/fallback-failed-turn-normalization.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/fallback-failed-turn-normalization.js +20 -0
- package/dist/core/extensions/builtin/compaction/fallback-failed-turn-normalization.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.js +54 -11
- package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/lane-policy.d.ts +3 -0
- package/dist/core/extensions/builtin/compaction/lane-policy.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/lane-policy.js +47 -23
- package/dist/core/extensions/builtin/compaction/lane-policy.js.map +1 -1
- package/dist/core/extensions/builtin/goal/agent-end-continuation.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/agent-end-continuation.js +11 -0
- package/dist/core/extensions/builtin/goal/agent-end-continuation.js.map +1 -1
- package/dist/core/extensions/builtin/goal/cache-warm-renderer.js +6 -4
- package/dist/core/extensions/builtin/goal/cache-warm-renderer.js.map +1 -1
- package/dist/core/extensions/builtin/goal/cache-warm.d.ts +25 -1
- package/dist/core/extensions/builtin/goal/cache-warm.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/cache-warm.js +29 -10
- package/dist/core/extensions/builtin/goal/cache-warm.js.map +1 -1
- package/dist/core/extensions/builtin/goal/continuation.d.ts +3 -1
- package/dist/core/extensions/builtin/goal/continuation.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/continuation.js +17 -2
- package/dist/core/extensions/builtin/goal/continuation.js.map +1 -1
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +1 -0
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -1
- package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts +1 -1
- package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/monitor-continuation.js +8 -3
- package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
- package/dist/core/extensions/builtin/gpt-account.d.ts +5 -1
- package/dist/core/extensions/builtin/gpt-account.d.ts.map +1 -1
- package/dist/core/extensions/builtin/gpt-account.js +9 -26
- package/dist/core/extensions/builtin/gpt-account.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/plugin-manifest.js +2 -2
- package/dist/core/extensions/builtin/hooks/plugin-manifest.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/safety.js +2 -2
- package/dist/core/extensions/builtin/hooks/safety.js.map +1 -1
- package/dist/core/extensions/builtin/monitor-state-event.d.ts +18 -0
- package/dist/core/extensions/builtin/monitor-state-event.d.ts.map +1 -1
- package/dist/core/extensions/builtin/monitor-state-event.js +23 -0
- package/dist/core/extensions/builtin/monitor-state-event.js.map +1 -1
- package/dist/core/extensions/builtin/oauth-login-interaction.d.ts +24 -0
- package/dist/core/extensions/builtin/oauth-login-interaction.d.ts.map +1 -0
- package/dist/core/extensions/builtin/oauth-login-interaction.js +77 -0
- package/dist/core/extensions/builtin/oauth-login-interaction.js.map +1 -0
- package/dist/core/extensions/builtin/permission-system/external-dir.d.ts.map +1 -1
- package/dist/core/extensions/builtin/permission-system/external-dir.js +5 -51
- package/dist/core/extensions/builtin/permission-system/external-dir.js.map +1 -1
- package/dist/core/extensions/builtin/permission-system/parsers.d.ts.map +1 -1
- package/dist/core/extensions/builtin/permission-system/parsers.js +5 -7
- package/dist/core/extensions/builtin/permission-system/parsers.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/execution-tooling.d.ts +14 -7
- package/dist/core/extensions/builtin/prompt-preset/execution-tooling.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/execution-tooling.js +34 -13
- package/dist/core/extensions/builtin/prompt-preset/execution-tooling.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts +6 -10
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +14 -9
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.d.ts +15 -15
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.js +49 -21
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js.map +1 -1
- package/dist/core/extensions/builtin/service-tier.d.ts +2 -0
- package/dist/core/extensions/builtin/service-tier.d.ts.map +1 -1
- package/dist/core/extensions/builtin/service-tier.js +17 -1
- package/dist/core/extensions/builtin/service-tier.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/durable-command.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/durable-command.js +3 -0
- package/dist/core/extensions/builtin/terminal/durable-command.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/durable-file.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/durable-file.js +2 -0
- package/dist/core/extensions/builtin/terminal/durable-file.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/extension.js +14 -2
- package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-notify.js +27 -5
- package/dist/core/extensions/builtin/terminal/monitor-notify.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts +17 -0
- package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-registry.js +76 -14
- package/dist/core/extensions/builtin/terminal/monitor-registry.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/notify.d.ts +2 -0
- package/dist/core/extensions/builtin/terminal/notify.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/notify.js +6 -1
- package/dist/core/extensions/builtin/terminal/notify.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/session-bundle.d.ts +3 -1
- package/dist/core/extensions/builtin/terminal/session-bundle.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/session-bundle.js +13 -0
- package/dist/core/extensions/builtin/terminal/session-bundle.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/shared.d.ts +13 -2
- package/dist/core/extensions/builtin/terminal/shared.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/shared.js +15 -2
- package/dist/core/extensions/builtin/terminal/shared.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/monitor.js +8 -1
- package/dist/core/extensions/builtin/terminal/tools/monitor.js.map +1 -1
- package/dist/core/extensions/builtin/tool-search/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/tool-search/index.js +1 -0
- package/dist/core/extensions/builtin/tool-search/index.js.map +1 -1
- package/dist/core/extensions/builtin/tool-search/service.d.ts +4 -0
- package/dist/core/extensions/builtin/tool-search/service.d.ts.map +1 -1
- package/dist/core/extensions/builtin/tool-search/service.js +11 -0
- package/dist/core/extensions/builtin/tool-search/service.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +1 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +8 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +9 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/high-reasoning-warning.d.ts.map +1 -1
- package/dist/core/high-reasoning-warning.js +4 -6
- package/dist/core/high-reasoning-warning.js.map +1 -1
- package/dist/core/sdk.d.ts +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +25 -6
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/settings-manager.js +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/settings-shapes.js.map +1 -1
- package/dist/core/tools/bounded-realpath.d.ts +28 -0
- package/dist/core/tools/bounded-realpath.d.ts.map +1 -0
- package/dist/core/tools/bounded-realpath.js +53 -0
- package/dist/core/tools/bounded-realpath.js.map +1 -0
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js +15 -13
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/filesystem-policy.d.ts +7 -0
- package/dist/core/tools/filesystem-policy.d.ts.map +1 -1
- package/dist/core/tools/filesystem-policy.js +25 -15
- package/dist/core/tools/filesystem-policy.js.map +1 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +13 -2
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +1 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/memory-tips.d.ts.map +1 -1
- package/dist/modes/interactive/tips/catalog/memory-tips.js +6 -0
- package/dist/modes/interactive/tips/catalog/memory-tips.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/subagent-tips.d.ts.map +1 -1
- package/dist/modes/interactive/tips/catalog/subagent-tips.js +6 -0
- package/dist/modes/interactive/tips/catalog/subagent-tips.js.map +1 -1
- package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -1
- package/dist/modes/rpc/host-lifecycle.js +31 -5
- package/dist/modes/rpc/host-lifecycle.js.map +1 -1
- package/dist/modes/rpc/host-watchdog.d.ts +11 -0
- package/dist/modes/rpc/host-watchdog.d.ts.map +1 -1
- package/dist/modes/rpc/host-watchdog.js +16 -2
- package/dist/modes/rpc/host-watchdog.js.map +1 -1
- package/dist/modes/rpc/multi-session-host.d.ts.map +1 -1
- package/dist/modes/rpc/multi-session-host.js +54 -16
- package/dist/modes/rpc/multi-session-host.js.map +1 -1
- package/dist/modes/rpc/socket-ownership.d.ts +46 -0
- package/dist/modes/rpc/socket-ownership.d.ts.map +1 -0
- package/dist/modes/rpc/socket-ownership.js +178 -0
- package/dist/modes/rpc/socket-ownership.js.map +1 -0
- package/dist/utils/fs-watch.d.ts +17 -0
- package/dist/utils/fs-watch.d.ts.map +1 -1
- package/dist/utils/fs-watch.js +38 -10
- package/dist/utils/fs-watch.js.map +1 -1
- package/dist/utils/paths.d.ts +33 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +109 -3
- package/dist/utils/paths.js.map +1 -1
- package/docs/development.md +3 -2
- package/docs/providers.md +5 -1
- package/docs/settings.md +1 -0
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +31 -0
- package/node_modules/@code-yeongyu/senpi-codemode/README.md +14 -1
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/protocol.ts +1 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/extension/runtime-factory.ts +3 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/extension/session-manager.ts +7 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/AGENTS.md +7 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/jl/kernel.ts +4 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-contract.ts +3 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-core.js +29 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-indirect-eval.js +10 -6
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-shell-capture.d.ts +16 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-shell-capture.js +44 -8
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-startup.ts +1 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel-contract.ts +3 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/transport.ts +9 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/rb/kernel.ts +4 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/session-env.ts +56 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-contract.ts +3 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-kernel.ts +9 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/output/output-meta.ts +26 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +17 -24
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/image.ts +12 -3
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +2 -2
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts +7 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js +19 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.js +24 -16
- package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/index.js +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +47 -178
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.d.ts +3 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.js +260 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic-callback-listener.d.ts +40 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic-callback-listener.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic-callback-listener.js +138 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic-callback-listener.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.d.ts +2 -3
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.js +42 -139
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/authorization-input.d.ts +6 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/authorization-input.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/authorization-input.js +29 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/authorization-input.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/error-details.d.ts +3 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/error-details.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/error-details.js +20 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/error-details.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/azure-openai-responses.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/github-copilot.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai-codex.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opengateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/recovery-stream-terminal.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/recovery-stream-terminal.js +16 -1
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/recovery-stream-terminal.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +7 -0
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +14 -3
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.d.ts +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.js +16 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
|
@@ -12,6 +12,7 @@ const MAX_PARKED_EXITS = 32;
|
|
|
12
12
|
export class TerminalSessionBundle {
|
|
13
13
|
#sinks = null;
|
|
14
14
|
#parkedMonitorEvents = [];
|
|
15
|
+
#parkedMonitorEndings = [];
|
|
15
16
|
#parkedExits = new Map();
|
|
16
17
|
#backgrounds = new Map();
|
|
17
18
|
#torndown = false;
|
|
@@ -19,6 +20,13 @@ export class TerminalSessionBundle {
|
|
|
19
20
|
this.manager = new TerminalManager(options);
|
|
20
21
|
this.monitors = new MonitorRegistry((event) => this.#dispatchMonitorEvent(event), {
|
|
21
22
|
onChange: (snapshot) => this.#sinks?.onMonitorState(snapshot),
|
|
23
|
+
onFire: (snapshot) => this.#sinks?.onMonitorState(snapshot, false),
|
|
24
|
+
onEnded: (event) => {
|
|
25
|
+
if (this.#sinks)
|
|
26
|
+
this.#sinks.onMonitorEnded(event);
|
|
27
|
+
else
|
|
28
|
+
this.#parkedMonitorEndings.push(event);
|
|
29
|
+
},
|
|
22
30
|
reserve: () => this.manager.reserve(),
|
|
23
31
|
});
|
|
24
32
|
}
|
|
@@ -29,12 +37,16 @@ export class TerminalSessionBundle {
|
|
|
29
37
|
this.#sinks = sinks;
|
|
30
38
|
const parkedMonitorEvents = this.#parkedMonitorEvents;
|
|
31
39
|
this.#parkedMonitorEvents = [];
|
|
40
|
+
const parkedMonitorEndings = this.#parkedMonitorEndings;
|
|
41
|
+
this.#parkedMonitorEndings = [];
|
|
32
42
|
const parkedExits = [...this.#parkedExits];
|
|
33
43
|
this.#parkedExits.clear();
|
|
34
44
|
sinks.onMonitorState(this.monitors.snapshot());
|
|
35
45
|
sinks.onBackgroundState(this.backgroundSnapshot());
|
|
36
46
|
for (const event of parkedMonitorEvents)
|
|
37
47
|
sinks.onMonitorEvent(event);
|
|
48
|
+
for (const event of parkedMonitorEndings)
|
|
49
|
+
sinks.onMonitorEnded(event);
|
|
38
50
|
for (const [id, runtime] of parkedExits)
|
|
39
51
|
sinks.onBackgroundExit(id, runtime);
|
|
40
52
|
}
|
|
@@ -74,6 +86,7 @@ export class TerminalSessionBundle {
|
|
|
74
86
|
this.#sinks?.onBackgroundState([]);
|
|
75
87
|
}
|
|
76
88
|
this.#torndown = true;
|
|
89
|
+
this.#parkedMonitorEndings = [];
|
|
77
90
|
this.#sinks = null;
|
|
78
91
|
await this.manager.teardown();
|
|
79
92
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-bundle.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/session-bundle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAA+B,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"session-bundle.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/session-bundle.ts"],"names":[],"mappings":"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","sourcesContent":["import type { WakeSourceStateItem } from \"../monitor-state-event.ts\";\nimport { TerminalManager, type TerminalManagerOptions } from \"./manager.ts\";\nimport type { MonitorEndedEvent } from \"./monitor-registry.ts\";\nimport { type MonitorEvent, MonitorRegistry, type MonitorSnapshotEntry } from \"./monitor-registry.ts\";\nimport type { TerminalRuntimeSession } from \"./runtime-session.ts\";\n\nexport interface TerminalEventSinks {\n\treadonly onMonitorEvent: (event: MonitorEvent) => void;\n\treadonly onMonitorState: (snapshot: readonly MonitorSnapshotEntry[], transition?: boolean) => void;\n\treadonly onMonitorEnded: (event: MonitorEndedEvent) => void;\n\treadonly onBackgroundState: (snapshot: readonly WakeSourceStateItem[]) => void;\n\treadonly onBackgroundExit: (id: string, runtime: TerminalRuntimeSession) => void;\n}\n\nconst MAX_PARKED_MONITOR_EVENTS = 100;\nconst MAX_PARKED_EXITS = 32;\n\n/**\n * The long-lived terminal runtime for one agent session: the PTY session manager plus\n * the monitor registry. A session reload replaces the extension runner and re-runs the\n * extension factory, so this state must outlive any single extension instance; event\n * routing goes through mutable sinks the current owner instance binds. While parked\n * (the reload window, or a headless reload that never re-binds) events buffer bounded.\n */\nexport class TerminalSessionBundle {\n\treadonly manager: TerminalManager;\n\treadonly monitors: MonitorRegistry;\n\t#sinks: TerminalEventSinks | null = null;\n\t#parkedMonitorEvents: MonitorEvent[] = [];\n\t#parkedMonitorEndings: MonitorEndedEvent[] = [];\n\t#parkedExits = new Map<string, TerminalRuntimeSession>();\n\t#backgrounds = new Map<string, WakeSourceStateItem>();\n\t#torndown = false;\n\n\tconstructor(options: TerminalManagerOptions) {\n\t\tthis.manager = new TerminalManager(options);\n\t\tthis.monitors = new MonitorRegistry((event) => this.#dispatchMonitorEvent(event), {\n\t\t\tonChange: (snapshot) => this.#sinks?.onMonitorState(snapshot),\n\t\t\tonFire: (snapshot) => this.#sinks?.onMonitorState(snapshot, false),\n\t\t\tonEnded: (event) => {\n\t\t\t\tif (this.#sinks) this.#sinks.onMonitorEnded(event);\n\t\t\t\telse this.#parkedMonitorEndings.push(event);\n\t\t\t},\n\t\t\treserve: () => this.manager.reserve(),\n\t\t});\n\t}\n\n\t/** Install live sinks, re-publish channel state, and flush everything buffered while parked. */\n\tbind(sinks: TerminalEventSinks): void {\n\t\tif (this.#torndown) return;\n\t\tthis.#sinks = sinks;\n\t\tconst parkedMonitorEvents = this.#parkedMonitorEvents;\n\t\tthis.#parkedMonitorEvents = [];\n\t\tconst parkedMonitorEndings = this.#parkedMonitorEndings;\n\t\tthis.#parkedMonitorEndings = [];\n\t\tconst parkedExits = [...this.#parkedExits];\n\t\tthis.#parkedExits.clear();\n\t\tsinks.onMonitorState(this.monitors.snapshot());\n\t\tsinks.onBackgroundState(this.backgroundSnapshot());\n\t\tfor (const event of parkedMonitorEvents) sinks.onMonitorEvent(event);\n\t\tfor (const event of parkedMonitorEndings) sinks.onMonitorEnded(event);\n\t\tfor (const [id, runtime] of parkedExits) sinks.onBackgroundExit(id, runtime);\n\t}\n\n\tpark(): void {\n\t\tthis.#sinks = null;\n\t}\n\n\tbackgroundSnapshot(): readonly WakeSourceStateItem[] {\n\t\treturn [...this.#backgrounds.values()];\n\t}\n\n\tnotifyBackgroundStart(id: string, description: string, startedAtMs = Date.now()): void {\n\t\tif (this.#torndown) return;\n\t\tthis.#backgrounds.set(id, { id, description, startedAtMs });\n\t\tthis.#sinks?.onBackgroundState(this.backgroundSnapshot());\n\t}\n\n\tnotifyBackgroundExit(id: string, runtime: TerminalRuntimeSession): void {\n\t\tif (this.#torndown) return;\n\t\tif (this.#backgrounds.delete(id)) this.#sinks?.onBackgroundState(this.backgroundSnapshot());\n\t\tif (this.#sinks) {\n\t\t\tthis.#sinks.onBackgroundExit(id, runtime);\n\t\t\treturn;\n\t\t}\n\t\tif (this.#parkedExits.size >= MAX_PARKED_EXITS) return;\n\t\tthis.#parkedExits.set(id, runtime);\n\t}\n\n\tasync teardown(): Promise<void> {\n\t\tif (this.#torndown) return;\n\t\tthis.#parkedMonitorEvents = [];\n\t\tthis.#parkedExits.clear();\n\t\tthis.monitors.dispose();\n\t\tif (this.#backgrounds.size > 0) {\n\t\t\tthis.#backgrounds.clear();\n\t\t\tthis.#sinks?.onBackgroundState([]);\n\t\t}\n\t\tthis.#torndown = true;\n\t\tthis.#parkedMonitorEndings = [];\n\t\tthis.#sinks = null;\n\t\tawait this.manager.teardown();\n\t}\n\n\t#dispatchMonitorEvent(event: MonitorEvent): void {\n\t\tif (this.#torndown) return;\n\t\tif (this.#sinks) {\n\t\t\tthis.#sinks.onMonitorEvent(event);\n\t\t\treturn;\n\t\t}\n\t\tthis.#parkedMonitorEvents.push(event);\n\t\tif (this.#parkedMonitorEvents.length > MAX_PARKED_MONITOR_EVENTS) this.#parkedMonitorEvents.shift();\n\t}\n}\n\nconst parkedBundles = new Map<string, TerminalSessionBundle>();\n\n/** Park a bundle across a reload; at most one parked bundle per session, older ones torn down. */\nexport async function parkBundle(sessionKey: string, bundle: TerminalSessionBundle): Promise<void> {\n\tconst previous = parkedBundles.get(sessionKey);\n\tparkedBundles.set(sessionKey, bundle);\n\tif (previous && previous !== bundle) await previous.teardown();\n}\n\nexport function claimParkedBundle(sessionKey: string): TerminalSessionBundle | undefined {\n\tconst bundle = parkedBundles.get(sessionKey);\n\tparkedBundles.delete(sessionKey);\n\treturn bundle;\n}\n\nexport async function teardownParkedBundle(sessionKey: string): Promise<void> {\n\tconst bundle = parkedBundles.get(sessionKey);\n\tparkedBundles.delete(sessionKey);\n\tawait bundle?.teardown();\n}\n"]}
|
|
@@ -52,8 +52,19 @@ export declare const FIRE_BUDGET_AUTO_MUTE_SUMMARY = "auto-muted: fire budget (2
|
|
|
52
52
|
/**
|
|
53
53
|
* Non-interactive environment for foreground one-shot commands (codex-style):
|
|
54
54
|
* cooperative tools (`gh`, `git`, pagers, color libs) skip spinners/colors at
|
|
55
|
-
* the source instead of flooding the captured stream with redraw frames
|
|
56
|
-
*
|
|
55
|
+
* the source instead of flooding the captured stream with redraw frames, and
|
|
56
|
+
* `git` never blocks the captured foreground PTY on interactive input.
|
|
57
|
+
* - `GIT_EDITOR: "true"`: git spawns `/usr/bin/true` as the editor, which exits 0
|
|
58
|
+
* immediately (git treats a zero-exit editor as accepted), so a `git commit`
|
|
59
|
+
* without `-m` aborts with "Aborting commit due to empty commit message" and a
|
|
60
|
+
* `git rebase -i` accepts the todo list instead of parking the tool inside
|
|
61
|
+
* nvim on COMMIT_EDITMSG until the timeout kills it.
|
|
62
|
+
* - `GIT_TERMINAL_PROMPT: "0"`: git fails fast ("could not read Username",
|
|
63
|
+
* exit 128) instead of prompting for credentials on the captured PTY where
|
|
64
|
+
* nobody can type (same opt-out `package-manager.ts` already uses for its own
|
|
65
|
+
* git calls).
|
|
66
|
+
* Background sessions keep the user's real TERM and git settings for
|
|
67
|
+
* interactive apps.
|
|
57
68
|
*/
|
|
58
69
|
export declare const FOREGROUND_ENV_OVERRIDES: Readonly<Record<string, string>>;
|
|
59
70
|
/** Resolve a single named key to its PTY byte sequence, or null when unknown. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/shared.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,kBAAkB,SAAS,CAAC;AACzC,eAAO,MAAM,oBAAoB,gBAAgB,CAAC;AAClD,eAAO,MAAM,kBAAkB,cAAc,CAAC;AAC9C,eAAO,MAAM,mBAAmB,eAAe,CAAC;AAChD,eAAO,MAAM,oBAAoB,gBAAgB,CAAC;AAClD,eAAO,MAAM,qBAAqB,YAAY,CAAC;AAE/C,wEAAwE;AACxE,eAAO,MAAM,wBAAwB,+EAM3B,CAAC;AAEX,eAAO,MAAM,YAAY,MAAM,CAAC;AAChC,eAAO,MAAM,YAAY,KAAK,CAAC;AAC/B,eAAO,MAAM,kBAAkB,QAAS,CAAC;AACzC,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,2FAA2F;AAC3F,eAAO,MAAM,wBAAwB,UAAY,CAAC;AAClD,gGAAgG;AAChG,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,OAAO,CAAC;AAEjD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC;;;GAGG;AACH,eAAO,MAAM,yBAAyB,QAA0B,CAAC;AACjE;;;;;GAKG;AACH,eAAO,MAAM,mCAAmC,MAAM,CAAC;AACvD,+FAA+F;AAC/F,eAAO,MAAM,qBAAqB,QAAsB,CAAC;AACzD;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,+DAAkG,CAAC;AAE7I
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/shared.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,kBAAkB,SAAS,CAAC;AACzC,eAAO,MAAM,oBAAoB,gBAAgB,CAAC;AAClD,eAAO,MAAM,kBAAkB,cAAc,CAAC;AAC9C,eAAO,MAAM,mBAAmB,eAAe,CAAC;AAChD,eAAO,MAAM,oBAAoB,gBAAgB,CAAC;AAClD,eAAO,MAAM,qBAAqB,YAAY,CAAC;AAE/C,wEAAwE;AACxE,eAAO,MAAM,wBAAwB,+EAM3B,CAAC;AAEX,eAAO,MAAM,YAAY,MAAM,CAAC;AAChC,eAAO,MAAM,YAAY,KAAK,CAAC;AAC/B,eAAO,MAAM,kBAAkB,QAAS,CAAC;AACzC,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,2FAA2F;AAC3F,eAAO,MAAM,wBAAwB,UAAY,CAAC;AAClD,gGAAgG;AAChG,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,OAAO,CAAC;AAEjD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC;;;GAGG;AACH,eAAO,MAAM,yBAAyB,QAA0B,CAAC;AACjE;;;;;GAKG;AACH,eAAO,MAAM,mCAAmC,MAAM,CAAC;AACvD,+FAA+F;AAC/F,eAAO,MAAM,qBAAqB,QAAsB,CAAC;AACzD;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,+DAAkG,CAAC;AAE7I;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CASrE,CAAC;AAiCF,iFAAiF;AACjF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ7D;AAED,2FAA2F;AAC3F,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CASvF;AAED,oFAAoF;AACpF,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMzD"}
|
|
@@ -58,8 +58,19 @@ export const FIRE_BUDGET_AUTO_MUTE_SUMMARY = `auto-muted: fire budget (${DEFAULT
|
|
|
58
58
|
/**
|
|
59
59
|
* Non-interactive environment for foreground one-shot commands (codex-style):
|
|
60
60
|
* cooperative tools (`gh`, `git`, pagers, color libs) skip spinners/colors at
|
|
61
|
-
* the source instead of flooding the captured stream with redraw frames
|
|
62
|
-
*
|
|
61
|
+
* the source instead of flooding the captured stream with redraw frames, and
|
|
62
|
+
* `git` never blocks the captured foreground PTY on interactive input.
|
|
63
|
+
* - `GIT_EDITOR: "true"`: git spawns `/usr/bin/true` as the editor, which exits 0
|
|
64
|
+
* immediately (git treats a zero-exit editor as accepted), so a `git commit`
|
|
65
|
+
* without `-m` aborts with "Aborting commit due to empty commit message" and a
|
|
66
|
+
* `git rebase -i` accepts the todo list instead of parking the tool inside
|
|
67
|
+
* nvim on COMMIT_EDITMSG until the timeout kills it.
|
|
68
|
+
* - `GIT_TERMINAL_PROMPT: "0"`: git fails fast ("could not read Username",
|
|
69
|
+
* exit 128) instead of prompting for credentials on the captured PTY where
|
|
70
|
+
* nobody can type (same opt-out `package-manager.ts` already uses for its own
|
|
71
|
+
* git calls).
|
|
72
|
+
* Background sessions keep the user's real TERM and git settings for
|
|
73
|
+
* interactive apps.
|
|
63
74
|
*/
|
|
64
75
|
export const FOREGROUND_ENV_OVERRIDES = {
|
|
65
76
|
NO_COLOR: "1",
|
|
@@ -68,6 +79,8 @@ export const FOREGROUND_ENV_OVERRIDES = {
|
|
|
68
79
|
PAGER: "cat",
|
|
69
80
|
GIT_PAGER: "cat",
|
|
70
81
|
GH_PAGER: "cat",
|
|
82
|
+
GIT_EDITOR: "true",
|
|
83
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
71
84
|
};
|
|
72
85
|
/**
|
|
73
86
|
* Named-key aliases the model can send via `bash_input {keys:[...]}`. Values are the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/shared.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AACzC,MAAM,CAAC,MAAM,oBAAoB,GAAG,aAAa,CAAC;AAClD,MAAM,CAAC,MAAM,kBAAkB,GAAG,WAAW,CAAC;AAC9C,MAAM,CAAC,MAAM,mBAAmB,GAAG,YAAY,CAAC;AAChD,MAAM,CAAC,MAAM,oBAAoB,GAAG,aAAa,CAAC;AAClD,MAAM,CAAC,MAAM,qBAAqB,GAAG,SAAS,CAAC;AAE/C,wEAAwE;AACxE,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACvC,oBAAoB;IACpB,kBAAkB;IAClB,mBAAmB;IACnB,oBAAoB;IACpB,qBAAqB;CACZ,CAAC;AAEX,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAC;AAChC,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,CAAC;AAC/B,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AACzC,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AACvC,2FAA2F;AAC3F,MAAM,CAAC,MAAM,wBAAwB,GAAG,SAAS,CAAC;AAClD,gGAAgG;AAChG,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAC;AAC7C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,IAAI,CAAC;AAEjD;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AACtC;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AACjE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mCAAmC,GAAG,GAAG,CAAC;AACvD,+FAA+F;AAC/F,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AACzD;;;;GAIG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,4BAA4B,mCAAmC,gCAAgC,CAAC;AAE7I
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/shared.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared constants and helpers for the persistent-terminal builtin extension.\n */\n\nexport const TERMINAL_BASH_TOOL = \"bash\";\nexport const TERMINAL_OUTPUT_TOOL = \"bash_output\";\nexport const TERMINAL_KILL_TOOL = \"kill_bash\";\nexport const TERMINAL_INPUT_TOOL = \"bash_input\";\nexport const TERMINAL_RESIZE_TOOL = \"bash_resize\";\nexport const TERMINAL_MONITOR_TOOL = \"monitor\";\n\n/** Companion tools that must never dangle without a live PTY `bash`. */\nexport const TERMINAL_COMPANION_TOOLS = [\n\tTERMINAL_OUTPUT_TOOL,\n\tTERMINAL_KILL_TOOL,\n\tTERMINAL_INPUT_TOOL,\n\tTERMINAL_RESIZE_TOOL,\n\tTERMINAL_MONITOR_TOOL,\n] as const;\n\nexport const DEFAULT_COLS = 120;\nexport const DEFAULT_ROWS = 40;\nexport const DEFAULT_SCROLLBACK = 10_000;\nexport const DEFAULT_MAX_SESSIONS = 32;\n/** Upper bound on decoded output retained per session for delta reads and `view:\"log\"`. */\nexport const MAX_SESSION_OUTPUT_CHARS = 1_000_000;\n/** Grace window used to capture a background command's early output before returning its id. */\nexport const BACKGROUND_START_GRACE_MS = 250;\n/**\n * After a foreground session has been killed (abort or timeout), how long to keep\n * waiting for its exit to settle before releasing the tool anyway. A surviving\n * descendant that holds the PTY open (or a kill that never lands) must not keep\n * the agent blocked forever.\n */\nexport const KILLED_SESSION_EXIT_GRACE_MS = 5000;\n\n/**\n * Admission cap on durable (restart-surviving) monitors per session. Ephemeral monitors\n * never count against it: only entries the manifest keeps across a restart do.\n */\nexport const MAX_DURABLE_MONITORS = 5;\n/**\n * Absolute lifetime of a durable monitor, measured from its registration. It is a deadline,\n * never a sliding window: neither a restore nor a rearm extends it.\n */\nexport const DURABLE_MONITOR_EXPIRY_MS = 7 * 24 * 60 * 60 * 1000;\n/**\n * Per-monitor rolling fire budget: one durable command watch may deliver at most this many\n * matched line events inside any FIRE_BUDGET_WINDOW_MS window before the registry auto-mutes\n * it. The session-global wake budget only counts consecutive line-only wakes on an idle\n * session, so a busy session needs this per-monitor backstop against a runaway watch.\n */\nexport const DEFAULT_DURABLE_MONITOR_FIRE_BUDGET = 200;\n/** Width of the rolling fire-budget window: the budget replenishes after this span elapses. */\nexport const FIRE_BUDGET_WINDOW_MS = 24 * 60 * 60 * 1000;\n/**\n * The ONE summary emitted when the fire budget mutes a watch. Machine-consumed: the monitor\n * notifier exempts exactly this summary from its completion handling, so the mute must not\n * clear the session-global wake streak.\n */\nexport const FIRE_BUDGET_AUTO_MUTE_SUMMARY = `auto-muted: fire budget (${DEFAULT_DURABLE_MONITOR_FIRE_BUDGET}/24h) reached; rearm to resume`;\n\n/**\n * Non-interactive environment for foreground one-shot commands (codex-style):\n * cooperative tools (`gh`, `git`, pagers, color libs) skip spinners/colors at\n * the source instead of flooding the captured stream with redraw frames, and\n * `git` never blocks the captured foreground PTY on interactive input.\n * - `GIT_EDITOR: \"true\"`: git spawns `/usr/bin/true` as the editor, which exits 0\n * immediately (git treats a zero-exit editor as accepted), so a `git commit`\n * without `-m` aborts with \"Aborting commit due to empty commit message\" and a\n * `git rebase -i` accepts the todo list instead of parking the tool inside\n * nvim on COMMIT_EDITMSG until the timeout kills it.\n * - `GIT_TERMINAL_PROMPT: \"0\"`: git fails fast (\"could not read Username\",\n * exit 128) instead of prompting for credentials on the captured PTY where\n * nobody can type (same opt-out `package-manager.ts` already uses for its own\n * git calls).\n * Background sessions keep the user's real TERM and git settings for\n * interactive apps.\n */\nexport const FOREGROUND_ENV_OVERRIDES: Readonly<Record<string, string>> = {\n\tNO_COLOR: \"1\",\n\tTERM: \"dumb\",\n\tCOLORTERM: \"\",\n\tPAGER: \"cat\",\n\tGIT_PAGER: \"cat\",\n\tGH_PAGER: \"cat\",\n\tGIT_EDITOR: \"true\",\n\tGIT_TERMINAL_PROMPT: \"0\",\n};\n\n/**\n * Named-key aliases the model can send via `bash_input {keys:[...]}`. Values are the\n * raw byte sequences a PTY expects (control chars + xterm cursor/function escapes).\n */\nconst KEY_SEQUENCES: Record<string, string> = {\n\tenter: \"\\r\",\n\treturn: \"\\r\",\n\ttab: \"\\t\",\n\tescape: \"\\x1b\",\n\tesc: \"\\x1b\",\n\tspace: \" \",\n\tbackspace: \"\\x7f\",\n\tdelete: \"\\x1b[3~\",\n\tup: \"\\x1b[A\",\n\tdown: \"\\x1b[B\",\n\tright: \"\\x1b[C\",\n\tleft: \"\\x1b[D\",\n\thome: \"\\x1b[H\",\n\tend: \"\\x1b[F\",\n\tpageup: \"\\x1b[5~\",\n\tpagedown: \"\\x1b[6~\",\n\t\"ctrl+c\": \"\\x03\",\n\t\"ctrl+d\": \"\\x04\",\n\t\"ctrl+z\": \"\\x1a\",\n\t\"ctrl+l\": \"\\x0c\",\n\t\"ctrl+u\": \"\\x15\",\n\t\"ctrl+a\": \"\\x01\",\n\t\"ctrl+e\": \"\\x05\",\n\t\"ctrl+\\\\\": \"\\x1c\",\n};\n\n/** Resolve a single named key to its PTY byte sequence, or null when unknown. */\nexport function resolveKeySequence(key: string): string | null {\n\tconst normalized = key.trim().toLowerCase();\n\tif (normalized.length === 0) return null;\n\tconst mapped = KEY_SEQUENCES[normalized];\n\tif (mapped !== undefined) return mapped;\n\t// Single printable character passes through verbatim.\n\tif ([...normalized].length === 1) return key;\n\treturn null;\n}\n\n/** Build a PTY-ready payload from a list of named keys, returning the unknown keys too. */\nexport function encodeKeys(keys: readonly string[]): { data: string; unknown: string[] } {\n\tlet data = \"\";\n\tconst unknown: string[] = [];\n\tfor (const key of keys) {\n\t\tconst sequence = resolveKeySequence(key);\n\t\tif (sequence === null) unknown.push(key);\n\t\telse data += sequence;\n\t}\n\treturn { data, unknown };\n}\n\n/** Compile a user-supplied regex, tolerating invalid patterns by returning null. */\nexport function safeRegExp(pattern: string): RegExp | null {\n\ttry {\n\t\treturn new RegExp(pattern);\n\t} catch {\n\t\treturn null;\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"monitor.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/terminal/tools/monitor.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAU5C,OAAO,KAAK,EAAuB,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAC3F,OAAO,EAGN,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EAEvB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGhD,eAAO,MAAM,0BAA0B,SAAU,CAAC;AAClD,eAAO,MAAM,sBAAsB,UAAY,CAAC;AAEhD;;;;;GAKG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;EAkDxB,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,aAAa,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"monitor.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/terminal/tools/monitor.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAU5C,OAAO,KAAK,EAAuB,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAC3F,OAAO,EAGN,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EAEvB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGhD,eAAO,MAAM,0BAA0B,SAAU,CAAC;AAClD,eAAO,MAAM,sBAAsB,UAAY,CAAC;AAEhD;;;;;GAKG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;EAkDxB,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,aAAa,CAAC,CAAC;AAmGxD,4GAA4G;AAC5G,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAElG;AAED,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAEpE;AAwCD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,mBAAmB;;;;;;;;;;;;;;;;;;yBAwB1C,MAAM,SACZ,YAAY,YACT,WAAW,cACT,SAAS,YACX;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GACxB,OAAO,CAAC,kBAAkB,CAAC;EAmF/B"}
|
|
@@ -82,12 +82,14 @@ async function createMonitor(ctx, registry, input, execCtx) {
|
|
|
82
82
|
// Durability needs an absolute directory: a restore runs in a different process whose
|
|
83
83
|
// process cwd is unrelated, so the spec must carry the resolved path the spawn used.
|
|
84
84
|
const cwd = resolve(execCtx?.cwd ?? ctx.cwd);
|
|
85
|
+
const timeoutMs = input.persistent ? undefined : resolveTimeoutMs(input.timeout_ms);
|
|
86
|
+
const deadlineMs = timeoutMs === undefined ? null : Date.now() + timeoutMs;
|
|
85
87
|
const { id, runtime } = await spawnCommandSession(ctx, {
|
|
86
88
|
command: input.command,
|
|
87
89
|
cols: resolveDimension(undefined, ctx.defaultCols || DEFAULT_COLS),
|
|
88
90
|
rows: resolveDimension(undefined, ctx.defaultRows || DEFAULT_ROWS),
|
|
89
91
|
cwd,
|
|
90
|
-
...(
|
|
92
|
+
...(timeoutMs === undefined ? {} : { timeoutMs }),
|
|
91
93
|
});
|
|
92
94
|
ctx.onMonitorRearmed?.(id);
|
|
93
95
|
const monitorId = registry.register({
|
|
@@ -95,6 +97,9 @@ async function createMonitor(ctx, registry, input, execCtx) {
|
|
|
95
97
|
description: input.description,
|
|
96
98
|
runtime,
|
|
97
99
|
filter,
|
|
100
|
+
command: input.command,
|
|
101
|
+
persistent: input.persistent === true,
|
|
102
|
+
deadlineMs,
|
|
98
103
|
// Only persistent command watches are restartable-command durable: those carry the fire budget.
|
|
99
104
|
durabilityClass: input.persistent === true ? "restartable-command" : "ephemeral",
|
|
100
105
|
// Same deadline the manifest writer persists, so the footer warns off the live record too.
|
|
@@ -225,6 +230,8 @@ export function createMonitorTool(ctx) {
|
|
|
225
230
|
path: input.path,
|
|
226
231
|
event: input.event ?? "create",
|
|
227
232
|
timeoutMs: resolveTimeoutMs(input.timeout_ms),
|
|
233
|
+
persistent: input.persistent === true,
|
|
234
|
+
deadlineMs: input.persistent === true ? null : Date.now() + resolveTimeoutMs(input.timeout_ms),
|
|
228
235
|
cwd: execCtx?.cwd ?? ctx.cwd,
|
|
229
236
|
...(approvedParent !== undefined ? { approvedParent } : {}),
|
|
230
237
|
...(input.persistent === true ? { expiresAt: Date.now() + DURABLE_MONITOR_EXPIRY_MS } : {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"monitor.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/terminal/tools/monitor.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolve } from \"node:path\";\nimport { StringEnum } from \"@earendil-works/pi-ai\";\nimport { type Static, Type } from \"typebox\";\nimport { APPROVED_MONITOR_PARENT } from \"../monitor-permission.ts\";\nimport { MonitorRegistry } from \"../monitor-registry.ts\";\nimport {\n\tDEFAULT_COLS,\n\tDEFAULT_ROWS,\n\tDURABLE_MONITOR_EXPIRY_MS,\n\tMAX_DURABLE_MONITORS,\n\tTERMINAL_MONITOR_TOOL,\n} from \"../shared.ts\";\nimport type { MonitorRegistration, TerminalManifestWriter } from \"../terminal-manifest.ts\";\nimport {\n\terrorResult,\n\tresolveTerminalId,\n\ttype TerminalToolContext,\n\ttype TerminalToolResult,\n\ttextResult,\n} from \"./context.ts\";\nimport { renderMonitorCall } from \"./render.ts\";\nimport { spawnCommandSession } from \"./spawn.ts\";\n\nexport const DEFAULT_MONITOR_TIMEOUT_MS = 300_000;\nexport const MAX_MONITOR_TIMEOUT_MS = 3_600_000;\n\n/**\n * One flat object schema, no top-level union: several provider payload paths\n * (e.g. Anthropic's legacy input_schema conversion) rebuild tool schemas from\n * top-level `properties` only, so a root anyOf would reach the model as an\n * empty schema. Branch requirements are enforced at runtime in `execute`.\n */\nexport const monitorSchema = Type.Object({\n\taction: Type.Optional(\n\t\tStringEnum([\"create\", \"rearm\"] as const, {\n\t\t\tdescription: \"Defaults to create. rearm resumes a monitor paused by the wake budget.\",\n\t\t}),\n\t),\n\tdescription: Type.Optional(\n\t\tType.String({\n\t\t\tminLength: 1,\n\t\t\tmaxLength: 200,\n\t\t\tdescription: \"Create (required): specific label shown with every event, e.g. 'errors in deploy.log'.\",\n\t\t}),\n\t),\n\tcommand: Type.Optional(\n\t\tType.String({\n\t\t\tdescription:\n\t\t\t\t\"Create, command branch (XOR path): shell command to run and watch in a PTY-backed monitor session.\",\n\t\t}),\n\t),\n\tpath: Type.Optional(\n\t\tType.String({\n\t\t\tminLength: 1,\n\t\t\tdescription:\n\t\t\t\t\"Create, file branch (XOR command): one regular file to watch natively, whose parent directory must already exist; takes no filter.\",\n\t\t}),\n\t),\n\tevent: Type.Optional(\n\t\tStringEnum([\"create\", \"modify\"] as const, {\n\t\t\tdescription: \"File branch only: which file event fires the watch (defaults to create).\",\n\t\t}),\n\t),\n\tfilter: Type.Optional(\n\t\tType.String({ description: \"Only PTY output lines matching this regex become monitor events.\" }),\n\t),\n\ttimeout_ms: Type.Optional(\n\t\tType.Number({\n\t\t\tminimum: 1,\n\t\t\tmaximum: MAX_MONITOR_TIMEOUT_MS,\n\t\t\tdescription: \"Watcher deadline in milliseconds (default 300000; ignored when persistent).\",\n\t\t}),\n\t),\n\tpersistent: Type.Optional(\n\t\tType.Boolean({\n\t\t\tdescription:\n\t\t\t\t\"Standing watch: no deadline, and it survives a session restart (command re-run once, file rescanned and any detached change reported). Expires 7 days after creation; max 5 per session; stop one with kill_bash.\",\n\t\t}),\n\t),\n\tbash_id: Type.Optional(\n\t\tType.String({ description: \"Rearm: paused monitor id (mon_ or bash_id) to resume; omit for all paused.\" }),\n\t),\n});\nexport type MonitorInput = Static<typeof monitorSchema>;\n\ntype MonitorCreateInput = MonitorInput & { description: string; command: string };\ntype FileMonitorCreateInput = MonitorInput & { description: string; path: string };\n\nfunction isFileCreateInput(input: MonitorInput): input is FileMonitorCreateInput {\n\treturn (\n\t\ttypeof input.description === \"string\" &&\n\t\tinput.description.length > 0 &&\n\t\ttypeof input.path === \"string\" &&\n\t\tinput.path.length > 0\n\t);\n}\n\nfunction isCreateInput(input: MonitorInput): input is MonitorCreateInput {\n\treturn (\n\t\ttypeof input.description === \"string\" &&\n\t\tinput.description.length > 0 &&\n\t\ttypeof input.command === \"string\" &&\n\t\tinput.command.length > 0\n\t);\n}\n\nfunction resolveDimension(value: number | undefined, fallback: number): number {\n\tif (value === undefined || !Number.isFinite(value) || value < 1) return fallback;\n\treturn Math.trunc(value);\n}\n\nfunction resolveTimeoutMs(value: number | undefined): number {\n\tconst timeout = value ?? DEFAULT_MONITOR_TIMEOUT_MS;\n\treturn Math.min(Math.max(Math.trunc(timeout), 1), MAX_MONITOR_TIMEOUT_MS);\n}\n\nfunction compileFilter(filter: string | undefined): RegExp | undefined {\n\tif (filter === undefined) return undefined;\n\treturn new RegExp(filter);\n}\n\nasync function createMonitor(\n\tctx: TerminalToolContext,\n\tregistry: MonitorRegistry,\n\tinput: MonitorCreateInput,\n\texecCtx: { cwd?: string } | undefined,\n): Promise<TerminalToolResult> {\n\tlet filter: RegExp | undefined;\n\ttry {\n\t\tfilter = compileFilter(input.filter);\n\t} catch {\n\t\treturn errorResult(`Invalid monitor filter regex: ${input.filter}`);\n\t}\n\n\t// Durability needs an absolute directory: a restore runs in a different process whose\n\t// process cwd is unrelated, so the spec must carry the resolved path the spawn used.\n\tconst cwd = resolve(execCtx?.cwd ?? ctx.cwd);\n\tconst { id, runtime } = await spawnCommandSession(ctx, {\n\t\tcommand: input.command,\n\t\tcols: resolveDimension(undefined, ctx.defaultCols || DEFAULT_COLS),\n\t\trows: resolveDimension(undefined, ctx.defaultRows || DEFAULT_ROWS),\n\t\tcwd,\n\t\t...(input.persistent ? {} : { timeoutMs: resolveTimeoutMs(input.timeout_ms) }),\n\t});\n\tctx.onMonitorRearmed?.(id);\n\tconst monitorId = registry.register({\n\t\tid,\n\t\tdescription: input.description,\n\t\truntime,\n\t\tfilter,\n\t\t// Only persistent command watches are restartable-command durable: those carry the fire budget.\n\t\tdurabilityClass: input.persistent === true ? \"restartable-command\" : \"ephemeral\",\n\t\t// Same deadline the manifest writer persists, so the footer warns off the live record too.\n\t\t...(input.persistent === true ? { expiresAt: Date.now() + DURABLE_MONITOR_EXPIRY_MS } : {}),\n\t});\n\tctx.manager.bindMonitorId(monitorId, id);\n\t// The tool call site is the only place the branch inputs (command, persistent, filter)\n\t// live; hand the captured spec to the session's manifest writer for durable recording.\n\thandMonitorSpec(manifestSessionKey(ctx), {\n\t\tmonitorId,\n\t\tspec: {\n\t\t\tkind: \"command\",\n\t\t\tdescription: input.description,\n\t\t\tcommand: input.command,\n\t\t\tfilter: input.filter,\n\t\t\tcwd,\n\t\t\tpersistent: input.persistent === true,\n\t\t},\n\t});\n\treturn textResult(`Monitor started with ID: ${monitorId}`, {\n\t\tdetails: { monitor_id: monitorId, bash_id: id, monitor: true },\n\t});\n}\n\n/** Build the PTY-backed monitor tool. Monitor handles share TerminalManager's bash_N namespace. */\nconst manifestWriters = new Map<string, TerminalManifestWriter>();\n\n/** Bind the session's manifest writer so monitor tool calls can hand it specs captured at the call site. */\nexport function bindTerminalManifestWriter(sessionId: string, writer: TerminalManifestWriter): void {\n\tmanifestWriters.set(sessionId, writer);\n}\n\nexport function unbindTerminalManifestWriter(sessionId: string): void {\n\tmanifestWriters.delete(sessionId);\n}\n\n/** The durability session key for a tool context: the agent session id, when the context carries one. */\nfunction manifestSessionKey(ctx: TerminalToolContext): string | undefined {\n\treturn ctx.getSessionContext?.()?.sessionManager?.getSessionId?.();\n}\n\n/** Hand a spec captured at the monitor tool call site to the session's bound writer, if any. */\nfunction handMonitorSpec(sessionKey: string | undefined, registration: MonitorRegistration): void {\n\tconst writer = sessionKey === undefined ? undefined : manifestWriters.get(sessionKey);\n\tvoid writer?.recordRegister(registration);\n}\n\n/** Persist a durable file watch's baseline checkpoint through the writer's debounced path. */\nfunction handFileCheckpoint(\n\tsessionKey: string | undefined,\n\tmonitorId: string,\n\tregistry: MonitorRegistry,\n\truntimeId: string,\n): void {\n\tconst writer = sessionKey === undefined ? undefined : manifestWriters.get(sessionKey);\n\tconst checkpoint = registry.fileCheckpoint(runtimeId);\n\tif (writer && checkpoint) writer.scheduleCheckpoint(monitorId, checkpoint);\n}\n\n/**\n * Admission control for a durable create: refuse once the session already holds\n * MAX_DURABLE_MONITORS restart-surviving monitors. Checked BEFORE any spawn or registry\n * registration so a refused call leaves no PTY and no manifest entry behind. A context\n * with no bound writer persists nothing, so it has no durable population to cap.\n */\nfunction durableAdmissionError(ctx: TerminalToolContext): TerminalToolResult | undefined {\n\tconst sessionKey = manifestSessionKey(ctx);\n\tconst writer = sessionKey === undefined ? undefined : manifestWriters.get(sessionKey);\n\tif (writer === undefined || writer.durableCount() < MAX_DURABLE_MONITORS) return undefined;\n\treturn errorResult(\n\t\t`Cannot start another persistent monitor: this session already holds ${MAX_DURABLE_MONITORS} durable monitors (the maximum). Stop one with kill_bash first.`,\n\t);\n}\n\nexport function createMonitorTool(ctx: TerminalToolContext) {\n\tlet fallbackRegistry: MonitorRegistry | undefined;\n\tconst getRegistry = (): MonitorRegistry => {\n\t\tconst sessionRegistry = ctx.monitorRegistry;\n\t\tif (sessionRegistry) return sessionRegistry;\n\t\tfallbackRegistry ??= new MonitorRegistry((event) => ctx.onMonitorEvent?.(event));\n\t\treturn fallbackRegistry;\n\t};\n\treturn {\n\t\tname: TERMINAL_MONITOR_TOOL,\n\t\tlabel: \"monitor\",\n\t\tdescription:\n\t\t\t\"Subscribe to a change instead of polling. Pass command XOR path, never both: command watches a PTY session, injecting matching newline-terminated output lines (stderr merged) plus an exit summary; path natively watches one file and fires once, where create (the default) fires only when the file appears after registration, so use event modify for an existing file, and filter is rejected. Returns a bash_id immediately; peek with bash_output, stop with kill_bash.\",\n\t\tpromptSnippet:\n\t\t\t\"Subscribe to a command's output or a file's create/modify event as injected events instead of polling\",\n\t\tpromptGuidelines: [\n\t\t\t\"Waiting on observable state (CI checks, builds, log patterns, deploys, a file landing) means a monitor, never a foreground sleep/poll loop.\",\n\t\t\t'Waiting for one file to appear or change is the path branch: `monitor({ description, path, event? })` beats wrapping `test -f` in a shell poll loop; a file that already exists needs `event: \"modify\"`, since `create` only fires on appearance, and registration needs the parent directory to exist already — when the run creates that directory too, use the `command` branch instead.',\n\t\t\t\"Shape the command for the events you need: one-shot gate = `until <cond>; do sleep 1; done; printf 'READY\\\\n'` with filter ^READY$; stream = `tail -n 0 -F <log> | grep --line-buffered <pat>` with persistent: true, then kill_bash.\",\n\t\t\t\"Sleep loops belong INSIDE the monitor command, never in your turn: about to sleep, re-poll bash_output, or foreground-block on a long command means register a monitor and keep working.\",\n\t\t],\n\t\tparameters: monitorSchema,\n\t\trenderCall: renderMonitorCall,\n\t\tasync execute(\n\t\t\t_toolCallId: string,\n\t\t\tinput: MonitorInput,\n\t\t\t_signal?: AbortSignal,\n\t\t\t_onUpdate?: undefined,\n\t\t\texecCtx?: { cwd?: string },\n\t\t): Promise<TerminalToolResult> {\n\t\t\tconst registry = getRegistry();\n\t\t\tif (input.action === \"rearm\") {\n\t\t\t\tif (input.bash_id === undefined || input.bash_id.length === 0) {\n\t\t\t\t\tconst resumed = registry.resume();\n\t\t\t\t\tif (resumed.length === 0) return textResult(\"No paused monitors to re-arm.\");\n\t\t\t\t\tctx.onMonitorsResumed?.(resumed.map((monitor) => monitor.id));\n\t\t\t\t\tconst total = resumed.reduce((sum, monitor) => sum + monitor.mutedDropped, 0);\n\t\t\t\t\treturn textResult(\n\t\t\t\t\t\ttotal > 0\n\t\t\t\t\t\t\t? `Re-armed ${resumed.length} paused monitor(s) (${total} line(s) dropped while muted).`\n\t\t\t\t\t\t\t: `Re-armed ${resumed.length} paused monitor(s).`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst bashId = resolveTerminalId(ctx.manager, input.bash_id);\n\t\t\t\tconst dropped = registry.mutedDropped(bashId);\n\t\t\t\tconst outcome = registry.rearm(bashId);\n\t\t\t\tif (outcome === \"not_found\") return errorResult(`No active monitor found with id: ${bashId}`);\n\t\t\t\tif (outcome === \"not_paused\") return textResult(`Monitor ${bashId} is not paused; no action taken.`);\n\t\t\t\tctx.onMonitorRearmed?.(bashId);\n\t\t\t\treturn textResult(\n\t\t\t\t\tdropped > 0\n\t\t\t\t\t\t? `Monitor ${bashId} re-armed (${dropped} line(s) dropped while muted).`\n\t\t\t\t\t\t: `Monitor ${bashId} re-armed.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst fileInput = isFileCreateInput(input);\n\t\t\tconst commandInput = isCreateInput(input);\n\t\t\tif (fileInput && commandInput) return errorResult(\"monitor accepts either command or path, not both.\");\n\t\t\t// Admission runs before either create branch touches a PTY or the registry.\n\t\t\tif (input.persistent === true && (fileInput || commandInput)) {\n\t\t\t\tconst refused = durableAdmissionError(ctx);\n\t\t\t\tif (refused) return refused;\n\t\t\t}\n\t\t\tif (fileInput) {\n\t\t\t\tif (input.filter !== undefined) return errorResult(\"Native file monitors do not support filter.\");\n\t\t\t\tif (!ctx.monitorRegistry)\n\t\t\t\t\treturn errorResult(\"Native file monitors require a lifecycle-owned monitor registry.\");\n\t\t\t\ttry {\n\t\t\t\t\tconst approvedParent = (input as Record<string | symbol, unknown>)[APPROVED_MONITOR_PARENT] as\n\t\t\t\t\t\t| string\n\t\t\t\t\t\t| undefined;\n\t\t\t\t\tconst { id, monitorId } = await ctx.monitorRegistry.registerFile({\n\t\t\t\t\t\tdescription: input.description,\n\t\t\t\t\t\tpath: input.path,\n\t\t\t\t\t\tevent: input.event ?? \"create\",\n\t\t\t\t\t\ttimeoutMs: resolveTimeoutMs(input.timeout_ms),\n\t\t\t\t\t\tcwd: execCtx?.cwd ?? ctx.cwd,\n\t\t\t\t\t\t...(approvedParent !== undefined ? { approvedParent } : {}),\n\t\t\t\t\t\t...(input.persistent === true ? { expiresAt: Date.now() + DURABLE_MONITOR_EXPIRY_MS } : {}),\n\t\t\t\t\t});\n\t\t\t\t\tctx.manager.bindMonitorId(monitorId, id);\n\t\t\t\t\t// Same spec capture as the command branch: durability inputs live only here.\n\t\t\t\t\tconst sessionKey = manifestSessionKey(ctx);\n\t\t\t\t\thandMonitorSpec(sessionKey, {\n\t\t\t\t\t\tmonitorId,\n\t\t\t\t\t\tspec: {\n\t\t\t\t\t\t\tkind: \"file\",\n\t\t\t\t\t\t\tdescription: input.description,\n\t\t\t\t\t\t\tpath: input.path,\n\t\t\t\t\t\t\tevent: input.event ?? \"create\",\n\t\t\t\t\t\t\ttimeoutMs: resolveTimeoutMs(input.timeout_ms),\n\t\t\t\t\t\t\tcwd: execCtx?.cwd ?? ctx.cwd,\n\t\t\t\t\t\t\tpersistent: input.persistent === true,\n\t\t\t\t\t\t\t...(approvedParent !== undefined ? { approvedParent } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t\t// A durable watch checkpoints the registry's own identity tuple straight away, so a\n\t\t\t\t\t// restart before the first change still has a baseline (digest included) to compare to.\n\t\t\t\t\tif (input.persistent === true) handFileCheckpoint(sessionKey, monitorId, ctx.monitorRegistry, id);\n\t\t\t\t\treturn textResult(`Monitor started with ID: ${monitorId}`, {\n\t\t\t\t\t\tdetails: { monitor_id: monitorId, bash_id: id, monitor: true },\n\t\t\t\t\t});\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn errorResult(error instanceof Error ? error.message : String(error));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!commandInput) return errorResult(\"monitor requires description and command or path to start a watcher.\");\n\t\t\treturn createMonitor(ctx, registry, input, execCtx);\n\t\t},\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"monitor.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/terminal/tools/monitor.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolve } from \"node:path\";\nimport { StringEnum } from \"@earendil-works/pi-ai\";\nimport { type Static, Type } from \"typebox\";\nimport { APPROVED_MONITOR_PARENT } from \"../monitor-permission.ts\";\nimport { MonitorRegistry } from \"../monitor-registry.ts\";\nimport {\n\tDEFAULT_COLS,\n\tDEFAULT_ROWS,\n\tDURABLE_MONITOR_EXPIRY_MS,\n\tMAX_DURABLE_MONITORS,\n\tTERMINAL_MONITOR_TOOL,\n} from \"../shared.ts\";\nimport type { MonitorRegistration, TerminalManifestWriter } from \"../terminal-manifest.ts\";\nimport {\n\terrorResult,\n\tresolveTerminalId,\n\ttype TerminalToolContext,\n\ttype TerminalToolResult,\n\ttextResult,\n} from \"./context.ts\";\nimport { renderMonitorCall } from \"./render.ts\";\nimport { spawnCommandSession } from \"./spawn.ts\";\n\nexport const DEFAULT_MONITOR_TIMEOUT_MS = 300_000;\nexport const MAX_MONITOR_TIMEOUT_MS = 3_600_000;\n\n/**\n * One flat object schema, no top-level union: several provider payload paths\n * (e.g. Anthropic's legacy input_schema conversion) rebuild tool schemas from\n * top-level `properties` only, so a root anyOf would reach the model as an\n * empty schema. Branch requirements are enforced at runtime in `execute`.\n */\nexport const monitorSchema = Type.Object({\n\taction: Type.Optional(\n\t\tStringEnum([\"create\", \"rearm\"] as const, {\n\t\t\tdescription: \"Defaults to create. rearm resumes a monitor paused by the wake budget.\",\n\t\t}),\n\t),\n\tdescription: Type.Optional(\n\t\tType.String({\n\t\t\tminLength: 1,\n\t\t\tmaxLength: 200,\n\t\t\tdescription: \"Create (required): specific label shown with every event, e.g. 'errors in deploy.log'.\",\n\t\t}),\n\t),\n\tcommand: Type.Optional(\n\t\tType.String({\n\t\t\tdescription:\n\t\t\t\t\"Create, command branch (XOR path): shell command to run and watch in a PTY-backed monitor session.\",\n\t\t}),\n\t),\n\tpath: Type.Optional(\n\t\tType.String({\n\t\t\tminLength: 1,\n\t\t\tdescription:\n\t\t\t\t\"Create, file branch (XOR command): one regular file to watch natively, whose parent directory must already exist; takes no filter.\",\n\t\t}),\n\t),\n\tevent: Type.Optional(\n\t\tStringEnum([\"create\", \"modify\"] as const, {\n\t\t\tdescription: \"File branch only: which file event fires the watch (defaults to create).\",\n\t\t}),\n\t),\n\tfilter: Type.Optional(\n\t\tType.String({ description: \"Only PTY output lines matching this regex become monitor events.\" }),\n\t),\n\ttimeout_ms: Type.Optional(\n\t\tType.Number({\n\t\t\tminimum: 1,\n\t\t\tmaximum: MAX_MONITOR_TIMEOUT_MS,\n\t\t\tdescription: \"Watcher deadline in milliseconds (default 300000; ignored when persistent).\",\n\t\t}),\n\t),\n\tpersistent: Type.Optional(\n\t\tType.Boolean({\n\t\t\tdescription:\n\t\t\t\t\"Standing watch: no deadline, and it survives a session restart (command re-run once, file rescanned and any detached change reported). Expires 7 days after creation; max 5 per session; stop one with kill_bash.\",\n\t\t}),\n\t),\n\tbash_id: Type.Optional(\n\t\tType.String({ description: \"Rearm: paused monitor id (mon_ or bash_id) to resume; omit for all paused.\" }),\n\t),\n});\nexport type MonitorInput = Static<typeof monitorSchema>;\n\ntype MonitorCreateInput = MonitorInput & { description: string; command: string };\ntype FileMonitorCreateInput = MonitorInput & { description: string; path: string };\n\nfunction isFileCreateInput(input: MonitorInput): input is FileMonitorCreateInput {\n\treturn (\n\t\ttypeof input.description === \"string\" &&\n\t\tinput.description.length > 0 &&\n\t\ttypeof input.path === \"string\" &&\n\t\tinput.path.length > 0\n\t);\n}\n\nfunction isCreateInput(input: MonitorInput): input is MonitorCreateInput {\n\treturn (\n\t\ttypeof input.description === \"string\" &&\n\t\tinput.description.length > 0 &&\n\t\ttypeof input.command === \"string\" &&\n\t\tinput.command.length > 0\n\t);\n}\n\nfunction resolveDimension(value: number | undefined, fallback: number): number {\n\tif (value === undefined || !Number.isFinite(value) || value < 1) return fallback;\n\treturn Math.trunc(value);\n}\n\nfunction resolveTimeoutMs(value: number | undefined): number {\n\tconst timeout = value ?? DEFAULT_MONITOR_TIMEOUT_MS;\n\treturn Math.min(Math.max(Math.trunc(timeout), 1), MAX_MONITOR_TIMEOUT_MS);\n}\n\nfunction compileFilter(filter: string | undefined): RegExp | undefined {\n\tif (filter === undefined) return undefined;\n\treturn new RegExp(filter);\n}\n\nasync function createMonitor(\n\tctx: TerminalToolContext,\n\tregistry: MonitorRegistry,\n\tinput: MonitorCreateInput,\n\texecCtx: { cwd?: string } | undefined,\n): Promise<TerminalToolResult> {\n\tlet filter: RegExp | undefined;\n\ttry {\n\t\tfilter = compileFilter(input.filter);\n\t} catch {\n\t\treturn errorResult(`Invalid monitor filter regex: ${input.filter}`);\n\t}\n\n\t// Durability needs an absolute directory: a restore runs in a different process whose\n\t// process cwd is unrelated, so the spec must carry the resolved path the spawn used.\n\tconst cwd = resolve(execCtx?.cwd ?? ctx.cwd);\n\tconst timeoutMs = input.persistent ? undefined : resolveTimeoutMs(input.timeout_ms);\n\tconst deadlineMs = timeoutMs === undefined ? null : Date.now() + timeoutMs;\n\tconst { id, runtime } = await spawnCommandSession(ctx, {\n\t\tcommand: input.command,\n\t\tcols: resolveDimension(undefined, ctx.defaultCols || DEFAULT_COLS),\n\t\trows: resolveDimension(undefined, ctx.defaultRows || DEFAULT_ROWS),\n\t\tcwd,\n\t\t...(timeoutMs === undefined ? {} : { timeoutMs }),\n\t});\n\tctx.onMonitorRearmed?.(id);\n\tconst monitorId = registry.register({\n\t\tid,\n\t\tdescription: input.description,\n\t\truntime,\n\t\tfilter,\n\t\tcommand: input.command,\n\t\tpersistent: input.persistent === true,\n\t\tdeadlineMs,\n\t\t// Only persistent command watches are restartable-command durable: those carry the fire budget.\n\t\tdurabilityClass: input.persistent === true ? \"restartable-command\" : \"ephemeral\",\n\t\t// Same deadline the manifest writer persists, so the footer warns off the live record too.\n\t\t...(input.persistent === true ? { expiresAt: Date.now() + DURABLE_MONITOR_EXPIRY_MS } : {}),\n\t});\n\tctx.manager.bindMonitorId(monitorId, id);\n\t// The tool call site is the only place the branch inputs (command, persistent, filter)\n\t// live; hand the captured spec to the session's manifest writer for durable recording.\n\thandMonitorSpec(manifestSessionKey(ctx), {\n\t\tmonitorId,\n\t\tspec: {\n\t\t\tkind: \"command\",\n\t\t\tdescription: input.description,\n\t\t\tcommand: input.command,\n\t\t\tfilter: input.filter,\n\t\t\tcwd,\n\t\t\tpersistent: input.persistent === true,\n\t\t},\n\t});\n\treturn textResult(`Monitor started with ID: ${monitorId}`, {\n\t\tdetails: { monitor_id: monitorId, bash_id: id, monitor: true },\n\t});\n}\n\n/** Build the PTY-backed monitor tool. Monitor handles share TerminalManager's bash_N namespace. */\nconst manifestWriters = new Map<string, TerminalManifestWriter>();\n\n/** Bind the session's manifest writer so monitor tool calls can hand it specs captured at the call site. */\nexport function bindTerminalManifestWriter(sessionId: string, writer: TerminalManifestWriter): void {\n\tmanifestWriters.set(sessionId, writer);\n}\n\nexport function unbindTerminalManifestWriter(sessionId: string): void {\n\tmanifestWriters.delete(sessionId);\n}\n\n/** The durability session key for a tool context: the agent session id, when the context carries one. */\nfunction manifestSessionKey(ctx: TerminalToolContext): string | undefined {\n\treturn ctx.getSessionContext?.()?.sessionManager?.getSessionId?.();\n}\n\n/** Hand a spec captured at the monitor tool call site to the session's bound writer, if any. */\nfunction handMonitorSpec(sessionKey: string | undefined, registration: MonitorRegistration): void {\n\tconst writer = sessionKey === undefined ? undefined : manifestWriters.get(sessionKey);\n\tvoid writer?.recordRegister(registration);\n}\n\n/** Persist a durable file watch's baseline checkpoint through the writer's debounced path. */\nfunction handFileCheckpoint(\n\tsessionKey: string | undefined,\n\tmonitorId: string,\n\tregistry: MonitorRegistry,\n\truntimeId: string,\n): void {\n\tconst writer = sessionKey === undefined ? undefined : manifestWriters.get(sessionKey);\n\tconst checkpoint = registry.fileCheckpoint(runtimeId);\n\tif (writer && checkpoint) writer.scheduleCheckpoint(monitorId, checkpoint);\n}\n\n/**\n * Admission control for a durable create: refuse once the session already holds\n * MAX_DURABLE_MONITORS restart-surviving monitors. Checked BEFORE any spawn or registry\n * registration so a refused call leaves no PTY and no manifest entry behind. A context\n * with no bound writer persists nothing, so it has no durable population to cap.\n */\nfunction durableAdmissionError(ctx: TerminalToolContext): TerminalToolResult | undefined {\n\tconst sessionKey = manifestSessionKey(ctx);\n\tconst writer = sessionKey === undefined ? undefined : manifestWriters.get(sessionKey);\n\tif (writer === undefined || writer.durableCount() < MAX_DURABLE_MONITORS) return undefined;\n\treturn errorResult(\n\t\t`Cannot start another persistent monitor: this session already holds ${MAX_DURABLE_MONITORS} durable monitors (the maximum). Stop one with kill_bash first.`,\n\t);\n}\n\nexport function createMonitorTool(ctx: TerminalToolContext) {\n\tlet fallbackRegistry: MonitorRegistry | undefined;\n\tconst getRegistry = (): MonitorRegistry => {\n\t\tconst sessionRegistry = ctx.monitorRegistry;\n\t\tif (sessionRegistry) return sessionRegistry;\n\t\tfallbackRegistry ??= new MonitorRegistry((event) => ctx.onMonitorEvent?.(event));\n\t\treturn fallbackRegistry;\n\t};\n\treturn {\n\t\tname: TERMINAL_MONITOR_TOOL,\n\t\tlabel: \"monitor\",\n\t\tdescription:\n\t\t\t\"Subscribe to a change instead of polling. Pass command XOR path, never both: command watches a PTY session, injecting matching newline-terminated output lines (stderr merged) plus an exit summary; path natively watches one file and fires once, where create (the default) fires only when the file appears after registration, so use event modify for an existing file, and filter is rejected. Returns a bash_id immediately; peek with bash_output, stop with kill_bash.\",\n\t\tpromptSnippet:\n\t\t\t\"Subscribe to a command's output or a file's create/modify event as injected events instead of polling\",\n\t\tpromptGuidelines: [\n\t\t\t\"Waiting on observable state (CI checks, builds, log patterns, deploys, a file landing) means a monitor, never a foreground sleep/poll loop.\",\n\t\t\t'Waiting for one file to appear or change is the path branch: `monitor({ description, path, event? })` beats wrapping `test -f` in a shell poll loop; a file that already exists needs `event: \"modify\"`, since `create` only fires on appearance, and registration needs the parent directory to exist already — when the run creates that directory too, use the `command` branch instead.',\n\t\t\t\"Shape the command for the events you need: one-shot gate = `until <cond>; do sleep 1; done; printf 'READY\\\\n'` with filter ^READY$; stream = `tail -n 0 -F <log> | grep --line-buffered <pat>` with persistent: true, then kill_bash.\",\n\t\t\t\"Sleep loops belong INSIDE the monitor command, never in your turn: about to sleep, re-poll bash_output, or foreground-block on a long command means register a monitor and keep working.\",\n\t\t],\n\t\tparameters: monitorSchema,\n\t\trenderCall: renderMonitorCall,\n\t\tasync execute(\n\t\t\t_toolCallId: string,\n\t\t\tinput: MonitorInput,\n\t\t\t_signal?: AbortSignal,\n\t\t\t_onUpdate?: undefined,\n\t\t\texecCtx?: { cwd?: string },\n\t\t): Promise<TerminalToolResult> {\n\t\t\tconst registry = getRegistry();\n\t\t\tif (input.action === \"rearm\") {\n\t\t\t\tif (input.bash_id === undefined || input.bash_id.length === 0) {\n\t\t\t\t\tconst resumed = registry.resume();\n\t\t\t\t\tif (resumed.length === 0) return textResult(\"No paused monitors to re-arm.\");\n\t\t\t\t\tctx.onMonitorsResumed?.(resumed.map((monitor) => monitor.id));\n\t\t\t\t\tconst total = resumed.reduce((sum, monitor) => sum + monitor.mutedDropped, 0);\n\t\t\t\t\treturn textResult(\n\t\t\t\t\t\ttotal > 0\n\t\t\t\t\t\t\t? `Re-armed ${resumed.length} paused monitor(s) (${total} line(s) dropped while muted).`\n\t\t\t\t\t\t\t: `Re-armed ${resumed.length} paused monitor(s).`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst bashId = resolveTerminalId(ctx.manager, input.bash_id);\n\t\t\t\tconst dropped = registry.mutedDropped(bashId);\n\t\t\t\tconst outcome = registry.rearm(bashId);\n\t\t\t\tif (outcome === \"not_found\") return errorResult(`No active monitor found with id: ${bashId}`);\n\t\t\t\tif (outcome === \"not_paused\") return textResult(`Monitor ${bashId} is not paused; no action taken.`);\n\t\t\t\tctx.onMonitorRearmed?.(bashId);\n\t\t\t\treturn textResult(\n\t\t\t\t\tdropped > 0\n\t\t\t\t\t\t? `Monitor ${bashId} re-armed (${dropped} line(s) dropped while muted).`\n\t\t\t\t\t\t: `Monitor ${bashId} re-armed.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst fileInput = isFileCreateInput(input);\n\t\t\tconst commandInput = isCreateInput(input);\n\t\t\tif (fileInput && commandInput) return errorResult(\"monitor accepts either command or path, not both.\");\n\t\t\t// Admission runs before either create branch touches a PTY or the registry.\n\t\t\tif (input.persistent === true && (fileInput || commandInput)) {\n\t\t\t\tconst refused = durableAdmissionError(ctx);\n\t\t\t\tif (refused) return refused;\n\t\t\t}\n\t\t\tif (fileInput) {\n\t\t\t\tif (input.filter !== undefined) return errorResult(\"Native file monitors do not support filter.\");\n\t\t\t\tif (!ctx.monitorRegistry)\n\t\t\t\t\treturn errorResult(\"Native file monitors require a lifecycle-owned monitor registry.\");\n\t\t\t\ttry {\n\t\t\t\t\tconst approvedParent = (input as Record<string | symbol, unknown>)[APPROVED_MONITOR_PARENT] as\n\t\t\t\t\t\t| string\n\t\t\t\t\t\t| undefined;\n\t\t\t\t\tconst { id, monitorId } = await ctx.monitorRegistry.registerFile({\n\t\t\t\t\t\tdescription: input.description,\n\t\t\t\t\t\tpath: input.path,\n\t\t\t\t\t\tevent: input.event ?? \"create\",\n\t\t\t\t\t\ttimeoutMs: resolveTimeoutMs(input.timeout_ms),\n\t\t\t\t\t\tpersistent: input.persistent === true,\n\t\t\t\t\t\tdeadlineMs: input.persistent === true ? null : Date.now() + resolveTimeoutMs(input.timeout_ms),\n\t\t\t\t\t\tcwd: execCtx?.cwd ?? ctx.cwd,\n\t\t\t\t\t\t...(approvedParent !== undefined ? { approvedParent } : {}),\n\t\t\t\t\t\t...(input.persistent === true ? { expiresAt: Date.now() + DURABLE_MONITOR_EXPIRY_MS } : {}),\n\t\t\t\t\t});\n\t\t\t\t\tctx.manager.bindMonitorId(monitorId, id);\n\t\t\t\t\t// Same spec capture as the command branch: durability inputs live only here.\n\t\t\t\t\tconst sessionKey = manifestSessionKey(ctx);\n\t\t\t\t\thandMonitorSpec(sessionKey, {\n\t\t\t\t\t\tmonitorId,\n\t\t\t\t\t\tspec: {\n\t\t\t\t\t\t\tkind: \"file\",\n\t\t\t\t\t\t\tdescription: input.description,\n\t\t\t\t\t\t\tpath: input.path,\n\t\t\t\t\t\t\tevent: input.event ?? \"create\",\n\t\t\t\t\t\t\ttimeoutMs: resolveTimeoutMs(input.timeout_ms),\n\t\t\t\t\t\t\tcwd: execCtx?.cwd ?? ctx.cwd,\n\t\t\t\t\t\t\tpersistent: input.persistent === true,\n\t\t\t\t\t\t\t...(approvedParent !== undefined ? { approvedParent } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t\t// A durable watch checkpoints the registry's own identity tuple straight away, so a\n\t\t\t\t\t// restart before the first change still has a baseline (digest included) to compare to.\n\t\t\t\t\tif (input.persistent === true) handFileCheckpoint(sessionKey, monitorId, ctx.monitorRegistry, id);\n\t\t\t\t\treturn textResult(`Monitor started with ID: ${monitorId}`, {\n\t\t\t\t\t\tdetails: { monitor_id: monitorId, bash_id: id, monitor: true },\n\t\t\t\t\t});\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn errorResult(error instanceof Error ? error.message : String(error));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!commandInput) return errorResult(\"monitor requires description and command or path to start a watcher.\");\n\t\t\treturn createMonitor(ctx, registry, input, execCtx);\n\t\t},\n\t};\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/tool-search/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAErE,OAAO,EAAwD,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGvG,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/tool-search/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAErE,OAAO,EAAwD,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGvG,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,CAgDtF;AAWD,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAUlF;AAED,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -40,6 +40,7 @@ export function createToolSearchExtension(service) {
|
|
|
40
40
|
return doc?.source === "extension" && !pi.getActiveTools().includes(name);
|
|
41
41
|
},
|
|
42
42
|
searchToolName: TOOL_SEARCH_TOOL_NAME,
|
|
43
|
+
onFallback: (reason) => service.noteNativeInjectionFailure(reason),
|
|
43
44
|
});
|
|
44
45
|
pi.on("before_provider_request", (event, ctx) => nativeAdapter.applyBeforeRequest(event.model ?? ctx.model, event.payload));
|
|
45
46
|
pi.on("after_provider_response", (event) => nativeAdapter.noteResponseStatus(event.status));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/tool-search/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/tool-search/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { bindToProviderScope } from \"@earendil-works/pi-ai/node/provider-scope\";\nimport type { ExtensionAPI, ExtensionFactory } from \"../../types.ts\";\nimport { AnthropicNativeToolSearchAdapter, isMcpNativeToolSearchEnabled } from \"./native-search.ts\";\nimport { getToolSearchService, installScopedToolSearchService, ToolSearchService } from \"./service.ts\";\nimport { createToolSearchTool, TOOL_SEARCH_TOOL_NAME } from \"./tool.ts\";\n\nexport function createToolSearchExtension(service: ToolSearchService): ExtensionFactory {\n\treturn (pi: ExtensionAPI): void => {\n\t\tservice.bindRuntime(pi);\n\n\t\tpi.on(\"session_start\", (_event, ctx) => {\n\t\t\tservice.beginSession();\n\t\t\tservice.maybeRehydrateFromHistory(ctx.sessionManager.getEntries());\n\t\t});\n\t\tpi.on(\"context\", (event) => {\n\t\t\tservice.maybeRehydrateFromHistory(event.messages);\n\t\t});\n\t\tpi.registerLazyToolActivator((toolName) => service.activateTool(toolName));\n\t\tlet toolRegistered = false;\n\t\tservice.bindToolRegistrar(() => {\n\t\t\tif (toolRegistered) return;\n\t\t\ttoolRegistered = true;\n\t\t\tpi.registerTool(createToolSearchTool(service));\n\t\t});\n\n\t\tconst nativeAdapter = new AnthropicNativeToolSearchAdapter({\n\t\t\tenabled: () => {\n\t\t\t\tconst active = new Set(pi.getActiveTools());\n\t\t\t\treturn service\n\t\t\t\t\t.getCatalog()\n\t\t\t\t\t.some(\n\t\t\t\t\t\t(doc) =>\n\t\t\t\t\t\t\t(doc.source === \"extension\" && !active.has(doc.name)) ||\n\t\t\t\t\t\t\t(doc.source === \"mcp\" && isMcpNativeToolSearchEnabled()),\n\t\t\t\t\t);\n\t\t\t},\n\t\t\tgetCatalog: () => service.getCatalog(),\n\t\t\tgetToolDefinition: (name) => {\n\t\t\t\tconst tool = pi.getAllTools().find((candidate) => candidate.name === name);\n\t\t\t\treturn tool === undefined ? undefined : { description: tool.description, parameters: tool.parameters };\n\t\t\t},\n\t\t\tisDeferrable: (name) => {\n\t\t\t\tconst doc = service.getCatalog().find((candidate) => candidate.name === name);\n\t\t\t\tif (doc?.source === \"mcp\") return isMcpNativeToolSearchEnabled();\n\t\t\t\treturn doc?.source === \"extension\" && !pi.getActiveTools().includes(name);\n\t\t\t},\n\t\t\tsearchToolName: TOOL_SEARCH_TOOL_NAME,\n\t\t\tonFallback: (reason) => service.noteNativeInjectionFailure(reason),\n\t\t});\n\t\tpi.on(\"before_provider_request\", (event, ctx) =>\n\t\t\tnativeAdapter.applyBeforeRequest(event.model ?? ctx.model, event.payload),\n\t\t);\n\t\tpi.on(\"after_provider_response\", (event) => nativeAdapter.noteResponseStatus(event.status));\n\t};\n}\n\nfunction hasProviderScope(): boolean {\n\ttry {\n\t\tbindToProviderScope(() => undefined);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport default function toolSearchExtension(pi: ExtensionAPI): void | Promise<void> {\n\tconst runtime = {\n\t\tgetAllTools: () => pi.getAllTools(),\n\t\tgetActiveTools: () => pi.getActiveTools(),\n\t\tsetActiveTools: (names: readonly string[]) => pi.setActiveTools([...names]),\n\t};\n\tconst sessionOwned = hasProviderScope();\n\tconst service = sessionOwned ? new ToolSearchService(runtime) : getToolSearchService(runtime);\n\tif (sessionOwned) installScopedToolSearchService(service);\n\treturn createToolSearchExtension(service)(pi);\n}\n\nexport { getToolSearchService, ToolSearchService } from \"./service.ts\";\nexport { createToolSearchTool, TOOL_SEARCH_TOOL_NAME } from \"./tool.ts\";\n"]}
|
|
@@ -15,6 +15,10 @@ type RuntimeApi = Pick<ExtensionAPI, "getActiveTools" | "getAllTools" | "setActi
|
|
|
15
15
|
export declare class ToolSearchService {
|
|
16
16
|
#private;
|
|
17
17
|
constructor(runtime: ToolSearchRuntime);
|
|
18
|
+
/** Record that a native-injected request was rejected; the session consumes it once. */
|
|
19
|
+
noteNativeInjectionFailure(reason: string): void;
|
|
20
|
+
/** Consume the pending native-injection failure, if any (one-shot). */
|
|
21
|
+
takeNativeInjectionFailure(): string | null;
|
|
18
22
|
bindRuntime(runtime: RuntimeApi): void;
|
|
19
23
|
bindActivationRuntime(runtime: Pick<RuntimeApi, "getActiveTools" | "setActiveTools">): void;
|
|
20
24
|
/** Register the resident search tool only after a searchable catalog exists. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/tool-search/service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,iBAAiB,EAAkB,MAAM,kBAAkB,CAAC;AAC3F,OAAO,KAAK,EAAE,kBAAkB,EAAoB,MAAM,sBAAsB,CAAC;AAIjF,MAAM,WAAW,qBAAqB;IACrC,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,iBAAiB;IACjC,WAAW,IAAI,QAAQ,EAAE,CAAC;IAC1B,cAAc,IAAI,MAAM,EAAE,CAAC;IAC3B,cAAc,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;CAC/C;AAED,KAAK,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,gBAAgB,GAAG,aAAa,GAAG,gBAAgB,CAAC,CAAC;AAO1F,wEAAwE;AACxE,qBAAa,iBAAiB;;gBASjB,OAAO,EAAE,iBAAiB;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/tool-search/service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,iBAAiB,EAAkB,MAAM,kBAAkB,CAAC;AAC3F,OAAO,KAAK,EAAE,kBAAkB,EAAoB,MAAM,sBAAsB,CAAC;AAIjF,MAAM,WAAW,qBAAqB;IACrC,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,iBAAiB;IACjC,WAAW,IAAI,QAAQ,EAAE,CAAC;IAC1B,cAAc,IAAI,MAAM,EAAE,CAAC;IAC3B,cAAc,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;CAC/C;AAED,KAAK,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,gBAAgB,GAAG,aAAa,GAAG,gBAAgB,CAAC,CAAC;AAO1F,wEAAwE;AACxE,qBAAa,iBAAiB;;gBASjB,OAAO,EAAE,iBAAiB;IAUtC,wFAAwF;IACxF,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAIhD,uEAAuE;IACvE,0BAA0B,IAAI,MAAM,GAAG,IAAI;IAM3C,WAAW,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;IAItC,qBAAqB,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,gBAAgB,GAAG,gBAAgB,CAAC,GAAG,IAAI;IAI3F,gFAAgF;IAChF,iBAAiB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;IAI7C,YAAY,IAAI,IAAI;IAQpB,mEAAmE;IACnE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,kBAAkB,EAAE,EAAE,KAAK,EAAE,qBAAqB,GAAG,IAAI;IAO5F,UAAU,IAAI,kBAAkB,EAAE;IAKlC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,EAAE,OAAO,GAAE,iBAAsB,GAAG,UAAU,EAAE;IAIhF,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,EAAE;IAclD,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAOnC,iFAAiF;IACjF,yBAAyB,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,MAAM,EAAE;CAsEjE;AAkCD,gGAAgG;AAChG,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAE7E;AAED,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,CAanF;AAED,wBAAgB,8BAA8B,IAAI,IAAI,CAErD"}
|
|
@@ -19,6 +19,17 @@ export class ToolSearchService {
|
|
|
19
19
|
hooks: { activate: (names) => this.#promoteExtensionTools(names) },
|
|
20
20
|
});
|
|
21
21
|
}
|
|
22
|
+
#nativeInjectionFailure = null;
|
|
23
|
+
/** Record that a native-injected request was rejected; the session consumes it once. */
|
|
24
|
+
noteNativeInjectionFailure(reason) {
|
|
25
|
+
this.#nativeInjectionFailure = reason;
|
|
26
|
+
}
|
|
27
|
+
/** Consume the pending native-injection failure, if any (one-shot). */
|
|
28
|
+
takeNativeInjectionFailure() {
|
|
29
|
+
const reason = this.#nativeInjectionFailure;
|
|
30
|
+
this.#nativeInjectionFailure = null;
|
|
31
|
+
return reason;
|
|
32
|
+
}
|
|
22
33
|
bindRuntime(runtime) {
|
|
23
34
|
this.#runtime = runtime;
|
|
24
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/tool-search/service.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { basename, extname } from \"node:path\";\nimport type { ExtensionAPI, ToolInfo } from \"../../types.ts\";\nimport { type Bm25Result, type Bm25SearchOptions, buildBm25Index } from \"./engine/bm25.ts\";\nimport type { ToolSearchDocument, ToolSearchSource } from \"./engine/document.ts\";\nimport { deriveExtensionRegistrationId, rehydrate } from \"./engine/marker.ts\";\nimport { TOOL_SEARCH_TOOL_NAME } from \"./tool.ts\";\n\nexport interface ToolSearchFeederHooks {\n\t/** Activate every named match, including names already active as stubs. */\n\tactivate(names: readonly string[]): void;\n}\n\nexport interface ToolSearchRuntime {\n\tgetAllTools(): ToolInfo[];\n\tgetActiveTools(): string[];\n\tsetActiveTools(names: readonly string[]): void;\n}\n\ntype RuntimeApi = Pick<ExtensionAPI, \"getActiveTools\" | \"getAllTools\" | \"setActiveTools\">;\n\ninterface FeedState {\n\tdocs: ToolSearchDocument[];\n\thooks: ToolSearchFeederHooks;\n}\n\n/** Session-scoped owner of the live generalized tool-search catalog. */\nexport class ToolSearchService {\n\t#runtime: ToolSearchRuntime;\n\treadonly #feeds = new Map<ToolSearchSource, FeedState>();\n\t#extensionDocs: ToolSearchDocument[] = [];\n\t#extensionFingerprint = \"\";\n\t#registryGeneration = 0;\n\t#historyScannedGeneration = -1;\n\t#registerToolSearch: (() => void) | undefined;\n\n\tconstructor(runtime: ToolSearchRuntime) {\n\t\tthis.#runtime = runtime;\n\t\tthis.#feeds.set(\"extension\", {\n\t\t\tdocs: [],\n\t\t\thooks: { activate: (names) => this.#promoteExtensionTools(names) },\n\t\t});\n\t}\n\n\tbindRuntime(runtime: RuntimeApi): void {\n\t\tthis.#runtime = runtime;\n\t}\n\n\tbindActivationRuntime(runtime: Pick<RuntimeApi, \"getActiveTools\" | \"setActiveTools\">): void {\n\t\tthis.#runtime = { ...this.#runtime, ...runtime };\n\t}\n\n\t/** Register the resident search tool only after a searchable catalog exists. */\n\tbindToolRegistrar(register: () => void): void {\n\t\tthis.#registerToolSearch = register;\n\t}\n\n\tbeginSession(): void {\n\t\tthis.#feeds.delete(\"mcp\");\n\t\tthis.#registryGeneration += 1;\n\t\tthis.#historyScannedGeneration = -1;\n\t\tthis.#refreshExtensionDocs();\n\t\tthis.#syncToolSearchLifecycle();\n\t}\n\n\t/** Replace one source's catalog generation and activation hook. */\n\tfeed(source: \"mcp\", docs: readonly ToolSearchDocument[], hooks: ToolSearchFeederHooks): void {\n\t\tconst validDocs = docs.filter((doc) => isValidDocument(doc, source));\n\t\tthis.#feeds.set(source, { docs: validDocs, hooks });\n\t\tthis.#registryGeneration += 1;\n\t\tthis.#syncToolSearchLifecycle();\n\t}\n\n\tgetCatalog(): ToolSearchDocument[] {\n\t\tthis.#refreshExtensionDocs();\n\t\treturn [...(this.#feeds.get(\"mcp\")?.docs ?? []), ...this.#extensionDocs];\n\t}\n\n\tsearch(query: string, limit = 10, options: Bm25SearchOptions = {}): Bm25Result[] {\n\t\treturn buildBm25Index(this.getCatalog()).search(query, limit, options);\n\t}\n\n\t/** Route all matches through their owning feeder, even when already active. */\n\tactivate(matches: readonly Bm25Result[]): string[] {\n\t\tconst namesBySource = new Map<ToolSearchSource, string[]>();\n\t\tfor (const match of matches) {\n\t\t\tconst names = namesBySource.get(match.doc.source) ?? [];\n\t\t\tnames.push(match.name);\n\t\t\tnamesBySource.set(match.doc.source, names);\n\t\t}\n\t\tfor (const [source, names] of namesBySource) {\n\t\t\tthis.#feeds.get(source)?.hooks.activate(names);\n\t\t}\n\t\tconst active = new Set(this.#runtime.getActiveTools());\n\t\treturn matches.map(({ name }) => name).filter((name) => active.has(name));\n\t}\n\n\tactivateTool(name: string): boolean {\n\t\tconst doc = this.getCatalog().find((candidate) => candidate.name === name);\n\t\tif (doc === undefined) return false;\n\t\tthis.#feeds.get(doc.source)?.hooks.activate([name]);\n\t\treturn this.#runtime.getActiveTools().includes(name);\n\t}\n\n\t/** Replay ownership-aware and legacy MCP history once per catalog generation. */\n\tmaybeRehydrateFromHistory(messages: readonly unknown[]): string[] {\n\t\tconst catalog = this.getCatalog();\n\t\tif (this.#historyScannedGeneration === this.#registryGeneration) return [];\n\t\tthis.#historyScannedGeneration = this.#registryGeneration;\n\t\tconst docsByName = new Map(\n\t\t\tcatalog.map((doc) => [\n\t\t\t\tdoc.name,\n\t\t\t\t{\n\t\t\t\t\tname: doc.name,\n\t\t\t\t\tregistrationId: doc.registrationId,\n\t\t\t\t\tsource: doc.source,\n\t\t\t\t\tallowLazyActivation: true,\n\t\t\t\t},\n\t\t\t]),\n\t\t);\n\t\tconst restored = rehydrate(messages, docsByName);\n\t\tif (restored.length > 0) this.#activateNames(restored, catalog);\n\t\treturn restored;\n\t}\n\n\t#refreshExtensionDocs(): void {\n\t\tconst docs = this.#runtime\n\t\t\t.getAllTools()\n\t\t\t.filter((tool) => tool.exposure === \"search\" && tool.allowLazyActivation)\n\t\t\t.map(extensionDocument)\n\t\t\t.filter((doc): doc is ToolSearchDocument => doc !== undefined)\n\t\t\t.sort((left, right) => left.name.localeCompare(right.name));\n\t\tconst fingerprint = JSON.stringify(docs);\n\t\tif (fingerprint === this.#extensionFingerprint) return;\n\t\tthis.#extensionDocs = docs;\n\t\tthis.#extensionFingerprint = fingerprint;\n\t\tthis.#feeds.set(\"extension\", {\n\t\t\tdocs,\n\t\t\thooks: { activate: (names) => this.#promoteExtensionTools(names) },\n\t\t});\n\t\tthis.#registryGeneration += 1;\n\t\tthis.#syncToolSearchLifecycle();\n\t}\n\n\t#activateNames(names: readonly string[], catalog = this.getCatalog()): void {\n\t\tconst sourceByName = new Map(catalog.map((doc) => [doc.name, doc.source] as const));\n\t\tconst namesBySource = new Map<ToolSearchSource, string[]>();\n\t\tfor (const name of names) {\n\t\t\tconst source = sourceByName.get(name);\n\t\t\tif (source === undefined) continue;\n\t\t\tconst sourceNames = namesBySource.get(source) ?? [];\n\t\t\tsourceNames.push(name);\n\t\t\tnamesBySource.set(source, sourceNames);\n\t\t}\n\t\tfor (const [source, sourceNames] of namesBySource) this.#feeds.get(source)?.hooks.activate(sourceNames);\n\t}\n\n\t#syncToolSearchLifecycle(): void {\n\t\tconst hasDocuments = this.#extensionDocs.length > 0 || (this.#feeds.get(\"mcp\")?.docs.length ?? 0) > 0;\n\t\tif (hasDocuments) this.#registerToolSearch?.();\n\t\tconst current = this.#runtime.getActiveTools();\n\t\tconst isActive = current.includes(TOOL_SEARCH_TOOL_NAME);\n\t\tif (hasDocuments === isActive) return;\n\t\tthis.#runtime.setActiveTools(\n\t\t\thasDocuments ? [...current, TOOL_SEARCH_TOOL_NAME] : current.filter((name) => name !== TOOL_SEARCH_TOOL_NAME),\n\t\t);\n\t}\n\n\t#promoteExtensionTools(names: readonly string[]): void {\n\t\tif (names.length === 0) return;\n\t\tconst current = this.#runtime.getActiveTools();\n\t\tconst active = new Set(current);\n\t\tconst added = [...new Set(names.filter((name) => !active.has(name)))].sort();\n\t\tthis.#runtime.setActiveTools([...current, ...added]);\n\t}\n}\n\nfunction extensionDocument(tool: ToolInfo): ToolSearchDocument | undefined {\n\tif (tool.name.length === 0) return undefined;\n\tconst ownerLabel = extensionOwnerLabel(tool);\n\tconst registrationId = deriveExtensionRegistrationId(tool.sourceInfo, tool.name);\n\tif (registrationId.length === 0) return undefined;\n\treturn {\n\t\tname: tool.name,\n\t\tlabel: tool.label,\n\t\taliases: [],\n\t\tdescription: tool.description,\n\t\tsearchText: tool.searchText,\n\t\tkeywords: tool.searchKeywords,\n\t\tsource: \"extension\",\n\t\tgroup: tool.searchGroup ?? ownerLabel,\n\t\townerLabel,\n\t\tregistrationId,\n\t};\n}\n\nfunction extensionOwnerLabel(tool: ToolInfo): string {\n\tconst fileName = basename(tool.sourceInfo.path);\n\tconst extension = extname(fileName);\n\treturn extension.length === 0 ? fileName : fileName.slice(0, -extension.length);\n}\n\nfunction isValidDocument(doc: ToolSearchDocument, source: ToolSearchSource): boolean {\n\treturn doc.source === source && doc.name.length > 0 && doc.registrationId.length > 0;\n}\n\nconst scopedService = new AsyncLocalStorage<ToolSearchService>();\nlet service: ToolSearchService | null = null;\n\n/** Make a session-owned service visible to later builtins loaded in the same provider scope. */\nexport function installScopedToolSearchService(value: ToolSearchService): void {\n\tscopedService.enterWith(value);\n}\n\nexport function getToolSearchService(runtime?: ToolSearchRuntime): ToolSearchService {\n\tconst scoped = scopedService.getStore();\n\tif (scoped !== undefined) {\n\t\tif (runtime !== undefined) scoped.bindRuntime(runtime);\n\t\treturn scoped;\n\t}\n\tif (service === null) {\n\t\tif (runtime === undefined) throw new Error(\"ToolSearchService runtime is not bound\");\n\t\tservice = new ToolSearchService(runtime);\n\t} else if (runtime !== undefined) {\n\t\tservice.bindRuntime(runtime);\n\t}\n\treturn service;\n}\n\nexport function resetToolSearchServiceForTests(): void {\n\tservice = null;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/tool-search/service.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { basename, extname } from \"node:path\";\nimport type { ExtensionAPI, ToolInfo } from \"../../types.ts\";\nimport { type Bm25Result, type Bm25SearchOptions, buildBm25Index } from \"./engine/bm25.ts\";\nimport type { ToolSearchDocument, ToolSearchSource } from \"./engine/document.ts\";\nimport { deriveExtensionRegistrationId, rehydrate } from \"./engine/marker.ts\";\nimport { TOOL_SEARCH_TOOL_NAME } from \"./tool.ts\";\n\nexport interface ToolSearchFeederHooks {\n\t/** Activate every named match, including names already active as stubs. */\n\tactivate(names: readonly string[]): void;\n}\n\nexport interface ToolSearchRuntime {\n\tgetAllTools(): ToolInfo[];\n\tgetActiveTools(): string[];\n\tsetActiveTools(names: readonly string[]): void;\n}\n\ntype RuntimeApi = Pick<ExtensionAPI, \"getActiveTools\" | \"getAllTools\" | \"setActiveTools\">;\n\ninterface FeedState {\n\tdocs: ToolSearchDocument[];\n\thooks: ToolSearchFeederHooks;\n}\n\n/** Session-scoped owner of the live generalized tool-search catalog. */\nexport class ToolSearchService {\n\t#runtime: ToolSearchRuntime;\n\treadonly #feeds = new Map<ToolSearchSource, FeedState>();\n\t#extensionDocs: ToolSearchDocument[] = [];\n\t#extensionFingerprint = \"\";\n\t#registryGeneration = 0;\n\t#historyScannedGeneration = -1;\n\t#registerToolSearch: (() => void) | undefined;\n\n\tconstructor(runtime: ToolSearchRuntime) {\n\t\tthis.#runtime = runtime;\n\t\tthis.#feeds.set(\"extension\", {\n\t\t\tdocs: [],\n\t\t\thooks: { activate: (names) => this.#promoteExtensionTools(names) },\n\t\t});\n\t}\n\n\t#nativeInjectionFailure: string | null = null;\n\n\t/** Record that a native-injected request was rejected; the session consumes it once. */\n\tnoteNativeInjectionFailure(reason: string): void {\n\t\tthis.#nativeInjectionFailure = reason;\n\t}\n\n\t/** Consume the pending native-injection failure, if any (one-shot). */\n\ttakeNativeInjectionFailure(): string | null {\n\t\tconst reason = this.#nativeInjectionFailure;\n\t\tthis.#nativeInjectionFailure = null;\n\t\treturn reason;\n\t}\n\n\tbindRuntime(runtime: RuntimeApi): void {\n\t\tthis.#runtime = runtime;\n\t}\n\n\tbindActivationRuntime(runtime: Pick<RuntimeApi, \"getActiveTools\" | \"setActiveTools\">): void {\n\t\tthis.#runtime = { ...this.#runtime, ...runtime };\n\t}\n\n\t/** Register the resident search tool only after a searchable catalog exists. */\n\tbindToolRegistrar(register: () => void): void {\n\t\tthis.#registerToolSearch = register;\n\t}\n\n\tbeginSession(): void {\n\t\tthis.#feeds.delete(\"mcp\");\n\t\tthis.#registryGeneration += 1;\n\t\tthis.#historyScannedGeneration = -1;\n\t\tthis.#refreshExtensionDocs();\n\t\tthis.#syncToolSearchLifecycle();\n\t}\n\n\t/** Replace one source's catalog generation and activation hook. */\n\tfeed(source: \"mcp\", docs: readonly ToolSearchDocument[], hooks: ToolSearchFeederHooks): void {\n\t\tconst validDocs = docs.filter((doc) => isValidDocument(doc, source));\n\t\tthis.#feeds.set(source, { docs: validDocs, hooks });\n\t\tthis.#registryGeneration += 1;\n\t\tthis.#syncToolSearchLifecycle();\n\t}\n\n\tgetCatalog(): ToolSearchDocument[] {\n\t\tthis.#refreshExtensionDocs();\n\t\treturn [...(this.#feeds.get(\"mcp\")?.docs ?? []), ...this.#extensionDocs];\n\t}\n\n\tsearch(query: string, limit = 10, options: Bm25SearchOptions = {}): Bm25Result[] {\n\t\treturn buildBm25Index(this.getCatalog()).search(query, limit, options);\n\t}\n\n\t/** Route all matches through their owning feeder, even when already active. */\n\tactivate(matches: readonly Bm25Result[]): string[] {\n\t\tconst namesBySource = new Map<ToolSearchSource, string[]>();\n\t\tfor (const match of matches) {\n\t\t\tconst names = namesBySource.get(match.doc.source) ?? [];\n\t\t\tnames.push(match.name);\n\t\t\tnamesBySource.set(match.doc.source, names);\n\t\t}\n\t\tfor (const [source, names] of namesBySource) {\n\t\t\tthis.#feeds.get(source)?.hooks.activate(names);\n\t\t}\n\t\tconst active = new Set(this.#runtime.getActiveTools());\n\t\treturn matches.map(({ name }) => name).filter((name) => active.has(name));\n\t}\n\n\tactivateTool(name: string): boolean {\n\t\tconst doc = this.getCatalog().find((candidate) => candidate.name === name);\n\t\tif (doc === undefined) return false;\n\t\tthis.#feeds.get(doc.source)?.hooks.activate([name]);\n\t\treturn this.#runtime.getActiveTools().includes(name);\n\t}\n\n\t/** Replay ownership-aware and legacy MCP history once per catalog generation. */\n\tmaybeRehydrateFromHistory(messages: readonly unknown[]): string[] {\n\t\tconst catalog = this.getCatalog();\n\t\tif (this.#historyScannedGeneration === this.#registryGeneration) return [];\n\t\tthis.#historyScannedGeneration = this.#registryGeneration;\n\t\tconst docsByName = new Map(\n\t\t\tcatalog.map((doc) => [\n\t\t\t\tdoc.name,\n\t\t\t\t{\n\t\t\t\t\tname: doc.name,\n\t\t\t\t\tregistrationId: doc.registrationId,\n\t\t\t\t\tsource: doc.source,\n\t\t\t\t\tallowLazyActivation: true,\n\t\t\t\t},\n\t\t\t]),\n\t\t);\n\t\tconst restored = rehydrate(messages, docsByName);\n\t\tif (restored.length > 0) this.#activateNames(restored, catalog);\n\t\treturn restored;\n\t}\n\n\t#refreshExtensionDocs(): void {\n\t\tconst docs = this.#runtime\n\t\t\t.getAllTools()\n\t\t\t.filter((tool) => tool.exposure === \"search\" && tool.allowLazyActivation)\n\t\t\t.map(extensionDocument)\n\t\t\t.filter((doc): doc is ToolSearchDocument => doc !== undefined)\n\t\t\t.sort((left, right) => left.name.localeCompare(right.name));\n\t\tconst fingerprint = JSON.stringify(docs);\n\t\tif (fingerprint === this.#extensionFingerprint) return;\n\t\tthis.#extensionDocs = docs;\n\t\tthis.#extensionFingerprint = fingerprint;\n\t\tthis.#feeds.set(\"extension\", {\n\t\t\tdocs,\n\t\t\thooks: { activate: (names) => this.#promoteExtensionTools(names) },\n\t\t});\n\t\tthis.#registryGeneration += 1;\n\t\tthis.#syncToolSearchLifecycle();\n\t}\n\n\t#activateNames(names: readonly string[], catalog = this.getCatalog()): void {\n\t\tconst sourceByName = new Map(catalog.map((doc) => [doc.name, doc.source] as const));\n\t\tconst namesBySource = new Map<ToolSearchSource, string[]>();\n\t\tfor (const name of names) {\n\t\t\tconst source = sourceByName.get(name);\n\t\t\tif (source === undefined) continue;\n\t\t\tconst sourceNames = namesBySource.get(source) ?? [];\n\t\t\tsourceNames.push(name);\n\t\t\tnamesBySource.set(source, sourceNames);\n\t\t}\n\t\tfor (const [source, sourceNames] of namesBySource) this.#feeds.get(source)?.hooks.activate(sourceNames);\n\t}\n\n\t#syncToolSearchLifecycle(): void {\n\t\tconst hasDocuments = this.#extensionDocs.length > 0 || (this.#feeds.get(\"mcp\")?.docs.length ?? 0) > 0;\n\t\tif (hasDocuments) this.#registerToolSearch?.();\n\t\tconst current = this.#runtime.getActiveTools();\n\t\tconst isActive = current.includes(TOOL_SEARCH_TOOL_NAME);\n\t\tif (hasDocuments === isActive) return;\n\t\tthis.#runtime.setActiveTools(\n\t\t\thasDocuments ? [...current, TOOL_SEARCH_TOOL_NAME] : current.filter((name) => name !== TOOL_SEARCH_TOOL_NAME),\n\t\t);\n\t}\n\n\t#promoteExtensionTools(names: readonly string[]): void {\n\t\tif (names.length === 0) return;\n\t\tconst current = this.#runtime.getActiveTools();\n\t\tconst active = new Set(current);\n\t\tconst added = [...new Set(names.filter((name) => !active.has(name)))].sort();\n\t\tthis.#runtime.setActiveTools([...current, ...added]);\n\t}\n}\n\nfunction extensionDocument(tool: ToolInfo): ToolSearchDocument | undefined {\n\tif (tool.name.length === 0) return undefined;\n\tconst ownerLabel = extensionOwnerLabel(tool);\n\tconst registrationId = deriveExtensionRegistrationId(tool.sourceInfo, tool.name);\n\tif (registrationId.length === 0) return undefined;\n\treturn {\n\t\tname: tool.name,\n\t\tlabel: tool.label,\n\t\taliases: [],\n\t\tdescription: tool.description,\n\t\tsearchText: tool.searchText,\n\t\tkeywords: tool.searchKeywords,\n\t\tsource: \"extension\",\n\t\tgroup: tool.searchGroup ?? ownerLabel,\n\t\townerLabel,\n\t\tregistrationId,\n\t};\n}\n\nfunction extensionOwnerLabel(tool: ToolInfo): string {\n\tconst fileName = basename(tool.sourceInfo.path);\n\tconst extension = extname(fileName);\n\treturn extension.length === 0 ? fileName : fileName.slice(0, -extension.length);\n}\n\nfunction isValidDocument(doc: ToolSearchDocument, source: ToolSearchSource): boolean {\n\treturn doc.source === source && doc.name.length > 0 && doc.registrationId.length > 0;\n}\n\nconst scopedService = new AsyncLocalStorage<ToolSearchService>();\nlet service: ToolSearchService | null = null;\n\n/** Make a session-owned service visible to later builtins loaded in the same provider scope. */\nexport function installScopedToolSearchService(value: ToolSearchService): void {\n\tscopedService.enterWith(value);\n}\n\nexport function getToolSearchService(runtime?: ToolSearchRuntime): ToolSearchService {\n\tconst scoped = scopedService.getStore();\n\tif (scoped !== undefined) {\n\t\tif (runtime !== undefined) scoped.bindRuntime(runtime);\n\t\treturn scoped;\n\t}\n\tif (service === null) {\n\t\tif (runtime === undefined) throw new Error(\"ToolSearchService runtime is not bound\");\n\t\tservice = new ToolSearchService(runtime);\n\t} else if (runtime !== undefined) {\n\t\tservice.bindRuntime(runtime);\n\t}\n\treturn service;\n}\n\nexport function resetToolSearchServiceForTests(): void {\n\tservice = null;\n}\n"]}
|