@code-yeongyu/senpi 2026.8.10 → 2026.8.11-3
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 +119 -0
- package/dist/brand-dir-migration.d.ts +28 -0
- package/dist/brand-dir-migration.d.ts.map +1 -0
- package/dist/brand-dir-migration.js +77 -0
- package/dist/brand-dir-migration.js.map +1 -0
- package/dist/cli/grok-neo-gate.d.ts +0 -8
- package/dist/cli/grok-neo-gate.d.ts.map +1 -1
- package/dist/cli/grok-neo-gate.js +4 -2
- package/dist/cli/grok-neo-gate.js.map +1 -1
- package/dist/cli-main.d.ts +1 -1
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/cli-main.js +4 -0
- package/dist/cli-main.js.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +3 -2
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +27 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +41 -9
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +8 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +65 -8
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/brand.d.ts +79 -0
- package/dist/core/brand.d.ts.map +1 -0
- package/dist/core/brand.js +141 -0
- package/dist/core/brand.js.map +1 -0
- package/dist/core/dynamic-prompt/identity.d.ts.map +1 -1
- package/dist/core/dynamic-prompt/identity.js +2 -1
- package/dist/core/dynamic-prompt/identity.js.map +1 -1
- package/dist/core/experimental.d.ts.map +1 -1
- package/dist/core/experimental.js +2 -1
- package/dist/core/experimental.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/availability.d.ts +2 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/availability.d.ts.map +1 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/availability.js +24 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/availability.js.map +1 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/index.d.ts +4 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/index.js +5 -2
- package/dist/core/extensions/builtin/claude-sdk-oauth/index.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.d.ts +6 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.js +16 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.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 +10 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-commit-boundary.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/log.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/log.js +2 -1
- package/dist/core/extensions/builtin/compaction/log.js.map +1 -1
- package/dist/core/extensions/builtin/config-reload/generated-shim-filter.d.ts.map +1 -1
- package/dist/core/extensions/builtin/config-reload/generated-shim-filter.js +4 -4
- package/dist/core/extensions/builtin/config-reload/generated-shim-filter.js.map +1 -1
- package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/index.js +5 -0
- package/dist/core/extensions/builtin/goal/index.js.map +1 -1
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts +2 -2
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +3 -3
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -1
- package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/monitor-continuation.js +6 -0
- package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
- package/dist/core/extensions/builtin/goal/store.d.ts +3 -2
- package/dist/core/extensions/builtin/goal/store.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/store.js +128 -101
- package/dist/core/extensions/builtin/goal/store.js.map +1 -1
- package/dist/core/extensions/builtin/goal/transitions.js +2 -1
- package/dist/core/extensions/builtin/goal/transitions.js.map +1 -1
- package/dist/core/extensions/builtin/help/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/help/index.js +3 -2
- package/dist/core/extensions/builtin/help/index.js.map +1 -1
- package/dist/core/extensions/builtin/imagegen/auth.d.ts +45 -0
- package/dist/core/extensions/builtin/imagegen/auth.d.ts.map +1 -0
- package/dist/core/extensions/builtin/imagegen/auth.js +137 -0
- package/dist/core/extensions/builtin/imagegen/auth.js.map +1 -0
- package/dist/core/extensions/builtin/imagegen/index.d.ts +5 -0
- package/dist/core/extensions/builtin/imagegen/index.d.ts.map +1 -0
- package/dist/core/extensions/builtin/imagegen/index.js +46 -0
- package/dist/core/extensions/builtin/imagegen/index.js.map +1 -0
- package/dist/core/extensions/builtin/imagegen/paths.d.ts +26 -0
- package/dist/core/extensions/builtin/imagegen/paths.d.ts.map +1 -0
- package/dist/core/extensions/builtin/imagegen/paths.js +52 -0
- package/dist/core/extensions/builtin/imagegen/paths.js.map +1 -0
- package/dist/core/extensions/builtin/imagegen/skill/SKILL.md +67 -0
- package/dist/core/extensions/builtin/imagegen/state.d.ts +26 -0
- package/dist/core/extensions/builtin/imagegen/state.d.ts.map +1 -0
- package/dist/core/extensions/builtin/imagegen/state.js +35 -0
- package/dist/core/extensions/builtin/imagegen/state.js.map +1 -0
- package/dist/core/extensions/builtin/imagegen/tool.d.ts +31 -0
- package/dist/core/extensions/builtin/imagegen/tool.d.ts.map +1 -0
- package/dist/core/extensions/builtin/imagegen/tool.js +174 -0
- package/dist/core/extensions/builtin/imagegen/tool.js.map +1 -0
- package/dist/core/extensions/builtin/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/index.js +9 -1
- package/dist/core/extensions/builtin/index.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/control-inventory.d.ts +14 -0
- package/dist/core/extensions/builtin/mcp/control-inventory.d.ts.map +1 -0
- package/dist/core/extensions/builtin/mcp/control-inventory.js +22 -0
- package/dist/core/extensions/builtin/mcp/control-inventory.js.map +1 -0
- package/dist/core/extensions/builtin/mcp/expose/native-search.d.ts +2 -44
- package/dist/core/extensions/builtin/mcp/expose/native-search.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/expose/native-search.js +3 -97
- package/dist/core/extensions/builtin/mcp/expose/native-search.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/expose/proxy.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/expose/proxy.js +15 -4
- package/dist/core/extensions/builtin/mcp/expose/proxy.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/expose/session.d.ts +2 -1
- package/dist/core/extensions/builtin/mcp/expose/session.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/expose/session.js +2 -2
- package/dist/core/extensions/builtin/mcp/expose/session.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/expose/tier-b.d.ts +13 -11
- package/dist/core/extensions/builtin/mcp/expose/tier-b.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/expose/tier-b.js +58 -59
- package/dist/core/extensions/builtin/mcp/expose/tier-b.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/index.js +28 -36
- package/dist/core/extensions/builtin/mcp/index.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/service-register.d.ts +2 -1
- package/dist/core/extensions/builtin/mcp/service-register.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/service-register.js +2 -2
- package/dist/core/extensions/builtin/mcp/service-register.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/service-types.d.ts +4 -0
- package/dist/core/extensions/builtin/mcp/service-types.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/service-types.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/service.d.ts +6 -11
- package/dist/core/extensions/builtin/mcp/service.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/service.js +79 -41
- package/dist/core/extensions/builtin/mcp/service.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/wrap.d.ts +2 -0
- package/dist/core/extensions/builtin/mcp/wrap.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/wrap.js +3 -0
- package/dist/core/extensions/builtin/mcp/wrap.js.map +1 -1
- package/dist/core/extensions/builtin/openai-image-gen/externalize.d.ts +27 -0
- package/dist/core/extensions/builtin/openai-image-gen/externalize.d.ts.map +1 -0
- package/dist/core/extensions/builtin/openai-image-gen/externalize.js +133 -0
- package/dist/core/extensions/builtin/openai-image-gen/externalize.js.map +1 -0
- package/dist/core/extensions/builtin/openai-image-gen/gate.d.ts +21 -0
- package/dist/core/extensions/builtin/openai-image-gen/gate.d.ts.map +1 -0
- package/dist/core/extensions/builtin/openai-image-gen/gate.js +63 -0
- package/dist/core/extensions/builtin/openai-image-gen/gate.js.map +1 -0
- package/dist/core/extensions/builtin/openai-image-gen/index.d.ts +14 -0
- package/dist/core/extensions/builtin/openai-image-gen/index.d.ts.map +1 -0
- package/dist/core/extensions/builtin/openai-image-gen/index.js +77 -0
- package/dist/core/extensions/builtin/openai-image-gen/index.js.map +1 -0
- package/dist/core/extensions/builtin/openai-image-gen/inject.d.ts +15 -0
- package/dist/core/extensions/builtin/openai-image-gen/inject.d.ts.map +1 -0
- package/dist/core/extensions/builtin/openai-image-gen/inject.js +42 -0
- package/dist/core/extensions/builtin/openai-image-gen/inject.js.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js +2 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-5.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-5.js +2 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-5.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.5.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.5.js +2 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.5.js.map +1 -1
- 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 +2 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/grok-4.5.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/grok-4.5.js +6 -5
- package/dist/core/extensions/builtin/prompt-preset/grok-4.5.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js +2 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.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 +8 -1
- package/dist/core/extensions/builtin/terminal/monitor-notify.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/notify.d.ts +3 -1
- package/dist/core/extensions/builtin/terminal/notify.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/notify.js +4 -1
- package/dist/core/extensions/builtin/terminal/notify.js.map +1 -1
- package/dist/core/extensions/builtin/tool-search/engine/bm25.d.ts +22 -0
- package/dist/core/extensions/builtin/tool-search/engine/bm25.d.ts.map +1 -0
- package/dist/core/extensions/builtin/{mcp/expose → tool-search/engine}/bm25.js +16 -31
- package/dist/core/extensions/builtin/tool-search/engine/bm25.js.map +1 -0
- package/dist/core/extensions/builtin/tool-search/engine/document.d.ts +14 -0
- package/dist/core/extensions/builtin/tool-search/engine/document.d.ts.map +1 -0
- package/dist/core/extensions/builtin/tool-search/engine/document.js +2 -0
- package/dist/core/extensions/builtin/tool-search/engine/document.js.map +1 -0
- package/dist/core/extensions/builtin/tool-search/engine/marker.d.ts +55 -0
- package/dist/core/extensions/builtin/tool-search/engine/marker.d.ts.map +1 -0
- package/dist/core/extensions/builtin/tool-search/engine/marker.js +189 -0
- package/dist/core/extensions/builtin/tool-search/engine/marker.js.map +1 -0
- package/dist/core/extensions/builtin/tool-search/index.d.ts +7 -0
- package/dist/core/extensions/builtin/tool-search/index.d.ts.map +1 -0
- package/dist/core/extensions/builtin/tool-search/index.js +71 -0
- package/dist/core/extensions/builtin/tool-search/index.js.map +1 -0
- package/dist/core/extensions/builtin/tool-search/native-search.d.ts +52 -0
- package/dist/core/extensions/builtin/tool-search/native-search.d.ts.map +1 -0
- package/dist/core/extensions/builtin/tool-search/native-search.js +116 -0
- package/dist/core/extensions/builtin/tool-search/native-search.js.map +1 -0
- package/dist/core/extensions/builtin/tool-search/service.d.ts +38 -0
- package/dist/core/extensions/builtin/tool-search/service.d.ts.map +1 -0
- package/dist/core/extensions/builtin/tool-search/service.js +200 -0
- package/dist/core/extensions/builtin/tool-search/service.js.map +1 -0
- package/dist/core/extensions/builtin/tool-search/tool.d.ts +21 -0
- package/dist/core/extensions/builtin/tool-search/tool.d.ts.map +1 -0
- package/dist/core/extensions/builtin/tool-search/tool.js +95 -0
- package/dist/core/extensions/builtin/tool-search/tool.js.map +1 -0
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +3 -0
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +44 -4
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js +11 -0
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +1 -4
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +0 -7
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/generated-shim-banner.d.ts +15 -0
- package/dist/core/generated-shim-banner.d.ts.map +1 -0
- package/dist/core/generated-shim-banner.js +26 -0
- package/dist/core/generated-shim-banner.js.map +1 -0
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +7 -3
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +2 -1
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/provider-composer.d.ts +10 -1
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +9 -0
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +3 -5
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/session-log.d.ts.map +1 -1
- package/dist/core/session-log.js +4 -2
- package/dist/core/session-log.js.map +1 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +3 -2
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/telemetry.d.ts.map +1 -1
- package/dist/core/telemetry.js +2 -1
- package/dist/core/telemetry.js.map +1 -1
- package/dist/core/timings.d.ts +0 -4
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js +2 -1
- package/dist/core/timings.js.map +1 -1
- package/dist/inspector-policy.d.ts.map +1 -1
- package/dist/inspector-policy.js +2 -1
- package/dist/inspector-policy.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +5 -4
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +4 -0
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +1 -8
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +6 -7
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/cli-tips.d.ts.map +1 -1
- package/dist/modes/interactive/tips/catalog/cli-tips.js +2 -1
- package/dist/modes/interactive/tips/catalog/cli-tips.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/ethos-tips.d.ts.map +1 -1
- package/dist/modes/interactive/tips/catalog/ethos-tips.js +4 -3
- package/dist/modes/interactive/tips/catalog/ethos-tips.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/model-tips.d.ts.map +1 -1
- package/dist/modes/interactive/tips/catalog/model-tips.js +2 -1
- package/dist/modes/interactive/tips/catalog/model-tips.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/session-tips.d.ts.map +1 -1
- package/dist/modes/interactive/tips/catalog/session-tips.js +2 -1
- package/dist/modes/interactive/tips/catalog/session-tips.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/settings-tips.d.ts.map +1 -1
- package/dist/modes/interactive/tips/catalog/settings-tips.js +3 -2
- package/dist/modes/interactive/tips/catalog/settings-tips.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/workspace-tips.d.ts.map +1 -1
- package/dist/modes/interactive/tips/catalog/workspace-tips.js +4 -3
- package/dist/modes/interactive/tips/catalog/workspace-tips.js.map +1 -1
- package/dist/modes/provider-native-rendering.d.ts.map +1 -1
- package/dist/modes/provider-native-rendering.js +33 -0
- package/dist/modes/provider-native-rendering.js.map +1 -1
- package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
- package/dist/modes/rpc/connection-handler.js +130 -4
- package/dist/modes/rpc/connection-handler.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +2 -1
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +31 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/nearest-parent-config.d.ts +6 -1
- package/dist/nearest-parent-config.d.ts.map +1 -1
- package/dist/nearest-parent-config.js +18 -2
- package/dist/nearest-parent-config.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +13 -1
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/rpc-entry.js +2 -0
- package/dist/rpc-entry.js.map +1 -1
- package/dist/self-update-bootstrap.d.ts.map +1 -1
- package/dist/self-update-bootstrap.js +6 -0
- package/dist/self-update-bootstrap.js.map +1 -1
- package/dist/senpi +3 -2
- package/dist/utils/pi-user-agent.d.ts +1 -1
- package/dist/utils/pi-user-agent.d.ts.map +1 -1
- package/dist/utils/pi-user-agent.js +4 -3
- package/dist/utils/pi-user-agent.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +2 -1
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts +3 -0
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +37 -6
- package/dist/utils/version-check.js.map +1 -1
- package/dist/valid-cwd.d.ts +2 -0
- package/dist/valid-cwd.d.ts.map +1 -0
- package/dist/valid-cwd.js +14 -0
- package/dist/valid-cwd.js.map +1 -0
- package/docs/environment-variables.md +7 -0
- package/docs/extensions.md +50 -13
- package/docs/mcp.md +2 -0
- package/docs/rpc.md +54 -0
- package/docs/skills.md +8 -0
- package/examples/extensions/searchable-tools.ts +49 -0
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +36 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- 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 +5 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts +4 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +2 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +9 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
- 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 +4 -2
- 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-completions.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +7 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.d.ts +8 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.js +222 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.lazy.d.ts +3 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.lazy.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.lazy.js +10 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.lazy.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +113 -4
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.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/api/transform-messages.d.ts +5 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/openai-codex.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/openai-codex.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/openai-codex.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts +10 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts +32 -0
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +32 -0
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.js +36 -13
- package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/openai-responses-compat.d.ts +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/openai-responses-compat.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/openai-responses-compat.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/all.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/all.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/all.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-workers-ai.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/google.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/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/providers/images/register-builtins.d.ts +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/images/register-builtins.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/images/register-builtins.js +18 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/images/register-builtins.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-images.d.ts +3 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-images.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-images.js +16 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-images.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +7 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/wire-identity.d.ts +14 -0
- package/node_modules/@earendil-works/pi-ai/dist/wire-identity.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/wire-identity.js +24 -0
- package/node_modules/@earendil-works/pi-ai/dist/wire-identity.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/package.json +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/pipe-fallback.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/pipe-fallback.js +11 -3
- package/node_modules/@earendil-works/pi-pty/dist/pipe-fallback.js.map +1 -1
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +8 -8
- package/dist/core/extensions/builtin/mcp/expose/bm25.d.ts +0 -30
- package/dist/core/extensions/builtin/mcp/expose/bm25.d.ts.map +0 -1
- package/dist/core/extensions/builtin/mcp/expose/bm25.js.map +0 -1
- package/dist/core/extensions/builtin/mcp/expose/lazy-activate.d.ts +0 -15
- package/dist/core/extensions/builtin/mcp/expose/lazy-activate.d.ts.map +0 -1
- package/dist/core/extensions/builtin/mcp/expose/lazy-activate.js +0 -33
- package/dist/core/extensions/builtin/mcp/expose/lazy-activate.js.map +0 -1
- package/dist/core/extensions/builtin/mcp/expose/tool-search.d.ts +0 -43
- package/dist/core/extensions/builtin/mcp/expose/tool-search.d.ts.map +0 -1
- package/dist/core/extensions/builtin/mcp/expose/tool-search.js +0 -125
- package/dist/core/extensions/builtin/mcp/expose/tool-search.js.map +0 -1
- package/dist/core/omo-native-detect.d.ts +0 -3
- package/dist/core/omo-native-detect.d.ts.map +0 -1
- package/dist/core/omo-native-detect.js +0 -64
- package/dist/core/omo-native-detect.js.map +0 -1
- package/dist/core/omo-native-detect.test.d.ts +0 -2
- package/dist/core/omo-native-detect.test.d.ts.map +0 -1
- package/dist/core/omo-native-detect.test.js +0 -47
- package/dist/core/omo-native-detect.test.js.map +0 -1
- package/dist/modes/interactive/components/footer-omo-native-badge.test.d.ts +0 -2
- package/dist/modes/interactive/components/footer-omo-native-badge.test.d.ts.map +0 -1
- package/dist/modes/interactive/components/footer-omo-native-badge.test.js +0 -52
- package/dist/modes/interactive/components/footer-omo-native-badge.test.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipe-fallback.js","sourceRoot":"","sources":["../src/pipe-fallback.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport type { NativePtyLoadResult } from \"./native-loader.ts\";\n\nexport interface PipeFallbackSessionOptions {\n\treadonly command: string;\n\treadonly args?: readonly string[];\n\treadonly cwd?: string;\n\treadonly env?: Readonly<Record<string, string | undefined>>;\n\treadonly timeoutMs?: number;\n}\n\nexport interface PipeFallbackSessionError {\n\treadonly code: \"spawn_error\";\n\treadonly message: string;\n}\n\nexport interface PipeFallbackSessionExit {\n\treadonly exitCode: number | null;\n\treadonly signal: NodeJS.Signals | null;\n\treadonly timedOut: boolean;\n\treadonly error?: PipeFallbackSessionError;\n}\n\nexport type PipeFallbackOperationResult =\n\t| {\n\t\t\treadonly ok: true;\n\t\t\treadonly note: string;\n\t }\n\t| {\n\t\t\treadonly ok: false;\n\t\t\treadonly code: \"exited\" | \"not_pty\" | \"not_started\" | \"stdin_unavailable\";\n\t\t\treadonly note: string;\n\t };\n\ntype ChildProcessHandle = ReturnType<typeof spawn>;\ntype DataHandler = (chunk: Buffer) => void;\ntype ExitHandler = (exit: PipeFallbackSessionExit) => void;\n\nconst PIPE_FALLBACK_NOTE =\n\t\"Running with child_process pipe fallback because no PTY backend is active; terminal screen state and resize are unavailable.\";\n\nexport function isPipeFallbackForced(env: Readonly<Record<string, string | undefined>> = process.env): boolean {\n\tconst value = env.SENPI_PTY_FORCE_PIPE;\n\treturn value === \"1\" || value === \"true\";\n}\n\nexport function shouldUsePipeFallback(\n\tnativeLoadResult: NativePtyLoadResult,\n\tenv: Readonly<Record<string, string | undefined>> = process.env,\n): boolean {\n\treturn isPipeFallbackForced(env) || nativeLoadResult.native === null;\n}\n\n/**\n * Terminate the child, preferring its whole process group on POSIX. The\n * detached child is its own group leader and grandchildren inherit the stdio\n * pipes, so leaving them alive keeps 'close' from ever firing (the POSIX twin\n * of the Windows taskkill /T branch below). Every path that stops a child must\n * go through here: when the group signal is unavailable (Windows, no pid) or\n * the group is already gone, it still falls back to a direct kill, so the\n * child is never left running.\n */\nexport function terminateChildTree(\n\tchild: Pick<ChildProcessHandle, \"pid\" | \"kill\">,\n\tsignal: NodeJS.Signals,\n): \"group\" | \"direct\" {\n\tconst pid = child.pid;\n\tif (pid !== undefined && process.platform !== \"win32\") {\n\t\ttry {\n\t\t\tprocess.kill(-pid, signal);\n\t\t\treturn \"group\";\n\t\t} catch {\n\t\t\t// Group already gone — fall through to the direct kill.\n\t\t}\n\t}\n\tchild.kill(signal);\n\treturn \"direct\";\n}\n\nfunction normalizeSpawnError(command: string, error: Error): PipeFallbackSessionError {\n\treturn {\n\t\tcode: \"spawn_error\",\n\t\tmessage: `Failed to spawn pipe fallback command \"${command}\": ${error.message}`,\n\t};\n}\n\nfunction toBuffer(chunk: string | Buffer): Buffer {\n\treturn Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n}\n\nfunction validateTimeout(timeoutMs: number | undefined): void {\n\tif (timeoutMs === undefined) return;\n\tif (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n\t\tthrow new Error(\"Invalid timeoutMs: must be a finite positive number\");\n\t}\n}\n\nexport class PipeFallbackSession {\n\treadonly backend = \"pipe-fallback\";\n\treadonly note = PIPE_FALLBACK_NOTE;\n\treadonly options: PipeFallbackSessionOptions;\n\tprivate child: ChildProcessHandle | null = null;\n\tprivate exitResult: PipeFallbackSessionExit | null = null;\n\tprivate exitPromise: Promise<PipeFallbackSessionExit>;\n\tprivate resolveExit: ((exit: PipeFallbackSessionExit) => void) | null = null;\n\tprivate spawnError: PipeFallbackSessionError | undefined;\n\tprivate timedOut = false;\n\tprivate timeoutHandle: NodeJS.Timeout | undefined;\n\tprivate readonly dataHandlers = new Set<DataHandler>();\n\tprivate readonly exitHandlers = new Set<ExitHandler>();\n\n\tconstructor(options: PipeFallbackSessionOptions) {\n\t\tthis.options = {\n\t\t\t...options,\n\t\t\targs: options.args ? [...options.args] : undefined,\n\t\t\tenv: options.env ? { ...options.env } : undefined,\n\t\t};\n\t\tthis.exitPromise = new Promise((resolve) => {\n\t\t\tthis.resolveExit = resolve;\n\t\t});\n\t}\n\n\tstart(): this {\n\t\tif (this.exitResult !== null) throw new Error(\"Cannot restart exited pipe fallback session\");\n\t\tif (this.child !== null) throw new Error(\"Pipe fallback session has already been started\");\n\t\tvalidateTimeout(this.options.timeoutMs);\n\n\t\ttry {\n\t\t\tconst child = spawn(this.options.command, [...(this.options.args ?? [])], {\n\t\t\t\tcwd: this.options.cwd,\n\t\t\t\tenv: this.options.env ? { ...process.env, ...this.options.env } : process.env,\n\t\t\t\tstdio: [\"pipe\", \"pipe\", \"pipe\"],\n\t\t\t\t// Detach on POSIX so the child leads its own session with no\n\t\t\t\t// controlling terminal. Without this, a tty-reading program (e.g. a\n\t\t\t\t// sudo password prompt) opens /dev/tty — the user's real terminal —\n\t\t\t\t// and races the TUI's raw-mode stdin reader byte-by-byte, splitting\n\t\t\t\t// keystrokes and Kitty escape sequences between the two readers.\n\t\t\t\t// Detached, the /dev/tty open fails with a clear error instead.\n\t\t\t\tdetached: process.platform !== \"win32\",\n\t\t\t\twindowsHide: true,\n\t\t\t});\n\t\t\tthis.child = child;\n\t\t\tchild.stdout?.on(\"data\", (chunk: string | Buffer) => this.emitData(toBuffer(chunk)));\n\t\t\tchild.stderr?.on(\"data\", (chunk: string | Buffer) => this.emitData(toBuffer(chunk)));\n\t\t\tchild.stdin?.on(\"error\", () => {});\n\t\t\tchild.on(\"error\", (error: Error) => {\n\t\t\t\tthis.spawnError = normalizeSpawnError(this.options.command, error);\n\t\t\t});\n\t\t\tchild.on(\"close\", (exitCode, signal) => {\n\t\t\t\tthis.settleExit({\n\t\t\t\t\texitCode: this.spawnError ? null : exitCode,\n\t\t\t\t\tsignal,\n\t\t\t\t\ttimedOut: this.timedOut,\n\t\t\t\t\terror: this.spawnError,\n\t\t\t\t});\n\t\t\t});\n\t\t\tif (this.options.timeoutMs !== undefined) {\n\t\t\t\tthis.timeoutHandle = setTimeout(() => {\n\t\t\t\t\tthis.timedOut = true;\n\t\t\t\t\tterminateChildTree(child, \"SIGTERM\");\n\t\t\t\t}, this.options.timeoutMs);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst cause = error instanceof Error ? error : new Error(String(error));\n\t\t\tthis.settleExit({\n\t\t\t\texitCode: null,\n\t\t\t\tsignal: null,\n\t\t\t\ttimedOut: false,\n\t\t\t\terror: normalizeSpawnError(this.options.command, cause),\n\t\t\t});\n\t\t}\n\t\treturn this;\n\t}\n\n\tonData(handler: DataHandler): () => void {\n\t\tthis.dataHandlers.add(handler);\n\t\treturn () => this.dataHandlers.delete(handler);\n\t}\n\n\tonExit(handler: ExitHandler): () => void {\n\t\tconst exitResult = this.exitResult;\n\t\tif (exitResult !== null) queueMicrotask(() => handler(exitResult));\n\t\telse this.exitHandlers.add(handler);\n\t\treturn () => this.exitHandlers.delete(handler);\n\t}\n\n\twrite(data: string | Uint8Array): PipeFallbackOperationResult {\n\t\tif (this.exitResult !== null) {\n\t\t\treturn { ok: false, code: \"exited\", note: \"Cannot write to pipe fallback stdin: session has exited.\" };\n\t\t}\n\t\tif (this.child === null) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tcode: \"not_started\",\n\t\t\t\tnote: \"Cannot write to pipe fallback stdin: session has not started.\",\n\t\t\t};\n\t\t}\n\t\tif (!this.child.stdin || this.child.stdin.destroyed || this.child.stdin.writableEnded) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tcode: \"stdin_unavailable\",\n\t\t\t\tnote: \"Cannot write to pipe fallback stdin: child stdin is unavailable.\",\n\t\t\t};\n\t\t}\n\t\tconst accepted = this.child.stdin.write(data);\n\t\treturn {\n\t\t\tok: true,\n\t\t\tnote: accepted\n\t\t\t\t? \"Wrote stdin through child_process pipe fallback; this is not a PTY.\"\n\t\t\t\t: \"Queued stdin through child_process pipe fallback with stream backpressure; this is not a PTY.\",\n\t\t};\n\t}\n\n\tcloseInput(): PipeFallbackOperationResult {\n\t\tif (this.exitResult !== null) {\n\t\t\treturn { ok: false, code: \"exited\", note: \"Cannot close pipe fallback stdin: session has exited.\" };\n\t\t}\n\t\tif (this.child === null) {\n\t\t\treturn { ok: false, code: \"not_started\", note: \"Cannot close pipe fallback stdin: session has not started.\" };\n\t\t}\n\t\tthis.child.stdin?.end();\n\t\treturn { ok: true, note: \"Closed child_process pipe fallback stdin.\" };\n\t}\n\n\tresize(cols: number, rows: number): PipeFallbackOperationResult {\n\t\treturn {\n\t\t\tok: false,\n\t\t\tcode: \"not_pty\",\n\t\t\tnote: `Cannot resize pipe fallback session to ${cols}x${rows}: child_process pipes are not a PTY; session is still valid.`,\n\t\t};\n\t}\n\n\tkill(signal: NodeJS.Signals = \"SIGTERM\"): PipeFallbackOperationResult {\n\t\tif (this.exitResult !== null) {\n\t\t\treturn { ok: false, code: \"exited\", note: \"Cannot kill pipe fallback session: session has exited.\" };\n\t\t}\n\t\tif (this.child === null) {\n\t\t\treturn { ok: false, code: \"not_started\", note: \"Cannot kill pipe fallback session: session has not started.\" };\n\t\t}\n\t\tconst pid = this.child.pid;\n\t\tif (process.platform === \"win32\" && pid !== undefined) {\n\t\t\t// On Windows child.kill() TerminateProcess-es only the direct child, leaving\n\t\t\t// grandchildren (e.g. `sleep` under `bash.exe -c`) alive and holding the stdout\n\t\t\t// pipe open — so 'close' never fires and waitExit() hangs teardown. taskkill /T /F\n\t\t\t// terminates the whole tree so the pipe EOFs and the session settles.\n\t\t\ttry {\n\t\t\t\tspawn(\"taskkill\", [\"/pid\", String(pid), \"/T\", \"/F\"], { stdio: \"ignore\", windowsHide: true });\n\t\t\t\treturn { ok: true, note: `Terminated child_process pipe fallback process tree (pid ${pid}).` };\n\t\t\t} catch {\n\t\t\t\t// Fall through to the direct kill if taskkill is unavailable.\n\t\t\t}\n\t\t}\n\t\tif (terminateChildTree(this.child, signal) === \"group\") {\n\t\t\treturn { ok: true, note: `Sent ${signal} to child_process pipe fallback process group (pgid ${pid}).` };\n\t\t}\n\t\treturn { ok: true, note: `Sent ${signal} to child_process pipe fallback session.` };\n\t}\n\n\twaitExit(): Promise<PipeFallbackSessionExit> {\n\t\treturn this.exitPromise;\n\t}\n\n\tprivate emitData(chunk: Buffer): void {\n\t\tfor (const handler of this.dataHandlers) handler(chunk);\n\t}\n\n\tprivate settleExit(exit: PipeFallbackSessionExit): void {\n\t\tif (this.exitResult !== null) return;\n\t\tif (this.timeoutHandle) clearTimeout(this.timeoutHandle);\n\t\tthis.exitResult = exit;\n\t\tthis.resolveExit?.(exit);\n\t\tfor (const handler of this.exitHandlers) handler(exit);\n\t\tthis.exitHandlers.clear();\n\t}\n}\n\nexport function createPipeFallbackSession(options: PipeFallbackSessionOptions): PipeFallbackSession {\n\treturn new PipeFallbackSession(options).start();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"pipe-fallback.js","sourceRoot":"","sources":["../src/pipe-fallback.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport type { NativePtyLoadResult } from \"./native-loader.ts\";\n\nexport interface PipeFallbackSessionOptions {\n\treadonly command: string;\n\treadonly args?: readonly string[];\n\treadonly cwd?: string;\n\treadonly env?: Readonly<Record<string, string | undefined>>;\n\treadonly timeoutMs?: number;\n}\n\nexport interface PipeFallbackSessionError {\n\treadonly code: \"spawn_error\";\n\treadonly message: string;\n}\n\nexport interface PipeFallbackSessionExit {\n\treadonly exitCode: number | null;\n\treadonly signal: NodeJS.Signals | null;\n\treadonly timedOut: boolean;\n\treadonly error?: PipeFallbackSessionError;\n}\n\nexport type PipeFallbackOperationResult =\n\t| {\n\t\t\treadonly ok: true;\n\t\t\treadonly note: string;\n\t }\n\t| {\n\t\t\treadonly ok: false;\n\t\t\treadonly code: \"exited\" | \"not_pty\" | \"not_started\" | \"stdin_unavailable\";\n\t\t\treadonly note: string;\n\t };\n\ntype ChildProcessHandle = ReturnType<typeof spawn>;\ntype DataHandler = (chunk: Buffer) => void;\ntype ExitHandler = (exit: PipeFallbackSessionExit) => void;\n\nconst PIPE_FALLBACK_NOTE =\n\t\"Running with child_process pipe fallback because no PTY backend is active; terminal screen state and resize are unavailable.\";\n\nexport function isPipeFallbackForced(env: Readonly<Record<string, string | undefined>> = process.env): boolean {\n\tconst value = env.SENPI_PTY_FORCE_PIPE;\n\treturn value === \"1\" || value === \"true\";\n}\n\nexport function shouldUsePipeFallback(\n\tnativeLoadResult: NativePtyLoadResult,\n\tenv: Readonly<Record<string, string | undefined>> = process.env,\n): boolean {\n\treturn isPipeFallbackForced(env) || nativeLoadResult.native === null;\n}\n\n/**\n * Terminate the child, preferring its whole process group on POSIX. The\n * detached child is its own group leader and grandchildren inherit the stdio\n * pipes, so leaving them alive keeps 'close' from ever firing (the POSIX twin\n * of the Windows taskkill /T branch below). Every path that stops a child must\n * go through here: when the group signal is unavailable (Windows, no pid) or\n * the group is already gone, it still falls back to a direct kill, so the\n * child is never left running.\n */\nexport function terminateChildTree(\n\tchild: Pick<ChildProcessHandle, \"pid\" | \"kill\">,\n\tsignal: NodeJS.Signals,\n): \"group\" | \"direct\" {\n\tconst pid = child.pid;\n\tif (pid !== undefined && process.platform !== \"win32\") {\n\t\ttry {\n\t\t\tprocess.kill(-pid, signal);\n\t\t\treturn \"group\";\n\t\t} catch {\n\t\t\t// Group already gone — fall through to the direct kill.\n\t\t}\n\t}\n\tchild.kill(signal);\n\treturn \"direct\";\n}\n\nfunction normalizeSpawnError(command: string, error: Error): PipeFallbackSessionError {\n\treturn {\n\t\tcode: \"spawn_error\",\n\t\tmessage: `Failed to spawn pipe fallback command \"${command}\": ${error.message}`,\n\t};\n}\n\nfunction toBuffer(chunk: string | Buffer): Buffer {\n\treturn Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n}\n\nfunction validateTimeout(timeoutMs: number | undefined): void {\n\tif (timeoutMs === undefined) return;\n\tif (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n\t\tthrow new Error(\"Invalid timeoutMs: must be a finite positive number\");\n\t}\n}\n\nexport class PipeFallbackSession {\n\treadonly backend = \"pipe-fallback\";\n\treadonly note = PIPE_FALLBACK_NOTE;\n\treadonly options: PipeFallbackSessionOptions;\n\tprivate child: ChildProcessHandle | null = null;\n\tprivate exitResult: PipeFallbackSessionExit | null = null;\n\tprivate exitPromise: Promise<PipeFallbackSessionExit>;\n\tprivate resolveExit: ((exit: PipeFallbackSessionExit) => void) | null = null;\n\tprivate spawnError: PipeFallbackSessionError | undefined;\n\tprivate timedOut = false;\n\tprivate timeoutHandle: NodeJS.Timeout | undefined;\n\tprivate readonly dataHandlers = new Set<DataHandler>();\n\tprivate readonly exitHandlers = new Set<ExitHandler>();\n\n\tconstructor(options: PipeFallbackSessionOptions) {\n\t\tthis.options = {\n\t\t\t...options,\n\t\t\targs: options.args ? [...options.args] : undefined,\n\t\t\tenv: options.env ? { ...options.env } : undefined,\n\t\t};\n\t\tthis.exitPromise = new Promise((resolve) => {\n\t\t\tthis.resolveExit = resolve;\n\t\t});\n\t}\n\n\tstart(): this {\n\t\tif (this.exitResult !== null) throw new Error(\"Cannot restart exited pipe fallback session\");\n\t\tif (this.child !== null) throw new Error(\"Pipe fallback session has already been started\");\n\t\tvalidateTimeout(this.options.timeoutMs);\n\n\t\ttry {\n\t\t\tconst child = spawn(this.options.command, [...(this.options.args ?? [])], {\n\t\t\t\tcwd: this.options.cwd,\n\t\t\t\tenv: this.options.env ? { ...process.env, ...this.options.env } : process.env,\n\t\t\t\tstdio: [\"pipe\", \"pipe\", \"pipe\"],\n\t\t\t\t// Detach on POSIX so the child leads its own session with no\n\t\t\t\t// controlling terminal. Without this, a tty-reading program (e.g. a\n\t\t\t\t// sudo password prompt) opens /dev/tty — the user's real terminal —\n\t\t\t\t// and races the TUI's raw-mode stdin reader byte-by-byte, splitting\n\t\t\t\t// keystrokes and Kitty escape sequences between the two readers.\n\t\t\t\t// Detached, the /dev/tty open fails with a clear error instead.\n\t\t\t\tdetached: process.platform !== \"win32\",\n\t\t\t\twindowsHide: true,\n\t\t\t});\n\t\t\tthis.child = child;\n\t\t\tchild.stdout?.on(\"data\", (chunk: string | Buffer) => this.emitData(toBuffer(chunk)));\n\t\t\tchild.stderr?.on(\"data\", (chunk: string | Buffer) => this.emitData(toBuffer(chunk)));\n\t\t\tchild.stdin?.on(\"error\", () => {});\n\t\t\tchild.on(\"error\", (error: Error) => {\n\t\t\t\tthis.spawnError = normalizeSpawnError(this.options.command, error);\n\t\t\t});\n\t\t\tchild.on(\"close\", (exitCode, signal) => {\n\t\t\t\tthis.settleExit({\n\t\t\t\t\texitCode: this.spawnError ? null : exitCode,\n\t\t\t\t\tsignal,\n\t\t\t\t\ttimedOut: this.timedOut,\n\t\t\t\t\terror: this.spawnError,\n\t\t\t\t});\n\t\t\t});\n\t\t\tif (this.options.timeoutMs !== undefined) {\n\t\t\t\tthis.timeoutHandle = setTimeout(() => {\n\t\t\t\t\tthis.timedOut = true;\n\t\t\t\t\tterminateChildTree(child, \"SIGTERM\");\n\t\t\t\t}, this.options.timeoutMs);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst cause = error instanceof Error ? error : new Error(String(error));\n\t\t\tthis.settleExit({\n\t\t\t\texitCode: null,\n\t\t\t\tsignal: null,\n\t\t\t\ttimedOut: false,\n\t\t\t\terror: normalizeSpawnError(this.options.command, cause),\n\t\t\t});\n\t\t}\n\t\treturn this;\n\t}\n\n\tonData(handler: DataHandler): () => void {\n\t\tthis.dataHandlers.add(handler);\n\t\treturn () => this.dataHandlers.delete(handler);\n\t}\n\n\tonExit(handler: ExitHandler): () => void {\n\t\tconst exitResult = this.exitResult;\n\t\tif (exitResult !== null) queueMicrotask(() => handler(exitResult));\n\t\telse this.exitHandlers.add(handler);\n\t\treturn () => this.exitHandlers.delete(handler);\n\t}\n\n\twrite(data: string | Uint8Array): PipeFallbackOperationResult {\n\t\tif (this.exitResult !== null) {\n\t\t\treturn { ok: false, code: \"exited\", note: \"Cannot write to pipe fallback stdin: session has exited.\" };\n\t\t}\n\t\tif (this.child === null) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tcode: \"not_started\",\n\t\t\t\tnote: \"Cannot write to pipe fallback stdin: session has not started.\",\n\t\t\t};\n\t\t}\n\t\tif (!this.child.stdin || this.child.stdin.destroyed || this.child.stdin.writableEnded) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tcode: \"stdin_unavailable\",\n\t\t\t\tnote: \"Cannot write to pipe fallback stdin: child stdin is unavailable.\",\n\t\t\t};\n\t\t}\n\t\tconst accepted = this.child.stdin.write(data);\n\t\treturn {\n\t\t\tok: true,\n\t\t\tnote: accepted\n\t\t\t\t? \"Wrote stdin through child_process pipe fallback; this is not a PTY.\"\n\t\t\t\t: \"Queued stdin through child_process pipe fallback with stream backpressure; this is not a PTY.\",\n\t\t};\n\t}\n\n\tcloseInput(): PipeFallbackOperationResult {\n\t\tif (this.exitResult !== null) {\n\t\t\treturn { ok: false, code: \"exited\", note: \"Cannot close pipe fallback stdin: session has exited.\" };\n\t\t}\n\t\tif (this.child === null) {\n\t\t\treturn { ok: false, code: \"not_started\", note: \"Cannot close pipe fallback stdin: session has not started.\" };\n\t\t}\n\t\tthis.child.stdin?.end();\n\t\treturn { ok: true, note: \"Closed child_process pipe fallback stdin.\" };\n\t}\n\n\tresize(cols: number, rows: number): PipeFallbackOperationResult {\n\t\treturn {\n\t\t\tok: false,\n\t\t\tcode: \"not_pty\",\n\t\t\tnote: `Cannot resize pipe fallback session to ${cols}x${rows}: child_process pipes are not a PTY; session is still valid.`,\n\t\t};\n\t}\n\n\tkill(signal: NodeJS.Signals = \"SIGTERM\"): PipeFallbackOperationResult {\n\t\tif (this.exitResult !== null) {\n\t\t\treturn { ok: false, code: \"exited\", note: \"Cannot kill pipe fallback session: session has exited.\" };\n\t\t}\n\t\tif (this.child === null) {\n\t\t\treturn { ok: false, code: \"not_started\", note: \"Cannot kill pipe fallback session: session has not started.\" };\n\t\t}\n\t\tconst child = this.child;\n\t\tconst pid = child.pid;\n\t\tif (process.platform === \"win32\" && pid !== undefined) {\n\t\t\t// On Windows child.kill() TerminateProcess-es only the direct child, leaving\n\t\t\t// grandchildren (e.g. `sleep` under `bash.exe -c`) alive and holding the stdout\n\t\t\t// pipe open — so 'close' never fires and waitExit() hangs teardown. taskkill /T /F\n\t\t\t// terminates the whole tree so the pipe EOFs and the session settles.\n\t\t\ttry {\n\t\t\t\tconst killer = spawn(\"taskkill.exe\", [\"/pid\", String(pid), \"/T\", \"/F\"], {\n\t\t\t\t\tstdio: \"ignore\",\n\t\t\t\t\twindowsHide: true,\n\t\t\t\t});\n\t\t\t\tkiller.once(\"error\", () => {\n\t\t\t\t\tterminateChildTree(child, signal);\n\t\t\t\t});\n\t\t\t\treturn { ok: true, note: `Terminated child_process pipe fallback process tree (pid ${pid}).` };\n\t\t\t} catch {\n\t\t\t\tterminateChildTree(child, signal);\n\t\t\t\treturn { ok: true, note: `Sent ${signal} to child_process pipe fallback session.` };\n\t\t\t}\n\t\t}\n\t\tif (terminateChildTree(this.child, signal) === \"group\") {\n\t\t\treturn { ok: true, note: `Sent ${signal} to child_process pipe fallback process group (pgid ${pid}).` };\n\t\t}\n\t\treturn { ok: true, note: `Sent ${signal} to child_process pipe fallback session.` };\n\t}\n\n\twaitExit(): Promise<PipeFallbackSessionExit> {\n\t\treturn this.exitPromise;\n\t}\n\n\tprivate emitData(chunk: Buffer): void {\n\t\tfor (const handler of this.dataHandlers) handler(chunk);\n\t}\n\n\tprivate settleExit(exit: PipeFallbackSessionExit): void {\n\t\tif (this.exitResult !== null) return;\n\t\tif (this.timeoutHandle) clearTimeout(this.timeoutHandle);\n\t\tthis.exitResult = exit;\n\t\tthis.resolveExit?.(exit);\n\t\tfor (const handler of this.exitHandlers) handler(exit);\n\t\tthis.exitHandlers.clear();\n\t}\n}\n\nexport function createPipeFallbackSession(options: PipeFallbackSessionOptions): PipeFallbackSession {\n\treturn new PipeFallbackSession(options).start();\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@earendil-works/pi-tui",
|
|
3
3
|
"private": true,
|
|
4
|
-
"version": "2026.8.
|
|
4
|
+
"version": "2026.8.11-3",
|
|
5
5
|
"description": "Terminal User Interface library with differential rendering for efficient text-based applications",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-yeongyu/senpi",
|
|
3
|
-
"version": "2026.8.
|
|
3
|
+
"version": "2026.8.11-3",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"piConfig": {
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
"dev": "tsc -p tsconfig.build.json --watch --preserveWatchOutput",
|
|
39
39
|
"build": "tsc -p tsconfig.build.json && npm run copy-assets && shx chmod +x dist/cli.js dist/rpc-entry.js && shx cp dist/cli.js dist/senpi && shx chmod +x dist/senpi",
|
|
40
40
|
"build:binary": "npm --prefix ../tui run build && npm --prefix ../ai run build && npm --prefix ../agent run build && npm --prefix ../protocol run build && npm --prefix ../client run build && npm run build && node ../../scripts/prepare-bun-compile-assets.mjs && bun build --compile --compile-autoload-package-json --external=css-tree --no-compile-autoload-dotenv --minify --keep-names ./dist/bun/cli.js ./src/utils/image-resize-worker.ts ../../node_modules/jsdom/lib/jsdom/living/xhr/xhr-sync-worker.js --outfile dist/pi && npm run copy-binary-assets",
|
|
41
|
-
"copy-assets": "shx mkdir -p dist/modes/interactive/theme && shx cp src/modes/interactive/theme/*.json dist/modes/interactive/theme/ && shx mkdir -p dist/modes/interactive/assets && shx cp src/modes/interactive/assets/*.png dist/modes/interactive/assets/ && shx mkdir -p dist/core/export-html/vendor && shx cp src/core/export-html/template.html src/core/export-html/template.css src/core/export-html/template.js dist/core/export-html/ && shx cp src/core/export-html/vendor/*.js dist/core/export-html/vendor/",
|
|
42
|
-
"copy-binary-assets": "shx cp package.json dist/ && shx cp README.md dist/ && shx cp CHANGELOG.md dist/ && shx mkdir -p dist/theme && shx cp src/modes/interactive/theme/*.json dist/theme/ && shx mkdir -p dist/assets && shx cp src/modes/interactive/assets/*.png dist/assets/ && shx mkdir -p dist/export-html/vendor && shx cp src/core/export-html/template.html src/core/export-html/template.css src/core/export-html/template.js dist/export-html/ && shx cp -r docs dist/ && shx cp -r examples dist/ && shx mkdir -p dist/node_modules && shx cp -r ../../node_modules/css-tree ../../node_modules/mdn-data ../../node_modules/source-map-js dist/node_modules/ && shx cp ../../node_modules/@silvia-odwyer/photon-node/photon_rs_bg.wasm dist/ && shx mkdir -p dist/native/darwin dist/native/win32 && shx cp -r ../../packages/tui/native/darwin/prebuilds dist/native/darwin/ && shx cp -r ../../packages/tui/native/win32/prebuilds dist/native/win32/ && node ../../scripts/copy-pty-native.mjs",
|
|
41
|
+
"copy-assets": "shx mkdir -p dist/modes/interactive/theme && shx cp src/modes/interactive/theme/*.json dist/modes/interactive/theme/ && shx mkdir -p dist/modes/interactive/assets && shx cp src/modes/interactive/assets/*.png dist/modes/interactive/assets/ && shx mkdir -p dist/core/export-html/vendor && shx cp src/core/export-html/template.html src/core/export-html/template.css src/core/export-html/template.js dist/core/export-html/ && shx cp src/core/export-html/vendor/*.js dist/core/export-html/vendor/ && shx mkdir -p dist/core/extensions/builtin/imagegen/skill && shx cp src/core/extensions/builtin/imagegen/skill/SKILL.md dist/core/extensions/builtin/imagegen/skill/",
|
|
42
|
+
"copy-binary-assets": "shx cp package.json dist/ && shx cp README.md dist/ && shx cp CHANGELOG.md dist/ && shx mkdir -p dist/theme && shx cp src/modes/interactive/theme/*.json dist/theme/ && shx mkdir -p dist/assets && shx cp src/modes/interactive/assets/*.png dist/assets/ && shx mkdir -p dist/export-html/vendor && shx cp src/core/export-html/template.html src/core/export-html/template.css src/core/export-html/template.js dist/export-html/ && shx cp -r docs dist/ && shx cp -r examples dist/ && shx mkdir -p dist/node_modules && shx cp -r ../../node_modules/css-tree ../../node_modules/mdn-data ../../node_modules/source-map-js dist/node_modules/ && shx cp ../../node_modules/@silvia-odwyer/photon-node/photon_rs_bg.wasm dist/ && shx mkdir -p dist/native/darwin dist/native/win32 && shx cp -r ../../packages/tui/native/darwin/prebuilds dist/native/darwin/ && shx cp -r ../../packages/tui/native/win32/prebuilds dist/native/win32/ && shx mkdir -p dist/core/extensions/builtin/imagegen/skill && shx cp src/core/extensions/builtin/imagegen/skill/SKILL.md dist/core/extensions/builtin/imagegen/skill/ && node ../../scripts/copy-pty-native.mjs",
|
|
43
43
|
"qa:app-server": "node scripts/qa-app-server/run-all.mjs",
|
|
44
44
|
"test": "vitest --run",
|
|
45
45
|
"prepublishOnly": "npm run clean && npm run build && npm run shrinkwrap",
|
|
@@ -48,11 +48,11 @@
|
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@anthropic-ai/sdk": "0.91.1",
|
|
50
50
|
"@aws-sdk/client-bedrock-runtime": "3.1095.0",
|
|
51
|
-
"@code-yeongyu/senpi-codemode": "2026.8.
|
|
52
|
-
"@earendil-works/pi-agent-core": "npm:@code-yeongyu/senpi-agent-core@2026.8.
|
|
53
|
-
"@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.8.
|
|
54
|
-
"@earendil-works/pi-pty": "npm:@code-yeongyu/senpi-pty@2026.8.
|
|
55
|
-
"@earendil-works/pi-tui": "npm:@code-yeongyu/senpi-tui@2026.8.
|
|
51
|
+
"@code-yeongyu/senpi-codemode": "2026.8.11-3",
|
|
52
|
+
"@earendil-works/pi-agent-core": "npm:@code-yeongyu/senpi-agent-core@2026.8.11-3",
|
|
53
|
+
"@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.8.11-3",
|
|
54
|
+
"@earendil-works/pi-pty": "npm:@code-yeongyu/senpi-pty@2026.8.11-3",
|
|
55
|
+
"@earendil-works/pi-tui": "npm:@code-yeongyu/senpi-tui@2026.8.11-3",
|
|
56
56
|
"@mistralai/mistralai": "2.5.0",
|
|
57
57
|
"@modelcontextprotocol/sdk": "1.30.0",
|
|
58
58
|
"@mozilla/readability": "0.6.0",
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
export interface Bm25Doc {
|
|
2
|
-
/** Full senpi tool name, e.g. `mcp_docs_get-library-docs`. Returned in results. */
|
|
3
|
-
readonly name: string;
|
|
4
|
-
/** Bare MCP tool name, e.g. `get-library-docs`. Used for exact-name matching. */
|
|
5
|
-
readonly toolName: string;
|
|
6
|
-
readonly description?: string;
|
|
7
|
-
readonly server: string;
|
|
8
|
-
}
|
|
9
|
-
export interface Bm25Result {
|
|
10
|
-
readonly name: string;
|
|
11
|
-
readonly score: number;
|
|
12
|
-
readonly exact: boolean;
|
|
13
|
-
readonly doc: Bm25Doc;
|
|
14
|
-
}
|
|
15
|
-
export interface Bm25SearchOptions {
|
|
16
|
-
/** Restrict results to a single server (by server name). */
|
|
17
|
-
readonly server?: string;
|
|
18
|
-
/** Disable the exact-name short-circuit (used to prove BM25-alone behaviour). */
|
|
19
|
-
readonly exactMatch?: boolean;
|
|
20
|
-
}
|
|
21
|
-
export interface Bm25Index {
|
|
22
|
-
search(query: string, limit?: number, options?: Bm25SearchOptions): Bm25Result[];
|
|
23
|
-
}
|
|
24
|
-
export declare function buildBm25Index(docs: readonly Bm25Doc[]): Bm25Index;
|
|
25
|
-
/** Tokenise a tool identifier or description into lowercase word tokens,
|
|
26
|
-
* splitting snake_case, kebab-case and camelCase / PascalCase boundaries. */
|
|
27
|
-
export declare function tokenizeToolText(text: string): string[];
|
|
28
|
-
/** Normalise a tool name for exact matching: lowercase, strip separators. */
|
|
29
|
-
export declare function normalizeToolName(name: string): string;
|
|
30
|
-
//# sourceMappingURL=bm25.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bm25.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/mcp/expose/bm25.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,OAAO;IACvB,mFAAmF;IACnF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IACjC,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,iFAAiF;IACjF,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,SAAS;IACzB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,UAAU,EAAE,CAAC;CACjF;AAYD,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,SAAS,CAgClE;AA+DD;6EAC6E;AAC7E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAYvD;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bm25.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/mcp/expose/bm25.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,sEAAsE;AACtE,8EAA8E;AAC9E,6EAA6E;AAC7E,yEAAyE;AACzE,6EAA6E;AAC7E,qDAAqD;AACrD,EAAE;AACF,2EAA2E;AAE3E,MAAM,OAAO,GAAG,GAAG,CAAC;AACpB,MAAM,MAAM,GAAG,GAAG,CAAC;AAEnB,+EAA+E;AAC/E,gEAAgE;AAChE,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAC5B,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAC9B,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAqCnC,MAAM,aAAa,GAAG,EAAE,CAAC;AAEzB,MAAM,UAAU,cAAc,CAAC,IAAwB;IACtD,MAAM,OAAO,GAAiB,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;YAC1C,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,CAAC;IACF,CAAC;IACD,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC1E,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAC1E,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAEhC,OAAO;QACN,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,aAAa,EAAE,OAAO,GAAG,EAAE;YAChD,MAAM,IAAI,GACT,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;YACzG,MAAM,UAAU,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;YAC3C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YAEvC,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,KAAK,KAAK,CAAC;YAC9C,MAAM,SAAS,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;YAC3C,MAAM,OAAO,GAAiB,EAAE,CAAC;YACjC,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;gBAC1B,MAAM,KAAK,GAAG,QAAQ,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;gBACrF,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;gBACzE,IAAI,CAAC,KAAK,IAAI,KAAK,IAAI,CAAC;oBAAE,SAAS;gBACnC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YACtE,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC7B,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;QAC7C,CAAC;KACD,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,GAAY;IAC7B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,iBAAiB,CAAC,CAAC;IAClE,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAC,CAAC;IACtE,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC,CAAC;IACtE,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE,wBAAwB,CAAC,CAAC;IACtF,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC;IACvD,OAAO;QACN,GAAG;QACH,MAAM;QACN,QAAQ,EAAE,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC;QACrC,YAAY,EAAE,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC7C,QAAQ;KACR,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,QAA6B,EAAE,MAAyB,EAAE,MAAc;IACzF,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;IAC1D,CAAC;AACF,CAAC;AAED,SAAS,SAAS,CACjB,KAAiB,EACjB,UAA6B,EAC7B,OAAoC,EACpC,SAAiB,EACjB,QAAgB;IAEhB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC/B,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QAC7B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACf,MAAM,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,EAAE,KAAK,SAAS;YAAE,SAAS;QAC/B,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC7D,MAAM,KAAK,GAAG,EAAE,GAAG,OAAO,GAAG,CAAC,CAAC,GAAG,MAAM,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC;QACvF,KAAK,IAAI,GAAG,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,SAAS,cAAc,CAAC,WAAmB,EAAE,QAAgB;IAC5D,2EAA2E;IAC3E,gEAAgE;IAChE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,WAAW,GAAG,GAAG,CAAC,GAAG,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC,CAAC;IACjF,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC9B,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAiB,EAAE,SAAiB;IAC7D,OAAO,SAAS,KAAK,KAAK,CAAC,QAAQ,IAAI,SAAS,KAAK,KAAK,CAAC,YAAY,CAAC;AACzE,CAAC;AAED,SAAS,cAAc,CAAC,IAAgB,EAAE,KAAiB;IAC1D,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IAChE,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC5C,CAAC;AAED;6EAC6E;AAC7E,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC5C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,MAAM,cAAc,GAAG,IAAI;QAC1B,2FAA2F;SAC1F,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC;SACtC,OAAO,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,GAAG,IAAI,cAAc,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC;QACzD,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAC/B,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC7C,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AACnD,CAAC","sourcesContent":["// Zero-dependency BM25 tool-search engine (todo 30).\n//\n// Ranks MCP tools by relevance of a free-text query against tokenised\n// name + description, with a server-name field boost. A normalised exact-name\n// match short-circuits BEFORE BM25 (hyphen/underscore/case-insensitive) so a\n// query equal to a tool's own name always wins rank-1 even when raw BM25\n// term-frequency would float noisier tools above it (codex #21503 regression\n// class). Constants k1=0.9, b=0.4 are SPEC-verified.\n//\n// Ranking is deterministic: equal scores tie-break by ascending full name.\n\nconst BM25_K1 = 0.9;\nconst BM25_B = 0.4;\n\n// Field weights applied to term frequency. Name tokens matter most; the server\n// name gets a modest boost; description is the baseline signal.\nconst NAME_FIELD_WEIGHT = 3;\nconst SERVER_FIELD_WEIGHT = 2;\nconst DESCRIPTION_FIELD_WEIGHT = 1;\n\nexport interface Bm25Doc {\n\t/** Full senpi tool name, e.g. `mcp_docs_get-library-docs`. Returned in results. */\n\treadonly name: string;\n\t/** Bare MCP tool name, e.g. `get-library-docs`. Used for exact-name matching. */\n\treadonly toolName: string;\n\treadonly description?: string;\n\treadonly server: string;\n}\n\nexport interface Bm25Result {\n\treadonly name: string;\n\treadonly score: number;\n\treadonly exact: boolean;\n\treadonly doc: Bm25Doc;\n}\n\nexport interface Bm25SearchOptions {\n\t/** Restrict results to a single server (by server name). */\n\treadonly server?: string;\n\t/** Disable the exact-name short-circuit (used to prove BM25-alone behaviour). */\n\treadonly exactMatch?: boolean;\n}\n\nexport interface Bm25Index {\n\tsearch(query: string, limit?: number, options?: Bm25SearchOptions): Bm25Result[];\n}\n\ninterface IndexedDoc {\n\treadonly doc: Bm25Doc;\n\treadonly termFreq: ReadonlyMap<string, number>;\n\treadonly length: number;\n\treadonly normName: string;\n\treadonly normToolName: string;\n}\n\nconst DEFAULT_LIMIT = 25;\n\nexport function buildBm25Index(docs: readonly Bm25Doc[]): Bm25Index {\n\tconst indexed: IndexedDoc[] = docs.map(indexDoc);\n\tconst docFreq = new Map<string, number>();\n\tfor (const entry of indexed) {\n\t\tfor (const term of entry.termFreq.keys()) {\n\t\t\tdocFreq.set(term, (docFreq.get(term) ?? 0) + 1);\n\t\t}\n\t}\n\tconst totalLength = indexed.reduce((sum, entry) => sum + entry.length, 0);\n\tconst avgLength = indexed.length === 0 ? 0 : totalLength / indexed.length;\n\tconst docCount = indexed.length;\n\n\treturn {\n\t\tsearch(query, limit = DEFAULT_LIMIT, options = {}): Bm25Result[] {\n\t\t\tconst pool =\n\t\t\t\toptions.server === undefined ? indexed : indexed.filter((entry) => entry.doc.server === options.server);\n\t\t\tconst queryTerms = tokenizeToolText(query);\n\t\t\tif (queryTerms.length === 0) return [];\n\n\t\t\tconst useExact = options.exactMatch !== false;\n\t\t\tconst normQuery = normalizeToolName(query);\n\t\t\tconst results: Bm25Result[] = [];\n\t\t\tfor (const entry of pool) {\n\t\t\t\tconst exact = useExact && normQuery.length > 0 && isExactNameMatch(entry, normQuery);\n\t\t\t\tconst score = bm25Score(entry, queryTerms, docFreq, avgLength, docCount);\n\t\t\t\tif (!exact && score <= 0) continue;\n\t\t\t\tresults.push({ doc: entry.doc, exact, name: entry.doc.name, score });\n\t\t\t}\n\t\t\tresults.sort(compareResults);\n\t\t\treturn results.slice(0, Math.max(0, limit));\n\t\t},\n\t};\n}\n\nfunction indexDoc(doc: Bm25Doc): IndexedDoc {\n\tconst termFreq = new Map<string, number>();\n\taddField(termFreq, tokenizeToolText(doc.name), NAME_FIELD_WEIGHT);\n\taddField(termFreq, tokenizeToolText(doc.toolName), NAME_FIELD_WEIGHT);\n\taddField(termFreq, tokenizeToolText(doc.server), SERVER_FIELD_WEIGHT);\n\taddField(termFreq, tokenizeToolText(doc.description ?? \"\"), DESCRIPTION_FIELD_WEIGHT);\n\tlet length = 0;\n\tfor (const count of termFreq.values()) length += count;\n\treturn {\n\t\tdoc,\n\t\tlength,\n\t\tnormName: normalizeToolName(doc.name),\n\t\tnormToolName: normalizeToolName(doc.toolName),\n\t\ttermFreq,\n\t};\n}\n\nfunction addField(termFreq: Map<string, number>, tokens: readonly string[], weight: number): void {\n\tfor (const token of tokens) {\n\t\ttermFreq.set(token, (termFreq.get(token) ?? 0) + weight);\n\t}\n}\n\nfunction bm25Score(\n\tentry: IndexedDoc,\n\tqueryTerms: readonly string[],\n\tdocFreq: ReadonlyMap<string, number>,\n\tavgLength: number,\n\tdocCount: number,\n): number {\n\tlet score = 0;\n\tconst seen = new Set<string>();\n\tfor (const term of queryTerms) {\n\t\tif (seen.has(term)) continue;\n\t\tseen.add(term);\n\t\tconst tf = entry.termFreq.get(term);\n\t\tif (tf === undefined) continue;\n\t\tconst idf = inverseDocFreq(docFreq.get(term) ?? 0, docCount);\n\t\tconst denom = tf + BM25_K1 * (1 - BM25_B + (BM25_B * entry.length) / (avgLength || 1));\n\t\tscore += idf * ((tf * (BM25_K1 + 1)) / (denom || 1));\n\t}\n\treturn score;\n}\n\nfunction inverseDocFreq(termDocFreq: number, docCount: number): number {\n\t// BM25 idf with the standard +1 smoothing; clamped to be non-negative so a\n\t// term present in every doc never contributes a negative score.\n\tconst value = Math.log(1 + (docCount - termDocFreq + 0.5) / (termDocFreq + 0.5));\n\treturn value < 0 ? 0 : value;\n}\n\nfunction isExactNameMatch(entry: IndexedDoc, normQuery: string): boolean {\n\treturn normQuery === entry.normName || normQuery === entry.normToolName;\n}\n\nfunction compareResults(left: Bm25Result, right: Bm25Result): number {\n\tif (left.exact !== right.exact) return left.exact ? -1 : 1;\n\tif (right.score !== left.score) return right.score - left.score;\n\treturn left.name.localeCompare(right.name);\n}\n\n/** Tokenise a tool identifier or description into lowercase word tokens,\n * splitting snake_case, kebab-case and camelCase / PascalCase boundaries. */\nexport function tokenizeToolText(text: string): string[] {\n\tif (text.length === 0) return [];\n\tconst withBoundaries = text\n\t\t// camelCase / PascalCase: insert a space at lower->Upper and Upper->UpperLower boundaries.\n\t\t.replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n\t\t.replace(/([A-Z]+)([A-Z][a-z])/g, \"$1 $2\");\n\tconst tokens: string[] = [];\n\tfor (const raw of withBoundaries.split(/[^a-zA-Z0-9]+/)) {\n\t\tif (raw.length === 0) continue;\n\t\ttokens.push(raw.toLowerCase());\n\t}\n\treturn tokens;\n}\n\n/** Normalise a tool name for exact matching: lowercase, strip separators. */\nexport function normalizeToolName(name: string): string {\n\treturn name.toLowerCase().replace(/[-_\\s]+/g, \"\");\n}\n"]}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export interface LazySearchableTool {
|
|
2
|
-
readonly name: string;
|
|
3
|
-
}
|
|
4
|
-
export interface LazyActivationState {
|
|
5
|
-
readonly searchable: readonly LazySearchableTool[];
|
|
6
|
-
readonly active: readonly string[];
|
|
7
|
-
}
|
|
8
|
-
export interface LazyToolActivatorDeps {
|
|
9
|
-
readonly getSearchable: () => readonly LazySearchableTool[];
|
|
10
|
-
readonly getActiveTools: () => readonly string[];
|
|
11
|
-
readonly activate: (names: readonly string[]) => void;
|
|
12
|
-
}
|
|
13
|
-
export declare function resolveLazyActivationTargets(requested: readonly string[], state: LazyActivationState): readonly string[];
|
|
14
|
-
export declare function createLazyToolActivator(deps: LazyToolActivatorDeps): (toolName: string) => boolean;
|
|
15
|
-
//# sourceMappingURL=lazy-activate.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lazy-activate.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/mcp/expose/lazy-activate.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,UAAU,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACnD,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,aAAa,EAAE,MAAM,SAAS,kBAAkB,EAAE,CAAC;IAC5D,QAAQ,CAAC,cAAc,EAAE,MAAM,SAAS,MAAM,EAAE,CAAC;IACjD,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;CACtD;AAED,wBAAgB,4BAA4B,CAC3C,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,KAAK,EAAE,mBAAmB,GACxB,SAAS,MAAM,EAAE,CASnB;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,qBAAqB,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAUlG"}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
// Lazy tool activation for code-mode (eval) callers.
|
|
2
|
-
//
|
|
3
|
-
// An eval cell that names an MCP tool held inactive by SEARCH-mode exposure used
|
|
4
|
-
// to fail with `inactive_tool`, even though tool_search may promote that exact
|
|
5
|
-
// tool. Eligibility is therefore the tier-B searchable catalog and nothing else:
|
|
6
|
-
// permission-denied tools, `list_changed` rug-pull additions, removed-tool
|
|
7
|
-
// tombstones, and model-gated tools (look_at / read_video) are never eligible.
|
|
8
|
-
// Activation is delegated to the tier-B `activate()` path so stub-swap, name
|
|
9
|
-
// filtering, and active-set ordering keep their existing semantics.
|
|
10
|
-
export function resolveLazyActivationTargets(requested, state) {
|
|
11
|
-
const eligible = new Set(state.searchable.map((tool) => tool.name));
|
|
12
|
-
const active = new Set(state.active);
|
|
13
|
-
const targets = [];
|
|
14
|
-
for (const name of requested) {
|
|
15
|
-
if (!eligible.has(name) || active.has(name) || targets.includes(name))
|
|
16
|
-
continue;
|
|
17
|
-
targets.push(name);
|
|
18
|
-
}
|
|
19
|
-
return targets;
|
|
20
|
-
}
|
|
21
|
-
export function createLazyToolActivator(deps) {
|
|
22
|
-
return (toolName) => {
|
|
23
|
-
const targets = resolveLazyActivationTargets([toolName], {
|
|
24
|
-
searchable: deps.getSearchable(),
|
|
25
|
-
active: deps.getActiveTools(),
|
|
26
|
-
});
|
|
27
|
-
if (targets.length === 0)
|
|
28
|
-
return false;
|
|
29
|
-
deps.activate(targets);
|
|
30
|
-
return true;
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
//# sourceMappingURL=lazy-activate.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lazy-activate.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/mcp/expose/lazy-activate.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,iFAAiF;AACjF,+EAA+E;AAC/E,iFAAiF;AACjF,2EAA2E;AAC3E,+EAA+E;AAC/E,6EAA6E;AAC7E,oEAAoE;AAiBpE,MAAM,UAAU,4BAA4B,CAC3C,SAA4B,EAC5B,KAA0B;IAE1B,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC9B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,SAAS;QAChF,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,IAA2B;IAClE,OAAO,CAAC,QAAgB,EAAW,EAAE;QACpC,MAAM,OAAO,GAAG,4BAA4B,CAAC,CAAC,QAAQ,CAAC,EAAE;YACxD,UAAU,EAAE,IAAI,CAAC,aAAa,EAAE;YAChC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE;SAC7B,CAAC,CAAC;QACH,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACvC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACb,CAAC,CAAC;AACH,CAAC","sourcesContent":["// Lazy tool activation for code-mode (eval) callers.\n//\n// An eval cell that names an MCP tool held inactive by SEARCH-mode exposure used\n// to fail with `inactive_tool`, even though tool_search may promote that exact\n// tool. Eligibility is therefore the tier-B searchable catalog and nothing else:\n// permission-denied tools, `list_changed` rug-pull additions, removed-tool\n// tombstones, and model-gated tools (look_at / read_video) are never eligible.\n// Activation is delegated to the tier-B `activate()` path so stub-swap, name\n// filtering, and active-set ordering keep their existing semantics.\n\nexport interface LazySearchableTool {\n\treadonly name: string;\n}\n\nexport interface LazyActivationState {\n\treadonly searchable: readonly LazySearchableTool[];\n\treadonly active: readonly string[];\n}\n\nexport interface LazyToolActivatorDeps {\n\treadonly getSearchable: () => readonly LazySearchableTool[];\n\treadonly getActiveTools: () => readonly string[];\n\treadonly activate: (names: readonly string[]) => void;\n}\n\nexport function resolveLazyActivationTargets(\n\trequested: readonly string[],\n\tstate: LazyActivationState,\n): readonly string[] {\n\tconst eligible = new Set(state.searchable.map((tool) => tool.name));\n\tconst active = new Set(state.active);\n\tconst targets: string[] = [];\n\tfor (const name of requested) {\n\t\tif (!eligible.has(name) || active.has(name) || targets.includes(name)) continue;\n\t\ttargets.push(name);\n\t}\n\treturn targets;\n}\n\nexport function createLazyToolActivator(deps: LazyToolActivatorDeps): (toolName: string) => boolean {\n\treturn (toolName: string): boolean => {\n\t\tconst targets = resolveLazyActivationTargets([toolName], {\n\t\t\tsearchable: deps.getSearchable(),\n\t\t\tactive: deps.getActiveTools(),\n\t\t});\n\t\tif (targets.length === 0) return false;\n\t\tdeps.activate(targets);\n\t\treturn true;\n\t};\n}\n"]}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { Type } from "typebox";
|
|
2
|
-
import type { ToolDefinition } from "../../../types.ts";
|
|
3
|
-
import { type Bm25Doc } from "./bm25.ts";
|
|
4
|
-
export declare const TOOL_SEARCH_TOOL_NAME = "tool_search";
|
|
5
|
-
/** Stable, machine-parseable marker embedded in every activating result so
|
|
6
|
-
* activations survive compaction/restart. Kept human-readable on purpose. */
|
|
7
|
-
export declare const TOOL_SEARCH_ACTIVATION_MARKER = "[tool_search:activated]";
|
|
8
|
-
export type SearchableMcpTool = Bm25Doc;
|
|
9
|
-
export interface McpSearchDeps {
|
|
10
|
-
/** Full current catalog (all MCP tools, active or not) to rank over. */
|
|
11
|
-
getSearchableTools(): readonly SearchableMcpTool[];
|
|
12
|
-
/** Current active tool names (includes non-MCP tools). */
|
|
13
|
-
getActiveTools(): string[];
|
|
14
|
-
/** Replace the active set. Implementations should preserve registration. */
|
|
15
|
-
setActiveTools(names: readonly string[]): void;
|
|
16
|
-
}
|
|
17
|
-
export interface McpSearchDetails {
|
|
18
|
-
query: string;
|
|
19
|
-
activated: string[];
|
|
20
|
-
}
|
|
21
|
-
declare const ParamsSchema: Type.TObject<{
|
|
22
|
-
query: Type.TString;
|
|
23
|
-
server: Type.TOptional<Type.TString>;
|
|
24
|
-
}>;
|
|
25
|
-
type McpSearchTool = ToolDefinition<typeof ParamsSchema, McpSearchDetails, unknown>;
|
|
26
|
-
export declare function createMcpSearchTool(deps: McpSearchDeps): McpSearchTool;
|
|
27
|
-
interface RankedMatch {
|
|
28
|
-
readonly name: string;
|
|
29
|
-
readonly doc: SearchableMcpTool;
|
|
30
|
-
}
|
|
31
|
-
export declare function buildMcpSearchResultText(query: string, matches: readonly RankedMatch[], server: string | undefined): string;
|
|
32
|
-
/**
|
|
33
|
-
* Replay tool_search activations recorded in prior history so a
|
|
34
|
-
* compacted/restarted session restores its active tool set without re-searching.
|
|
35
|
-
* Only names still present in `validNames` are restored (removed tools stay
|
|
36
|
-
* dropped). Deterministic: returns a de-duplicated, sorted list.
|
|
37
|
-
*/
|
|
38
|
-
export declare function rehydrateActiveToolsFromHistory(messages: readonly unknown[], validNames: ReadonlySet<string>): string[];
|
|
39
|
-
/** Stable union: dedupe and sort so the active-tools array is byte-stable
|
|
40
|
-
* across turns (prompt-cache friendly). */
|
|
41
|
-
export declare function unionStable(current: readonly string[], added: readonly string[]): string[];
|
|
42
|
-
export {};
|
|
43
|
-
//# sourceMappingURL=tool-search.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tool-search.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/mcp/expose/tool-search.ts"],"names":[],"mappings":"AAYA,OAAO,EAAe,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,KAAK,OAAO,EAAkB,MAAM,WAAW,CAAC;AAEzD,eAAO,MAAM,qBAAqB,gBAAgB,CAAC;AACnD;6EAC6E;AAC7E,eAAO,MAAM,6BAA6B,4BAA4B,CAAC;AAGvE,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC;AAExC,MAAM,WAAW,aAAa;IAC7B,wEAAwE;IACxE,kBAAkB,IAAI,SAAS,iBAAiB,EAAE,CAAC;IACnD,0DAA0D;IAC1D,cAAc,IAAI,MAAM,EAAE,CAAC;IAC3B,4EAA4E;IAC5E,cAAc,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;CAC/C;AAED,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,QAAA,MAAM,YAAY;;;EAGhB,CAAC;AAGH,KAAK,aAAa,GAAG,cAAc,CAAC,OAAO,YAAY,EAAE,gBAAgB,EAAE,OAAO,CAAC,CAAC;AAEpF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,aAAa,GAAG,aAAa,CAmCtE;AAED,UAAU,WAAW;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,iBAAiB,CAAC;CAChC;AAED,wBAAgB,wBAAwB,CACvC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,SAAS,WAAW,EAAE,EAC/B,MAAM,EAAE,MAAM,GAAG,SAAS,GACxB,MAAM,CAgBR;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC9C,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,GAC7B,MAAM,EAAE,CAUV;AAsBD;2CAC2C;AAC3C,wBAAgB,WAAW,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAE1F"}
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
// tool_search tool + promotion engine (todo 31).
|
|
2
|
-
//
|
|
3
|
-
// `tool_search` is an always-active tool that ranks the full MCP catalog with
|
|
4
|
-
// the local BM25 engine and PROMOTES matched tools into the active set via
|
|
5
|
-
// setActiveTools (effective the NEXT turn — senpi semantics). Promotion state
|
|
6
|
-
// is derivable from history: each result embeds a stable activation marker so a
|
|
7
|
-
// compaction/restart can replay activations at session_start
|
|
8
|
-
// (rehydrateActiveToolsFromHistory). Activated tools persist for the session;
|
|
9
|
-
// there is no auto-eviction in v1. Every setActiveTools call is stable-sorted.
|
|
10
|
-
import { Text } from "@earendil-works/pi-tui";
|
|
11
|
-
import { Type } from "typebox";
|
|
12
|
-
import { buildBm25Index } from "./bm25.js";
|
|
13
|
-
export const TOOL_SEARCH_TOOL_NAME = "tool_search";
|
|
14
|
-
/** Stable, machine-parseable marker embedded in every activating result so
|
|
15
|
-
* activations survive compaction/restart. Kept human-readable on purpose. */
|
|
16
|
-
export const TOOL_SEARCH_ACTIVATION_MARKER = "[tool_search:activated]";
|
|
17
|
-
const MAX_RESULTS = 10;
|
|
18
|
-
const ParamsSchema = Type.Object({
|
|
19
|
-
query: Type.String({ description: "Natural-language description of the capability you need." }),
|
|
20
|
-
server: Type.Optional(Type.String({ description: "Optional: restrict the search to a single MCP server name." })),
|
|
21
|
-
});
|
|
22
|
-
export function createMcpSearchTool(deps) {
|
|
23
|
-
return {
|
|
24
|
-
name: TOOL_SEARCH_TOOL_NAME,
|
|
25
|
-
label: "MCP tool search",
|
|
26
|
-
description: "Search the catalog of available MCP tools by capability. Matched tools are activated and become callable on your NEXT turn. Use this before calling an MCP tool that is not already active.",
|
|
27
|
-
promptSnippet: "Search MCP servers for a tool by capability; matched tools activate next turn.",
|
|
28
|
-
parameters: ParamsSchema,
|
|
29
|
-
executionMode: "parallel",
|
|
30
|
-
async execute(_toolCallId, params) {
|
|
31
|
-
const searchable = deps.getSearchableTools();
|
|
32
|
-
const index = buildBm25Index(searchable);
|
|
33
|
-
const matches = index.search(params.query, MAX_RESULTS, params.server ? { server: params.server } : {});
|
|
34
|
-
const activated = matches.map((match) => match.name);
|
|
35
|
-
if (activated.length > 0) {
|
|
36
|
-
deps.setActiveTools(unionStable(deps.getActiveTools(), activated));
|
|
37
|
-
}
|
|
38
|
-
const text = buildMcpSearchResultText(params.query, matches, params.server);
|
|
39
|
-
return {
|
|
40
|
-
content: [{ type: "text", text }],
|
|
41
|
-
details: { activated, query: params.query },
|
|
42
|
-
};
|
|
43
|
-
},
|
|
44
|
-
renderCall(args, theme) {
|
|
45
|
-
const filter = args.server ? ` @${args.server}` : "";
|
|
46
|
-
return new Text(theme.fg("toolTitle", theme.bold(`${TOOL_SEARCH_TOOL_NAME} "${args.query}"${filter}`)), 0, 0);
|
|
47
|
-
},
|
|
48
|
-
renderResult(result, options, theme) {
|
|
49
|
-
const count = result.details?.activated.length ?? 0;
|
|
50
|
-
const title = options.isPartial
|
|
51
|
-
? `${TOOL_SEARCH_TOOL_NAME}: searching`
|
|
52
|
-
: `${TOOL_SEARCH_TOOL_NAME}: ${count} tool(s) activated`;
|
|
53
|
-
return new Text(theme.fg("toolOutput", title), 0, 0);
|
|
54
|
-
},
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
export function buildMcpSearchResultText(query, matches, server) {
|
|
58
|
-
const scope = server ? ` on server "${server}"` : "";
|
|
59
|
-
if (matches.length === 0) {
|
|
60
|
-
return `No MCP tools matched "${query}"${scope}. No tools were activated; try different keywords or run tool_search with a broader query. Your active tool set is unchanged.`;
|
|
61
|
-
}
|
|
62
|
-
const bullets = matches
|
|
63
|
-
.map((match) => `- ${match.name} — ${oneLine(match.doc.description) ?? "(no description)"}`)
|
|
64
|
-
.join("\n");
|
|
65
|
-
const names = matches.map((match) => match.name).join(" ");
|
|
66
|
-
return [
|
|
67
|
-
`Found ${matches.length} MCP tool(s) matching "${query}"${scope}. They are now active and callable from your NEXT turn:`,
|
|
68
|
-
"",
|
|
69
|
-
bullets,
|
|
70
|
-
"",
|
|
71
|
-
`${TOOL_SEARCH_ACTIVATION_MARKER} ${names}`,
|
|
72
|
-
].join("\n");
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Replay tool_search activations recorded in prior history so a
|
|
76
|
-
* compacted/restarted session restores its active tool set without re-searching.
|
|
77
|
-
* Only names still present in `validNames` are restored (removed tools stay
|
|
78
|
-
* dropped). Deterministic: returns a de-duplicated, sorted list.
|
|
79
|
-
*/
|
|
80
|
-
export function rehydrateActiveToolsFromHistory(messages, validNames) {
|
|
81
|
-
const restored = new Set();
|
|
82
|
-
for (const message of messages) {
|
|
83
|
-
for (const segment of extractActivationSegments(message)) {
|
|
84
|
-
for (const name of segment.trim().split(/\s+/)) {
|
|
85
|
-
if (name.length > 0 && validNames.has(name))
|
|
86
|
-
restored.add(name);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return [...restored].sort();
|
|
91
|
-
}
|
|
92
|
-
function extractActivationSegments(message) {
|
|
93
|
-
let blob;
|
|
94
|
-
try {
|
|
95
|
-
blob = JSON.stringify(message) ?? "";
|
|
96
|
-
}
|
|
97
|
-
catch {
|
|
98
|
-
return [];
|
|
99
|
-
}
|
|
100
|
-
const segments = [];
|
|
101
|
-
let cursor = blob.indexOf(TOOL_SEARCH_ACTIVATION_MARKER);
|
|
102
|
-
while (cursor >= 0) {
|
|
103
|
-
const rest = blob.slice(cursor + TOOL_SEARCH_ACTIVATION_MARKER.length);
|
|
104
|
-
// Tool names are [a-zA-Z0-9_-]; stop at the first JSON string terminator
|
|
105
|
-
// (quote / escape) or newline so we never swallow the rest of the blob.
|
|
106
|
-
const end = rest.search(/["\\\n]/);
|
|
107
|
-
segments.push(end < 0 ? rest : rest.slice(0, end));
|
|
108
|
-
cursor = blob.indexOf(TOOL_SEARCH_ACTIVATION_MARKER, cursor + TOOL_SEARCH_ACTIVATION_MARKER.length);
|
|
109
|
-
}
|
|
110
|
-
return segments;
|
|
111
|
-
}
|
|
112
|
-
/** Stable union: dedupe and sort so the active-tools array is byte-stable
|
|
113
|
-
* across turns (prompt-cache friendly). */
|
|
114
|
-
export function unionStable(current, added) {
|
|
115
|
-
return [...new Set([...current, ...added])].sort();
|
|
116
|
-
}
|
|
117
|
-
function oneLine(text) {
|
|
118
|
-
if (text === undefined)
|
|
119
|
-
return undefined;
|
|
120
|
-
const collapsed = text.replace(/\s+/g, " ").trim();
|
|
121
|
-
if (collapsed.length === 0)
|
|
122
|
-
return undefined;
|
|
123
|
-
return collapsed.length <= 100 ? collapsed : `${collapsed.slice(0, 97)}...`;
|
|
124
|
-
}
|
|
125
|
-
//# sourceMappingURL=tool-search.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tool-search.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/mcp/expose/tool-search.ts"],"names":[],"mappings":"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","sourcesContent":["// tool_search tool + promotion engine (todo 31).\n//\n// `tool_search` is an always-active tool that ranks the full MCP catalog with\n// the local BM25 engine and PROMOTES matched tools into the active set via\n// setActiveTools (effective the NEXT turn — senpi semantics). Promotion state\n// is derivable from history: each result embeds a stable activation marker so a\n// compaction/restart can replay activations at session_start\n// (rehydrateActiveToolsFromHistory). Activated tools persist for the session;\n// there is no auto-eviction in v1. Every setActiveTools call is stable-sorted.\n\nimport type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport { Text } from \"@earendil-works/pi-tui\";\nimport { type Static, Type } from \"typebox\";\nimport type { ToolDefinition } from \"../../../types.ts\";\nimport { type Bm25Doc, buildBm25Index } from \"./bm25.ts\";\n\nexport const TOOL_SEARCH_TOOL_NAME = \"tool_search\";\n/** Stable, machine-parseable marker embedded in every activating result so\n * activations survive compaction/restart. Kept human-readable on purpose. */\nexport const TOOL_SEARCH_ACTIVATION_MARKER = \"[tool_search:activated]\";\nconst MAX_RESULTS = 10;\n\nexport type SearchableMcpTool = Bm25Doc;\n\nexport interface McpSearchDeps {\n\t/** Full current catalog (all MCP tools, active or not) to rank over. */\n\tgetSearchableTools(): readonly SearchableMcpTool[];\n\t/** Current active tool names (includes non-MCP tools). */\n\tgetActiveTools(): string[];\n\t/** Replace the active set. Implementations should preserve registration. */\n\tsetActiveTools(names: readonly string[]): void;\n}\n\nexport interface McpSearchDetails {\n\tquery: string;\n\tactivated: string[];\n}\n\nconst ParamsSchema = Type.Object({\n\tquery: Type.String({ description: \"Natural-language description of the capability you need.\" }),\n\tserver: Type.Optional(Type.String({ description: \"Optional: restrict the search to a single MCP server name.\" })),\n});\ntype Params = Static<typeof ParamsSchema>;\n\ntype McpSearchTool = ToolDefinition<typeof ParamsSchema, McpSearchDetails, unknown>;\n\nexport function createMcpSearchTool(deps: McpSearchDeps): McpSearchTool {\n\treturn {\n\t\tname: TOOL_SEARCH_TOOL_NAME,\n\t\tlabel: \"MCP tool search\",\n\t\tdescription:\n\t\t\t\"Search the catalog of available MCP tools by capability. Matched tools are activated and become callable on your NEXT turn. Use this before calling an MCP tool that is not already active.\",\n\t\tpromptSnippet: \"Search MCP servers for a tool by capability; matched tools activate next turn.\",\n\t\tparameters: ParamsSchema,\n\t\texecutionMode: \"parallel\",\n\t\tasync execute(_toolCallId, params: Params): Promise<AgentToolResult<McpSearchDetails>> {\n\t\t\tconst searchable = deps.getSearchableTools();\n\t\t\tconst index = buildBm25Index(searchable);\n\t\t\tconst matches = index.search(params.query, MAX_RESULTS, params.server ? { server: params.server } : {});\n\t\t\tconst activated = matches.map((match) => match.name);\n\t\t\tif (activated.length > 0) {\n\t\t\t\tdeps.setActiveTools(unionStable(deps.getActiveTools(), activated));\n\t\t\t}\n\t\t\tconst text = buildMcpSearchResultText(params.query, matches, params.server);\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text }],\n\t\t\t\tdetails: { activated, query: params.query },\n\t\t\t};\n\t\t},\n\t\trenderCall(args, theme) {\n\t\t\tconst filter = args.server ? ` @${args.server}` : \"\";\n\t\t\treturn new Text(theme.fg(\"toolTitle\", theme.bold(`${TOOL_SEARCH_TOOL_NAME} \"${args.query}\"${filter}`)), 0, 0);\n\t\t},\n\t\trenderResult(result, options, theme) {\n\t\t\tconst count = result.details?.activated.length ?? 0;\n\t\t\tconst title = options.isPartial\n\t\t\t\t? `${TOOL_SEARCH_TOOL_NAME}: searching`\n\t\t\t\t: `${TOOL_SEARCH_TOOL_NAME}: ${count} tool(s) activated`;\n\t\t\treturn new Text(theme.fg(\"toolOutput\", title), 0, 0);\n\t\t},\n\t};\n}\n\ninterface RankedMatch {\n\treadonly name: string;\n\treadonly doc: SearchableMcpTool;\n}\n\nexport function buildMcpSearchResultText(\n\tquery: string,\n\tmatches: readonly RankedMatch[],\n\tserver: string | undefined,\n): string {\n\tconst scope = server ? ` on server \"${server}\"` : \"\";\n\tif (matches.length === 0) {\n\t\treturn `No MCP tools matched \"${query}\"${scope}. No tools were activated; try different keywords or run tool_search with a broader query. Your active tool set is unchanged.`;\n\t}\n\tconst bullets = matches\n\t\t.map((match) => `- ${match.name} — ${oneLine(match.doc.description) ?? \"(no description)\"}`)\n\t\t.join(\"\\n\");\n\tconst names = matches.map((match) => match.name).join(\" \");\n\treturn [\n\t\t`Found ${matches.length} MCP tool(s) matching \"${query}\"${scope}. They are now active and callable from your NEXT turn:`,\n\t\t\"\",\n\t\tbullets,\n\t\t\"\",\n\t\t`${TOOL_SEARCH_ACTIVATION_MARKER} ${names}`,\n\t].join(\"\\n\");\n}\n\n/**\n * Replay tool_search activations recorded in prior history so a\n * compacted/restarted session restores its active tool set without re-searching.\n * Only names still present in `validNames` are restored (removed tools stay\n * dropped). Deterministic: returns a de-duplicated, sorted list.\n */\nexport function rehydrateActiveToolsFromHistory(\n\tmessages: readonly unknown[],\n\tvalidNames: ReadonlySet<string>,\n): string[] {\n\tconst restored = new Set<string>();\n\tfor (const message of messages) {\n\t\tfor (const segment of extractActivationSegments(message)) {\n\t\t\tfor (const name of segment.trim().split(/\\s+/)) {\n\t\t\t\tif (name.length > 0 && validNames.has(name)) restored.add(name);\n\t\t\t}\n\t\t}\n\t}\n\treturn [...restored].sort();\n}\n\nfunction extractActivationSegments(message: unknown): string[] {\n\tlet blob: string;\n\ttry {\n\t\tblob = JSON.stringify(message) ?? \"\";\n\t} catch {\n\t\treturn [];\n\t}\n\tconst segments: string[] = [];\n\tlet cursor = blob.indexOf(TOOL_SEARCH_ACTIVATION_MARKER);\n\twhile (cursor >= 0) {\n\t\tconst rest = blob.slice(cursor + TOOL_SEARCH_ACTIVATION_MARKER.length);\n\t\t// Tool names are [a-zA-Z0-9_-]; stop at the first JSON string terminator\n\t\t// (quote / escape) or newline so we never swallow the rest of the blob.\n\t\tconst end = rest.search(/[\"\\\\\\n]/);\n\t\tsegments.push(end < 0 ? rest : rest.slice(0, end));\n\t\tcursor = blob.indexOf(TOOL_SEARCH_ACTIVATION_MARKER, cursor + TOOL_SEARCH_ACTIVATION_MARKER.length);\n\t}\n\treturn segments;\n}\n\n/** Stable union: dedupe and sort so the active-tools array is byte-stable\n * across turns (prompt-cache friendly). */\nexport function unionStable(current: readonly string[], added: readonly string[]): string[] {\n\treturn [...new Set([...current, ...added])].sort();\n}\n\nfunction oneLine(text: string | undefined): string | undefined {\n\tif (text === undefined) return undefined;\n\tconst collapsed = text.replace(/\\s+/g, \" \").trim();\n\tif (collapsed.length === 0) return undefined;\n\treturn collapsed.length <= 100 ? collapsed : `${collapsed.slice(0, 97)}...`;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"omo-native-detect.d.ts","sourceRoot":"","sources":["../../src/core/omo-native-detect.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AA+B3D,wBAAgB,sBAAsB,CACrC,QAAQ,EAAE,aAAa,EAAE,GAAG,SAAS,EACrC,QAAQ,EAAE,MAAM,EAChB,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GACnD,OAAO,CA+BT"}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
-
import { homedir } from "node:os";
|
|
3
|
-
import { join, resolve } from "node:path";
|
|
4
|
-
import { isLocalPath, resolvePath } from "../utils/paths.js";
|
|
5
|
-
/**
|
|
6
|
-
* Synchronous, dependency-free detection of the "OMO Native" local install: a settings
|
|
7
|
-
* `packages` entry that is a local path resolving to a dir whose package.json name is
|
|
8
|
-
* `@code-yeongyu/omo-senpi`, whose derived repo root (pluginPath/../../..) contains both
|
|
9
|
-
* workspace packages `@oh-my-opencode/omo-senpi` and `@oh-my-opencode/senpi-task`.
|
|
10
|
-
*
|
|
11
|
-
* This mirrors gates 1 and 2 of the beta `detectOmoLocalInstall` (beta/omo-local-update.ts)
|
|
12
|
-
* but drops gate 3 (the `git rev-parse --show-toplevel` integrity check) so it stays sync and
|
|
13
|
-
* cheap enough for footer rendering. The beta module's export policy forbids importing its
|
|
14
|
-
* helpers into production core, so this isolated module is the footer's own detection.
|
|
15
|
-
*/
|
|
16
|
-
const OMO_SENPI_PLUGIN_PACKAGE = "@code-yeongyu/omo-senpi";
|
|
17
|
-
const OMO_SENPI_WORKSPACE_PACKAGE = "@oh-my-opencode/omo-senpi";
|
|
18
|
-
const SENPI_TASK_WORKSPACE_PACKAGE = "@oh-my-opencode/senpi-task";
|
|
19
|
-
function homeDir() {
|
|
20
|
-
return process.env.HOME || homedir();
|
|
21
|
-
}
|
|
22
|
-
function readPackageName(packageJsonPath) {
|
|
23
|
-
try {
|
|
24
|
-
const json = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
25
|
-
const name = json.name;
|
|
26
|
-
return typeof name === "string" ? name : undefined;
|
|
27
|
-
}
|
|
28
|
-
catch {
|
|
29
|
-
return undefined;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
export function detectOmoNativeInstall(packages, agentDir, env = process.env) {
|
|
33
|
-
// The omo launcher marks every senpi spawn it owns; omo-ai global installs load the plugin via
|
|
34
|
-
// --extension, so no settings.packages entry ever exists for them and the env marker is the only
|
|
35
|
-
// signal available at footer-render time.
|
|
36
|
-
if (env.OMO_NATIVE === "1") {
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
if (!packages) {
|
|
40
|
-
return false;
|
|
41
|
-
}
|
|
42
|
-
for (const entry of packages) {
|
|
43
|
-
const source = typeof entry === "string" ? entry : entry.source;
|
|
44
|
-
if (!isLocalPath(source)) {
|
|
45
|
-
continue;
|
|
46
|
-
}
|
|
47
|
-
const pluginPath = resolvePath(source, agentDir, { homeDir: homeDir(), trim: true });
|
|
48
|
-
if (readPackageName(join(pluginPath, "package.json")) !== OMO_SENPI_PLUGIN_PACKAGE) {
|
|
49
|
-
continue;
|
|
50
|
-
}
|
|
51
|
-
const repoRoot = resolve(pluginPath, "..", "..", "..");
|
|
52
|
-
const omoSenpiPkg = join(repoRoot, "packages", "omo-senpi", "package.json");
|
|
53
|
-
if (!existsSync(omoSenpiPkg) || readPackageName(omoSenpiPkg) !== OMO_SENPI_WORKSPACE_PACKAGE) {
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
const senpiTaskPkg = join(repoRoot, "packages", "senpi-task", "package.json");
|
|
57
|
-
if (!existsSync(senpiTaskPkg) || readPackageName(senpiTaskPkg) !== SENPI_TASK_WORKSPACE_PACKAGE) {
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
return true;
|
|
61
|
-
}
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
//# sourceMappingURL=omo-native-detect.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"omo-native-detect.js","sourceRoot":"","sources":["../../src/core/omo-native-detect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAG7D;;;;;;;;;;GAUG;AACH,MAAM,wBAAwB,GAAG,yBAAyB,CAAC;AAC3D,MAAM,2BAA2B,GAAG,2BAA2B,CAAC;AAChE,MAAM,4BAA4B,GAAG,4BAA4B,CAAC;AAElE,SAAS,OAAO;IACf,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,EAAE,CAAC;AACtC,CAAC;AAED,SAAS,eAAe,CAAC,eAAuB;IAC/C,IAAI,CAAC;QACJ,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAuB,CAAC;QACtF,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC;AAED,MAAM,UAAU,sBAAsB,CACrC,QAAqC,EACrC,QAAgB,EAChB,GAAG,GAAuC,OAAO,CAAC,GAAG;IAErD,+FAA+F;IAC/F,iGAAiG;IACjG,0CAA0C;IAC1C,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC;IACb,CAAC;IACD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,OAAO,KAAK,CAAC;IACd,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;QAChE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,SAAS;QACV,CAAC;QACD,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACrF,IAAI,eAAe,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,KAAK,wBAAwB,EAAE,CAAC;YACpF,SAAS;QACV,CAAC;QACD,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACvD,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;QAC5E,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,eAAe,CAAC,WAAW,CAAC,KAAK,2BAA2B,EAAE,CAAC;YAC9F,SAAS;QACV,CAAC;QACD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC;QAC9E,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,eAAe,CAAC,YAAY,CAAC,KAAK,4BAA4B,EAAE,CAAC;YACjG,SAAS;QACV,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport { isLocalPath, resolvePath } from \"../utils/paths.ts\";\nimport type { PackageSource } from \"./settings-manager.ts\";\n\n/**\n * Synchronous, dependency-free detection of the \"OMO Native\" local install: a settings\n * `packages` entry that is a local path resolving to a dir whose package.json name is\n * `@code-yeongyu/omo-senpi`, whose derived repo root (pluginPath/../../..) contains both\n * workspace packages `@oh-my-opencode/omo-senpi` and `@oh-my-opencode/senpi-task`.\n *\n * This mirrors gates 1 and 2 of the beta `detectOmoLocalInstall` (beta/omo-local-update.ts)\n * but drops gate 3 (the `git rev-parse --show-toplevel` integrity check) so it stays sync and\n * cheap enough for footer rendering. The beta module's export policy forbids importing its\n * helpers into production core, so this isolated module is the footer's own detection.\n */\nconst OMO_SENPI_PLUGIN_PACKAGE = \"@code-yeongyu/omo-senpi\";\nconst OMO_SENPI_WORKSPACE_PACKAGE = \"@oh-my-opencode/omo-senpi\";\nconst SENPI_TASK_WORKSPACE_PACKAGE = \"@oh-my-opencode/senpi-task\";\n\nfunction homeDir(): string {\n\treturn process.env.HOME || homedir();\n}\n\nfunction readPackageName(packageJsonPath: string): string | undefined {\n\ttry {\n\t\tconst json = JSON.parse(readFileSync(packageJsonPath, \"utf-8\")) as { name?: unknown };\n\t\tconst name = json.name;\n\t\treturn typeof name === \"string\" ? name : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function detectOmoNativeInstall(\n\tpackages: PackageSource[] | undefined,\n\tagentDir: string,\n\tenv: Record<string, string | undefined> = process.env,\n): boolean {\n\t// The omo launcher marks every senpi spawn it owns; omo-ai global installs load the plugin via\n\t// --extension, so no settings.packages entry ever exists for them and the env marker is the only\n\t// signal available at footer-render time.\n\tif (env.OMO_NATIVE === \"1\") {\n\t\treturn true;\n\t}\n\tif (!packages) {\n\t\treturn false;\n\t}\n\tfor (const entry of packages) {\n\t\tconst source = typeof entry === \"string\" ? entry : entry.source;\n\t\tif (!isLocalPath(source)) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst pluginPath = resolvePath(source, agentDir, { homeDir: homeDir(), trim: true });\n\t\tif (readPackageName(join(pluginPath, \"package.json\")) !== OMO_SENPI_PLUGIN_PACKAGE) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst repoRoot = resolve(pluginPath, \"..\", \"..\", \"..\");\n\t\tconst omoSenpiPkg = join(repoRoot, \"packages\", \"omo-senpi\", \"package.json\");\n\t\tif (!existsSync(omoSenpiPkg) || readPackageName(omoSenpiPkg) !== OMO_SENPI_WORKSPACE_PACKAGE) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst senpiTaskPkg = join(repoRoot, \"packages\", \"senpi-task\", \"package.json\");\n\t\tif (!existsSync(senpiTaskPkg) || readPackageName(senpiTaskPkg) !== SENPI_TASK_WORKSPACE_PACKAGE) {\n\t\t\tcontinue;\n\t\t}\n\t\treturn true;\n\t}\n\treturn false;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"omo-native-detect.test.d.ts","sourceRoot":"","sources":["../../src/core/omo-native-detect.test.ts"],"names":[],"mappings":""}
|