@ashx-j/lunr 0.2.26 → 0.2.27
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 +16 -1
- package/LICENSE +22 -0
- package/dist/builtin-extensions/ashxj-thinking.d.ts +1 -1
- package/dist/builtin-extensions/ashxj-thinking.d.ts.map +1 -1
- package/dist/builtin-extensions/ashxj-thinking.js +1 -1
- package/dist/builtin-extensions/ashxj-thinking.js.map +1 -1
- package/dist/builtin-extensions/ashxj-tui.d.ts +11 -1
- package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
- package/dist/builtin-extensions/ashxj-tui.js +6 -10
- package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
- package/dist/builtin-extensions/lunr-cron.d.ts +4 -5
- package/dist/builtin-extensions/lunr-cron.d.ts.map +1 -1
- package/dist/builtin-extensions/lunr-cron.js +94 -108
- package/dist/builtin-extensions/lunr-cron.js.map +1 -1
- package/dist/builtin-extensions/lunr-local-providers/local-servers.d.ts.map +1 -1
- package/dist/builtin-extensions/lunr-local-providers/local-servers.js +3 -1
- package/dist/builtin-extensions/lunr-local-providers/local-servers.js.map +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.d.ts.map +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.js +2 -2
- package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.js.map +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.d.ts.map +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js.map +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.d.ts.map +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.js +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.js.map +1 -1
- package/dist/builtin-extensions/pi-intercom/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-intercom/index.js +2 -2
- package/dist/builtin-extensions/pi-intercom/index.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.d.ts +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.js +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/index.js +1 -15
- package/dist/builtin-extensions/pi-lsp-extension/src/index.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.d.ts +6 -0
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.js +187 -132
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.d.ts +8 -0
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.js +142 -112
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.d.ts +12 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.js +14 -7
- package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.d.ts +11 -3
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.js +67 -41
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.d.ts +4 -2
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.js +3 -0
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/commands.d.ts +2 -1
- package/dist/builtin-extensions/pi-mcp-adapter/commands.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/commands.js +6 -6
- package/dist/builtin-extensions/pi-mcp-adapter/commands.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/config.d.ts +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/config.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/config.js +11 -5
- package/dist/builtin-extensions/pi-mcp-adapter/config.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js +2 -2
- package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.js +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/index.js +48 -40
- package/dist/builtin-extensions/pi-mcp-adapter/index.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/init.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/init.js +3 -1
- package/dist/builtin-extensions/pi-mcp-adapter/init.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.d.ts +12 -40
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.js +166 -235
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.d.ts +5 -0
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.js +43 -13
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.d.ts +14 -3
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.js +73 -21
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.js +4 -4
- package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/server-manager.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js +2 -2
- package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/state.d.ts +2 -0
- package/dist/builtin-extensions/pi-mcp-adapter/state.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/state.js.map +1 -1
- package/dist/builtin-extensions/pi-ollama-cloud/index.d.ts +1 -1
- package/dist/builtin-extensions/pi-ollama-cloud/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-ollama-cloud/index.js +1 -1
- package/dist/builtin-extensions/pi-ollama-cloud/index.js.map +1 -1
- package/dist/builtin-extensions/pi-ollama-cloud/models.d.ts +11 -5
- package/dist/builtin-extensions/pi-ollama-cloud/models.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-ollama-cloud/models.js +12 -32
- package/dist/builtin-extensions/pi-ollama-cloud/models.js.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/index.js +5 -3
- package/dist/builtin-extensions/pi-prompt-template-model/index.js.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts +2 -1
- package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js +21 -12
- package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js +7 -24
- package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js +39 -77
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js +15 -31
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js +7 -2
- package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +10 -2
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +8 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +106 -24
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +25 -5
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts +7 -8
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js +60 -32
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/utils.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/utils.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/utils.js +15 -5
- package/dist/builtin-extensions/pi-subagents/src/shared/utils.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js +4 -3
- package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js +17 -8
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/watchdog/review.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js +3 -3
- package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js.map +1 -1
- package/dist/builtin-extensions/pi-tps.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-tps.js +20 -17
- package/dist/builtin-extensions/pi-tps.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/activity.d.ts +1 -0
- package/dist/builtin-extensions/pi-web-access/activity.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/activity.js +27 -5
- package/dist/builtin-extensions/pi-web-access/activity.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/bounded-body.d.ts +3 -0
- package/dist/builtin-extensions/pi-web-access/bounded-body.d.ts.map +1 -0
- package/dist/builtin-extensions/pi-web-access/bounded-body.js +43 -0
- package/dist/builtin-extensions/pi-web-access/bounded-body.js.map +1 -0
- package/dist/builtin-extensions/pi-web-access/content-page.d.ts +24 -0
- package/dist/builtin-extensions/pi-web-access/content-page.d.ts.map +1 -0
- package/dist/builtin-extensions/pi-web-access/content-page.js +57 -0
- package/dist/builtin-extensions/pi-web-access/content-page.js.map +1 -0
- package/dist/builtin-extensions/pi-web-access/extract.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/extract.js +7 -2
- package/dist/builtin-extensions/pi-web-access/extract.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/github-extract.d.ts +0 -1
- package/dist/builtin-extensions/pi-web-access/github-extract.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/github-extract.js +147 -36
- package/dist/builtin-extensions/pi-web-access/github-extract.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/index.js +48 -73
- package/dist/builtin-extensions/pi-web-access/index.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts +12 -4
- package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/session-cleanup.js +35 -12
- package/dist/builtin-extensions/pi-web-access/session-cleanup.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/storage.d.ts +9 -6
- package/dist/builtin-extensions/pi-web-access/storage.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/storage.js +36 -24
- package/dist/builtin-extensions/pi-web-access/storage.js.map +1 -1
- package/dist/builtin-extensions/simple-pi-memory.d.ts +1 -1
- package/dist/builtin-extensions/simple-pi-memory.d.ts.map +1 -1
- package/dist/builtin-extensions/simple-pi-memory.js +1 -1
- package/dist/builtin-extensions/simple-pi-memory.js.map +1 -1
- package/dist/cli/install-cli.d.ts.map +1 -1
- package/dist/cli/install-cli.js +38 -30
- package/dist/cli/install-cli.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts +13 -0
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +75 -11
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +1 -0
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +1 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +40 -6
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +309 -76
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/browser/runtime.d.ts +2 -0
- package/dist/core/browser/runtime.d.ts.map +1 -1
- package/dist/core/browser/runtime.js +80 -45
- package/dist/core/browser/runtime.js.map +1 -1
- package/dist/core/browser/setup.d.ts.map +1 -1
- package/dist/core/browser/setup.js +12 -1
- package/dist/core/browser/setup.js.map +1 -1
- package/dist/core/computer-use/adapter.d.ts.map +1 -1
- package/dist/core/computer-use/adapter.js +7 -2
- package/dist/core/computer-use/adapter.js.map +1 -1
- package/dist/core/computer-use/image.d.ts.map +1 -1
- package/dist/core/computer-use/image.js +17 -5
- package/dist/core/computer-use/image.js.map +1 -1
- package/dist/core/computer-use/schemas.d.ts.map +1 -1
- package/dist/core/computer-use/schemas.js +23 -6
- package/dist/core/computer-use/schemas.js.map +1 -1
- package/dist/core/computer-use/workflow.d.ts.map +1 -1
- package/dist/core/computer-use/workflow.js +459 -119
- package/dist/core/computer-use/workflow.js.map +1 -1
- package/dist/core/cron/jobs.d.ts +26 -8
- package/dist/core/cron/jobs.d.ts.map +1 -1
- package/dist/core/cron/jobs.js +357 -232
- package/dist/core/cron/jobs.js.map +1 -1
- package/dist/core/cron/origin-context.d.ts +1 -0
- package/dist/core/cron/origin-context.d.ts.map +1 -1
- package/dist/core/cron/origin-context.js.map +1 -1
- package/dist/core/cron/scheduler.d.ts +22 -17
- package/dist/core/cron/scheduler.d.ts.map +1 -1
- package/dist/core/cron/scheduler.js +153 -73
- package/dist/core/cron/scheduler.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +1 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +8 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +8 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +4 -0
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +22 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/large-subagent-launch.d.ts +1 -1
- package/dist/core/large-subagent-launch.d.ts.map +1 -1
- package/dist/core/large-subagent-launch.js +7 -7
- package/dist/core/large-subagent-launch.js.map +1 -1
- package/dist/core/model-registry.d.ts +2 -0
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +5 -0
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-runtime.d.ts +4 -1
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +40 -4
- 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.map +1 -1
- package/dist/core/permissions.d.ts +3 -3
- package/dist/core/permissions.d.ts.map +1 -1
- package/dist/core/permissions.js +11 -35
- package/dist/core/permissions.js.map +1 -1
- package/dist/core/plan-mode.d.ts +5 -13
- package/dist/core/plan-mode.d.ts.map +1 -1
- package/dist/core/plan-mode.js +126 -116
- package/dist/core/plan-mode.js.map +1 -1
- package/dist/core/project-trust.d.ts.map +1 -1
- package/dist/core/project-trust.js +1 -1
- package/dist/core/project-trust.js.map +1 -1
- package/dist/core/prompt-resource-bridge.d.ts +12 -0
- package/dist/core/prompt-resource-bridge.d.ts.map +1 -0
- package/dist/core/prompt-resource-bridge.js +9 -0
- package/dist/core/prompt-resource-bridge.js.map +1 -0
- package/dist/core/protected-targets.d.ts +6 -0
- package/dist/core/protected-targets.d.ts.map +1 -0
- package/dist/core/protected-targets.js +45 -0
- package/dist/core/protected-targets.js.map +1 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +7 -0
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/rollback.d.ts +19 -3
- package/dist/core/rollback.d.ts.map +1 -1
- package/dist/core/rollback.js +172 -56
- package/dist/core/rollback.js.map +1 -1
- package/dist/core/runtime-credentials.d.ts +3 -0
- package/dist/core/runtime-credentials.d.ts.map +1 -1
- package/dist/core/runtime-credentials.js +14 -1
- package/dist/core/runtime-credentials.js.map +1 -1
- package/dist/core/sdk.d.ts +3 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +1 -0
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +6 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +95 -32
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-ownership.d.ts.map +1 -1
- package/dist/core/session-ownership.js +8 -3
- package/dist/core/session-ownership.js.map +1 -1
- package/dist/core/session-retention.d.ts.map +1 -1
- package/dist/core/session-retention.js +18 -7
- package/dist/core/session-retention.js.map +1 -1
- package/dist/core/session-startup-settings.d.ts +10 -0
- package/dist/core/session-startup-settings.d.ts.map +1 -0
- package/dist/core/session-startup-settings.js +70 -0
- package/dist/core/session-startup-settings.js.map +1 -0
- package/dist/core/subscriptions.d.ts +16 -7
- package/dist/core/subscriptions.d.ts.map +1 -1
- package/dist/core/subscriptions.js +96 -55
- package/dist/core/subscriptions.js.map +1 -1
- package/dist/core/trust-manager.d.ts +2 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +6 -1
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/core/update-check.d.ts.map +1 -1
- package/dist/core/update-check.js.map +1 -1
- package/dist/core/usage-adapters/kimi-coding.d.ts +2 -2
- package/dist/core/usage-adapters/kimi-coding.d.ts.map +1 -1
- package/dist/core/usage-adapters/kimi-coding.js +2 -2
- package/dist/core/usage-adapters/kimi-coding.js.map +1 -1
- package/dist/core/usage-adapters/openai-codex.d.ts +3 -2
- package/dist/core/usage-adapters/openai-codex.d.ts.map +1 -1
- package/dist/core/usage-adapters/openai-codex.js +3 -3
- package/dist/core/usage-adapters/openai-codex.js.map +1 -1
- package/dist/core/usage-adapters/xai.d.ts +2 -2
- package/dist/core/usage-adapters/xai.d.ts.map +1 -1
- package/dist/core/usage-adapters/xai.js +3 -3
- package/dist/core/usage-adapters/xai.js.map +1 -1
- package/dist/core/usage-adapters/zai.d.ts +2 -2
- package/dist/core/usage-adapters/zai.d.ts.map +1 -1
- package/dist/core/usage-adapters/zai.js +2 -2
- package/dist/core/usage-adapters/zai.js.map +1 -1
- package/dist/core/usage-service.d.ts +9 -2
- package/dist/core/usage-service.d.ts.map +1 -1
- package/dist/core/usage-service.js +95 -50
- package/dist/core/usage-service.js.map +1 -1
- package/dist/gateway/agent-bridge.d.ts +9 -1
- package/dist/gateway/agent-bridge.d.ts.map +1 -1
- package/dist/gateway/agent-bridge.js +91 -37
- package/dist/gateway/agent-bridge.js.map +1 -1
- package/dist/gateway/buttons.d.ts +8 -1
- package/dist/gateway/buttons.d.ts.map +1 -1
- package/dist/gateway/buttons.js +76 -18
- package/dist/gateway/buttons.js.map +1 -1
- package/dist/gateway/commands.d.ts +1 -0
- package/dist/gateway/commands.d.ts.map +1 -1
- package/dist/gateway/commands.js +10 -4
- package/dist/gateway/commands.js.map +1 -1
- package/dist/gateway/cron.d.ts +12 -11
- package/dist/gateway/cron.d.ts.map +1 -1
- package/dist/gateway/cron.js +65 -56
- package/dist/gateway/cron.js.map +1 -1
- package/dist/gateway/index.d.ts.map +1 -1
- package/dist/gateway/index.js +2 -1
- package/dist/gateway/index.js.map +1 -1
- package/dist/gateway/mobile-commands.d.ts +1 -0
- package/dist/gateway/mobile-commands.d.ts.map +1 -1
- package/dist/gateway/mobile-commands.js +56 -14
- package/dist/gateway/mobile-commands.js.map +1 -1
- package/dist/gateway/presenter.d.ts +12 -2
- package/dist/gateway/presenter.d.ts.map +1 -1
- package/dist/gateway/presenter.js +73 -38
- package/dist/gateway/presenter.js.map +1 -1
- package/dist/gateway/router.d.ts +2 -2
- package/dist/gateway/router.d.ts.map +1 -1
- package/dist/gateway/router.js +17 -2
- package/dist/gateway/router.js.map +1 -1
- package/dist/gateway/service.d.ts +2 -0
- package/dist/gateway/service.d.ts.map +1 -1
- package/dist/gateway/service.js +153 -0
- package/dist/gateway/service.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +86 -33
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +6 -4
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/copyable-text.d.ts.map +1 -1
- package/dist/modes/interactive/components/copyable-text.js +3 -2
- package/dist/modes/interactive/components/copyable-text.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +1 -1
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +2 -2
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +96 -109
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/smooth-streaming.d.ts.map +1 -1
- package/dist/modes/interactive/smooth-streaming.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/node-runtime/{adapter-VFG7WNPX.js → adapter-247RTYLS.js} +4 -5
- package/dist/node-runtime/agent-session-services-KDMSPQDY.js +53 -0
- package/dist/node-runtime/{brave-UWDA3I22.js → brave-2AFFAXNN.js} +1 -1
- package/dist/node-runtime/{builtin-extensions-I2HIFEMY.js → builtin-extensions-OX6KELNX.js} +8 -7
- package/dist/node-runtime/{chunk-QH6YL7VK.js → chunk-252ZVPPF.js} +3 -3
- package/dist/node-runtime/{chunk-PCEW76PM.js → chunk-2OIPYKLZ.js} +6 -6
- package/dist/node-runtime/{chunk-XBWPBZBN.js → chunk-2SWW7KMW.js} +1 -1
- package/dist/node-runtime/{chunk-UQUCFAJ3.js → chunk-2VIW3IMF.js} +40 -7
- package/dist/node-runtime/{chunk-UOEDI7RP.js → chunk-4KNKQGHM.js} +2 -2
- package/dist/node-runtime/{chunk-FQMM2EZ2.js → chunk-64XTQNLA.js} +29 -7
- package/dist/node-runtime/{chunk-SPVDBUOS.js → chunk-6O3IW3IA.js} +2 -2
- package/dist/node-runtime/{chunk-5ZQXRPMC.js → chunk-6ZZHGUSA.js} +2 -2
- package/dist/node-runtime/chunk-A2WO6WIN.js +1197 -0
- package/dist/node-runtime/{chunk-WIF24I7G.js → chunk-APVM5NEU.js} +149 -144
- package/dist/node-runtime/{chunk-RCR3XAQY.js → chunk-AYHH7YSD.js} +177 -144
- package/dist/node-runtime/{chunk-LWYIVUGV.js → chunk-B2IBAXNX.js} +48 -31
- package/dist/node-runtime/{chunk-M3LZLQW2.js → chunk-BDRGN3L2.js} +1 -0
- package/dist/node-runtime/{chunk-GJ2RDBRL.js → chunk-BYC6RKCN.js} +4 -2
- package/dist/node-runtime/{chunk-UVWCDQYF.js → chunk-C3P6Q3B2.js} +455 -278
- package/dist/node-runtime/{chunk-SN2KSMPQ.js → chunk-DQSCFU7R.js} +13 -7
- package/dist/node-runtime/{chunk-4SBQAI4T.js → chunk-EBLAZVSA.js} +2058 -73
- package/dist/node-runtime/{chunk-2KIPT4HJ.js → chunk-EPR2F3GU.js} +68 -20
- package/dist/node-runtime/{chunk-CSFI6YXL.js → chunk-ES6PBSIE.js} +1 -1
- package/dist/node-runtime/{chunk-IF24A3FH.js → chunk-EVM653DD.js} +4 -4
- package/dist/node-runtime/{chunk-HTFRRDSF.js → chunk-F2SMQ6ES.js} +3 -2
- package/dist/node-runtime/chunk-F2V2F4ZG.js +114 -0
- package/dist/node-runtime/{chunk-IKU6Y7DL.js → chunk-FE3WZI7F.js} +9 -6
- package/dist/node-runtime/{chunk-GYIXXQAO.js → chunk-FIRA54AC.js} +2 -5
- package/dist/node-runtime/{chunk-6VYZ5UFP.js → chunk-FLGEEH27.js} +1 -1
- package/dist/node-runtime/{chunk-5EFIU3OM.js → chunk-FTKEZL27.js} +1 -1
- package/dist/node-runtime/{chunk-RGQAEOM5.js → chunk-FYIFPFXE.js} +23 -6
- package/dist/node-runtime/{chunk-HMBGROQK.js → chunk-GLDXBBL6.js} +3 -3
- package/dist/node-runtime/{chunk-KWA4OC2J.js → chunk-H6YBCWKG.js} +1 -1
- package/dist/node-runtime/{chunk-2MI5OPMN.js → chunk-HNNHHJAB.js} +68 -50
- package/dist/node-runtime/{chunk-I74LN5JG.js → chunk-HUD2RFJW.js} +2 -2
- package/dist/node-runtime/{chunk-I54LGHWM.js → chunk-I2H5QMWW.js} +3 -3
- package/dist/node-runtime/{chunk-XHIRAZ26.js → chunk-IAZSK7KK.js} +1 -1
- package/dist/node-runtime/{chunk-X3PGBLQ7.js → chunk-IHHTWSXN.js} +9 -9
- package/dist/node-runtime/{chunk-DAPBPCBP.js → chunk-IPP5BIV5.js} +25 -3
- package/dist/node-runtime/{chunk-QFWG2RVL.js → chunk-IXG6F4NT.js} +11 -0
- package/dist/node-runtime/{chunk-RDDAZOMU.js → chunk-JL4HYQXK.js} +1 -1
- package/dist/node-runtime/{chunk-CDVHZOOK.js → chunk-JQYNHAKX.js} +1 -1
- package/dist/node-runtime/{chunk-L24TPBS4.js → chunk-JWEVT363.js} +37 -29
- package/dist/node-runtime/{chunk-2HMIRK7W.js → chunk-LHV3V67B.js} +5 -5
- package/dist/node-runtime/{chunk-UAEOTO52.js → chunk-MNQXDFPV.js} +6 -2
- package/dist/node-runtime/{chunk-T4DA4XE7.js → chunk-MQPKUHRN.js} +162 -82
- package/dist/node-runtime/{chunk-MPKSOJBT.js → chunk-NHATCSOI.js} +4 -7
- package/dist/node-runtime/{chunk-RMQZU2YU.js → chunk-NNNR3QIY.js} +1 -1
- package/dist/node-runtime/{chunk-RWTKOC3B.js → chunk-QBTJG3UM.js} +1 -1
- package/dist/node-runtime/{chunk-P7XBVXGT.js → chunk-QNVMKNNN.js} +18 -14
- package/dist/node-runtime/{chunk-GS42T6MX.js → chunk-QW3AAHWN.js} +1 -1
- package/dist/node-runtime/{chunk-DVQSHCVP.js → chunk-R4WSB2MQ.js} +5 -5
- package/dist/node-runtime/{chunk-B4HP6ZWM.js → chunk-RHCGYWO7.js} +1 -1
- package/dist/node-runtime/{chunk-2CFDTH5B.js → chunk-RLGY2QIL.js} +45 -59
- package/dist/node-runtime/{chunk-KKUTQQV7.js → chunk-RYRGL7P4.js} +1 -1
- package/dist/node-runtime/{chunk-5Q4A37RB.js → chunk-TCT6PCUR.js} +32 -11
- package/dist/node-runtime/{chunk-D5UCKPBQ.js → chunk-UBWW2PID.js} +1 -1
- package/dist/node-runtime/{chunk-E75WFZ33.js → chunk-UNUZICC4.js} +3 -3
- package/dist/node-runtime/{chunk-RAK2QA2B.js → chunk-UYRKUKFE.js} +4 -4
- package/dist/node-runtime/{chunk-LWJXTA6Z.js → chunk-VSUEAI7O.js} +1377 -45
- package/dist/node-runtime/{chunk-NAY6UUQZ.js → chunk-WDIVLMOH.js} +1 -1
- package/dist/node-runtime/{chunk-E24EO34J.js → chunk-WPXUR3HE.js} +1 -1
- package/dist/node-runtime/{chunk-SLVOAQOY.js → chunk-WXYNALHD.js} +113 -1
- package/dist/node-runtime/{chunk-KJ6DWS3K.js → chunk-XEOCUEUJ.js} +121 -60
- package/dist/node-runtime/chunk-YD3IZAZ7.js +47 -0
- package/dist/node-runtime/chunk-YSB6URMT.js +41 -0
- package/dist/node-runtime/{chunk-LJTIVM7I.js → chunk-ZDJUR45D.js} +427 -126
- package/dist/node-runtime/{chunk-YWOJIGFY.js → chunk-ZEVFBFNF.js} +95 -142
- package/dist/node-runtime/{chunk-5B6VKFEV.js → chunk-ZIQUS5QO.js} +1 -1
- package/dist/node-runtime/cli-runtime.js +4 -4
- package/dist/node-runtime/{command-FSBU2EVZ.js → command-3HMSY6W2.js} +5 -5
- package/dist/node-runtime/{commands-EMBQQVVT.js → commands-D6A6H4TS.js} +11 -18
- package/dist/node-runtime/{commands-NAAL7KNT.js → commands-OCSSEEWJ.js} +16 -16
- package/dist/node-runtime/{config-QDD5PUE2.js → config-CU7M7BTK.js} +1 -1
- package/dist/node-runtime/{config-D4QUPAHX.js → config-DS7XLMEM.js} +2 -2
- package/dist/node-runtime/{direct-tool-executor-4D7UXYU4.js → direct-tool-executor-2QJXVQD2.js} +6 -11
- package/dist/node-runtime/{exa-LL64QZR2.js → exa-6VBZNPGE.js} +1 -1
- package/dist/node-runtime/{export-html-VM4J2MNR.js → export-html-BRWF5AHI.js} +4 -4
- package/dist/node-runtime/{extension-input-E7BJZ35H.js → extension-input-VBBMX7YV.js} +5 -5
- package/dist/node-runtime/{extension-selector-WU42XDTU.js → extension-selector-T5AOG5XB.js} +5 -5
- package/dist/node-runtime/{extract-EQJE7FZZ.js → extract-BFX2N35A.js} +3 -3
- package/dist/node-runtime/{gateway-DQM333YV.js → gateway-6623C2U3.js} +51 -42
- package/dist/node-runtime/{gemini-search-35OCRFLN.js → gemini-search-C66QHDT6.js} +2 -2
- package/dist/node-runtime/{gemini-url-context-UQY3PHHW.js → gemini-url-context-T7DEK73R.js} +3 -3
- package/dist/node-runtime/{github-extract-F64RZOEA.js → github-extract-HOGE3D6F.js} +107 -38
- package/dist/node-runtime/{goal-NJEE5CTU.js → goal-AIHEDUYA.js} +5 -5
- package/dist/node-runtime/index.js +50 -48
- package/dist/node-runtime/{init-P5AUV77I.js → init-JBQJIPYI.js} +3 -6
- package/dist/node-runtime/{install-cli-NN4YAU44.js → install-cli-INGHIVBY.js} +30 -25
- package/dist/node-runtime/interactive-mode-FM5DNUSW.js +74 -0
- package/dist/node-runtime/{interactive-view-NGFAMHPW.js → interactive-view-K33PM4OS.js} +8 -8
- package/dist/node-runtime/{lsp-manager-3ASUSO4T.js → lsp-manager-S554V5HR.js} +240 -155
- package/dist/node-runtime/{lunr-browser-IR7TL3J7.js → lunr-browser-H4FDOR3C.js} +7 -7
- package/dist/node-runtime/{lunr-computer-use-Y23CCDIJ.js → lunr-computer-use-VDP2QNRQ.js} +9 -9
- package/dist/node-runtime/{lunr-cron-USHC4LXH.js → lunr-cron-LKVA5CZZ.js} +93 -80
- package/dist/node-runtime/main.js +42 -41
- package/dist/node-runtime/{mobile-commands-O5LCHL32.js → mobile-commands-XT3NQXLD.js} +12 -12
- package/dist/node-runtime/{model-runtime-OO5HFLWE.js → model-runtime-MZ2JMDV4.js} +4 -4
- package/dist/node-runtime/{openai-search-B3MSNCQA.js → openai-search-K72LJDYN.js} +1 -1
- package/dist/node-runtime/{package-manager-cli-Q7BL6KZO.js → package-manager-cli-CYM262SI.js} +20 -20
- package/dist/node-runtime/{parallel-AI2MNSCU.js → parallel-X724NCNU.js} +1 -1
- package/dist/node-runtime/{perplexity-QVJW3I35.js → perplexity-RDHQHVMK.js} +2 -2
- package/dist/node-runtime/{pi-intercom-QM53RLTS.js → pi-intercom-NHHEPBMI.js} +2 -2
- package/dist/node-runtime/{pi-mcp-adapter-3PHF4KZ4.js → pi-mcp-adapter-PP3GQJQ2.js} +98 -94
- package/dist/node-runtime/{pi-ollama-cloud-2F3Y2QNM.js → pi-ollama-cloud-4MNWIMFN.js} +11 -24
- package/dist/node-runtime/{pi-prompt-template-model-QWTCGLJU.js → pi-prompt-template-model-FTGELLS5.js} +32 -36
- package/dist/node-runtime/{pi-subagents-7IBSSGEW.js → pi-subagents-LT3CTO4E.js} +98 -106
- package/dist/node-runtime/{pi-web-access-WTGMNZ32.js → pi-web-access-Z3LP246C.js} +144 -108
- package/dist/node-runtime/{print-mode-XQ76CYMT.js → print-mode-2XHN5SUA.js} +3 -3
- package/dist/node-runtime/{process-registry-4FAKZQOL.js → process-registry-Q4QWIU33.js} +3 -3
- package/dist/node-runtime/{proxy-modes-5FAPSZEZ.js → proxy-modes-VEGC6QG5.js} +8 -15
- package/dist/node-runtime/rpc-entry.js +42 -41
- package/dist/node-runtime/{rpc-mode-O3XV4SID.js → rpc-mode-32DHJPEJ.js} +4 -4
- package/dist/node-runtime/{runtime-4VA6JKNF.js → runtime-EDUUGAQD.js} +56 -46
- package/dist/node-runtime/{runtime-EFPPD2UW.js → runtime-UGXM4NPQ.js} +2 -2
- package/dist/node-runtime/{runtime-bridges-7WVCLI76.js → runtime-bridges-DNKMNJCF.js} +7 -7
- package/dist/node-runtime/{service-MDQIPQ26.js → service-IHLGFLBT.js} +6 -4
- package/dist/node-runtime/{session-handoff-GWARVEWT.js → session-handoff-LNSPDTKY.js} +4 -4
- package/dist/node-runtime/{session-manager-JB5J6XBN.js → session-manager-YIFIAVGC.js} +3 -3
- package/dist/node-runtime/{session-selector-GIM4DHQ2.js → session-selector-I73U3EIO.js} +7 -7
- package/dist/node-runtime/{settings-manager-DJDM5AHM.js → settings-manager-P2TKGYTR.js} +5 -5
- package/dist/node-runtime/{setup-JBKOLJ6F.js → setup-H7CCELIL.js} +15 -1
- package/dist/node-runtime/{setup-PFBWRNUI.js → setup-OLQ4GXWS.js} +17 -17
- package/dist/node-runtime/{src-IVPNZ2BX.js → src-6RV4PXKJ.js} +64 -36
- package/dist/node-runtime/{subagent-executor-LPZ4BHWE.js → subagent-executor-Q5F7DBVM.js} +119 -58
- package/dist/node-runtime/{tavily-WEZFVFP7.js → tavily-KZBFYQB6.js} +1 -1
- package/dist/node-runtime/{theme-UOO5RVFN.js → theme-YLVZKKZD.js} +2 -2
- package/dist/node-runtime/{trust-manager-MMISNCYO.js → trust-manager-ZCU76D23.js} +2 -2
- package/dist/node-runtime/{update-cli-HNMOTNGX.js → update-cli-F3XXJANQ.js} +6 -6
- package/dist/node-runtime/{usage-service-LFB2SWYV.js → usage-service-CPAGBED5.js} +1 -1
- package/dist/node-runtime/{video-extract-OOZHR7SU.js → video-extract-UPKYIBW3.js} +3 -3
- package/dist/node-runtime/{workflow-OHPBEFO4.js → workflow-ICDI4N3J.js} +208 -78
- package/dist/node-runtime/{youtube-extract-FNPAUNHU.js → youtube-extract-77NT7FWH.js} +4 -4
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/exif-orientation.d.ts.map +1 -1
- package/dist/utils/exif-orientation.js +25 -10
- package/dist/utils/exif-orientation.js.map +1 -1
- package/dist/utils/image-resize-core.d.ts.map +1 -1
- package/dist/utils/image-resize-core.js +2 -0
- package/dist/utils/image-resize-core.js.map +1 -1
- package/dist/utils/paths.d.ts +4 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +33 -2
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/sanitize-terminal-text.d.ts +7 -0
- package/dist/utils/sanitize-terminal-text.d.ts.map +1 -0
- package/dist/utils/sanitize-terminal-text.js +67 -0
- package/dist/utils/sanitize-terminal-text.js.map +1 -0
- package/docs/browser.md +1 -1
- package/docs/custom-provider.md +3 -3
- package/docs/extensions.md +8 -4
- package/docs/features.md +15 -7
- package/docs/keybindings.md +1 -1
- package/docs/models.md +5 -5
- package/docs/packages.md +1 -1
- package/docs/providers.md +2 -2
- package/docs/rpc.md +7 -7
- package/docs/security.md +10 -5
- package/docs/sessions.md +2 -2
- package/docs/skills.md +1 -1
- package/docs/terminal-setup.md +7 -7
- package/docs/themes.md +1 -1
- package/docs/usage.md +1 -1
- package/examples/extensions/auto-commit-on-exit.ts +1 -1
- package/examples/extensions/bash-spawn-hook.ts +1 -1
- package/examples/extensions/built-in-tool-renderer.ts +1 -1
- package/examples/extensions/claude-rules.ts +1 -1
- package/examples/extensions/commands.ts +1 -1
- package/examples/extensions/custom-compaction.ts +1 -1
- package/examples/extensions/custom-provider-anthropic/index.ts +3 -3
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/doom-overlay/index.ts +1 -1
- package/examples/extensions/git-merge-and-resolve.ts +2 -2
- package/examples/extensions/gondolin/index.ts +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/hidden-thinking-label.ts +1 -1
- package/examples/extensions/inline-bash.ts +2 -2
- package/examples/extensions/input-transform-streaming.ts +2 -2
- package/examples/extensions/input-transform.ts +2 -2
- package/examples/extensions/interactive-shell.ts +1 -1
- package/examples/extensions/kimi-deferred-tools.ts +1 -1
- package/examples/extensions/mac-system-theme.ts +1 -1
- package/examples/extensions/minimal-mode.ts +1 -1
- package/examples/extensions/modal-editor.ts +1 -1
- package/examples/extensions/model-status.ts +1 -1
- package/examples/extensions/notify.ts +3 -3
- package/examples/extensions/overlay-qa-tests.ts +1 -1
- package/examples/extensions/overlay-test.ts +1 -1
- package/examples/extensions/pirate.ts +1 -1
- package/examples/extensions/preset.ts +3 -3
- package/examples/extensions/project-trust.ts +4 -4
- package/examples/extensions/prompt-customizer.ts +1 -1
- package/examples/extensions/rainbow-editor.ts +1 -1
- package/examples/extensions/rpc-demo.ts +1 -1
- package/examples/extensions/sandbox/index.ts +7 -7
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/shutdown-command.ts +5 -5
- package/examples/extensions/ssh.ts +2 -2
- package/examples/extensions/subagent/README.md +3 -3
- package/examples/extensions/subagent/index.ts +2 -2
- package/examples/extensions/titlebar-spinner.ts +1 -1
- package/examples/extensions/tool-override.ts +1 -1
- package/examples/extensions/tools.ts +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/extensions/working-indicator.ts +1 -1
- package/examples/extensions/working-message-test.ts +1 -1
- package/examples/sdk/01-minimal.ts +1 -1
- package/examples/sdk/03-custom-prompt.ts +1 -1
- package/examples/sdk/04-skills.ts +1 -1
- package/examples/sdk/06-extensions.ts +2 -2
- package/examples/sdk/08-prompt-templates.ts +1 -1
- package/install-lock/package-lock.json +24 -24
- package/install-lock/package.json +2 -2
- package/npm-shrinkwrap.json +60 -24
- package/package.json +9 -9
- package/dist/modes/interactive/components/exit-card.d.ts +0 -22
- package/dist/modes/interactive/components/exit-card.d.ts.map +0 -1
- package/dist/modes/interactive/components/exit-card.js +0 -69
- package/dist/modes/interactive/components/exit-card.js.map +0 -1
- package/dist/node-runtime/agent-session-services-5YXS2PLF.js +0 -51
- package/dist/node-runtime/chunk-2IDTZAG5.js +0 -1415
- package/dist/node-runtime/chunk-3MISGG4S.js +0 -769
- package/dist/node-runtime/chunk-4HXHDDCF.js +0 -16
- package/dist/node-runtime/chunk-5B5QN3ZQ.js +0 -356
- package/dist/node-runtime/chunk-7IQGBKBJ.js +0 -2033
- package/dist/node-runtime/chunk-AUXVGBO4.js +0 -19
- package/dist/node-runtime/chunk-PTFBPO3C.js +0 -50
- package/dist/node-runtime/interactive-mode-YOHZVMKX.js +0 -74
- package/dist/node-runtime/mcp-auth-flow-QVLFVLEO.js +0 -33
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github-extract.d.ts","sourceRoot":"","sources":["../../../src/builtin-extensions/pi-web-access/github-extract.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AA4BrD,MAAM,WAAW,aAAa;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;CAC/B;AA4ED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAiDhE;AAiWD,wBAAsB,aAAa,CAClC,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,WAAW,EACpB,UAAU,CAAC,EAAE,OAAO,GAClB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAsGlC;AAED,wBAAgB,eAAe,IAAI,IAAI,CAStC","sourcesContent":["// @ts-nocheck\nimport { existsSync, readFileSync, rmSync, statSync, readdirSync, openSync, readSync, closeSync, realpathSync } from \"node:fs\";\nimport { execFile } from \"node:child_process\";\nimport { extname, join, resolve as resolvePath, sep as pathSep } from \"node:path\";\nimport { activityMonitor } from \"./activity.ts\";\nimport type { ExtractedContent } from \"./extract.ts\";\nimport { checkGhAvailable, checkRepoSize, fetchViaApi, showGhHint } from \"./github-api.ts\";\nimport { registerSessionCleanup } from \"./session-cleanup.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst CONFIG_PATH = getWebSearchConfigPath();\n\nconst BINARY_EXTENSIONS = new Set([\n\t\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\", \".ico\", \".webp\", \".svg\", \".tiff\", \".tif\",\n\t\".mp3\", \".mp4\", \".avi\", \".mov\", \".mkv\", \".flv\", \".wmv\", \".wav\", \".ogg\", \".webm\", \".flac\", \".aac\",\n\t\".zip\", \".tar\", \".gz\", \".bz2\", \".xz\", \".7z\", \".rar\", \".zst\",\n\t\".exe\", \".dll\", \".so\", \".dylib\", \".bin\", \".o\", \".a\", \".lib\",\n\t\".woff\", \".woff2\", \".ttf\", \".otf\", \".eot\",\n\t\".pdf\", \".doc\", \".docx\", \".xls\", \".xlsx\", \".ppt\", \".pptx\",\n\t\".sqlite\", \".db\", \".sqlite3\",\n\t\".pyc\", \".pyo\", \".class\", \".jar\", \".war\",\n\t\".iso\", \".img\", \".dmg\",\n]);\n\nconst NOISE_DIRS = new Set([\n\t\"node_modules\", \"vendor\", \".next\", \"dist\", \"build\", \"__pycache__\",\n\t\".venv\", \"venv\", \".tox\", \".mypy_cache\", \".pytest_cache\",\n\t\"target\", \".gradle\", \".idea\", \".vscode\",\n]);\n\nconst MAX_INLINE_FILE_CHARS = 100_000;\nconst MAX_TREE_ENTRIES = 200;\n\nexport interface GitHubUrlInfo {\n\towner: string;\n\trepo: string;\n\tref?: string;\n\trefIsFullSha: boolean;\n\tpath?: string;\n\ttype: \"root\" | \"blob\" | \"tree\";\n}\n\ninterface CachedClone {\n\tlocalPath: string;\n\tclonePromise: Promise<string | null>;\n}\n\ninterface GitHubCloneConfig {\n\tenabled: boolean;\n\tmaxRepoSizeMB: number;\n\tcloneTimeoutSeconds: number;\n\tclonePath: string;\n}\n\nconst cloneCache = new Map<string, CachedClone>();\n\nlet cachedConfig: GitHubCloneConfig | null = null;\n\nfunction normalizeEnabled(value: unknown, fallback: boolean): boolean {\n\treturn typeof value === \"boolean\" ? value : fallback;\n}\n\nfunction normalizePositiveNumber(value: unknown, fallback: number): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value)) return fallback;\n\treturn value > 0 ? value : fallback;\n}\n\nfunction normalizeClonePath(value: unknown, fallback: string): string {\n\tif (typeof value !== \"string\") return fallback;\n\tconst normalized = value.trim();\n\treturn normalized.length > 0 ? normalized : fallback;\n}\n\nfunction loadGitHubConfig(): GitHubCloneConfig {\n\tif (cachedConfig) return cachedConfig;\n\n\tconst defaults: GitHubCloneConfig = {\n\t\tenabled: true,\n\t\tmaxRepoSizeMB: 350,\n\t\tcloneTimeoutSeconds: 30,\n\t\tclonePath: \"/tmp/pi-github-repos\",\n\t};\n\n\tif (!existsSync(CONFIG_PATH)) {\n\t\tcachedConfig = defaults;\n\t\treturn cachedConfig;\n\t}\n\n\tconst rawText = readFileSync(CONFIG_PATH, \"utf-8\");\n\tlet raw: { githubClone?: { enabled?: unknown; maxRepoSizeMB?: unknown; cloneTimeoutSeconds?: unknown; clonePath?: unknown } };\n\ttry {\n\t\traw = JSON.parse(rawText) as { githubClone?: { enabled?: unknown; maxRepoSizeMB?: unknown; cloneTimeoutSeconds?: unknown; clonePath?: unknown } };\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);\n\t}\n\n\tconst gc = raw.githubClone ?? {};\n\tcachedConfig = {\n\t\tenabled: normalizeEnabled(gc.enabled, defaults.enabled),\n\t\tmaxRepoSizeMB: normalizePositiveNumber(gc.maxRepoSizeMB, defaults.maxRepoSizeMB),\n\t\tcloneTimeoutSeconds: normalizePositiveNumber(gc.cloneTimeoutSeconds, defaults.cloneTimeoutSeconds),\n\t\tclonePath: normalizeClonePath(gc.clonePath, defaults.clonePath),\n\t};\n\treturn cachedConfig;\n}\n\nconst NON_CODE_SEGMENTS = new Set([\n\t\"issues\", \"pull\", \"pulls\", \"discussions\", \"releases\", \"wiki\",\n\t\"actions\", \"settings\", \"security\", \"projects\", \"graphs\",\n\t\"compare\", \"commits\", \"tags\", \"branches\", \"stargazers\",\n\t\"watchers\", \"network\", \"forks\", \"milestone\", \"labels\",\n\t\"packages\", \"codespaces\", \"contribute\", \"community\",\n\t\"sponsors\", \"invitations\", \"notifications\", \"insights\",\n]);\n\nexport function parseGitHubUrl(url: string): GitHubUrlInfo | null {\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(url);\n\t} catch {\n\t\treturn null;\n\t}\n\n\tconst host = parsed.hostname.toLowerCase();\n\tif (host !== \"github.com\" && host !== \"www.github.com\") return null;\n\n\tconst segments = parsed.pathname\n\t\t.split(\"/\")\n\t\t.filter(Boolean)\n\t\t.map((segment) => {\n\t\t\ttry {\n\t\t\t\treturn decodeURIComponent(segment);\n\t\t\t} catch {\n\t\t\t\treturn segment;\n\t\t\t}\n\t\t});\n\tif (segments.length < 2) return null;\n\n\tconst owner = segments[0];\n\tconst repo = segments[1].replace(/\\.git$/, \"\");\n\n\tif (NON_CODE_SEGMENTS.has(segments[2]?.toLowerCase())) return null;\n\n\tif (segments.length === 2) {\n\t\treturn { owner, repo, refIsFullSha: false, type: \"root\" };\n\t}\n\n\tconst action = segments[2];\n\tif (action !== \"blob\" && action !== \"tree\") return null;\n\tif (segments.length < 4) return null;\n\n\tconst ref = segments[3];\n\tconst refIsFullSha = /^[0-9a-f]{40}$/.test(ref);\n\tconst pathParts = segments.slice(4);\n\tconst path = pathParts.length > 0 ? pathParts.join(\"/\") : \"\";\n\n\treturn {\n\t\towner,\n\t\trepo,\n\t\tref,\n\t\trefIsFullSha,\n\t\tpath,\n\t\ttype: action as \"blob\" | \"tree\",\n\t};\n}\n\nfunction cacheKey(owner: string, repo: string, ref?: string): string {\n\treturn ref ? `${owner}/${repo}@${ref}` : `${owner}/${repo}`;\n}\n\nfunction cloneDir(config: GitHubCloneConfig, owner: string, repo: string, ref?: string): string {\n\tconst dirName = ref ? `${repo}@${ref}` : repo;\n\treturn join(config.clonePath, owner, dirName);\n}\n\nfunction execClone(args: string[], localPath: string, timeoutMs: number, signal?: AbortSignal): Promise<string | null> {\n\treturn new Promise((resolve) => {\n\t\tconst child = execFile(args[0], args.slice(1), { timeout: timeoutMs }, (err) => {\n\t\t\tif (err) {\n\t\t\t\ttry {\n\t\t\t\t\trmSync(localPath, { recursive: true, force: true });\n\t\t\t\t} catch {\n\t\t\t\t}\n\t\t\t\tresolve(null);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresolve(localPath);\n\t\t});\n\n\t\tif (signal) {\n\t\t\tconst onAbort = () => child.kill();\n\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\tchild.on(\"exit\", () => signal.removeEventListener(\"abort\", onAbort));\n\t\t}\n\t});\n}\n\nasync function cloneRepo(\n\towner: string,\n\trepo: string,\n\tref: string | undefined,\n\tconfig: GitHubCloneConfig,\n\tsignal?: AbortSignal,\n): Promise<string | null> {\n\tconst localPath = cloneDir(config, owner, repo, ref);\n\n\ttry {\n\t\trmSync(localPath, { recursive: true, force: true });\n\t} catch {\n\t}\n\n\tconst timeoutMs = config.cloneTimeoutSeconds * 1000;\n\tconst hasGh = await checkGhAvailable();\n\n\tif (hasGh) {\n\t\tconst args = [\"gh\", \"repo\", \"clone\", `${owner}/${repo}`, localPath, \"--\", \"--depth\", \"1\", \"--single-branch\"];\n\t\tif (ref) args.push(\"--branch\", ref);\n\t\treturn execClone(args, localPath, timeoutMs, signal);\n\t}\n\n\tshowGhHint();\n\n\tconst gitUrl = `https://github.com/${owner}/${repo}.git`;\n\tconst args = [\"git\", \"clone\", \"--depth\", \"1\", \"--single-branch\"];\n\tif (ref) args.push(\"--branch\", ref);\n\targs.push(gitUrl, localPath);\n\treturn execClone(args, localPath, timeoutMs, signal);\n}\n\nfunction isBinaryFile(filePath: string): boolean {\n\tconst ext = extname(filePath).toLowerCase();\n\tif (BINARY_EXTENSIONS.has(ext)) return true;\n\n\tlet fd: number;\n\ttry {\n\t\tfd = openSync(filePath, \"r\");\n\t} catch {\n\t\treturn false;\n\t}\n\ttry {\n\t\tconst buf = Buffer.alloc(512);\n\t\tconst bytesRead = readSync(fd, buf, 0, 512, 0);\n\t\tfor (let i = 0; i < bytesRead; i++) {\n\t\t\tif (buf[i] === 0) return true;\n\t\t}\n\t} catch {\n\t\treturn false;\n\t} finally {\n\t\tcloseSync(fd);\n\t}\n\n\treturn false;\n}\n\nfunction formatFileSize(bytes: number): string {\n\tif (bytes < 1024) return `${bytes} B`;\n\tif (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n\treturn `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction resolveWithinRepo(rootPath: string, relativePath: string): string | null {\n\tconst normalizedRoot = resolvePath(rootPath);\n\tconst candidate = resolvePath(normalizedRoot, relativePath);\n\tif (candidate !== normalizedRoot) {\n\t\tconst rootPrefix = normalizedRoot.endsWith(pathSep) ? normalizedRoot : normalizedRoot + pathSep;\n\t\tif (!candidate.startsWith(rootPrefix)) return null;\n\t}\n\n\tif (!existsSync(candidate)) return candidate;\n\n\ttry {\n\t\tconst realRoot = realpathSync(normalizedRoot);\n\t\tconst realCandidate = realpathSync(candidate);\n\t\tif (realCandidate === realRoot) return candidate;\n\t\tconst realRootPrefix = realRoot.endsWith(pathSep) ? realRoot : realRoot + pathSep;\n\t\treturn realCandidate.startsWith(realRootPrefix) ? candidate : null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction readTextFile(path: string): string | null {\n\ttry {\n\t\treturn readFileSync(path, \"utf-8\");\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction buildTree(rootPath: string): string {\n\tconst entries: string[] = [];\n\n\tfunction walk(dir: string, relPath: string): void {\n\t\tif (entries.length >= MAX_TREE_ENTRIES) return;\n\n\t\tlet items: string[];\n\t\ttry {\n\t\t\titems = readdirSync(dir).sort();\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const item of items) {\n\t\t\tif (entries.length >= MAX_TREE_ENTRIES) return;\n\t\t\tif (item === \".git\") continue;\n\n\t\t\tconst rel = relPath ? `${relPath}/${item}` : item;\n\t\t\tconst safePath = resolveWithinRepo(rootPath, rel);\n\t\t\tif (!safePath) {\n\t\t\t\tentries.push(`${rel} [outside repo skipped]`);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet stat;\n\t\t\ttry {\n\t\t\t\tstat = statSync(safePath);\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (stat.isDirectory()) {\n\t\t\t\tif (NOISE_DIRS.has(item)) {\n\t\t\t\t\tentries.push(`${rel}/ [skipped]`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tentries.push(`${rel}/`);\n\t\t\t\twalk(safePath, rel);\n\t\t\t} else {\n\t\t\t\tentries.push(rel);\n\t\t\t}\n\t\t}\n\t}\n\n\twalk(rootPath, \"\");\n\n\tif (entries.length >= MAX_TREE_ENTRIES) {\n\t\tentries.push(`... (truncated at ${MAX_TREE_ENTRIES} entries)`);\n\t}\n\n\treturn entries.join(\"\\n\");\n}\n\nfunction buildDirListing(rootPath: string, subPath: string): string {\n\tconst targetPath = resolveWithinRepo(rootPath, subPath);\n\tif (!targetPath) return \"(path escapes repository root)\";\n\tconst lines: string[] = [];\n\n\tlet items: string[];\n\ttry {\n\t\titems = readdirSync(targetPath).sort();\n\t} catch {\n\t\treturn \"(directory not readable)\";\n\t}\n\n\tfor (const item of items) {\n\t\tif (item === \".git\") continue;\n\t\tconst rel = subPath ? `${subPath}/${item}` : item;\n\t\tconst safePath = resolveWithinRepo(rootPath, rel);\n\t\tif (!safePath) {\n\t\t\tlines.push(` ${item} (outside repo)`);\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\tconst stat = statSync(safePath);\n\t\t\tif (stat.isDirectory()) {\n\t\t\t\tlines.push(` ${item}/`);\n\t\t\t} else {\n\t\t\t\tlines.push(` ${item} (${formatFileSize(stat.size)})`);\n\t\t\t}\n\t\t} catch {\n\t\t\tlines.push(` ${item} (unreadable)`);\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\nfunction readReadme(localPath: string): string | null {\n\tconst candidates = [\"README.md\", \"readme.md\", \"README\", \"README.txt\", \"README.rst\"];\n\tfor (const name of candidates) {\n\t\tconst readmePath = join(localPath, name);\n\t\tif (existsSync(readmePath)) {\n\t\t\ttry {\n\t\t\t\tconst content = readFileSync(readmePath, \"utf-8\");\n\t\t\t\treturn content.length > 8192 ? content.slice(0, 8192) + \"\\n\\n[README truncated at 8K chars]\" : content;\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction generateContent(localPath: string, info: GitHubUrlInfo): string {\n\tconst lines: string[] = [];\n\tlines.push(`Repository cloned to: ${localPath}`);\n\tlines.push(\"\");\n\n\tif (info.type === \"root\") {\n\t\tlines.push(\"## Structure\");\n\t\tlines.push(buildTree(localPath));\n\t\tlines.push(\"\");\n\n\t\tconst readme = readReadme(localPath);\n\t\tif (readme) {\n\t\t\tlines.push(\"## README.md\");\n\t\t\tlines.push(readme);\n\t\t\tlines.push(\"\");\n\t\t}\n\n\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\tif (info.type === \"tree\") {\n\t\tconst dirPath = info.path || \"\";\n\t\tconst fullDirPath = resolveWithinRepo(localPath, dirPath);\n\n\t\tif (!fullDirPath || !existsSync(fullDirPath)) {\n\t\t\tlines.push(`Path \\`${dirPath}\\` not found in clone. Showing repository root instead.`);\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"## Structure\");\n\t\t\tlines.push(buildTree(localPath));\n\t\t} else {\n\t\t\tlines.push(`## ${dirPath || \"/\"}`);\n\t\t\tlines.push(buildDirListing(localPath, dirPath));\n\t\t}\n\n\t\tlines.push(\"\");\n\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\tif (info.type === \"blob\") {\n\t\tconst filePath = info.path || \"\";\n\t\tconst fullFilePath = resolveWithinRepo(localPath, filePath);\n\n\t\tif (!fullFilePath || !existsSync(fullFilePath)) {\n\t\t\tlines.push(`Path \\`${filePath}\\` not found in clone. Showing repository root instead.`);\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"## Structure\");\n\t\t\tlines.push(buildTree(localPath));\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\n\t\tlet stat: ReturnType<typeof statSync>;\n\t\ttry {\n\t\t\tstat = statSync(fullFilePath);\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t\tlines.push(`Could not inspect \\`${filePath}\\`: ${message}`);\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\n\t\tif (stat.isDirectory()) {\n\t\t\tlines.push(`## ${filePath || \"/\"}`);\n\t\t\tlines.push(buildDirListing(localPath, filePath));\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\n\t\tif (isBinaryFile(fullFilePath)) {\n\t\t\tconst ext = extname(filePath).replace(\".\", \"\");\n\t\t\tlines.push(`## ${filePath}`);\n\t\t\tlines.push(`Binary file (${ext}, ${formatFileSize(stat.size)}). Use \\`read\\` or \\`bash\\` tools at the path above to inspect.`);\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\n\t\tconst content = readTextFile(fullFilePath);\n\t\tif (content === null) {\n\t\t\tlines.push(`Could not read \\`${filePath}\\` as UTF-8 text.`);\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\t\tlines.push(`## ${filePath}`);\n\n\t\tif (content.length > MAX_INLINE_FILE_CHARS) {\n\t\t\tlines.push(content.slice(0, MAX_INLINE_FILE_CHARS));\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(`[File truncated at 100K chars. Full file: ${fullFilePath}]`);\n\t\t} else {\n\t\t\tlines.push(content);\n\t\t}\n\n\t\tlines.push(\"\");\n\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\nasync function awaitCachedClone(\n\tcached: CachedClone,\n\turl: string,\n\towner: string,\n\trepo: string,\n\tinfo: GitHubUrlInfo,\n\tsignal?: AbortSignal,\n): Promise<ExtractedContent | null> {\n\tif (signal?.aborted) return null;\n\tconst result = await cached.clonePromise;\n\tif (signal?.aborted) return null;\n\tif (result) {\n\t\tconst content = generateContent(result, info);\n\t\tconst title = info.path ? `${owner}/${repo} - ${info.path}` : `${owner}/${repo}`;\n\t\treturn { url, title, content, error: null };\n\t}\n\treturn fetchViaApi(url, owner, repo, info);\n}\n\nexport async function extractGitHub(\n\turl: string,\n\tsignal?: AbortSignal,\n\tforceClone?: boolean,\n): Promise<ExtractedContent | null> {\n\tconst info = parseGitHubUrl(url);\n\tif (!info) return null;\n\n\tif (signal?.aborted) return null;\n\n\tconst config = loadGitHubConfig();\n\tif (!config.enabled) return null;\n\n\tconst { owner, repo } = info;\n\tconst key = cacheKey(owner, repo, info.ref);\n\n\tconst cached = cloneCache.get(key);\n\tif (cached) return awaitCachedClone(cached, url, owner, repo, info, signal);\n\n\tif (info.refIsFullSha) {\n\t\tif (signal?.aborted) return null;\n\t\tconst sizeNote = `Note: Commit SHA URLs use the GitHub API instead of cloning.`;\n\t\treturn fetchViaApi(url, owner, repo, info, sizeNote);\n\t}\n\n\tconst activityId = activityMonitor.logStart({ type: \"fetch\", url: `github.com/${owner}/${repo}` });\n\n\tif (!forceClone) {\n\t\tconst sizeKB = await checkRepoSize(owner, repo);\n\t\tif (signal?.aborted) {\n\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t\treturn null;\n\t\t}\n\t\tif (sizeKB !== null) {\n\t\t\tconst sizeMB = sizeKB / 1024;\n\t\t\tif (sizeMB > config.maxRepoSizeMB) {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tconst sizeNote =\n\t\t\t\t\t`Note: Repository is ${Math.round(sizeMB)}MB (threshold: ${config.maxRepoSizeMB}MB). ` +\n\t\t\t\t\t`Showing API-fetched content instead of full clone. Ask the user if they'd like to clone the full repo -- ` +\n\t\t\t\t\t`if yes, call fetch_content again with the same URL and add forceClone: true to the params.`;\n\t\t\t\tconst apiView = await fetchViaApi(url, owner, repo, info, sizeNote);\n\t\t\t\tif (apiView) {\n\t\t\t\t\tactivityMonitor.logComplete(activityId, 200);\n\t\t\t\t\treturn apiView;\n\t\t\t\t}\n\t\t\t\tactivityMonitor.logError(activityId, \"api fallback unavailable for oversized repository\");\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (signal?.aborted) {\n\t\tactivityMonitor.logComplete(activityId, 0);\n\t\treturn null;\n\t}\n\n\t// Re-check: another concurrent caller may have started a clone while we awaited the size check\n\tconst cachedAfterSizeCheck = cloneCache.get(key);\n\tif (cachedAfterSizeCheck) {\n\t\tconst cachedResult = await awaitCachedClone(cachedAfterSizeCheck, url, owner, repo, info, signal);\n\t\tif (signal?.aborted) {\n\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t} else if (cachedResult) {\n\t\t\tactivityMonitor.logComplete(activityId, 200);\n\t\t} else {\n\t\t\tactivityMonitor.logError(activityId, \"clone failed\");\n\t\t}\n\t\treturn cachedResult;\n\t}\n\n\tconst clonePromise = cloneRepo(owner, repo, info.ref, config, signal);\n\tconst localPath = cloneDir(config, owner, repo, info.ref);\n\tcloneCache.set(key, { localPath, clonePromise });\n\n\tconst result = await clonePromise;\n\tif (signal?.aborted) {\n\t\tif (!result) cloneCache.delete(key);\n\t\tactivityMonitor.logComplete(activityId, 0);\n\t\treturn null;\n\t}\n\n\tif (!result) {\n\t\tcloneCache.delete(key);\n\t\tif (signal?.aborted) {\n\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t\treturn null;\n\t\t}\n\n\t\tconst apiFallback = await fetchViaApi(url, owner, repo, info);\n\t\tif (apiFallback) {\n\t\t\tactivityMonitor.logComplete(activityId, 200);\n\t\t\treturn apiFallback;\n\t\t}\n\n\t\tactivityMonitor.logError(activityId, \"clone and API fallback failed\");\n\t\treturn null;\n\t}\n\n\tactivityMonitor.logComplete(activityId, 200);\n\tconst content = generateContent(result, info);\n\tconst title = info.path ? `${owner}/${repo} - ${info.path}` : `${owner}/${repo}`;\n\treturn { url, title, content, error: null };\n}\n\nexport function clearCloneCache(): void {\n\tfor (const entry of cloneCache.values()) {\n\t\ttry {\n\t\t\trmSync(entry.localPath, { recursive: true, force: true });\n\t\t} catch {\n\t\t}\n\t}\n\tcloneCache.clear();\n\tcachedConfig = null;\n}\n\nregisterSessionCleanup(clearCloneCache);\n"]}
|
|
1
|
+
{"version":3,"file":"github-extract.d.ts","sourceRoot":"","sources":["../../../src/builtin-extensions/pi-web-access/github-extract.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AA8BrD,MAAM,WAAW,aAAa;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;CAC/B;AAsID,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAiDhE;AA+XD,wBAAsB,aAAa,CAClC,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,WAAW,EACpB,UAAU,CAAC,EAAE,OAAO,GAClB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CA8GlC","sourcesContent":["// @ts-nocheck\nimport { existsSync, readFileSync, rmSync, statSync, readdirSync, openSync, readSync, closeSync, realpathSync } from \"node:fs\";\nimport { execFile } from \"node:child_process\";\nimport { extname, join, resolve as resolvePath, sep as pathSep } from \"node:path\";\nimport { activityMonitor } from \"./activity.ts\";\nimport type { ExtractedContent } from \"./extract.ts\";\nimport { checkGhAvailable, checkRepoSize, fetchViaApi, showGhHint } from \"./github-api.ts\";\nimport { getWebSession, type WebSession } from \"./session-cleanup.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst CONFIG_PATH = getWebSearchConfigPath();\n\nconst BINARY_EXTENSIONS = new Set([\n\t\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\", \".ico\", \".webp\", \".svg\", \".tiff\", \".tif\",\n\t\".mp3\", \".mp4\", \".avi\", \".mov\", \".mkv\", \".flv\", \".wmv\", \".wav\", \".ogg\", \".webm\", \".flac\", \".aac\",\n\t\".zip\", \".tar\", \".gz\", \".bz2\", \".xz\", \".7z\", \".rar\", \".zst\",\n\t\".exe\", \".dll\", \".so\", \".dylib\", \".bin\", \".o\", \".a\", \".lib\",\n\t\".woff\", \".woff2\", \".ttf\", \".otf\", \".eot\",\n\t\".pdf\", \".doc\", \".docx\", \".xls\", \".xlsx\", \".ppt\", \".pptx\",\n\t\".sqlite\", \".db\", \".sqlite3\",\n\t\".pyc\", \".pyo\", \".class\", \".jar\", \".war\",\n\t\".iso\", \".img\", \".dmg\",\n]);\n\nconst NOISE_DIRS = new Set([\n\t\"node_modules\", \"vendor\", \".next\", \"dist\", \"build\", \"__pycache__\",\n\t\".venv\", \"venv\", \".tox\", \".mypy_cache\", \".pytest_cache\",\n\t\"target\", \".gradle\", \".idea\", \".vscode\",\n]);\n\nconst MAX_INLINE_FILE_CHARS = 100_000;\nconst MAX_TREE_ENTRIES = 200;\nconst CLONE_TERMINATION_GRACE_MS = 1_000;\nconst CLONE_EXIT_CONFIRMATION_MS = 1_000;\n\nexport interface GitHubUrlInfo {\n\towner: string;\n\trepo: string;\n\tref?: string;\n\trefIsFullSha: boolean;\n\tpath?: string;\n\ttype: \"root\" | \"blob\" | \"tree\";\n}\n\ninterface CachedClone {\n\tlocalPath: string;\n\tclonePromise: Promise<string | null>;\n\tcontroller: AbortController;\n\towners: Set<WebSession | symbol>;\n\tcleanup?: Promise<void>;\n}\n\ninterface GitHubCloneConfig {\n\tenabled: boolean;\n\tmaxRepoSizeMB: number;\n\tcloneTimeoutSeconds: number;\n\tclonePath: string;\n}\n\nconst cloneCache = new Map<string, CachedClone>();\nconst standaloneOwner = Symbol(\"standalone clone caller\");\n\nfunction removeClone(key: string, entry: CachedClone): void {\n\tif (cloneCache.get(key) !== entry) return;\n\ttry { rmSync(entry.localPath, { recursive: true, force: true }); } catch {}\n\tcloneCache.delete(key);\n\tif (cloneCache.size === 0) cachedConfig = null;\n}\n\n/** Never release a clone directory while its command may still be writing into it. */\nasync function finishClone(key: string, entry: CachedClone): Promise<void> {\n\tlet deadline: ReturnType<typeof setTimeout> | undefined;\n\ttry {\n\t\tawait Promise.race([\n\t\t\tentry.clonePromise.catch(() => undefined),\n\t\t\tnew Promise<never>((_resolve, reject) => {\n\t\t\t\tdeadline = setTimeout(() => reject(new Error(\n\t\t\t\t\t\"GitHub clone cleanup could not confirm command completion after termination; clone retained until completion\",\n\t\t\t\t)), CLONE_TERMINATION_GRACE_MS + CLONE_EXIT_CONFIRMATION_MS);\n\t\t\t}),\n\t\t]);\n\t} catch (error) {\n\t\t// Keep the failed cleanup visible to new callers, but permit retry after the command eventually exits.\n\t\tvoid entry.clonePromise.catch(() => undefined).then(() => removeClone(key, entry));\n\t\tthrow error;\n\t} finally {\n\t\tclearTimeout(deadline);\n\t}\n\tremoveClone(key, entry);\n}\n\n/** Keep a shared clone alive until its final session releases it, including pending clones. */\nfunction acquireClone(key: string, entry: CachedClone): void {\n\tconst owner = getWebSession() ?? standaloneOwner;\n\tif (typeof owner !== \"symbol\" && owner.closed) throw new Error(\"Web session closed\");\n\tif (entry.owners.has(owner)) return;\n\tentry.owners.add(owner);\n\tif (typeof owner !== \"symbol\") owner.cleanups.add(async () => {\n\t\tentry.owners.delete(owner);\n\t\tif (entry.owners.size > 0) return;\n\t\tentry.controller.abort();\n\t\tentry.cleanup = finishClone(key, entry);\n\t\tawait entry.cleanup;\n\t});\n}\n\nasync function findClone(key: string): Promise<CachedClone | undefined> {\n\tconst entry = cloneCache.get(key);\n\tif (entry?.cleanup) {\n\t\tawait entry.cleanup;\n\t\treturn findClone(key);\n\t}\n\tif (entry && !getWebSession()?.closed) acquireClone(key, entry);\n\treturn entry;\n}\n\nlet cachedConfig: GitHubCloneConfig | null = null;\n\nfunction normalizeEnabled(value: unknown, fallback: boolean): boolean {\n\treturn typeof value === \"boolean\" ? value : fallback;\n}\n\nfunction normalizePositiveNumber(value: unknown, fallback: number): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value)) return fallback;\n\treturn value > 0 ? value : fallback;\n}\n\nfunction normalizeClonePath(value: unknown, fallback: string): string {\n\tif (typeof value !== \"string\") return fallback;\n\tconst normalized = value.trim();\n\treturn normalized.length > 0 ? normalized : fallback;\n}\n\nfunction loadGitHubConfig(): GitHubCloneConfig {\n\tif (cachedConfig) return cachedConfig;\n\n\tconst defaults: GitHubCloneConfig = {\n\t\tenabled: true,\n\t\tmaxRepoSizeMB: 350,\n\t\tcloneTimeoutSeconds: 30,\n\t\tclonePath: \"/tmp/pi-github-repos\",\n\t};\n\n\tif (!existsSync(CONFIG_PATH)) {\n\t\tcachedConfig = defaults;\n\t\treturn cachedConfig;\n\t}\n\n\tconst rawText = readFileSync(CONFIG_PATH, \"utf-8\");\n\tlet raw: { githubClone?: { enabled?: unknown; maxRepoSizeMB?: unknown; cloneTimeoutSeconds?: unknown; clonePath?: unknown } };\n\ttry {\n\t\traw = JSON.parse(rawText) as { githubClone?: { enabled?: unknown; maxRepoSizeMB?: unknown; cloneTimeoutSeconds?: unknown; clonePath?: unknown } };\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);\n\t}\n\n\tconst gc = raw.githubClone ?? {};\n\tcachedConfig = {\n\t\tenabled: normalizeEnabled(gc.enabled, defaults.enabled),\n\t\tmaxRepoSizeMB: normalizePositiveNumber(gc.maxRepoSizeMB, defaults.maxRepoSizeMB),\n\t\tcloneTimeoutSeconds: normalizePositiveNumber(gc.cloneTimeoutSeconds, defaults.cloneTimeoutSeconds),\n\t\tclonePath: normalizeClonePath(gc.clonePath, defaults.clonePath),\n\t};\n\treturn cachedConfig;\n}\n\nconst NON_CODE_SEGMENTS = new Set([\n\t\"issues\", \"pull\", \"pulls\", \"discussions\", \"releases\", \"wiki\",\n\t\"actions\", \"settings\", \"security\", \"projects\", \"graphs\",\n\t\"compare\", \"commits\", \"tags\", \"branches\", \"stargazers\",\n\t\"watchers\", \"network\", \"forks\", \"milestone\", \"labels\",\n\t\"packages\", \"codespaces\", \"contribute\", \"community\",\n\t\"sponsors\", \"invitations\", \"notifications\", \"insights\",\n]);\n\nexport function parseGitHubUrl(url: string): GitHubUrlInfo | null {\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(url);\n\t} catch {\n\t\treturn null;\n\t}\n\n\tconst host = parsed.hostname.toLowerCase();\n\tif (host !== \"github.com\" && host !== \"www.github.com\") return null;\n\n\tconst segments = parsed.pathname\n\t\t.split(\"/\")\n\t\t.filter(Boolean)\n\t\t.map((segment) => {\n\t\t\ttry {\n\t\t\t\treturn decodeURIComponent(segment);\n\t\t\t} catch {\n\t\t\t\treturn segment;\n\t\t\t}\n\t\t});\n\tif (segments.length < 2) return null;\n\n\tconst owner = segments[0];\n\tconst repo = segments[1].replace(/\\.git$/, \"\");\n\n\tif (NON_CODE_SEGMENTS.has(segments[2]?.toLowerCase())) return null;\n\n\tif (segments.length === 2) {\n\t\treturn { owner, repo, refIsFullSha: false, type: \"root\" };\n\t}\n\n\tconst action = segments[2];\n\tif (action !== \"blob\" && action !== \"tree\") return null;\n\tif (segments.length < 4) return null;\n\n\tconst ref = segments[3];\n\tconst refIsFullSha = /^[0-9a-f]{40}$/.test(ref);\n\tconst pathParts = segments.slice(4);\n\tconst path = pathParts.length > 0 ? pathParts.join(\"/\") : \"\";\n\n\treturn {\n\t\towner,\n\t\trepo,\n\t\tref,\n\t\trefIsFullSha,\n\t\tpath,\n\t\ttype: action as \"blob\" | \"tree\",\n\t};\n}\n\nfunction cacheKey(owner: string, repo: string, ref?: string): string {\n\treturn ref ? `${owner}/${repo}@${ref}` : `${owner}/${repo}`;\n}\n\nfunction cloneDir(config: GitHubCloneConfig, owner: string, repo: string, ref?: string): string {\n\tconst dirName = ref ? `${repo}@${ref}` : repo;\n\treturn join(config.clonePath, owner, dirName);\n}\n\nfunction execClone(args: string[], localPath: string, timeoutMs: number, signal?: AbortSignal): Promise<string | null> {\n\tif (signal?.aborted) return Promise.resolve(null);\n\treturn new Promise((resolve) => {\n\t\tlet failed = false;\n\t\tlet exited = false;\n\t\tlet closed = false;\n\t\tlet stopping = false;\n\t\tlet escalation: ReturnType<typeof setTimeout> | undefined;\n\t\t// An execFile callback may also report a kill error while the process is still alive.\n\t\tconst child = execFile(args[0], args.slice(1), {}, (err) => { failed = Boolean(err); });\n\t\tconst stop = () => {\n\t\t\tif (stopping || closed) return;\n\t\t\tstopping = true;\n\t\t\tescalation = setTimeout(() => {\n\t\t\t\ttry { child.kill(\"SIGKILL\"); } catch {}\n\t\t\t}, CLONE_TERMINATION_GRACE_MS);\n\t\t\ttry { child.kill(\"SIGTERM\"); } catch {}\n\t\t};\n\t\tconst timeout = setTimeout(stop, timeoutMs);\n\t\tchild.once(\"exit\", () => { exited = true; });\n\t\tchild.once(\"close\", () => {\n\t\t\t// Failed spawning has no PID. A spawned command must actually exit before output can be released.\n\t\t\tif (child.pid && !exited) return;\n\t\t\tclosed = true;\n\t\t\tclearTimeout(timeout);\n\t\t\tclearTimeout(escalation);\n\t\t\tsignal?.removeEventListener(\"abort\", stop);\n\t\t\tif (failed || stopping) {\n\t\t\t\ttry { rmSync(localPath, { recursive: true, force: true }); } catch {}\n\t\t\t\tresolve(null);\n\t\t\t} else {\n\t\t\t\tresolve(localPath);\n\t\t\t}\n\t\t});\n\t\tsignal?.addEventListener(\"abort\", stop, { once: true });\n\t});\n}\n\nasync function cloneRepo(\n\towner: string,\n\trepo: string,\n\tref: string | undefined,\n\tconfig: GitHubCloneConfig,\n\tsignal?: AbortSignal,\n): Promise<string | null> {\n\tconst localPath = cloneDir(config, owner, repo, ref);\n\n\ttry {\n\t\trmSync(localPath, { recursive: true, force: true });\n\t} catch {\n\t}\n\n\tconst timeoutMs = config.cloneTimeoutSeconds * 1000;\n\tconst hasGh = await checkGhAvailable();\n\tif (signal?.aborted) return null;\n\n\tif (hasGh) {\n\t\tconst args = [\"gh\", \"repo\", \"clone\", `${owner}/${repo}`, localPath, \"--\", \"--depth\", \"1\", \"--single-branch\"];\n\t\tif (ref) args.push(\"--branch\", ref);\n\t\treturn execClone(args, localPath, timeoutMs, signal);\n\t}\n\n\tshowGhHint();\n\n\tconst gitUrl = `https://github.com/${owner}/${repo}.git`;\n\tconst args = [\"git\", \"clone\", \"--depth\", \"1\", \"--single-branch\"];\n\tif (ref) args.push(\"--branch\", ref);\n\targs.push(gitUrl, localPath);\n\treturn execClone(args, localPath, timeoutMs, signal);\n}\n\nfunction isBinaryFile(filePath: string): boolean {\n\tconst ext = extname(filePath).toLowerCase();\n\tif (BINARY_EXTENSIONS.has(ext)) return true;\n\n\tlet fd: number;\n\ttry {\n\t\tfd = openSync(filePath, \"r\");\n\t} catch {\n\t\treturn false;\n\t}\n\ttry {\n\t\tconst buf = Buffer.alloc(512);\n\t\tconst bytesRead = readSync(fd, buf, 0, 512, 0);\n\t\tfor (let i = 0; i < bytesRead; i++) {\n\t\t\tif (buf[i] === 0) return true;\n\t\t}\n\t} catch {\n\t\treturn false;\n\t} finally {\n\t\tcloseSync(fd);\n\t}\n\n\treturn false;\n}\n\nfunction formatFileSize(bytes: number): string {\n\tif (bytes < 1024) return `${bytes} B`;\n\tif (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n\treturn `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction resolveWithinRepo(rootPath: string, relativePath: string): string | null {\n\tconst normalizedRoot = resolvePath(rootPath);\n\tconst candidate = resolvePath(normalizedRoot, relativePath);\n\tif (candidate !== normalizedRoot) {\n\t\tconst rootPrefix = normalizedRoot.endsWith(pathSep) ? normalizedRoot : normalizedRoot + pathSep;\n\t\tif (!candidate.startsWith(rootPrefix)) return null;\n\t}\n\n\tif (!existsSync(candidate)) return candidate;\n\n\ttry {\n\t\tconst realRoot = realpathSync(normalizedRoot);\n\t\tconst realCandidate = realpathSync(candidate);\n\t\tif (realCandidate === realRoot) return candidate;\n\t\tconst realRootPrefix = realRoot.endsWith(pathSep) ? realRoot : realRoot + pathSep;\n\t\treturn realCandidate.startsWith(realRootPrefix) ? candidate : null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction readTextFile(path: string): string | null {\n\ttry {\n\t\treturn readFileSync(path, \"utf-8\");\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction buildTree(rootPath: string): string {\n\tconst entries: string[] = [];\n\n\tfunction walk(dir: string, relPath: string): void {\n\t\tif (entries.length >= MAX_TREE_ENTRIES) return;\n\n\t\tlet items: string[];\n\t\ttry {\n\t\t\titems = readdirSync(dir).sort();\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const item of items) {\n\t\t\tif (entries.length >= MAX_TREE_ENTRIES) return;\n\t\t\tif (item === \".git\") continue;\n\n\t\t\tconst rel = relPath ? `${relPath}/${item}` : item;\n\t\t\tconst safePath = resolveWithinRepo(rootPath, rel);\n\t\t\tif (!safePath) {\n\t\t\t\tentries.push(`${rel} [outside repo skipped]`);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet stat;\n\t\t\ttry {\n\t\t\t\tstat = statSync(safePath);\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (stat.isDirectory()) {\n\t\t\t\tif (NOISE_DIRS.has(item)) {\n\t\t\t\t\tentries.push(`${rel}/ [skipped]`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tentries.push(`${rel}/`);\n\t\t\t\twalk(safePath, rel);\n\t\t\t} else {\n\t\t\t\tentries.push(rel);\n\t\t\t}\n\t\t}\n\t}\n\n\twalk(rootPath, \"\");\n\n\tif (entries.length >= MAX_TREE_ENTRIES) {\n\t\tentries.push(`... (truncated at ${MAX_TREE_ENTRIES} entries)`);\n\t}\n\n\treturn entries.join(\"\\n\");\n}\n\nfunction buildDirListing(rootPath: string, subPath: string): string {\n\tconst targetPath = resolveWithinRepo(rootPath, subPath);\n\tif (!targetPath) return \"(path escapes repository root)\";\n\tconst lines: string[] = [];\n\n\tlet items: string[];\n\ttry {\n\t\titems = readdirSync(targetPath).sort();\n\t} catch {\n\t\treturn \"(directory not readable)\";\n\t}\n\n\tfor (const item of items) {\n\t\tif (item === \".git\") continue;\n\t\tconst rel = subPath ? `${subPath}/${item}` : item;\n\t\tconst safePath = resolveWithinRepo(rootPath, rel);\n\t\tif (!safePath) {\n\t\t\tlines.push(` ${item} (outside repo)`);\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\tconst stat = statSync(safePath);\n\t\t\tif (stat.isDirectory()) {\n\t\t\t\tlines.push(` ${item}/`);\n\t\t\t} else {\n\t\t\t\tlines.push(` ${item} (${formatFileSize(stat.size)})`);\n\t\t\t}\n\t\t} catch {\n\t\t\tlines.push(` ${item} (unreadable)`);\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\nfunction readReadme(localPath: string): string | null {\n\tconst candidates = [\"README.md\", \"readme.md\", \"README\", \"README.txt\", \"README.rst\"];\n\tfor (const name of candidates) {\n\t\tconst readmePath = join(localPath, name);\n\t\tif (existsSync(readmePath)) {\n\t\t\ttry {\n\t\t\t\tconst content = readFileSync(readmePath, \"utf-8\");\n\t\t\t\treturn content.length > 8192 ? content.slice(0, 8192) + \"\\n\\n[README truncated at 8K chars]\" : content;\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction generateContent(localPath: string, info: GitHubUrlInfo): string {\n\tconst lines: string[] = [];\n\tlines.push(`Repository cloned to: ${localPath}`);\n\tlines.push(\"\");\n\n\tif (info.type === \"root\") {\n\t\tlines.push(\"## Structure\");\n\t\tlines.push(buildTree(localPath));\n\t\tlines.push(\"\");\n\n\t\tconst readme = readReadme(localPath);\n\t\tif (readme) {\n\t\t\tlines.push(\"## README.md\");\n\t\t\tlines.push(readme);\n\t\t\tlines.push(\"\");\n\t\t}\n\n\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\tif (info.type === \"tree\") {\n\t\tconst dirPath = info.path || \"\";\n\t\tconst fullDirPath = resolveWithinRepo(localPath, dirPath);\n\n\t\tif (!fullDirPath || !existsSync(fullDirPath)) {\n\t\t\tlines.push(`Path \\`${dirPath}\\` not found in clone. Showing repository root instead.`);\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"## Structure\");\n\t\t\tlines.push(buildTree(localPath));\n\t\t} else {\n\t\t\tlines.push(`## ${dirPath || \"/\"}`);\n\t\t\tlines.push(buildDirListing(localPath, dirPath));\n\t\t}\n\n\t\tlines.push(\"\");\n\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\tif (info.type === \"blob\") {\n\t\tconst filePath = info.path || \"\";\n\t\tconst fullFilePath = resolveWithinRepo(localPath, filePath);\n\n\t\tif (!fullFilePath || !existsSync(fullFilePath)) {\n\t\t\tlines.push(`Path \\`${filePath}\\` not found in clone. Showing repository root instead.`);\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"## Structure\");\n\t\t\tlines.push(buildTree(localPath));\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\n\t\tlet stat: ReturnType<typeof statSync>;\n\t\ttry {\n\t\t\tstat = statSync(fullFilePath);\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t\tlines.push(`Could not inspect \\`${filePath}\\`: ${message}`);\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\n\t\tif (stat.isDirectory()) {\n\t\t\tlines.push(`## ${filePath || \"/\"}`);\n\t\t\tlines.push(buildDirListing(localPath, filePath));\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\n\t\tif (isBinaryFile(fullFilePath)) {\n\t\t\tconst ext = extname(filePath).replace(\".\", \"\");\n\t\t\tlines.push(`## ${filePath}`);\n\t\t\tlines.push(`Binary file (${ext}, ${formatFileSize(stat.size)}). Use \\`read\\` or \\`bash\\` tools at the path above to inspect.`);\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\n\t\tconst content = readTextFile(fullFilePath);\n\t\tif (content === null) {\n\t\t\tlines.push(`Could not read \\`${filePath}\\` as UTF-8 text.`);\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\t\tlines.push(`## ${filePath}`);\n\n\t\tif (content.length > MAX_INLINE_FILE_CHARS) {\n\t\t\tlines.push(content.slice(0, MAX_INLINE_FILE_CHARS));\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(`[File truncated at 100K chars. Full file: ${fullFilePath}]`);\n\t\t} else {\n\t\t\tlines.push(content);\n\t\t}\n\n\t\tlines.push(\"\");\n\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\n/** Cancel the caller's wait without cancelling a clone leased by another session. */\nasync function waitForClone(clone: Promise<string | null>, signal?: AbortSignal): Promise<string | null> {\n\tif (!signal) return clone;\n\tif (signal.aborted) return null;\n\tlet onAbort: () => void = () => {};\n\tconst cancelled = new Promise<null>((resolve) => {\n\t\tonAbort = () => resolve(null);\n\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t});\n\ttry { return await Promise.race([clone, cancelled]); }\n\tfinally { signal.removeEventListener(\"abort\", onAbort); }\n}\n\nasync function awaitCachedClone(\n\tcached: CachedClone,\n\turl: string,\n\towner: string,\n\trepo: string,\n\tinfo: GitHubUrlInfo,\n\tsignal?: AbortSignal,\n): Promise<ExtractedContent | null> {\n\tif (signal?.aborted) return null;\n\tconst result = await waitForClone(cached.clonePromise, signal);\n\tif (signal?.aborted || getWebSession()?.closed) return null;\n\tif (result) {\n\t\tconst content = generateContent(result, info);\n\t\tconst title = info.path ? `${owner}/${repo} - ${info.path}` : `${owner}/${repo}`;\n\t\treturn { url, title, content, error: null };\n\t}\n\treturn fetchViaApi(url, owner, repo, info);\n}\n\nexport async function extractGitHub(\n\turl: string,\n\tsignal?: AbortSignal,\n\tforceClone?: boolean,\n): Promise<ExtractedContent | null> {\n\tconst info = parseGitHubUrl(url);\n\tif (!info) return null;\n\n\tif (signal?.aborted) return null;\n\n\tconst config = loadGitHubConfig();\n\tif (!config.enabled) return null;\n\n\tconst { owner, repo } = info;\n\tconst key = cacheKey(owner, repo, info.ref);\n\n\tconst cached = await findClone(key);\n\tif (signal?.aborted || getWebSession()?.closed) return null;\n\tif (cached) {\n\t\treturn awaitCachedClone(cached, url, owner, repo, info, signal);\n\t}\n\n\tif (info.refIsFullSha) {\n\t\tif (signal?.aborted) return null;\n\t\tconst sizeNote = `Note: Commit SHA URLs use the GitHub API instead of cloning.`;\n\t\treturn fetchViaApi(url, owner, repo, info, sizeNote);\n\t}\n\n\tconst activityId = activityMonitor.logStart({ type: \"fetch\", url: `github.com/${owner}/${repo}` });\n\n\tif (!forceClone) {\n\t\tconst sizeKB = await checkRepoSize(owner, repo);\n\t\tif (signal?.aborted) {\n\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t\treturn null;\n\t\t}\n\t\tif (sizeKB !== null) {\n\t\t\tconst sizeMB = sizeKB / 1024;\n\t\t\tif (sizeMB > config.maxRepoSizeMB) {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tconst sizeNote =\n\t\t\t\t\t`Note: Repository is ${Math.round(sizeMB)}MB (threshold: ${config.maxRepoSizeMB}MB). ` +\n\t\t\t\t\t`Showing API-fetched content instead of full clone. Ask the user if they'd like to clone the full repo -- ` +\n\t\t\t\t\t`if yes, call fetch_content again with the same URL and add forceClone: true to the params.`;\n\t\t\t\tconst apiView = await fetchViaApi(url, owner, repo, info, sizeNote);\n\t\t\t\tif (apiView) {\n\t\t\t\t\tactivityMonitor.logComplete(activityId, 200);\n\t\t\t\t\treturn apiView;\n\t\t\t\t}\n\t\t\t\tactivityMonitor.logError(activityId, \"api fallback unavailable for oversized repository\");\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (signal?.aborted) {\n\t\tactivityMonitor.logComplete(activityId, 0);\n\t\treturn null;\n\t}\n\n\t// Re-check: another concurrent caller may have started a clone while we awaited the size check\n\tlet cachedAfterSizeCheck = await findClone(key);\n\twhile (!cachedAfterSizeCheck && cloneCache.has(key)) cachedAfterSizeCheck = await findClone(key);\n\tif (signal?.aborted || getWebSession()?.closed) return null;\n\tif (cachedAfterSizeCheck) {\n\t\tconst cachedResult = await awaitCachedClone(cachedAfterSizeCheck, url, owner, repo, info, signal);\n\t\tif (signal?.aborted) {\n\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t} else if (cachedResult) {\n\t\t\tactivityMonitor.logComplete(activityId, 200);\n\t\t} else {\n\t\t\tactivityMonitor.logError(activityId, \"clone failed\");\n\t\t}\n\t\treturn cachedResult;\n\t}\n\n\tif (signal?.aborted || getWebSession()?.closed) return null;\n\tconst controller = new AbortController();\n\tconst clonePromise = cloneRepo(owner, repo, info.ref, config, controller.signal);\n\tconst localPath = cloneDir(config, owner, repo, info.ref);\n\tconst entry: CachedClone = { localPath, clonePromise, controller, owners: new Set() };\n\tcloneCache.set(key, entry);\n\tacquireClone(key, entry);\n\n\tconst result = await waitForClone(clonePromise, signal);\n\tif (signal?.aborted || getWebSession()?.closed) {\n\t\tactivityMonitor.logComplete(activityId, 0);\n\t\treturn null;\n\t}\n\n\tif (!result) {\n\t\tif (cloneCache.get(key) === entry) cloneCache.delete(key);\n\t\tif (signal?.aborted) {\n\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t\treturn null;\n\t\t}\n\n\t\tconst apiFallback = await fetchViaApi(url, owner, repo, info);\n\t\tif (apiFallback) {\n\t\t\tactivityMonitor.logComplete(activityId, 200);\n\t\t\treturn apiFallback;\n\t\t}\n\n\t\tactivityMonitor.logError(activityId, \"clone and API fallback failed\");\n\t\treturn null;\n\t}\n\n\tactivityMonitor.logComplete(activityId, 200);\n\tconst content = generateContent(result, info);\n\tconst title = info.path ? `${owner}/${repo} - ${info.path}` : `${owner}/${repo}`;\n\treturn { url, title, content, error: null };\n}\n"]}
|
|
@@ -4,7 +4,7 @@ import { execFile } from "node:child_process";
|
|
|
4
4
|
import { extname, join, resolve as resolvePath, sep as pathSep } from "node:path";
|
|
5
5
|
import { activityMonitor } from "./activity.js";
|
|
6
6
|
import { checkGhAvailable, checkRepoSize, fetchViaApi, showGhHint } from "./github-api.js";
|
|
7
|
-
import {
|
|
7
|
+
import { getWebSession } from "./session-cleanup.js";
|
|
8
8
|
import { getWebSearchConfigPath } from "./utils.js";
|
|
9
9
|
const CONFIG_PATH = getWebSearchConfigPath();
|
|
10
10
|
const BINARY_EXTENSIONS = new Set([
|
|
@@ -25,7 +25,70 @@ const NOISE_DIRS = new Set([
|
|
|
25
25
|
]);
|
|
26
26
|
const MAX_INLINE_FILE_CHARS = 100_000;
|
|
27
27
|
const MAX_TREE_ENTRIES = 200;
|
|
28
|
+
const CLONE_TERMINATION_GRACE_MS = 1_000;
|
|
29
|
+
const CLONE_EXIT_CONFIRMATION_MS = 1_000;
|
|
28
30
|
const cloneCache = new Map();
|
|
31
|
+
const standaloneOwner = Symbol("standalone clone caller");
|
|
32
|
+
function removeClone(key, entry) {
|
|
33
|
+
if (cloneCache.get(key) !== entry)
|
|
34
|
+
return;
|
|
35
|
+
try {
|
|
36
|
+
rmSync(entry.localPath, { recursive: true, force: true });
|
|
37
|
+
}
|
|
38
|
+
catch { }
|
|
39
|
+
cloneCache.delete(key);
|
|
40
|
+
if (cloneCache.size === 0)
|
|
41
|
+
cachedConfig = null;
|
|
42
|
+
}
|
|
43
|
+
/** Never release a clone directory while its command may still be writing into it. */
|
|
44
|
+
async function finishClone(key, entry) {
|
|
45
|
+
let deadline;
|
|
46
|
+
try {
|
|
47
|
+
await Promise.race([
|
|
48
|
+
entry.clonePromise.catch(() => undefined),
|
|
49
|
+
new Promise((_resolve, reject) => {
|
|
50
|
+
deadline = setTimeout(() => reject(new Error("GitHub clone cleanup could not confirm command completion after termination; clone retained until completion")), CLONE_TERMINATION_GRACE_MS + CLONE_EXIT_CONFIRMATION_MS);
|
|
51
|
+
}),
|
|
52
|
+
]);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
// Keep the failed cleanup visible to new callers, but permit retry after the command eventually exits.
|
|
56
|
+
void entry.clonePromise.catch(() => undefined).then(() => removeClone(key, entry));
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
clearTimeout(deadline);
|
|
61
|
+
}
|
|
62
|
+
removeClone(key, entry);
|
|
63
|
+
}
|
|
64
|
+
/** Keep a shared clone alive until its final session releases it, including pending clones. */
|
|
65
|
+
function acquireClone(key, entry) {
|
|
66
|
+
const owner = getWebSession() ?? standaloneOwner;
|
|
67
|
+
if (typeof owner !== "symbol" && owner.closed)
|
|
68
|
+
throw new Error("Web session closed");
|
|
69
|
+
if (entry.owners.has(owner))
|
|
70
|
+
return;
|
|
71
|
+
entry.owners.add(owner);
|
|
72
|
+
if (typeof owner !== "symbol")
|
|
73
|
+
owner.cleanups.add(async () => {
|
|
74
|
+
entry.owners.delete(owner);
|
|
75
|
+
if (entry.owners.size > 0)
|
|
76
|
+
return;
|
|
77
|
+
entry.controller.abort();
|
|
78
|
+
entry.cleanup = finishClone(key, entry);
|
|
79
|
+
await entry.cleanup;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
async function findClone(key) {
|
|
83
|
+
const entry = cloneCache.get(key);
|
|
84
|
+
if (entry?.cleanup) {
|
|
85
|
+
await entry.cleanup;
|
|
86
|
+
return findClone(key);
|
|
87
|
+
}
|
|
88
|
+
if (entry && !getWebSession()?.closed)
|
|
89
|
+
acquireClone(key, entry);
|
|
90
|
+
return entry;
|
|
91
|
+
}
|
|
29
92
|
let cachedConfig = null;
|
|
30
93
|
function normalizeEnabled(value, fallback) {
|
|
31
94
|
return typeof value === "boolean" ? value : fallback;
|
|
@@ -137,24 +200,53 @@ function cloneDir(config, owner, repo, ref) {
|
|
|
137
200
|
return join(config.clonePath, owner, dirName);
|
|
138
201
|
}
|
|
139
202
|
function execClone(args, localPath, timeoutMs, signal) {
|
|
203
|
+
if (signal?.aborted)
|
|
204
|
+
return Promise.resolve(null);
|
|
140
205
|
return new Promise((resolve) => {
|
|
141
|
-
|
|
142
|
-
|
|
206
|
+
let failed = false;
|
|
207
|
+
let exited = false;
|
|
208
|
+
let closed = false;
|
|
209
|
+
let stopping = false;
|
|
210
|
+
let escalation;
|
|
211
|
+
// An execFile callback may also report a kill error while the process is still alive.
|
|
212
|
+
const child = execFile(args[0], args.slice(1), {}, (err) => { failed = Boolean(err); });
|
|
213
|
+
const stop = () => {
|
|
214
|
+
if (stopping || closed)
|
|
215
|
+
return;
|
|
216
|
+
stopping = true;
|
|
217
|
+
escalation = setTimeout(() => {
|
|
143
218
|
try {
|
|
144
|
-
|
|
219
|
+
child.kill("SIGKILL");
|
|
145
220
|
}
|
|
146
|
-
catch {
|
|
221
|
+
catch { }
|
|
222
|
+
}, CLONE_TERMINATION_GRACE_MS);
|
|
223
|
+
try {
|
|
224
|
+
child.kill("SIGTERM");
|
|
225
|
+
}
|
|
226
|
+
catch { }
|
|
227
|
+
};
|
|
228
|
+
const timeout = setTimeout(stop, timeoutMs);
|
|
229
|
+
child.once("exit", () => { exited = true; });
|
|
230
|
+
child.once("close", () => {
|
|
231
|
+
// Failed spawning has no PID. A spawned command must actually exit before output can be released.
|
|
232
|
+
if (child.pid && !exited)
|
|
233
|
+
return;
|
|
234
|
+
closed = true;
|
|
235
|
+
clearTimeout(timeout);
|
|
236
|
+
clearTimeout(escalation);
|
|
237
|
+
signal?.removeEventListener("abort", stop);
|
|
238
|
+
if (failed || stopping) {
|
|
239
|
+
try {
|
|
240
|
+
rmSync(localPath, { recursive: true, force: true });
|
|
147
241
|
}
|
|
242
|
+
catch { }
|
|
148
243
|
resolve(null);
|
|
149
|
-
return;
|
|
150
244
|
}
|
|
151
|
-
|
|
245
|
+
else {
|
|
246
|
+
resolve(localPath);
|
|
247
|
+
}
|
|
152
248
|
});
|
|
153
|
-
|
|
154
|
-
const onAbort = () => child.kill();
|
|
155
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
156
|
-
child.on("exit", () => signal.removeEventListener("abort", onAbort));
|
|
157
|
-
}
|
|
249
|
+
signal?.addEventListener("abort", stop, { once: true });
|
|
158
250
|
});
|
|
159
251
|
}
|
|
160
252
|
async function cloneRepo(owner, repo, ref, config, signal) {
|
|
@@ -166,6 +258,8 @@ async function cloneRepo(owner, repo, ref, config, signal) {
|
|
|
166
258
|
}
|
|
167
259
|
const timeoutMs = config.cloneTimeoutSeconds * 1000;
|
|
168
260
|
const hasGh = await checkGhAvailable();
|
|
261
|
+
if (signal?.aborted)
|
|
262
|
+
return null;
|
|
169
263
|
if (hasGh) {
|
|
170
264
|
const args = ["gh", "repo", "clone", `${owner}/${repo}`, localPath, "--", "--depth", "1", "--single-branch"];
|
|
171
265
|
if (ref)
|
|
@@ -437,11 +531,29 @@ function generateContent(localPath, info) {
|
|
|
437
531
|
}
|
|
438
532
|
return lines.join("\n");
|
|
439
533
|
}
|
|
534
|
+
/** Cancel the caller's wait without cancelling a clone leased by another session. */
|
|
535
|
+
async function waitForClone(clone, signal) {
|
|
536
|
+
if (!signal)
|
|
537
|
+
return clone;
|
|
538
|
+
if (signal.aborted)
|
|
539
|
+
return null;
|
|
540
|
+
let onAbort = () => { };
|
|
541
|
+
const cancelled = new Promise((resolve) => {
|
|
542
|
+
onAbort = () => resolve(null);
|
|
543
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
544
|
+
});
|
|
545
|
+
try {
|
|
546
|
+
return await Promise.race([clone, cancelled]);
|
|
547
|
+
}
|
|
548
|
+
finally {
|
|
549
|
+
signal.removeEventListener("abort", onAbort);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
440
552
|
async function awaitCachedClone(cached, url, owner, repo, info, signal) {
|
|
441
553
|
if (signal?.aborted)
|
|
442
554
|
return null;
|
|
443
|
-
const result = await cached.clonePromise;
|
|
444
|
-
if (signal?.aborted)
|
|
555
|
+
const result = await waitForClone(cached.clonePromise, signal);
|
|
556
|
+
if (signal?.aborted || getWebSession()?.closed)
|
|
445
557
|
return null;
|
|
446
558
|
if (result) {
|
|
447
559
|
const content = generateContent(result, info);
|
|
@@ -461,9 +573,12 @@ export async function extractGitHub(url, signal, forceClone) {
|
|
|
461
573
|
return null;
|
|
462
574
|
const { owner, repo } = info;
|
|
463
575
|
const key = cacheKey(owner, repo, info.ref);
|
|
464
|
-
const cached =
|
|
465
|
-
if (
|
|
576
|
+
const cached = await findClone(key);
|
|
577
|
+
if (signal?.aborted || getWebSession()?.closed)
|
|
578
|
+
return null;
|
|
579
|
+
if (cached) {
|
|
466
580
|
return awaitCachedClone(cached, url, owner, repo, info, signal);
|
|
581
|
+
}
|
|
467
582
|
if (info.refIsFullSha) {
|
|
468
583
|
if (signal?.aborted)
|
|
469
584
|
return null;
|
|
@@ -502,7 +617,11 @@ export async function extractGitHub(url, signal, forceClone) {
|
|
|
502
617
|
return null;
|
|
503
618
|
}
|
|
504
619
|
// Re-check: another concurrent caller may have started a clone while we awaited the size check
|
|
505
|
-
|
|
620
|
+
let cachedAfterSizeCheck = await findClone(key);
|
|
621
|
+
while (!cachedAfterSizeCheck && cloneCache.has(key))
|
|
622
|
+
cachedAfterSizeCheck = await findClone(key);
|
|
623
|
+
if (signal?.aborted || getWebSession()?.closed)
|
|
624
|
+
return null;
|
|
506
625
|
if (cachedAfterSizeCheck) {
|
|
507
626
|
const cachedResult = await awaitCachedClone(cachedAfterSizeCheck, url, owner, repo, info, signal);
|
|
508
627
|
if (signal?.aborted) {
|
|
@@ -516,18 +635,22 @@ export async function extractGitHub(url, signal, forceClone) {
|
|
|
516
635
|
}
|
|
517
636
|
return cachedResult;
|
|
518
637
|
}
|
|
519
|
-
|
|
638
|
+
if (signal?.aborted || getWebSession()?.closed)
|
|
639
|
+
return null;
|
|
640
|
+
const controller = new AbortController();
|
|
641
|
+
const clonePromise = cloneRepo(owner, repo, info.ref, config, controller.signal);
|
|
520
642
|
const localPath = cloneDir(config, owner, repo, info.ref);
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
643
|
+
const entry = { localPath, clonePromise, controller, owners: new Set() };
|
|
644
|
+
cloneCache.set(key, entry);
|
|
645
|
+
acquireClone(key, entry);
|
|
646
|
+
const result = await waitForClone(clonePromise, signal);
|
|
647
|
+
if (signal?.aborted || getWebSession()?.closed) {
|
|
526
648
|
activityMonitor.logComplete(activityId, 0);
|
|
527
649
|
return null;
|
|
528
650
|
}
|
|
529
651
|
if (!result) {
|
|
530
|
-
cloneCache.
|
|
652
|
+
if (cloneCache.get(key) === entry)
|
|
653
|
+
cloneCache.delete(key);
|
|
531
654
|
if (signal?.aborted) {
|
|
532
655
|
activityMonitor.logComplete(activityId, 0);
|
|
533
656
|
return null;
|
|
@@ -545,16 +668,4 @@ export async function extractGitHub(url, signal, forceClone) {
|
|
|
545
668
|
const title = info.path ? `${owner}/${repo} - ${info.path}` : `${owner}/${repo}`;
|
|
546
669
|
return { url, title, content, error: null };
|
|
547
670
|
}
|
|
548
|
-
export function clearCloneCache() {
|
|
549
|
-
for (const entry of cloneCache.values()) {
|
|
550
|
-
try {
|
|
551
|
-
rmSync(entry.localPath, { recursive: true, force: true });
|
|
552
|
-
}
|
|
553
|
-
catch {
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
cloneCache.clear();
|
|
557
|
-
cachedConfig = null;
|
|
558
|
-
}
|
|
559
|
-
registerSessionCleanup(clearCloneCache);
|
|
560
671
|
//# sourceMappingURL=github-extract.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github-extract.js","sourceRoot":"","sources":["../../../src/builtin-extensions/pi-web-access/github-extract.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\nimport { existsSync, readFileSync, rmSync, statSync, readdirSync, openSync, readSync, closeSync, realpathSync } from \"node:fs\";\nimport { execFile } from \"node:child_process\";\nimport { extname, join, resolve as resolvePath, sep as pathSep } from \"node:path\";\nimport { activityMonitor } from \"./activity.ts\";\nimport type { ExtractedContent } from \"./extract.ts\";\nimport { checkGhAvailable, checkRepoSize, fetchViaApi, showGhHint } from \"./github-api.ts\";\nimport { registerSessionCleanup } from \"./session-cleanup.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst CONFIG_PATH = getWebSearchConfigPath();\n\nconst BINARY_EXTENSIONS = new Set([\n\t\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\", \".ico\", \".webp\", \".svg\", \".tiff\", \".tif\",\n\t\".mp3\", \".mp4\", \".avi\", \".mov\", \".mkv\", \".flv\", \".wmv\", \".wav\", \".ogg\", \".webm\", \".flac\", \".aac\",\n\t\".zip\", \".tar\", \".gz\", \".bz2\", \".xz\", \".7z\", \".rar\", \".zst\",\n\t\".exe\", \".dll\", \".so\", \".dylib\", \".bin\", \".o\", \".a\", \".lib\",\n\t\".woff\", \".woff2\", \".ttf\", \".otf\", \".eot\",\n\t\".pdf\", \".doc\", \".docx\", \".xls\", \".xlsx\", \".ppt\", \".pptx\",\n\t\".sqlite\", \".db\", \".sqlite3\",\n\t\".pyc\", \".pyo\", \".class\", \".jar\", \".war\",\n\t\".iso\", \".img\", \".dmg\",\n]);\n\nconst NOISE_DIRS = new Set([\n\t\"node_modules\", \"vendor\", \".next\", \"dist\", \"build\", \"__pycache__\",\n\t\".venv\", \"venv\", \".tox\", \".mypy_cache\", \".pytest_cache\",\n\t\"target\", \".gradle\", \".idea\", \".vscode\",\n]);\n\nconst MAX_INLINE_FILE_CHARS = 100_000;\nconst MAX_TREE_ENTRIES = 200;\n\nexport interface GitHubUrlInfo {\n\towner: string;\n\trepo: string;\n\tref?: string;\n\trefIsFullSha: boolean;\n\tpath?: string;\n\ttype: \"root\" | \"blob\" | \"tree\";\n}\n\ninterface CachedClone {\n\tlocalPath: string;\n\tclonePromise: Promise<string | null>;\n}\n\ninterface GitHubCloneConfig {\n\tenabled: boolean;\n\tmaxRepoSizeMB: number;\n\tcloneTimeoutSeconds: number;\n\tclonePath: string;\n}\n\nconst cloneCache = new Map<string, CachedClone>();\n\nlet cachedConfig: GitHubCloneConfig | null = null;\n\nfunction normalizeEnabled(value: unknown, fallback: boolean): boolean {\n\treturn typeof value === \"boolean\" ? value : fallback;\n}\n\nfunction normalizePositiveNumber(value: unknown, fallback: number): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value)) return fallback;\n\treturn value > 0 ? value : fallback;\n}\n\nfunction normalizeClonePath(value: unknown, fallback: string): string {\n\tif (typeof value !== \"string\") return fallback;\n\tconst normalized = value.trim();\n\treturn normalized.length > 0 ? normalized : fallback;\n}\n\nfunction loadGitHubConfig(): GitHubCloneConfig {\n\tif (cachedConfig) return cachedConfig;\n\n\tconst defaults: GitHubCloneConfig = {\n\t\tenabled: true,\n\t\tmaxRepoSizeMB: 350,\n\t\tcloneTimeoutSeconds: 30,\n\t\tclonePath: \"/tmp/pi-github-repos\",\n\t};\n\n\tif (!existsSync(CONFIG_PATH)) {\n\t\tcachedConfig = defaults;\n\t\treturn cachedConfig;\n\t}\n\n\tconst rawText = readFileSync(CONFIG_PATH, \"utf-8\");\n\tlet raw: { githubClone?: { enabled?: unknown; maxRepoSizeMB?: unknown; cloneTimeoutSeconds?: unknown; clonePath?: unknown } };\n\ttry {\n\t\traw = JSON.parse(rawText) as { githubClone?: { enabled?: unknown; maxRepoSizeMB?: unknown; cloneTimeoutSeconds?: unknown; clonePath?: unknown } };\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);\n\t}\n\n\tconst gc = raw.githubClone ?? {};\n\tcachedConfig = {\n\t\tenabled: normalizeEnabled(gc.enabled, defaults.enabled),\n\t\tmaxRepoSizeMB: normalizePositiveNumber(gc.maxRepoSizeMB, defaults.maxRepoSizeMB),\n\t\tcloneTimeoutSeconds: normalizePositiveNumber(gc.cloneTimeoutSeconds, defaults.cloneTimeoutSeconds),\n\t\tclonePath: normalizeClonePath(gc.clonePath, defaults.clonePath),\n\t};\n\treturn cachedConfig;\n}\n\nconst NON_CODE_SEGMENTS = new Set([\n\t\"issues\", \"pull\", \"pulls\", \"discussions\", \"releases\", \"wiki\",\n\t\"actions\", \"settings\", \"security\", \"projects\", \"graphs\",\n\t\"compare\", \"commits\", \"tags\", \"branches\", \"stargazers\",\n\t\"watchers\", \"network\", \"forks\", \"milestone\", \"labels\",\n\t\"packages\", \"codespaces\", \"contribute\", \"community\",\n\t\"sponsors\", \"invitations\", \"notifications\", \"insights\",\n]);\n\nexport function parseGitHubUrl(url: string): GitHubUrlInfo | null {\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(url);\n\t} catch {\n\t\treturn null;\n\t}\n\n\tconst host = parsed.hostname.toLowerCase();\n\tif (host !== \"github.com\" && host !== \"www.github.com\") return null;\n\n\tconst segments = parsed.pathname\n\t\t.split(\"/\")\n\t\t.filter(Boolean)\n\t\t.map((segment) => {\n\t\t\ttry {\n\t\t\t\treturn decodeURIComponent(segment);\n\t\t\t} catch {\n\t\t\t\treturn segment;\n\t\t\t}\n\t\t});\n\tif (segments.length < 2) return null;\n\n\tconst owner = segments[0];\n\tconst repo = segments[1].replace(/\\.git$/, \"\");\n\n\tif (NON_CODE_SEGMENTS.has(segments[2]?.toLowerCase())) return null;\n\n\tif (segments.length === 2) {\n\t\treturn { owner, repo, refIsFullSha: false, type: \"root\" };\n\t}\n\n\tconst action = segments[2];\n\tif (action !== \"blob\" && action !== \"tree\") return null;\n\tif (segments.length < 4) return null;\n\n\tconst ref = segments[3];\n\tconst refIsFullSha = /^[0-9a-f]{40}$/.test(ref);\n\tconst pathParts = segments.slice(4);\n\tconst path = pathParts.length > 0 ? pathParts.join(\"/\") : \"\";\n\n\treturn {\n\t\towner,\n\t\trepo,\n\t\tref,\n\t\trefIsFullSha,\n\t\tpath,\n\t\ttype: action as \"blob\" | \"tree\",\n\t};\n}\n\nfunction cacheKey(owner: string, repo: string, ref?: string): string {\n\treturn ref ? `${owner}/${repo}@${ref}` : `${owner}/${repo}`;\n}\n\nfunction cloneDir(config: GitHubCloneConfig, owner: string, repo: string, ref?: string): string {\n\tconst dirName = ref ? `${repo}@${ref}` : repo;\n\treturn join(config.clonePath, owner, dirName);\n}\n\nfunction execClone(args: string[], localPath: string, timeoutMs: number, signal?: AbortSignal): Promise<string | null> {\n\treturn new Promise((resolve) => {\n\t\tconst child = execFile(args[0], args.slice(1), { timeout: timeoutMs }, (err) => {\n\t\t\tif (err) {\n\t\t\t\ttry {\n\t\t\t\t\trmSync(localPath, { recursive: true, force: true });\n\t\t\t\t} catch {\n\t\t\t\t}\n\t\t\t\tresolve(null);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresolve(localPath);\n\t\t});\n\n\t\tif (signal) {\n\t\t\tconst onAbort = () => child.kill();\n\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\tchild.on(\"exit\", () => signal.removeEventListener(\"abort\", onAbort));\n\t\t}\n\t});\n}\n\nasync function cloneRepo(\n\towner: string,\n\trepo: string,\n\tref: string | undefined,\n\tconfig: GitHubCloneConfig,\n\tsignal?: AbortSignal,\n): Promise<string | null> {\n\tconst localPath = cloneDir(config, owner, repo, ref);\n\n\ttry {\n\t\trmSync(localPath, { recursive: true, force: true });\n\t} catch {\n\t}\n\n\tconst timeoutMs = config.cloneTimeoutSeconds * 1000;\n\tconst hasGh = await checkGhAvailable();\n\n\tif (hasGh) {\n\t\tconst args = [\"gh\", \"repo\", \"clone\", `${owner}/${repo}`, localPath, \"--\", \"--depth\", \"1\", \"--single-branch\"];\n\t\tif (ref) args.push(\"--branch\", ref);\n\t\treturn execClone(args, localPath, timeoutMs, signal);\n\t}\n\n\tshowGhHint();\n\n\tconst gitUrl = `https://github.com/${owner}/${repo}.git`;\n\tconst args = [\"git\", \"clone\", \"--depth\", \"1\", \"--single-branch\"];\n\tif (ref) args.push(\"--branch\", ref);\n\targs.push(gitUrl, localPath);\n\treturn execClone(args, localPath, timeoutMs, signal);\n}\n\nfunction isBinaryFile(filePath: string): boolean {\n\tconst ext = extname(filePath).toLowerCase();\n\tif (BINARY_EXTENSIONS.has(ext)) return true;\n\n\tlet fd: number;\n\ttry {\n\t\tfd = openSync(filePath, \"r\");\n\t} catch {\n\t\treturn false;\n\t}\n\ttry {\n\t\tconst buf = Buffer.alloc(512);\n\t\tconst bytesRead = readSync(fd, buf, 0, 512, 0);\n\t\tfor (let i = 0; i < bytesRead; i++) {\n\t\t\tif (buf[i] === 0) return true;\n\t\t}\n\t} catch {\n\t\treturn false;\n\t} finally {\n\t\tcloseSync(fd);\n\t}\n\n\treturn false;\n}\n\nfunction formatFileSize(bytes: number): string {\n\tif (bytes < 1024) return `${bytes} B`;\n\tif (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n\treturn `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction resolveWithinRepo(rootPath: string, relativePath: string): string | null {\n\tconst normalizedRoot = resolvePath(rootPath);\n\tconst candidate = resolvePath(normalizedRoot, relativePath);\n\tif (candidate !== normalizedRoot) {\n\t\tconst rootPrefix = normalizedRoot.endsWith(pathSep) ? normalizedRoot : normalizedRoot + pathSep;\n\t\tif (!candidate.startsWith(rootPrefix)) return null;\n\t}\n\n\tif (!existsSync(candidate)) return candidate;\n\n\ttry {\n\t\tconst realRoot = realpathSync(normalizedRoot);\n\t\tconst realCandidate = realpathSync(candidate);\n\t\tif (realCandidate === realRoot) return candidate;\n\t\tconst realRootPrefix = realRoot.endsWith(pathSep) ? realRoot : realRoot + pathSep;\n\t\treturn realCandidate.startsWith(realRootPrefix) ? candidate : null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction readTextFile(path: string): string | null {\n\ttry {\n\t\treturn readFileSync(path, \"utf-8\");\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction buildTree(rootPath: string): string {\n\tconst entries: string[] = [];\n\n\tfunction walk(dir: string, relPath: string): void {\n\t\tif (entries.length >= MAX_TREE_ENTRIES) return;\n\n\t\tlet items: string[];\n\t\ttry {\n\t\t\titems = readdirSync(dir).sort();\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const item of items) {\n\t\t\tif (entries.length >= MAX_TREE_ENTRIES) return;\n\t\t\tif (item === \".git\") continue;\n\n\t\t\tconst rel = relPath ? `${relPath}/${item}` : item;\n\t\t\tconst safePath = resolveWithinRepo(rootPath, rel);\n\t\t\tif (!safePath) {\n\t\t\t\tentries.push(`${rel} [outside repo skipped]`);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet stat;\n\t\t\ttry {\n\t\t\t\tstat = statSync(safePath);\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (stat.isDirectory()) {\n\t\t\t\tif (NOISE_DIRS.has(item)) {\n\t\t\t\t\tentries.push(`${rel}/ [skipped]`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tentries.push(`${rel}/`);\n\t\t\t\twalk(safePath, rel);\n\t\t\t} else {\n\t\t\t\tentries.push(rel);\n\t\t\t}\n\t\t}\n\t}\n\n\twalk(rootPath, \"\");\n\n\tif (entries.length >= MAX_TREE_ENTRIES) {\n\t\tentries.push(`... (truncated at ${MAX_TREE_ENTRIES} entries)`);\n\t}\n\n\treturn entries.join(\"\\n\");\n}\n\nfunction buildDirListing(rootPath: string, subPath: string): string {\n\tconst targetPath = resolveWithinRepo(rootPath, subPath);\n\tif (!targetPath) return \"(path escapes repository root)\";\n\tconst lines: string[] = [];\n\n\tlet items: string[];\n\ttry {\n\t\titems = readdirSync(targetPath).sort();\n\t} catch {\n\t\treturn \"(directory not readable)\";\n\t}\n\n\tfor (const item of items) {\n\t\tif (item === \".git\") continue;\n\t\tconst rel = subPath ? `${subPath}/${item}` : item;\n\t\tconst safePath = resolveWithinRepo(rootPath, rel);\n\t\tif (!safePath) {\n\t\t\tlines.push(` ${item} (outside repo)`);\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\tconst stat = statSync(safePath);\n\t\t\tif (stat.isDirectory()) {\n\t\t\t\tlines.push(` ${item}/`);\n\t\t\t} else {\n\t\t\t\tlines.push(` ${item} (${formatFileSize(stat.size)})`);\n\t\t\t}\n\t\t} catch {\n\t\t\tlines.push(` ${item} (unreadable)`);\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\nfunction readReadme(localPath: string): string | null {\n\tconst candidates = [\"README.md\", \"readme.md\", \"README\", \"README.txt\", \"README.rst\"];\n\tfor (const name of candidates) {\n\t\tconst readmePath = join(localPath, name);\n\t\tif (existsSync(readmePath)) {\n\t\t\ttry {\n\t\t\t\tconst content = readFileSync(readmePath, \"utf-8\");\n\t\t\t\treturn content.length > 8192 ? content.slice(0, 8192) + \"\\n\\n[README truncated at 8K chars]\" : content;\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction generateContent(localPath: string, info: GitHubUrlInfo): string {\n\tconst lines: string[] = [];\n\tlines.push(`Repository cloned to: ${localPath}`);\n\tlines.push(\"\");\n\n\tif (info.type === \"root\") {\n\t\tlines.push(\"## Structure\");\n\t\tlines.push(buildTree(localPath));\n\t\tlines.push(\"\");\n\n\t\tconst readme = readReadme(localPath);\n\t\tif (readme) {\n\t\t\tlines.push(\"## README.md\");\n\t\t\tlines.push(readme);\n\t\t\tlines.push(\"\");\n\t\t}\n\n\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\tif (info.type === \"tree\") {\n\t\tconst dirPath = info.path || \"\";\n\t\tconst fullDirPath = resolveWithinRepo(localPath, dirPath);\n\n\t\tif (!fullDirPath || !existsSync(fullDirPath)) {\n\t\t\tlines.push(`Path \\`${dirPath}\\` not found in clone. Showing repository root instead.`);\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"## Structure\");\n\t\t\tlines.push(buildTree(localPath));\n\t\t} else {\n\t\t\tlines.push(`## ${dirPath || \"/\"}`);\n\t\t\tlines.push(buildDirListing(localPath, dirPath));\n\t\t}\n\n\t\tlines.push(\"\");\n\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\tif (info.type === \"blob\") {\n\t\tconst filePath = info.path || \"\";\n\t\tconst fullFilePath = resolveWithinRepo(localPath, filePath);\n\n\t\tif (!fullFilePath || !existsSync(fullFilePath)) {\n\t\t\tlines.push(`Path \\`${filePath}\\` not found in clone. Showing repository root instead.`);\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"## Structure\");\n\t\t\tlines.push(buildTree(localPath));\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\n\t\tlet stat: ReturnType<typeof statSync>;\n\t\ttry {\n\t\t\tstat = statSync(fullFilePath);\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t\tlines.push(`Could not inspect \\`${filePath}\\`: ${message}`);\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\n\t\tif (stat.isDirectory()) {\n\t\t\tlines.push(`## ${filePath || \"/\"}`);\n\t\t\tlines.push(buildDirListing(localPath, filePath));\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\n\t\tif (isBinaryFile(fullFilePath)) {\n\t\t\tconst ext = extname(filePath).replace(\".\", \"\");\n\t\t\tlines.push(`## ${filePath}`);\n\t\t\tlines.push(`Binary file (${ext}, ${formatFileSize(stat.size)}). Use \\`read\\` or \\`bash\\` tools at the path above to inspect.`);\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\n\t\tconst content = readTextFile(fullFilePath);\n\t\tif (content === null) {\n\t\t\tlines.push(`Could not read \\`${filePath}\\` as UTF-8 text.`);\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\t\tlines.push(`## ${filePath}`);\n\n\t\tif (content.length > MAX_INLINE_FILE_CHARS) {\n\t\t\tlines.push(content.slice(0, MAX_INLINE_FILE_CHARS));\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(`[File truncated at 100K chars. Full file: ${fullFilePath}]`);\n\t\t} else {\n\t\t\tlines.push(content);\n\t\t}\n\n\t\tlines.push(\"\");\n\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\nasync function awaitCachedClone(\n\tcached: CachedClone,\n\turl: string,\n\towner: string,\n\trepo: string,\n\tinfo: GitHubUrlInfo,\n\tsignal?: AbortSignal,\n): Promise<ExtractedContent | null> {\n\tif (signal?.aborted) return null;\n\tconst result = await cached.clonePromise;\n\tif (signal?.aborted) return null;\n\tif (result) {\n\t\tconst content = generateContent(result, info);\n\t\tconst title = info.path ? `${owner}/${repo} - ${info.path}` : `${owner}/${repo}`;\n\t\treturn { url, title, content, error: null };\n\t}\n\treturn fetchViaApi(url, owner, repo, info);\n}\n\nexport async function extractGitHub(\n\turl: string,\n\tsignal?: AbortSignal,\n\tforceClone?: boolean,\n): Promise<ExtractedContent | null> {\n\tconst info = parseGitHubUrl(url);\n\tif (!info) return null;\n\n\tif (signal?.aborted) return null;\n\n\tconst config = loadGitHubConfig();\n\tif (!config.enabled) return null;\n\n\tconst { owner, repo } = info;\n\tconst key = cacheKey(owner, repo, info.ref);\n\n\tconst cached = cloneCache.get(key);\n\tif (cached) return awaitCachedClone(cached, url, owner, repo, info, signal);\n\n\tif (info.refIsFullSha) {\n\t\tif (signal?.aborted) return null;\n\t\tconst sizeNote = `Note: Commit SHA URLs use the GitHub API instead of cloning.`;\n\t\treturn fetchViaApi(url, owner, repo, info, sizeNote);\n\t}\n\n\tconst activityId = activityMonitor.logStart({ type: \"fetch\", url: `github.com/${owner}/${repo}` });\n\n\tif (!forceClone) {\n\t\tconst sizeKB = await checkRepoSize(owner, repo);\n\t\tif (signal?.aborted) {\n\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t\treturn null;\n\t\t}\n\t\tif (sizeKB !== null) {\n\t\t\tconst sizeMB = sizeKB / 1024;\n\t\t\tif (sizeMB > config.maxRepoSizeMB) {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tconst sizeNote =\n\t\t\t\t\t`Note: Repository is ${Math.round(sizeMB)}MB (threshold: ${config.maxRepoSizeMB}MB). ` +\n\t\t\t\t\t`Showing API-fetched content instead of full clone. Ask the user if they'd like to clone the full repo -- ` +\n\t\t\t\t\t`if yes, call fetch_content again with the same URL and add forceClone: true to the params.`;\n\t\t\t\tconst apiView = await fetchViaApi(url, owner, repo, info, sizeNote);\n\t\t\t\tif (apiView) {\n\t\t\t\t\tactivityMonitor.logComplete(activityId, 200);\n\t\t\t\t\treturn apiView;\n\t\t\t\t}\n\t\t\t\tactivityMonitor.logError(activityId, \"api fallback unavailable for oversized repository\");\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (signal?.aborted) {\n\t\tactivityMonitor.logComplete(activityId, 0);\n\t\treturn null;\n\t}\n\n\t// Re-check: another concurrent caller may have started a clone while we awaited the size check\n\tconst cachedAfterSizeCheck = cloneCache.get(key);\n\tif (cachedAfterSizeCheck) {\n\t\tconst cachedResult = await awaitCachedClone(cachedAfterSizeCheck, url, owner, repo, info, signal);\n\t\tif (signal?.aborted) {\n\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t} else if (cachedResult) {\n\t\t\tactivityMonitor.logComplete(activityId, 200);\n\t\t} else {\n\t\t\tactivityMonitor.logError(activityId, \"clone failed\");\n\t\t}\n\t\treturn cachedResult;\n\t}\n\n\tconst clonePromise = cloneRepo(owner, repo, info.ref, config, signal);\n\tconst localPath = cloneDir(config, owner, repo, info.ref);\n\tcloneCache.set(key, { localPath, clonePromise });\n\n\tconst result = await clonePromise;\n\tif (signal?.aborted) {\n\t\tif (!result) cloneCache.delete(key);\n\t\tactivityMonitor.logComplete(activityId, 0);\n\t\treturn null;\n\t}\n\n\tif (!result) {\n\t\tcloneCache.delete(key);\n\t\tif (signal?.aborted) {\n\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t\treturn null;\n\t\t}\n\n\t\tconst apiFallback = await fetchViaApi(url, owner, repo, info);\n\t\tif (apiFallback) {\n\t\t\tactivityMonitor.logComplete(activityId, 200);\n\t\t\treturn apiFallback;\n\t\t}\n\n\t\tactivityMonitor.logError(activityId, \"clone and API fallback failed\");\n\t\treturn null;\n\t}\n\n\tactivityMonitor.logComplete(activityId, 200);\n\tconst content = generateContent(result, info);\n\tconst title = info.path ? `${owner}/${repo} - ${info.path}` : `${owner}/${repo}`;\n\treturn { url, title, content, error: null };\n}\n\nexport function clearCloneCache(): void {\n\tfor (const entry of cloneCache.values()) {\n\t\ttry {\n\t\t\trmSync(entry.localPath, { recursive: true, force: true });\n\t\t} catch {\n\t\t}\n\t}\n\tcloneCache.clear();\n\tcachedConfig = null;\n}\n\nregisterSessionCleanup(clearCloneCache);\n"]}
|
|
1
|
+
{"version":3,"file":"github-extract.js","sourceRoot":"","sources":["../../../src/builtin-extensions/pi-web-access/github-extract.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\nimport { existsSync, readFileSync, rmSync, statSync, readdirSync, openSync, readSync, closeSync, realpathSync } from \"node:fs\";\nimport { execFile } from \"node:child_process\";\nimport { extname, join, resolve as resolvePath, sep as pathSep } from \"node:path\";\nimport { activityMonitor } from \"./activity.ts\";\nimport type { ExtractedContent } from \"./extract.ts\";\nimport { checkGhAvailable, checkRepoSize, fetchViaApi, showGhHint } from \"./github-api.ts\";\nimport { getWebSession, type WebSession } from \"./session-cleanup.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst CONFIG_PATH = getWebSearchConfigPath();\n\nconst BINARY_EXTENSIONS = new Set([\n\t\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\", \".ico\", \".webp\", \".svg\", \".tiff\", \".tif\",\n\t\".mp3\", \".mp4\", \".avi\", \".mov\", \".mkv\", \".flv\", \".wmv\", \".wav\", \".ogg\", \".webm\", \".flac\", \".aac\",\n\t\".zip\", \".tar\", \".gz\", \".bz2\", \".xz\", \".7z\", \".rar\", \".zst\",\n\t\".exe\", \".dll\", \".so\", \".dylib\", \".bin\", \".o\", \".a\", \".lib\",\n\t\".woff\", \".woff2\", \".ttf\", \".otf\", \".eot\",\n\t\".pdf\", \".doc\", \".docx\", \".xls\", \".xlsx\", \".ppt\", \".pptx\",\n\t\".sqlite\", \".db\", \".sqlite3\",\n\t\".pyc\", \".pyo\", \".class\", \".jar\", \".war\",\n\t\".iso\", \".img\", \".dmg\",\n]);\n\nconst NOISE_DIRS = new Set([\n\t\"node_modules\", \"vendor\", \".next\", \"dist\", \"build\", \"__pycache__\",\n\t\".venv\", \"venv\", \".tox\", \".mypy_cache\", \".pytest_cache\",\n\t\"target\", \".gradle\", \".idea\", \".vscode\",\n]);\n\nconst MAX_INLINE_FILE_CHARS = 100_000;\nconst MAX_TREE_ENTRIES = 200;\nconst CLONE_TERMINATION_GRACE_MS = 1_000;\nconst CLONE_EXIT_CONFIRMATION_MS = 1_000;\n\nexport interface GitHubUrlInfo {\n\towner: string;\n\trepo: string;\n\tref?: string;\n\trefIsFullSha: boolean;\n\tpath?: string;\n\ttype: \"root\" | \"blob\" | \"tree\";\n}\n\ninterface CachedClone {\n\tlocalPath: string;\n\tclonePromise: Promise<string | null>;\n\tcontroller: AbortController;\n\towners: Set<WebSession | symbol>;\n\tcleanup?: Promise<void>;\n}\n\ninterface GitHubCloneConfig {\n\tenabled: boolean;\n\tmaxRepoSizeMB: number;\n\tcloneTimeoutSeconds: number;\n\tclonePath: string;\n}\n\nconst cloneCache = new Map<string, CachedClone>();\nconst standaloneOwner = Symbol(\"standalone clone caller\");\n\nfunction removeClone(key: string, entry: CachedClone): void {\n\tif (cloneCache.get(key) !== entry) return;\n\ttry { rmSync(entry.localPath, { recursive: true, force: true }); } catch {}\n\tcloneCache.delete(key);\n\tif (cloneCache.size === 0) cachedConfig = null;\n}\n\n/** Never release a clone directory while its command may still be writing into it. */\nasync function finishClone(key: string, entry: CachedClone): Promise<void> {\n\tlet deadline: ReturnType<typeof setTimeout> | undefined;\n\ttry {\n\t\tawait Promise.race([\n\t\t\tentry.clonePromise.catch(() => undefined),\n\t\t\tnew Promise<never>((_resolve, reject) => {\n\t\t\t\tdeadline = setTimeout(() => reject(new Error(\n\t\t\t\t\t\"GitHub clone cleanup could not confirm command completion after termination; clone retained until completion\",\n\t\t\t\t)), CLONE_TERMINATION_GRACE_MS + CLONE_EXIT_CONFIRMATION_MS);\n\t\t\t}),\n\t\t]);\n\t} catch (error) {\n\t\t// Keep the failed cleanup visible to new callers, but permit retry after the command eventually exits.\n\t\tvoid entry.clonePromise.catch(() => undefined).then(() => removeClone(key, entry));\n\t\tthrow error;\n\t} finally {\n\t\tclearTimeout(deadline);\n\t}\n\tremoveClone(key, entry);\n}\n\n/** Keep a shared clone alive until its final session releases it, including pending clones. */\nfunction acquireClone(key: string, entry: CachedClone): void {\n\tconst owner = getWebSession() ?? standaloneOwner;\n\tif (typeof owner !== \"symbol\" && owner.closed) throw new Error(\"Web session closed\");\n\tif (entry.owners.has(owner)) return;\n\tentry.owners.add(owner);\n\tif (typeof owner !== \"symbol\") owner.cleanups.add(async () => {\n\t\tentry.owners.delete(owner);\n\t\tif (entry.owners.size > 0) return;\n\t\tentry.controller.abort();\n\t\tentry.cleanup = finishClone(key, entry);\n\t\tawait entry.cleanup;\n\t});\n}\n\nasync function findClone(key: string): Promise<CachedClone | undefined> {\n\tconst entry = cloneCache.get(key);\n\tif (entry?.cleanup) {\n\t\tawait entry.cleanup;\n\t\treturn findClone(key);\n\t}\n\tif (entry && !getWebSession()?.closed) acquireClone(key, entry);\n\treturn entry;\n}\n\nlet cachedConfig: GitHubCloneConfig | null = null;\n\nfunction normalizeEnabled(value: unknown, fallback: boolean): boolean {\n\treturn typeof value === \"boolean\" ? value : fallback;\n}\n\nfunction normalizePositiveNumber(value: unknown, fallback: number): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value)) return fallback;\n\treturn value > 0 ? value : fallback;\n}\n\nfunction normalizeClonePath(value: unknown, fallback: string): string {\n\tif (typeof value !== \"string\") return fallback;\n\tconst normalized = value.trim();\n\treturn normalized.length > 0 ? normalized : fallback;\n}\n\nfunction loadGitHubConfig(): GitHubCloneConfig {\n\tif (cachedConfig) return cachedConfig;\n\n\tconst defaults: GitHubCloneConfig = {\n\t\tenabled: true,\n\t\tmaxRepoSizeMB: 350,\n\t\tcloneTimeoutSeconds: 30,\n\t\tclonePath: \"/tmp/pi-github-repos\",\n\t};\n\n\tif (!existsSync(CONFIG_PATH)) {\n\t\tcachedConfig = defaults;\n\t\treturn cachedConfig;\n\t}\n\n\tconst rawText = readFileSync(CONFIG_PATH, \"utf-8\");\n\tlet raw: { githubClone?: { enabled?: unknown; maxRepoSizeMB?: unknown; cloneTimeoutSeconds?: unknown; clonePath?: unknown } };\n\ttry {\n\t\traw = JSON.parse(rawText) as { githubClone?: { enabled?: unknown; maxRepoSizeMB?: unknown; cloneTimeoutSeconds?: unknown; clonePath?: unknown } };\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);\n\t}\n\n\tconst gc = raw.githubClone ?? {};\n\tcachedConfig = {\n\t\tenabled: normalizeEnabled(gc.enabled, defaults.enabled),\n\t\tmaxRepoSizeMB: normalizePositiveNumber(gc.maxRepoSizeMB, defaults.maxRepoSizeMB),\n\t\tcloneTimeoutSeconds: normalizePositiveNumber(gc.cloneTimeoutSeconds, defaults.cloneTimeoutSeconds),\n\t\tclonePath: normalizeClonePath(gc.clonePath, defaults.clonePath),\n\t};\n\treturn cachedConfig;\n}\n\nconst NON_CODE_SEGMENTS = new Set([\n\t\"issues\", \"pull\", \"pulls\", \"discussions\", \"releases\", \"wiki\",\n\t\"actions\", \"settings\", \"security\", \"projects\", \"graphs\",\n\t\"compare\", \"commits\", \"tags\", \"branches\", \"stargazers\",\n\t\"watchers\", \"network\", \"forks\", \"milestone\", \"labels\",\n\t\"packages\", \"codespaces\", \"contribute\", \"community\",\n\t\"sponsors\", \"invitations\", \"notifications\", \"insights\",\n]);\n\nexport function parseGitHubUrl(url: string): GitHubUrlInfo | null {\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(url);\n\t} catch {\n\t\treturn null;\n\t}\n\n\tconst host = parsed.hostname.toLowerCase();\n\tif (host !== \"github.com\" && host !== \"www.github.com\") return null;\n\n\tconst segments = parsed.pathname\n\t\t.split(\"/\")\n\t\t.filter(Boolean)\n\t\t.map((segment) => {\n\t\t\ttry {\n\t\t\t\treturn decodeURIComponent(segment);\n\t\t\t} catch {\n\t\t\t\treturn segment;\n\t\t\t}\n\t\t});\n\tif (segments.length < 2) return null;\n\n\tconst owner = segments[0];\n\tconst repo = segments[1].replace(/\\.git$/, \"\");\n\n\tif (NON_CODE_SEGMENTS.has(segments[2]?.toLowerCase())) return null;\n\n\tif (segments.length === 2) {\n\t\treturn { owner, repo, refIsFullSha: false, type: \"root\" };\n\t}\n\n\tconst action = segments[2];\n\tif (action !== \"blob\" && action !== \"tree\") return null;\n\tif (segments.length < 4) return null;\n\n\tconst ref = segments[3];\n\tconst refIsFullSha = /^[0-9a-f]{40}$/.test(ref);\n\tconst pathParts = segments.slice(4);\n\tconst path = pathParts.length > 0 ? pathParts.join(\"/\") : \"\";\n\n\treturn {\n\t\towner,\n\t\trepo,\n\t\tref,\n\t\trefIsFullSha,\n\t\tpath,\n\t\ttype: action as \"blob\" | \"tree\",\n\t};\n}\n\nfunction cacheKey(owner: string, repo: string, ref?: string): string {\n\treturn ref ? `${owner}/${repo}@${ref}` : `${owner}/${repo}`;\n}\n\nfunction cloneDir(config: GitHubCloneConfig, owner: string, repo: string, ref?: string): string {\n\tconst dirName = ref ? `${repo}@${ref}` : repo;\n\treturn join(config.clonePath, owner, dirName);\n}\n\nfunction execClone(args: string[], localPath: string, timeoutMs: number, signal?: AbortSignal): Promise<string | null> {\n\tif (signal?.aborted) return Promise.resolve(null);\n\treturn new Promise((resolve) => {\n\t\tlet failed = false;\n\t\tlet exited = false;\n\t\tlet closed = false;\n\t\tlet stopping = false;\n\t\tlet escalation: ReturnType<typeof setTimeout> | undefined;\n\t\t// An execFile callback may also report a kill error while the process is still alive.\n\t\tconst child = execFile(args[0], args.slice(1), {}, (err) => { failed = Boolean(err); });\n\t\tconst stop = () => {\n\t\t\tif (stopping || closed) return;\n\t\t\tstopping = true;\n\t\t\tescalation = setTimeout(() => {\n\t\t\t\ttry { child.kill(\"SIGKILL\"); } catch {}\n\t\t\t}, CLONE_TERMINATION_GRACE_MS);\n\t\t\ttry { child.kill(\"SIGTERM\"); } catch {}\n\t\t};\n\t\tconst timeout = setTimeout(stop, timeoutMs);\n\t\tchild.once(\"exit\", () => { exited = true; });\n\t\tchild.once(\"close\", () => {\n\t\t\t// Failed spawning has no PID. A spawned command must actually exit before output can be released.\n\t\t\tif (child.pid && !exited) return;\n\t\t\tclosed = true;\n\t\t\tclearTimeout(timeout);\n\t\t\tclearTimeout(escalation);\n\t\t\tsignal?.removeEventListener(\"abort\", stop);\n\t\t\tif (failed || stopping) {\n\t\t\t\ttry { rmSync(localPath, { recursive: true, force: true }); } catch {}\n\t\t\t\tresolve(null);\n\t\t\t} else {\n\t\t\t\tresolve(localPath);\n\t\t\t}\n\t\t});\n\t\tsignal?.addEventListener(\"abort\", stop, { once: true });\n\t});\n}\n\nasync function cloneRepo(\n\towner: string,\n\trepo: string,\n\tref: string | undefined,\n\tconfig: GitHubCloneConfig,\n\tsignal?: AbortSignal,\n): Promise<string | null> {\n\tconst localPath = cloneDir(config, owner, repo, ref);\n\n\ttry {\n\t\trmSync(localPath, { recursive: true, force: true });\n\t} catch {\n\t}\n\n\tconst timeoutMs = config.cloneTimeoutSeconds * 1000;\n\tconst hasGh = await checkGhAvailable();\n\tif (signal?.aborted) return null;\n\n\tif (hasGh) {\n\t\tconst args = [\"gh\", \"repo\", \"clone\", `${owner}/${repo}`, localPath, \"--\", \"--depth\", \"1\", \"--single-branch\"];\n\t\tif (ref) args.push(\"--branch\", ref);\n\t\treturn execClone(args, localPath, timeoutMs, signal);\n\t}\n\n\tshowGhHint();\n\n\tconst gitUrl = `https://github.com/${owner}/${repo}.git`;\n\tconst args = [\"git\", \"clone\", \"--depth\", \"1\", \"--single-branch\"];\n\tif (ref) args.push(\"--branch\", ref);\n\targs.push(gitUrl, localPath);\n\treturn execClone(args, localPath, timeoutMs, signal);\n}\n\nfunction isBinaryFile(filePath: string): boolean {\n\tconst ext = extname(filePath).toLowerCase();\n\tif (BINARY_EXTENSIONS.has(ext)) return true;\n\n\tlet fd: number;\n\ttry {\n\t\tfd = openSync(filePath, \"r\");\n\t} catch {\n\t\treturn false;\n\t}\n\ttry {\n\t\tconst buf = Buffer.alloc(512);\n\t\tconst bytesRead = readSync(fd, buf, 0, 512, 0);\n\t\tfor (let i = 0; i < bytesRead; i++) {\n\t\t\tif (buf[i] === 0) return true;\n\t\t}\n\t} catch {\n\t\treturn false;\n\t} finally {\n\t\tcloseSync(fd);\n\t}\n\n\treturn false;\n}\n\nfunction formatFileSize(bytes: number): string {\n\tif (bytes < 1024) return `${bytes} B`;\n\tif (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n\treturn `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction resolveWithinRepo(rootPath: string, relativePath: string): string | null {\n\tconst normalizedRoot = resolvePath(rootPath);\n\tconst candidate = resolvePath(normalizedRoot, relativePath);\n\tif (candidate !== normalizedRoot) {\n\t\tconst rootPrefix = normalizedRoot.endsWith(pathSep) ? normalizedRoot : normalizedRoot + pathSep;\n\t\tif (!candidate.startsWith(rootPrefix)) return null;\n\t}\n\n\tif (!existsSync(candidate)) return candidate;\n\n\ttry {\n\t\tconst realRoot = realpathSync(normalizedRoot);\n\t\tconst realCandidate = realpathSync(candidate);\n\t\tif (realCandidate === realRoot) return candidate;\n\t\tconst realRootPrefix = realRoot.endsWith(pathSep) ? realRoot : realRoot + pathSep;\n\t\treturn realCandidate.startsWith(realRootPrefix) ? candidate : null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction readTextFile(path: string): string | null {\n\ttry {\n\t\treturn readFileSync(path, \"utf-8\");\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction buildTree(rootPath: string): string {\n\tconst entries: string[] = [];\n\n\tfunction walk(dir: string, relPath: string): void {\n\t\tif (entries.length >= MAX_TREE_ENTRIES) return;\n\n\t\tlet items: string[];\n\t\ttry {\n\t\t\titems = readdirSync(dir).sort();\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const item of items) {\n\t\t\tif (entries.length >= MAX_TREE_ENTRIES) return;\n\t\t\tif (item === \".git\") continue;\n\n\t\t\tconst rel = relPath ? `${relPath}/${item}` : item;\n\t\t\tconst safePath = resolveWithinRepo(rootPath, rel);\n\t\t\tif (!safePath) {\n\t\t\t\tentries.push(`${rel} [outside repo skipped]`);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet stat;\n\t\t\ttry {\n\t\t\t\tstat = statSync(safePath);\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (stat.isDirectory()) {\n\t\t\t\tif (NOISE_DIRS.has(item)) {\n\t\t\t\t\tentries.push(`${rel}/ [skipped]`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tentries.push(`${rel}/`);\n\t\t\t\twalk(safePath, rel);\n\t\t\t} else {\n\t\t\t\tentries.push(rel);\n\t\t\t}\n\t\t}\n\t}\n\n\twalk(rootPath, \"\");\n\n\tif (entries.length >= MAX_TREE_ENTRIES) {\n\t\tentries.push(`... (truncated at ${MAX_TREE_ENTRIES} entries)`);\n\t}\n\n\treturn entries.join(\"\\n\");\n}\n\nfunction buildDirListing(rootPath: string, subPath: string): string {\n\tconst targetPath = resolveWithinRepo(rootPath, subPath);\n\tif (!targetPath) return \"(path escapes repository root)\";\n\tconst lines: string[] = [];\n\n\tlet items: string[];\n\ttry {\n\t\titems = readdirSync(targetPath).sort();\n\t} catch {\n\t\treturn \"(directory not readable)\";\n\t}\n\n\tfor (const item of items) {\n\t\tif (item === \".git\") continue;\n\t\tconst rel = subPath ? `${subPath}/${item}` : item;\n\t\tconst safePath = resolveWithinRepo(rootPath, rel);\n\t\tif (!safePath) {\n\t\t\tlines.push(` ${item} (outside repo)`);\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\tconst stat = statSync(safePath);\n\t\t\tif (stat.isDirectory()) {\n\t\t\t\tlines.push(` ${item}/`);\n\t\t\t} else {\n\t\t\t\tlines.push(` ${item} (${formatFileSize(stat.size)})`);\n\t\t\t}\n\t\t} catch {\n\t\t\tlines.push(` ${item} (unreadable)`);\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\nfunction readReadme(localPath: string): string | null {\n\tconst candidates = [\"README.md\", \"readme.md\", \"README\", \"README.txt\", \"README.rst\"];\n\tfor (const name of candidates) {\n\t\tconst readmePath = join(localPath, name);\n\t\tif (existsSync(readmePath)) {\n\t\t\ttry {\n\t\t\t\tconst content = readFileSync(readmePath, \"utf-8\");\n\t\t\t\treturn content.length > 8192 ? content.slice(0, 8192) + \"\\n\\n[README truncated at 8K chars]\" : content;\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction generateContent(localPath: string, info: GitHubUrlInfo): string {\n\tconst lines: string[] = [];\n\tlines.push(`Repository cloned to: ${localPath}`);\n\tlines.push(\"\");\n\n\tif (info.type === \"root\") {\n\t\tlines.push(\"## Structure\");\n\t\tlines.push(buildTree(localPath));\n\t\tlines.push(\"\");\n\n\t\tconst readme = readReadme(localPath);\n\t\tif (readme) {\n\t\t\tlines.push(\"## README.md\");\n\t\t\tlines.push(readme);\n\t\t\tlines.push(\"\");\n\t\t}\n\n\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\tif (info.type === \"tree\") {\n\t\tconst dirPath = info.path || \"\";\n\t\tconst fullDirPath = resolveWithinRepo(localPath, dirPath);\n\n\t\tif (!fullDirPath || !existsSync(fullDirPath)) {\n\t\t\tlines.push(`Path \\`${dirPath}\\` not found in clone. Showing repository root instead.`);\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"## Structure\");\n\t\t\tlines.push(buildTree(localPath));\n\t\t} else {\n\t\t\tlines.push(`## ${dirPath || \"/\"}`);\n\t\t\tlines.push(buildDirListing(localPath, dirPath));\n\t\t}\n\n\t\tlines.push(\"\");\n\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\tif (info.type === \"blob\") {\n\t\tconst filePath = info.path || \"\";\n\t\tconst fullFilePath = resolveWithinRepo(localPath, filePath);\n\n\t\tif (!fullFilePath || !existsSync(fullFilePath)) {\n\t\t\tlines.push(`Path \\`${filePath}\\` not found in clone. Showing repository root instead.`);\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"## Structure\");\n\t\t\tlines.push(buildTree(localPath));\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\n\t\tlet stat: ReturnType<typeof statSync>;\n\t\ttry {\n\t\t\tstat = statSync(fullFilePath);\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t\tlines.push(`Could not inspect \\`${filePath}\\`: ${message}`);\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\n\t\tif (stat.isDirectory()) {\n\t\t\tlines.push(`## ${filePath || \"/\"}`);\n\t\t\tlines.push(buildDirListing(localPath, filePath));\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\n\t\tif (isBinaryFile(fullFilePath)) {\n\t\t\tconst ext = extname(filePath).replace(\".\", \"\");\n\t\t\tlines.push(`## ${filePath}`);\n\t\t\tlines.push(`Binary file (${ext}, ${formatFileSize(stat.size)}). Use \\`read\\` or \\`bash\\` tools at the path above to inspect.`);\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\n\t\tconst content = readTextFile(fullFilePath);\n\t\tif (content === null) {\n\t\t\tlines.push(`Could not read \\`${filePath}\\` as UTF-8 text.`);\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\t\tlines.push(`## ${filePath}`);\n\n\t\tif (content.length > MAX_INLINE_FILE_CHARS) {\n\t\t\tlines.push(content.slice(0, MAX_INLINE_FILE_CHARS));\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(`[File truncated at 100K chars. Full file: ${fullFilePath}]`);\n\t\t} else {\n\t\t\tlines.push(content);\n\t\t}\n\n\t\tlines.push(\"\");\n\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\n/** Cancel the caller's wait without cancelling a clone leased by another session. */\nasync function waitForClone(clone: Promise<string | null>, signal?: AbortSignal): Promise<string | null> {\n\tif (!signal) return clone;\n\tif (signal.aborted) return null;\n\tlet onAbort: () => void = () => {};\n\tconst cancelled = new Promise<null>((resolve) => {\n\t\tonAbort = () => resolve(null);\n\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t});\n\ttry { return await Promise.race([clone, cancelled]); }\n\tfinally { signal.removeEventListener(\"abort\", onAbort); }\n}\n\nasync function awaitCachedClone(\n\tcached: CachedClone,\n\turl: string,\n\towner: string,\n\trepo: string,\n\tinfo: GitHubUrlInfo,\n\tsignal?: AbortSignal,\n): Promise<ExtractedContent | null> {\n\tif (signal?.aborted) return null;\n\tconst result = await waitForClone(cached.clonePromise, signal);\n\tif (signal?.aborted || getWebSession()?.closed) return null;\n\tif (result) {\n\t\tconst content = generateContent(result, info);\n\t\tconst title = info.path ? `${owner}/${repo} - ${info.path}` : `${owner}/${repo}`;\n\t\treturn { url, title, content, error: null };\n\t}\n\treturn fetchViaApi(url, owner, repo, info);\n}\n\nexport async function extractGitHub(\n\turl: string,\n\tsignal?: AbortSignal,\n\tforceClone?: boolean,\n): Promise<ExtractedContent | null> {\n\tconst info = parseGitHubUrl(url);\n\tif (!info) return null;\n\n\tif (signal?.aborted) return null;\n\n\tconst config = loadGitHubConfig();\n\tif (!config.enabled) return null;\n\n\tconst { owner, repo } = info;\n\tconst key = cacheKey(owner, repo, info.ref);\n\n\tconst cached = await findClone(key);\n\tif (signal?.aborted || getWebSession()?.closed) return null;\n\tif (cached) {\n\t\treturn awaitCachedClone(cached, url, owner, repo, info, signal);\n\t}\n\n\tif (info.refIsFullSha) {\n\t\tif (signal?.aborted) return null;\n\t\tconst sizeNote = `Note: Commit SHA URLs use the GitHub API instead of cloning.`;\n\t\treturn fetchViaApi(url, owner, repo, info, sizeNote);\n\t}\n\n\tconst activityId = activityMonitor.logStart({ type: \"fetch\", url: `github.com/${owner}/${repo}` });\n\n\tif (!forceClone) {\n\t\tconst sizeKB = await checkRepoSize(owner, repo);\n\t\tif (signal?.aborted) {\n\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t\treturn null;\n\t\t}\n\t\tif (sizeKB !== null) {\n\t\t\tconst sizeMB = sizeKB / 1024;\n\t\t\tif (sizeMB > config.maxRepoSizeMB) {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tconst sizeNote =\n\t\t\t\t\t`Note: Repository is ${Math.round(sizeMB)}MB (threshold: ${config.maxRepoSizeMB}MB). ` +\n\t\t\t\t\t`Showing API-fetched content instead of full clone. Ask the user if they'd like to clone the full repo -- ` +\n\t\t\t\t\t`if yes, call fetch_content again with the same URL and add forceClone: true to the params.`;\n\t\t\t\tconst apiView = await fetchViaApi(url, owner, repo, info, sizeNote);\n\t\t\t\tif (apiView) {\n\t\t\t\t\tactivityMonitor.logComplete(activityId, 200);\n\t\t\t\t\treturn apiView;\n\t\t\t\t}\n\t\t\t\tactivityMonitor.logError(activityId, \"api fallback unavailable for oversized repository\");\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (signal?.aborted) {\n\t\tactivityMonitor.logComplete(activityId, 0);\n\t\treturn null;\n\t}\n\n\t// Re-check: another concurrent caller may have started a clone while we awaited the size check\n\tlet cachedAfterSizeCheck = await findClone(key);\n\twhile (!cachedAfterSizeCheck && cloneCache.has(key)) cachedAfterSizeCheck = await findClone(key);\n\tif (signal?.aborted || getWebSession()?.closed) return null;\n\tif (cachedAfterSizeCheck) {\n\t\tconst cachedResult = await awaitCachedClone(cachedAfterSizeCheck, url, owner, repo, info, signal);\n\t\tif (signal?.aborted) {\n\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t} else if (cachedResult) {\n\t\t\tactivityMonitor.logComplete(activityId, 200);\n\t\t} else {\n\t\t\tactivityMonitor.logError(activityId, \"clone failed\");\n\t\t}\n\t\treturn cachedResult;\n\t}\n\n\tif (signal?.aborted || getWebSession()?.closed) return null;\n\tconst controller = new AbortController();\n\tconst clonePromise = cloneRepo(owner, repo, info.ref, config, controller.signal);\n\tconst localPath = cloneDir(config, owner, repo, info.ref);\n\tconst entry: CachedClone = { localPath, clonePromise, controller, owners: new Set() };\n\tcloneCache.set(key, entry);\n\tacquireClone(key, entry);\n\n\tconst result = await waitForClone(clonePromise, signal);\n\tif (signal?.aborted || getWebSession()?.closed) {\n\t\tactivityMonitor.logComplete(activityId, 0);\n\t\treturn null;\n\t}\n\n\tif (!result) {\n\t\tif (cloneCache.get(key) === entry) cloneCache.delete(key);\n\t\tif (signal?.aborted) {\n\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t\treturn null;\n\t\t}\n\n\t\tconst apiFallback = await fetchViaApi(url, owner, repo, info);\n\t\tif (apiFallback) {\n\t\t\tactivityMonitor.logComplete(activityId, 200);\n\t\t\treturn apiFallback;\n\t\t}\n\n\t\tactivityMonitor.logError(activityId, \"clone and API fallback failed\");\n\t\treturn null;\n\t}\n\n\tactivityMonitor.logComplete(activityId, 200);\n\tconst content = generateContent(result, info);\n\tconst title = info.path ? `${owner}/${repo} - ${info.path}` : `${owner}/${repo}`;\n\treturn { url, title, content, error: null };\n}\n"]}
|