@greppleai/grip 0.0.0-stage → 0.0.1
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 +22 -0
- package/README.md +725 -2
- package/dist/bun/cli.d.ts +3 -0
- package/dist/bun/cli.d.ts.map +1 -0
- package/dist/bun/cli.js +11 -0
- package/dist/bun/cli.js.map +1 -0
- package/dist/bun/register-bedrock.d.ts +2 -0
- package/dist/bun/register-bedrock.d.ts.map +1 -0
- package/dist/bun/register-bedrock.js +4 -0
- package/dist/bun/register-bedrock.js.map +1 -0
- package/dist/bun/restore-sandbox-env.d.ts +13 -0
- package/dist/bun/restore-sandbox-env.d.ts.map +1 -0
- package/dist/bun/restore-sandbox-env.js +32 -0
- package/dist/bun/restore-sandbox-env.js.map +1 -0
- package/dist/cli/args.d.ts +70 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +441 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/config-selector.d.ts +14 -0
- package/dist/cli/config-selector.d.ts.map +1 -0
- package/dist/cli/config-selector.js +31 -0
- package/dist/cli/config-selector.js.map +1 -0
- package/dist/cli/file-processor.d.ts +15 -0
- package/dist/cli/file-processor.d.ts.map +1 -0
- package/dist/cli/file-processor.js +60 -0
- package/dist/cli/file-processor.js.map +1 -0
- package/dist/cli/initial-message.d.ts +18 -0
- package/dist/cli/initial-message.d.ts.map +1 -0
- package/dist/cli/initial-message.js +22 -0
- package/dist/cli/initial-message.js.map +1 -0
- package/dist/cli/list-models.d.ts +9 -0
- package/dist/cli/list-models.d.ts.map +1 -0
- package/dist/cli/list-models.js +98 -0
- package/dist/cli/list-models.js.map +1 -0
- package/dist/cli/session-picker.d.ts +9 -0
- package/dist/cli/session-picker.d.ts.map +1 -0
- package/dist/cli/session-picker.js +35 -0
- package/dist/cli/session-picker.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +14 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +82 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +406 -0
- package/dist/config.js.map +1 -0
- package/dist/core/agent-session.d.ts +970 -0
- package/dist/core/agent-session.d.ts.map +1 -0
- package/dist/core/agent-session.js +5176 -0
- package/dist/core/agent-session.js.map +1 -0
- package/dist/core/auth-guidance.d.ts +5 -0
- package/dist/core/auth-guidance.d.ts.map +1 -0
- package/dist/core/auth-guidance.js +21 -0
- package/dist/core/auth-guidance.js.map +1 -0
- package/dist/core/auth-storage.d.ts +150 -0
- package/dist/core/auth-storage.d.ts.map +1 -0
- package/dist/core/auth-storage.js +557 -0
- package/dist/core/auth-storage.js.map +1 -0
- package/dist/core/bash-executor.d.ts +26 -0
- package/dist/core/bash-executor.d.ts.map +1 -0
- package/dist/core/bash-executor.js +99 -0
- package/dist/core/bash-executor.js.map +1 -0
- package/dist/core/compaction/branch-summarization.d.ts +83 -0
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -0
- package/dist/core/compaction/branch-summarization.js +220 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -0
- package/dist/core/compaction/compaction.d.ts +65 -0
- package/dist/core/compaction/compaction.d.ts.map +1 -0
- package/dist/core/compaction/compaction.js +550 -0
- package/dist/core/compaction/compaction.js.map +1 -0
- package/dist/core/compaction/compression-detection-ledger.d.ts +34 -0
- package/dist/core/compaction/compression-detection-ledger.d.ts.map +1 -0
- package/dist/core/compaction/compression-detection-ledger.js +52 -0
- package/dist/core/compaction/compression-detection-ledger.js.map +1 -0
- package/dist/core/compaction/compression-detector.d.ts +71 -0
- package/dist/core/compaction/compression-detector.d.ts.map +1 -0
- package/dist/core/compaction/compression-detector.js +407 -0
- package/dist/core/compaction/compression-detector.js.map +1 -0
- package/dist/core/compaction/compression-economics.d.ts +55 -0
- package/dist/core/compaction/compression-economics.d.ts.map +1 -0
- package/dist/core/compaction/compression-economics.js +151 -0
- package/dist/core/compaction/compression-economics.js.map +1 -0
- package/dist/core/compaction/utils.d.ts +28 -0
- package/dist/core/compaction/utils.d.ts.map +1 -0
- package/dist/core/compaction/utils.js +165 -0
- package/dist/core/compaction/utils.js.map +1 -0
- package/dist/core/defaults.d.ts +3 -0
- package/dist/core/defaults.d.ts.map +1 -0
- package/dist/core/defaults.js +2 -0
- package/dist/core/defaults.js.map +1 -0
- package/dist/core/diagnostics.d.ts +18 -0
- package/dist/core/diagnostics.d.ts.map +1 -0
- package/dist/core/diagnostics.js +2 -0
- package/dist/core/diagnostics.js.map +1 -0
- package/dist/core/event-bus.d.ts +9 -0
- package/dist/core/event-bus.d.ts.map +1 -0
- package/dist/core/event-bus.js +25 -0
- package/dist/core/event-bus.js.map +1 -0
- package/dist/core/exec.d.ts +29 -0
- package/dist/core/exec.d.ts.map +1 -0
- package/dist/core/exec.js +75 -0
- package/dist/core/exec.js.map +1 -0
- package/dist/core/export-html/ansi-to-html.d.ts +22 -0
- package/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
- package/dist/core/export-html/ansi-to-html.js +245 -0
- package/dist/core/export-html/ansi-to-html.js.map +1 -0
- package/dist/core/export-html/index.d.ts +21 -0
- package/dist/core/export-html/index.d.ts.map +1 -0
- package/dist/core/export-html/index.js +230 -0
- package/dist/core/export-html/index.js.map +1 -0
- package/dist/core/export-html/template.css +1066 -0
- package/dist/core/export-html/template.html +55 -0
- package/dist/core/export-html/template.js +1864 -0
- package/dist/core/export-html/tool-renderer.d.ts +32 -0
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -0
- package/dist/core/export-html/tool-renderer.js +108 -0
- package/dist/core/export-html/tool-renderer.js.map +1 -0
- package/dist/core/export-html/vendor/highlight.min.js +1213 -0
- package/dist/core/export-html/vendor/marked.min.js +78 -0
- package/dist/core/extensions/loader.d.ts +24 -0
- package/dist/core/extensions/loader.d.ts.map +1 -0
- package/dist/core/extensions/loader.js +613 -0
- package/dist/core/extensions/loader.js.map +1 -0
- package/dist/core/extensions/runner.d.ts +160 -0
- package/dist/core/extensions/runner.d.ts.map +1 -0
- package/dist/core/extensions/runner.js +962 -0
- package/dist/core/extensions/runner.js.map +1 -0
- package/dist/core/extensions/types.d.ts +1311 -0
- package/dist/core/extensions/types.d.ts.map +1 -0
- package/dist/core/extensions/types.js +51 -0
- package/dist/core/extensions/types.js.map +1 -0
- package/dist/core/extensions/wrapper.d.ts +20 -0
- package/dist/core/extensions/wrapper.d.ts.map +1 -0
- package/dist/core/extensions/wrapper.js +22 -0
- package/dist/core/extensions/wrapper.js.map +1 -0
- package/dist/core/footer-data-provider.d.ts +52 -0
- package/dist/core/footer-data-provider.d.ts.map +1 -0
- package/dist/core/footer-data-provider.js +318 -0
- package/dist/core/footer-data-provider.js.map +1 -0
- package/dist/core/grip-agent.d.ts +240 -0
- package/dist/core/grip-agent.d.ts.map +1 -0
- package/dist/core/grip-agent.js +1243 -0
- package/dist/core/grip-agent.js.map +1 -0
- package/dist/core/grip-manifest.d.ts +9 -0
- package/dist/core/grip-manifest.d.ts.map +1 -0
- package/dist/core/grip-manifest.js +25 -0
- package/dist/core/grip-manifest.js.map +1 -0
- package/dist/core/hooks/aggregate.d.ts +5 -0
- package/dist/core/hooks/aggregate.d.ts.map +1 -0
- package/dist/core/hooks/aggregate.js +226 -0
- package/dist/core/hooks/aggregate.js.map +1 -0
- package/dist/core/hooks/config.d.ts +14 -0
- package/dist/core/hooks/config.d.ts.map +1 -0
- package/dist/core/hooks/config.js +372 -0
- package/dist/core/hooks/config.js.map +1 -0
- package/dist/core/hooks/executor.d.ts +12 -0
- package/dist/core/hooks/executor.d.ts.map +1 -0
- package/dist/core/hooks/executor.js +708 -0
- package/dist/core/hooks/executor.js.map +1 -0
- package/dist/core/hooks/index.d.ts +9 -0
- package/dist/core/hooks/index.d.ts.map +1 -0
- package/dist/core/hooks/index.js +14 -0
- package/dist/core/hooks/index.js.map +1 -0
- package/dist/core/hooks/matcher.d.ts +10 -0
- package/dist/core/hooks/matcher.d.ts.map +1 -0
- package/dist/core/hooks/matcher.js +70 -0
- package/dist/core/hooks/matcher.js.map +1 -0
- package/dist/core/hooks/trust-store.d.ts +38 -0
- package/dist/core/hooks/trust-store.d.ts.map +1 -0
- package/dist/core/hooks/trust-store.js +167 -0
- package/dist/core/hooks/trust-store.js.map +1 -0
- package/dist/core/hooks/types.d.ts +234 -0
- package/dist/core/hooks/types.d.ts.map +1 -0
- package/dist/core/hooks/types.js +52 -0
- package/dist/core/hooks/types.js.map +1 -0
- package/dist/core/http-dispatcher.d.ts +21 -0
- package/dist/core/http-dispatcher.d.ts.map +1 -0
- package/dist/core/http-dispatcher.js +82 -0
- package/dist/core/http-dispatcher.js.map +1 -0
- package/dist/core/instruction-resource-loader.d.ts +81 -0
- package/dist/core/instruction-resource-loader.d.ts.map +1 -0
- package/dist/core/instruction-resource-loader.js +574 -0
- package/dist/core/instruction-resource-loader.js.map +1 -0
- package/dist/core/keybindings.d.ts +399 -0
- package/dist/core/keybindings.d.ts.map +1 -0
- package/dist/core/keybindings.js +299 -0
- package/dist/core/keybindings.js.map +1 -0
- package/dist/core/lsp/abort.d.ts +3 -0
- package/dist/core/lsp/abort.d.ts.map +1 -0
- package/dist/core/lsp/abort.js +28 -0
- package/dist/core/lsp/abort.js.map +1 -0
- package/dist/core/lsp/client.d.ts +108 -0
- package/dist/core/lsp/client.d.ts.map +1 -0
- package/dist/core/lsp/client.js +586 -0
- package/dist/core/lsp/client.js.map +1 -0
- package/dist/core/lsp/config-loader.d.ts +44 -0
- package/dist/core/lsp/config-loader.d.ts.map +1 -0
- package/dist/core/lsp/config-loader.js +223 -0
- package/dist/core/lsp/config-loader.js.map +1 -0
- package/dist/core/lsp/config.d.ts +134 -0
- package/dist/core/lsp/config.d.ts.map +1 -0
- package/dist/core/lsp/config.js +682 -0
- package/dist/core/lsp/config.js.map +1 -0
- package/dist/core/lsp/diagnostics.d.ts +18 -0
- package/dist/core/lsp/diagnostics.d.ts.map +1 -0
- package/dist/core/lsp/diagnostics.js +311 -0
- package/dist/core/lsp/diagnostics.js.map +1 -0
- package/dist/core/lsp/file-sync.d.ts +58 -0
- package/dist/core/lsp/file-sync.d.ts.map +1 -0
- package/dist/core/lsp/file-sync.js +432 -0
- package/dist/core/lsp/file-sync.js.map +1 -0
- package/dist/core/lsp/integration.d.ts +62 -0
- package/dist/core/lsp/integration.d.ts.map +1 -0
- package/dist/core/lsp/integration.js +145 -0
- package/dist/core/lsp/integration.js.map +1 -0
- package/dist/core/lsp/language-map.d.ts +54 -0
- package/dist/core/lsp/language-map.d.ts.map +1 -0
- package/dist/core/lsp/language-map.js +300 -0
- package/dist/core/lsp/language-map.js.map +1 -0
- package/dist/core/lsp/manager.d.ts +120 -0
- package/dist/core/lsp/manager.d.ts.map +1 -0
- package/dist/core/lsp/manager.js +636 -0
- package/dist/core/lsp/manager.js.map +1 -0
- package/dist/core/lsp/navigation.d.ts +32 -0
- package/dist/core/lsp/navigation.d.ts.map +1 -0
- package/dist/core/lsp/navigation.js +327 -0
- package/dist/core/lsp/navigation.js.map +1 -0
- package/dist/core/lsp/portable-path.d.ts +18 -0
- package/dist/core/lsp/portable-path.d.ts.map +1 -0
- package/dist/core/lsp/portable-path.js +83 -0
- package/dist/core/lsp/portable-path.js.map +1 -0
- package/dist/core/lsp/refactor.d.ts +32 -0
- package/dist/core/lsp/refactor.d.ts.map +1 -0
- package/dist/core/lsp/refactor.js +519 -0
- package/dist/core/lsp/refactor.js.map +1 -0
- package/dist/core/lsp/transport.d.ts +39 -0
- package/dist/core/lsp/transport.d.ts.map +1 -0
- package/dist/core/lsp/transport.js +261 -0
- package/dist/core/lsp/transport.js.map +1 -0
- package/dist/core/messages.d.ts +34 -0
- package/dist/core/messages.d.ts.map +1 -0
- package/dist/core/messages.js +140 -0
- package/dist/core/messages.js.map +1 -0
- package/dist/core/model-registry.d.ts +148 -0
- package/dist/core/model-registry.d.ts.map +1 -0
- package/dist/core/model-registry.js +812 -0
- package/dist/core/model-registry.js.map +1 -0
- package/dist/core/model-resolver.d.ts +115 -0
- package/dist/core/model-resolver.d.ts.map +1 -0
- package/dist/core/model-resolver.js +498 -0
- package/dist/core/model-resolver.js.map +1 -0
- package/dist/core/output-guard.d.ts +7 -0
- package/dist/core/output-guard.d.ts.map +1 -0
- package/dist/core/output-guard.js +89 -0
- package/dist/core/output-guard.js.map +1 -0
- package/dist/core/package-manager.d.ts +209 -0
- package/dist/core/package-manager.d.ts.map +1 -0
- package/dist/core/package-manager.js +2341 -0
- package/dist/core/package-manager.js.map +1 -0
- package/dist/core/prompt-templates.d.ts +57 -0
- package/dist/core/prompt-templates.d.ts.map +1 -0
- package/dist/core/prompt-templates.js +353 -0
- package/dist/core/prompt-templates.js.map +1 -0
- package/dist/core/provider-display-names.d.ts +2 -0
- package/dist/core/provider-display-names.d.ts.map +1 -0
- package/dist/core/provider-display-names.js +33 -0
- package/dist/core/provider-display-names.js.map +1 -0
- package/dist/core/remote-workspace-protocol/contract.d.ts +456 -0
- package/dist/core/remote-workspace-protocol/contract.d.ts.map +1 -0
- package/dist/core/remote-workspace-protocol/contract.js +809 -0
- package/dist/core/remote-workspace-protocol/contract.js.map +1 -0
- package/dist/core/remote-workspace-protocol/session.d.ts +247 -0
- package/dist/core/remote-workspace-protocol/session.d.ts.map +1 -0
- package/dist/core/remote-workspace-protocol/session.js +1839 -0
- package/dist/core/remote-workspace-protocol/session.js.map +1 -0
- package/dist/core/resolve-config-value.d.ts +32 -0
- package/dist/core/resolve-config-value.d.ts.map +1 -0
- package/dist/core/resolve-config-value.js +257 -0
- package/dist/core/resolve-config-value.js.map +1 -0
- package/dist/core/resource-loader.d.ts +200 -0
- package/dist/core/resource-loader.d.ts.map +1 -0
- package/dist/core/resource-loader.js +1209 -0
- package/dist/core/resource-loader.js.map +1 -0
- package/dist/core/rules.d.ts +40 -0
- package/dist/core/rules.d.ts.map +1 -0
- package/dist/core/rules.js +57 -0
- package/dist/core/rules.js.map +1 -0
- package/dist/core/sandbox/command.d.ts +27 -0
- package/dist/core/sandbox/command.d.ts.map +1 -0
- package/dist/core/sandbox/command.js +124 -0
- package/dist/core/sandbox/command.js.map +1 -0
- package/dist/core/sandbox/docker.d.ts +169 -0
- package/dist/core/sandbox/docker.d.ts.map +1 -0
- package/dist/core/sandbox/docker.js +633 -0
- package/dist/core/sandbox/docker.js.map +1 -0
- package/dist/core/sandbox/lima.d.ts +38 -0
- package/dist/core/sandbox/lima.d.ts.map +1 -0
- package/dist/core/sandbox/lima.js +324 -0
- package/dist/core/sandbox/lima.js.map +1 -0
- package/dist/core/session/constants.d.ts +2 -0
- package/dist/core/session/constants.d.ts.map +1 -0
- package/dist/core/session/constants.js +2 -0
- package/dist/core/session/constants.js.map +1 -0
- package/dist/core/session/context-metadata.d.ts +5 -0
- package/dist/core/session/context-metadata.d.ts.map +1 -0
- package/dist/core/session/context-metadata.js +55 -0
- package/dist/core/session/context-metadata.js.map +1 -0
- package/dist/core/session/context.d.ts +14 -0
- package/dist/core/session/context.d.ts.map +1 -0
- package/dist/core/session/context.js +117 -0
- package/dist/core/session/context.js.map +1 -0
- package/dist/core/session/ids.d.ts +9 -0
- package/dist/core/session/ids.d.ts.map +1 -0
- package/dist/core/session/ids.js +21 -0
- package/dist/core/session/ids.js.map +1 -0
- package/dist/core/session/in-memory-session-manager.d.ts +17 -0
- package/dist/core/session/in-memory-session-manager.d.ts.map +1 -0
- package/dist/core/session/in-memory-session-manager.js +40 -0
- package/dist/core/session/in-memory-session-manager.js.map +1 -0
- package/dist/core/session/in-memory-session.d.ts +7 -0
- package/dist/core/session/in-memory-session.d.ts.map +1 -0
- package/dist/core/session/in-memory-session.js +11 -0
- package/dist/core/session/in-memory-session.js.map +1 -0
- package/dist/core/session/jsonl-errors.d.ts +36 -0
- package/dist/core/session/jsonl-errors.d.ts.map +1 -0
- package/dist/core/session/jsonl-errors.js +49 -0
- package/dist/core/session/jsonl-errors.js.map +1 -0
- package/dist/core/session/jsonl-helpers.d.ts +20 -0
- package/dist/core/session/jsonl-helpers.d.ts.map +1 -0
- package/dist/core/session/jsonl-helpers.js +21 -0
- package/dist/core/session/jsonl-helpers.js.map +1 -0
- package/dist/core/session/local-session-manager.d.ts +30 -0
- package/dist/core/session/local-session-manager.d.ts.map +1 -0
- package/dist/core/session/local-session-manager.js +205 -0
- package/dist/core/session/local-session-manager.js.map +1 -0
- package/dist/core/session/local-session.d.ts +9 -0
- package/dist/core/session/local-session.d.ts.map +1 -0
- package/dist/core/session/local-session.js +15 -0
- package/dist/core/session/local-session.js.map +1 -0
- package/dist/core/session/migrations.d.ts +11 -0
- package/dist/core/session/migrations.d.ts.map +1 -0
- package/dist/core/session/migrations.js +78 -0
- package/dist/core/session/migrations.js.map +1 -0
- package/dist/core/session/remote-session-client.d.ts +83 -0
- package/dist/core/session/remote-session-client.d.ts.map +1 -0
- package/dist/core/session/remote-session-client.js +224 -0
- package/dist/core/session/remote-session-client.js.map +1 -0
- package/dist/core/session/remote-session-manager.d.ts +32 -0
- package/dist/core/session/remote-session-manager.d.ts.map +1 -0
- package/dist/core/session/remote-session-manager.js +124 -0
- package/dist/core/session/remote-session-manager.js.map +1 -0
- package/dist/core/session/remote-session.d.ts +20 -0
- package/dist/core/session/remote-session.d.ts.map +1 -0
- package/dist/core/session/remote-session.js +33 -0
- package/dist/core/session/remote-session.js.map +1 -0
- package/dist/core/session/session-manager.d.ts +18 -0
- package/dist/core/session/session-manager.d.ts.map +1 -0
- package/dist/core/session/session-manager.js +2 -0
- package/dist/core/session/session-manager.js.map +1 -0
- package/dist/core/session/session.d.ts +140 -0
- package/dist/core/session/session.d.ts.map +1 -0
- package/dist/core/session/session.js +461 -0
- package/dist/core/session/session.js.map +1 -0
- package/dist/core/session/stores/in-memory-session-store.d.ts +39 -0
- package/dist/core/session/stores/in-memory-session-store.d.ts.map +1 -0
- package/dist/core/session/stores/in-memory-session-store.js +168 -0
- package/dist/core/session/stores/in-memory-session-store.js.map +1 -0
- package/dist/core/session/stores/jsonl-session-store.d.ts +97 -0
- package/dist/core/session/stores/jsonl-session-store.d.ts.map +1 -0
- package/dist/core/session/stores/jsonl-session-store.js +1140 -0
- package/dist/core/session/stores/jsonl-session-store.js.map +1 -0
- package/dist/core/session/stores/remote-session-store.d.ts +44 -0
- package/dist/core/session/stores/remote-session-store.d.ts.map +1 -0
- package/dist/core/session/stores/remote-session-store.js +159 -0
- package/dist/core/session/stores/remote-session-store.js.map +1 -0
- package/dist/core/session/stores/session-store.d.ts +42 -0
- package/dist/core/session/stores/session-store.d.ts.map +1 -0
- package/dist/core/session/stores/session-store.js +2 -0
- package/dist/core/session/stores/session-store.js.map +1 -0
- package/dist/core/session/types.d.ts +141 -0
- package/dist/core/session/types.d.ts.map +1 -0
- package/dist/core/session/types.js +2 -0
- package/dist/core/session/types.js.map +1 -0
- package/dist/core/session/usage-ledger.d.ts +18 -0
- package/dist/core/session/usage-ledger.d.ts.map +1 -0
- package/dist/core/session/usage-ledger.js +68 -0
- package/dist/core/session/usage-ledger.js.map +1 -0
- package/dist/core/session-cwd.d.ts +19 -0
- package/dist/core/session-cwd.d.ts.map +1 -0
- package/dist/core/session-cwd.js +38 -0
- package/dist/core/session-cwd.js.map +1 -0
- package/dist/core/settings-manager.d.ts +318 -0
- package/dist/core/settings-manager.d.ts.map +1 -0
- package/dist/core/settings-manager.js +991 -0
- package/dist/core/settings-manager.js.map +1 -0
- package/dist/core/skills.d.ts +40 -0
- package/dist/core/skills.d.ts.map +1 -0
- package/dist/core/skills.js +57 -0
- package/dist/core/skills.js.map +1 -0
- package/dist/core/slash-commands.d.ts +15 -0
- package/dist/core/slash-commands.d.ts.map +1 -0
- package/dist/core/slash-commands.js +36 -0
- package/dist/core/slash-commands.js.map +1 -0
- package/dist/core/source-info.d.ts +26 -0
- package/dist/core/source-info.d.ts.map +1 -0
- package/dist/core/source-info.js +27 -0
- package/dist/core/source-info.js.map +1 -0
- package/dist/core/system-prompt.d.ts +32 -0
- package/dist/core/system-prompt.d.ts.map +1 -0
- package/dist/core/system-prompt.js +131 -0
- package/dist/core/system-prompt.js.map +1 -0
- package/dist/core/telemetry.d.ts +3 -0
- package/dist/core/telemetry.d.ts.map +1 -0
- package/dist/core/telemetry.js +9 -0
- package/dist/core/telemetry.js.map +1 -0
- package/dist/core/timings.d.ts +10 -0
- package/dist/core/timings.d.ts.map +1 -0
- package/dist/core/timings.js +41 -0
- package/dist/core/timings.js.map +1 -0
- package/dist/core/tools/bash.d.ts +51 -0
- package/dist/core/tools/bash.d.ts.map +1 -0
- package/dist/core/tools/bash.js +310 -0
- package/dist/core/tools/bash.js.map +1 -0
- package/dist/core/tools/compress-context.d.ts +27 -0
- package/dist/core/tools/compress-context.d.ts.map +1 -0
- package/dist/core/tools/compress-context.js +142 -0
- package/dist/core/tools/compress-context.js.map +1 -0
- package/dist/core/tools/edit-diff.d.ts +82 -0
- package/dist/core/tools/edit-diff.d.ts.map +1 -0
- package/dist/core/tools/edit-diff.js +327 -0
- package/dist/core/tools/edit-diff.js.map +1 -0
- package/dist/core/tools/edit.d.ts +50 -0
- package/dist/core/tools/edit.d.ts.map +1 -0
- package/dist/core/tools/edit.js +324 -0
- package/dist/core/tools/edit.js.map +1 -0
- package/dist/core/tools/file-mutation-queue.d.ts +6 -0
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -0
- package/dist/core/tools/file-mutation-queue.js +60 -0
- package/dist/core/tools/file-mutation-queue.js.map +1 -0
- package/dist/core/tools/find.d.ts +22 -0
- package/dist/core/tools/find.d.ts.map +1 -0
- package/dist/core/tools/find.js +268 -0
- package/dist/core/tools/find.js.map +1 -0
- package/dist/core/tools/grep.d.ts +27 -0
- package/dist/core/tools/grep.d.ts.map +1 -0
- package/dist/core/tools/grep.js +332 -0
- package/dist/core/tools/grep.js.map +1 -0
- package/dist/core/tools/hash-store.d.ts +12 -0
- package/dist/core/tools/hash-store.d.ts.map +1 -0
- package/dist/core/tools/hash-store.js +48 -0
- package/dist/core/tools/hash-store.js.map +1 -0
- package/dist/core/tools/hashline/apply.d.ts +40 -0
- package/dist/core/tools/hashline/apply.d.ts.map +1 -0
- package/dist/core/tools/hashline/apply.js +261 -0
- package/dist/core/tools/hashline/apply.js.map +1 -0
- package/dist/core/tools/hashline/hash.d.ts +56 -0
- package/dist/core/tools/hashline/hash.d.ts.map +1 -0
- package/dist/core/tools/hashline/hash.js +196 -0
- package/dist/core/tools/hashline/hash.js.map +1 -0
- package/dist/core/tools/hashline/parse.d.ts +8 -0
- package/dist/core/tools/hashline/parse.d.ts.map +1 -0
- package/dist/core/tools/hashline/parse.js +41 -0
- package/dist/core/tools/hashline/parse.js.map +1 -0
- package/dist/core/tools/hashline/resolve.d.ts +51 -0
- package/dist/core/tools/hashline/resolve.d.ts.map +1 -0
- package/dist/core/tools/hashline/resolve.js +187 -0
- package/dist/core/tools/hashline/resolve.js.map +1 -0
- package/dist/core/tools/hashline-utils.d.ts +6 -0
- package/dist/core/tools/hashline-utils.d.ts.map +1 -0
- package/dist/core/tools/hashline-utils.js +23 -0
- package/dist/core/tools/hashline-utils.js.map +1 -0
- package/dist/core/tools/index.d.ts +36 -0
- package/dist/core/tools/index.d.ts.map +1 -0
- package/dist/core/tools/index.js +141 -0
- package/dist/core/tools/index.js.map +1 -0
- package/dist/core/tools/ls.d.ts +21 -0
- package/dist/core/tools/ls.d.ts.map +1 -0
- package/dist/core/tools/ls.js +156 -0
- package/dist/core/tools/ls.js.map +1 -0
- package/dist/core/tools/operations.d.ts +201 -0
- package/dist/core/tools/operations.d.ts.map +1 -0
- package/dist/core/tools/operations.js +697 -0
- package/dist/core/tools/operations.js.map +1 -0
- package/dist/core/tools/output-accumulator.d.ts +54 -0
- package/dist/core/tools/output-accumulator.d.ts.map +1 -0
- package/dist/core/tools/output-accumulator.js +184 -0
- package/dist/core/tools/output-accumulator.js.map +1 -0
- package/dist/core/tools/path-utils.d.ts +9 -0
- package/dist/core/tools/path-utils.d.ts.map +1 -0
- package/dist/core/tools/path-utils.js +99 -0
- package/dist/core/tools/path-utils.js.map +1 -0
- package/dist/core/tools/read.d.ts +32 -0
- package/dist/core/tools/read.d.ts.map +1 -0
- package/dist/core/tools/read.js +318 -0
- package/dist/core/tools/read.js.map +1 -0
- package/dist/core/tools/render-utils.d.ts +33 -0
- package/dist/core/tools/render-utils.d.ts.map +1 -0
- package/dist/core/tools/render-utils.js +61 -0
- package/dist/core/tools/render-utils.js.map +1 -0
- package/dist/core/tools/replace-diff.d.ts +16 -0
- package/dist/core/tools/replace-diff.d.ts.map +1 -0
- package/dist/core/tools/replace-diff.js +117 -0
- package/dist/core/tools/replace-diff.js.map +1 -0
- package/dist/core/tools/replace-normalize.d.ts +2 -0
- package/dist/core/tools/replace-normalize.d.ts.map +1 -0
- package/dist/core/tools/replace-normalize.js +73 -0
- package/dist/core/tools/replace-normalize.js.map +1 -0
- package/dist/core/tools/replace-render.d.ts +51 -0
- package/dist/core/tools/replace-render.d.ts.map +1 -0
- package/dist/core/tools/replace-render.js +162 -0
- package/dist/core/tools/replace-render.js.map +1 -0
- package/dist/core/tools/runtime.d.ts +2 -0
- package/dist/core/tools/runtime.d.ts.map +1 -0
- package/dist/core/tools/runtime.js +6 -0
- package/dist/core/tools/runtime.js.map +1 -0
- package/dist/core/tools/session-history.d.ts +55 -0
- package/dist/core/tools/session-history.d.ts.map +1 -0
- package/dist/core/tools/session-history.js +649 -0
- package/dist/core/tools/session-history.js.map +1 -0
- package/dist/core/tools/subagent-agents.d.ts +29 -0
- package/dist/core/tools/subagent-agents.d.ts.map +1 -0
- package/dist/core/tools/subagent-agents.js +223 -0
- package/dist/core/tools/subagent-agents.js.map +1 -0
- package/dist/core/tools/subagent.d.ts +185 -0
- package/dist/core/tools/subagent.d.ts.map +1 -0
- package/dist/core/tools/subagent.js +1309 -0
- package/dist/core/tools/subagent.js.map +1 -0
- package/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -0
- package/dist/core/tools/tool-definition-wrapper.js +34 -0
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -0
- package/dist/core/tools/truncate.d.ts +39 -0
- package/dist/core/tools/truncate.d.ts.map +1 -0
- package/dist/core/tools/truncate.js +215 -0
- package/dist/core/tools/truncate.js.map +1 -0
- package/dist/core/tools/websearch.d.ts +33 -0
- package/dist/core/tools/websearch.d.ts.map +1 -0
- package/dist/core/tools/websearch.js +341 -0
- package/dist/core/tools/websearch.js.map +1 -0
- package/dist/core/tools/workspace-tool-host.d.ts +102 -0
- package/dist/core/tools/workspace-tool-host.d.ts.map +1 -0
- package/dist/core/tools/workspace-tool-host.js +348 -0
- package/dist/core/tools/workspace-tool-host.js.map +1 -0
- package/dist/core/tools/write.d.ts +16 -0
- package/dist/core/tools/write.d.ts.map +1 -0
- package/dist/core/tools/write.js +204 -0
- package/dist/core/tools/write.js.map +1 -0
- package/dist/core/workspace-identity.d.ts +7 -0
- package/dist/core/workspace-identity.d.ts.map +1 -0
- package/dist/core/workspace-identity.js +2 -0
- package/dist/core/workspace-identity.js.map +1 -0
- package/dist/daemon/command.d.ts +6 -0
- package/dist/daemon/command.d.ts.map +1 -0
- package/dist/daemon/command.js +58 -0
- package/dist/daemon/command.js.map +1 -0
- package/dist/daemon/config.d.ts +43 -0
- package/dist/daemon/config.d.ts.map +1 -0
- package/dist/daemon/config.js +304 -0
- package/dist/daemon/config.js.map +1 -0
- package/dist/daemon/help.d.ts +2 -0
- package/dist/daemon/help.d.ts.map +1 -0
- package/dist/daemon/help.js +42 -0
- package/dist/daemon/help.js.map +1 -0
- package/dist/daemon/lsp-config.d.ts +4 -0
- package/dist/daemon/lsp-config.d.ts.map +1 -0
- package/dist/daemon/lsp-config.js +155 -0
- package/dist/daemon/lsp-config.js.map +1 -0
- package/dist/daemon/security.d.ts +19 -0
- package/dist/daemon/security.d.ts.map +1 -0
- package/dist/daemon/security.js +175 -0
- package/dist/daemon/security.js.map +1 -0
- package/dist/daemon/server.d.ts +20 -0
- package/dist/daemon/server.d.ts.map +1 -0
- package/dist/daemon/server.js +400 -0
- package/dist/daemon/server.js.map +1 -0
- package/dist/daemon/workspace-runtime.d.ts +46 -0
- package/dist/daemon/workspace-runtime.d.ts.map +1 -0
- package/dist/daemon/workspace-runtime.js +673 -0
- package/dist/daemon/workspace-runtime.js.map +1 -0
- package/dist/index.d.ts +109 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +107 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +39 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +763 -0
- package/dist/main.js.map +1 -0
- package/dist/migrations.d.ts +35 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/migrations.js +412 -0
- package/dist/migrations.js.map +1 -0
- package/dist/modes/interactive/components/assistant-message.d.ts +29 -0
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/assistant-message.js +149 -0
- package/dist/modes/interactive/components/assistant-message.js.map +1 -0
- package/dist/modes/interactive/components/bash-execution.d.ts +36 -0
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
- package/dist/modes/interactive/components/bash-execution.js +173 -0
- package/dist/modes/interactive/components/bash-execution.js.map +1 -0
- package/dist/modes/interactive/components/bordered-loader.d.ts +18 -0
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
- package/dist/modes/interactive/components/bordered-loader.js +54 -0
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -0
- package/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/branch-summary-message.js +44 -0
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/compaction-summary-message.js +45 -0
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
- package/dist/modes/interactive/components/config-selector.d.ts +74 -0
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/config-selector.js +514 -0
- package/dist/modes/interactive/components/config-selector.js.map +1 -0
- package/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
- package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -0
- package/dist/modes/interactive/components/countdown-timer.js +33 -0
- package/dist/modes/interactive/components/countdown-timer.js.map +1 -0
- package/dist/modes/interactive/components/custom-editor.d.ts +25 -0
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
- package/dist/modes/interactive/components/custom-editor.js +85 -0
- package/dist/modes/interactive/components/custom-editor.js.map +1 -0
- package/dist/modes/interactive/components/custom-message.d.ts +20 -0
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/custom-message.js +80 -0
- package/dist/modes/interactive/components/custom-message.js.map +1 -0
- package/dist/modes/interactive/components/diff.d.ts +12 -0
- package/dist/modes/interactive/components/diff.d.ts.map +1 -0
- package/dist/modes/interactive/components/diff.js +118 -0
- package/dist/modes/interactive/components/diff.js.map +1 -0
- package/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
- package/dist/modes/interactive/components/dynamic-border.js +21 -0
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -0
- package/dist/modes/interactive/components/extension-editor.d.ts +22 -0
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
- package/dist/modes/interactive/components/extension-editor.js +128 -0
- package/dist/modes/interactive/components/extension-editor.js.map +1 -0
- package/dist/modes/interactive/components/extension-input.d.ts +23 -0
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
- package/dist/modes/interactive/components/extension-input.js +61 -0
- package/dist/modes/interactive/components/extension-input.js.map +1 -0
- package/dist/modes/interactive/components/extension-selector.d.ts +26 -0
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/extension-selector.js +83 -0
- package/dist/modes/interactive/components/extension-selector.js.map +1 -0
- package/dist/modes/interactive/components/footer.d.ts +36 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -0
- package/dist/modes/interactive/components/footer.js +227 -0
- package/dist/modes/interactive/components/footer.js.map +1 -0
- package/dist/modes/interactive/components/hook-execution.d.ts +19 -0
- package/dist/modes/interactive/components/hook-execution.d.ts.map +1 -0
- package/dist/modes/interactive/components/hook-execution.js +184 -0
- package/dist/modes/interactive/components/hook-execution.js.map +1 -0
- package/dist/modes/interactive/components/keybinding-hints.d.ts +13 -0
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -0
- package/dist/modes/interactive/components/keybinding-hints.js +36 -0
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -0
- package/dist/modes/interactive/components/login-dialog.d.ts +55 -0
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -0
- package/dist/modes/interactive/components/login-dialog.js +176 -0
- package/dist/modes/interactive/components/login-dialog.js.map +1 -0
- package/dist/modes/interactive/components/markdown-transform.d.ts +4 -0
- package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -0
- package/dist/modes/interactive/components/markdown-transform.js +19 -0
- package/dist/modes/interactive/components/markdown-transform.js.map +1 -0
- package/dist/modes/interactive/components/mermaid.d.ts +14 -0
- package/dist/modes/interactive/components/mermaid.d.ts.map +1 -0
- package/dist/modes/interactive/components/mermaid.js +228 -0
- package/dist/modes/interactive/components/mermaid.js.map +1 -0
- package/dist/modes/interactive/components/model-selector.d.ts +52 -0
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/model-selector.js +296 -0
- package/dist/modes/interactive/components/model-selector.js.map +1 -0
- package/dist/modes/interactive/components/oauth-selector.d.ts +33 -0
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/oauth-selector.js +165 -0
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +50 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/scoped-models-selector.js +300 -0
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -0
- package/dist/modes/interactive/components/session-selector-search.d.ts +22 -0
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -0
- package/dist/modes/interactive/components/session-selector-search.js +144 -0
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -0
- package/dist/modes/interactive/components/session-selector.d.ts +108 -0
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/session-selector.js +835 -0
- package/dist/modes/interactive/components/session-selector.js.map +1 -0
- package/dist/modes/interactive/components/settings-selector.d.ts +81 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/settings-selector.js +455 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -0
- package/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/show-images-selector.js +39 -0
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -0
- package/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/skill-invocation-message.js +47 -0
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -0
- package/dist/modes/interactive/components/theme-selector.d.ts +11 -0
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/theme-selector.js +50 -0
- package/dist/modes/interactive/components/theme-selector.js.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.js +51 -0
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -0
- package/dist/modes/interactive/components/tool-execution.d.ts +67 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
- package/dist/modes/interactive/components/tool-execution.js +306 -0
- package/dist/modes/interactive/components/tool-execution.js.map +1 -0
- package/dist/modes/interactive/components/tree-selector.d.ts +127 -0
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/tree-selector.js +1098 -0
- package/dist/modes/interactive/components/tree-selector.js.map +1 -0
- package/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/user-message-selector.js +114 -0
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -0
- package/dist/modes/interactive/components/user-message.d.ts +16 -0
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/user-message.js +49 -0
- package/dist/modes/interactive/components/user-message.js.map +1 -0
- package/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
- package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -0
- package/dist/modes/interactive/components/visual-truncate.js +33 -0
- package/dist/modes/interactive/components/visual-truncate.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +557 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-mode.js +5859 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -0
- package/dist/modes/interactive/theme/dark.json +86 -0
- package/dist/modes/interactive/theme/light.json +85 -0
- package/dist/modes/interactive/theme/theme-schema.json +335 -0
- package/dist/modes/interactive/theme/theme.d.ts +106 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -0
- package/dist/modes/interactive/theme/theme.js +1030 -0
- package/dist/modes/interactive/theme/theme.js.map +1 -0
- package/dist/modes/json-event.d.ts +28 -0
- package/dist/modes/json-event.d.ts.map +1 -0
- package/dist/modes/json-event.js +12 -0
- package/dist/modes/json-event.js.map +1 -0
- package/dist/modes/print-mode.d.ts +29 -0
- package/dist/modes/print-mode.d.ts.map +1 -0
- package/dist/modes/print-mode.js +142 -0
- package/dist/modes/print-mode.js.map +1 -0
- package/dist/modes/rpc/jsonl.d.ts +17 -0
- package/dist/modes/rpc/jsonl.d.ts.map +1 -0
- package/dist/modes/rpc/jsonl.js +49 -0
- package/dist/modes/rpc/jsonl.js.map +1 -0
- package/dist/modes/rpc/rpc-client.d.ts +321 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-client.js +755 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -0
- package/dist/modes/rpc/rpc-mode.d.ts +20 -0
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-mode.js +963 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -0
- package/dist/modes/rpc/rpc-types.d.ts +652 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-types.js +8 -0
- package/dist/modes/rpc/rpc-types.js.map +1 -0
- package/dist/package-manager-cli.d.ts +4 -0
- package/dist/package-manager-cli.d.ts.map +1 -0
- package/dist/package-manager-cli.js +488 -0
- package/dist/package-manager-cli.js.map +1 -0
- package/dist/utils/ansi.d.ts +2 -0
- package/dist/utils/ansi.d.ts.map +1 -0
- package/dist/utils/ansi.js +25 -0
- package/dist/utils/ansi.js.map +1 -0
- package/dist/utils/changelog.d.ts +23 -0
- package/dist/utils/changelog.d.ts.map +1 -0
- package/dist/utils/changelog.js +74 -0
- package/dist/utils/changelog.js.map +1 -0
- package/dist/utils/child-process.d.ts +15 -0
- package/dist/utils/child-process.d.ts.map +1 -0
- package/dist/utils/child-process.js +88 -0
- package/dist/utils/child-process.js.map +1 -0
- package/dist/utils/clipboard-image.d.ts +13 -0
- package/dist/utils/clipboard-image.d.ts.map +1 -0
- package/dist/utils/clipboard-image.js +248 -0
- package/dist/utils/clipboard-image.js.map +1 -0
- package/dist/utils/clipboard-native.d.ts +11 -0
- package/dist/utils/clipboard-native.d.ts.map +1 -0
- package/dist/utils/clipboard-native.js +20 -0
- package/dist/utils/clipboard-native.js.map +1 -0
- package/dist/utils/clipboard.d.ts +4 -0
- package/dist/utils/clipboard.d.ts.map +1 -0
- package/dist/utils/clipboard.js +171 -0
- package/dist/utils/clipboard.js.map +1 -0
- package/dist/utils/deprecation.d.ts +4 -0
- package/dist/utils/deprecation.d.ts.map +1 -0
- package/dist/utils/deprecation.js +13 -0
- package/dist/utils/deprecation.js.map +1 -0
- package/dist/utils/directory-completions.d.ts +5 -0
- package/dist/utils/directory-completions.d.ts.map +1 -0
- package/dist/utils/directory-completions.js +64 -0
- package/dist/utils/directory-completions.js.map +1 -0
- package/dist/utils/exif-orientation.d.ts +6 -0
- package/dist/utils/exif-orientation.d.ts.map +1 -0
- package/dist/utils/exif-orientation.js +166 -0
- package/dist/utils/exif-orientation.js.map +1 -0
- package/dist/utils/frontmatter.d.ts +8 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +26 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/dist/utils/fs-watch.d.ts +5 -0
- package/dist/utils/fs-watch.d.ts.map +1 -0
- package/dist/utils/fs-watch.js +25 -0
- package/dist/utils/fs-watch.js.map +1 -0
- package/dist/utils/git.d.ts +27 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +237 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/grip-user-agent.d.ts +2 -0
- package/dist/utils/grip-user-agent.d.ts.map +1 -0
- package/dist/utils/grip-user-agent.js +5 -0
- package/dist/utils/grip-user-agent.js.map +1 -0
- package/dist/utils/html.d.ts +7 -0
- package/dist/utils/html.d.ts.map +1 -0
- package/dist/utils/html.js +40 -0
- package/dist/utils/html.js.map +1 -0
- package/dist/utils/image-convert.d.ts +12 -0
- package/dist/utils/image-convert.d.ts.map +1 -0
- package/dist/utils/image-convert.js +43 -0
- package/dist/utils/image-convert.js.map +1 -0
- package/dist/utils/image-process.d.ts +18 -0
- package/dist/utils/image-process.d.ts.map +1 -0
- package/dist/utils/image-process.js +83 -0
- package/dist/utils/image-process.js.map +1 -0
- package/dist/utils/image-resize-core.d.ts +30 -0
- package/dist/utils/image-resize-core.d.ts.map +1 -0
- package/dist/utils/image-resize-core.js +133 -0
- package/dist/utils/image-resize-core.js.map +1 -0
- package/dist/utils/image-resize-worker.d.ts +2 -0
- package/dist/utils/image-resize-worker.d.ts.map +1 -0
- package/dist/utils/image-resize-worker.js +31 -0
- package/dist/utils/image-resize-worker.js.map +1 -0
- package/dist/utils/image-resize.d.ts +19 -0
- package/dist/utils/image-resize.d.ts.map +1 -0
- package/dist/utils/image-resize.js +81 -0
- package/dist/utils/image-resize.js.map +1 -0
- package/dist/utils/json.d.ts +3 -0
- package/dist/utils/json.d.ts.map +1 -0
- package/dist/utils/json.js +7 -0
- package/dist/utils/json.js.map +1 -0
- package/dist/utils/mime.d.ts +3 -0
- package/dist/utils/mime.d.ts.map +1 -0
- package/dist/utils/mime.js +110 -0
- package/dist/utils/mime.js.map +1 -0
- package/dist/utils/open-browser.d.ts +9 -0
- package/dist/utils/open-browser.d.ts.map +1 -0
- package/dist/utils/open-browser.js +22 -0
- package/dist/utils/open-browser.js.map +1 -0
- package/dist/utils/paths.d.ts +31 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +87 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/photon.d.ts +22 -0
- package/dist/utils/photon.d.ts.map +1 -0
- package/dist/utils/photon.js +125 -0
- package/dist/utils/photon.js.map +1 -0
- package/dist/utils/shell.d.ts +28 -0
- package/dist/utils/shell.d.ts.map +1 -0
- package/dist/utils/shell.js +188 -0
- package/dist/utils/shell.js.map +1 -0
- package/dist/utils/sleep.d.ts +5 -0
- package/dist/utils/sleep.d.ts.map +1 -0
- package/dist/utils/sleep.js +17 -0
- package/dist/utils/sleep.js.map +1 -0
- package/dist/utils/syntax-highlight.d.ts +12 -0
- package/dist/utils/syntax-highlight.d.ts.map +1 -0
- package/dist/utils/syntax-highlight.js +125 -0
- package/dist/utils/syntax-highlight.js.map +1 -0
- package/dist/utils/tools-manager.d.ts +5 -0
- package/dist/utils/tools-manager.d.ts.map +1 -0
- package/dist/utils/tools-manager.js +329 -0
- package/dist/utils/tools-manager.js.map +1 -0
- package/dist/utils/version-check.d.ts +14 -0
- package/dist/utils/version-check.d.ts.map +1 -0
- package/dist/utils/version-check.js +91 -0
- package/dist/utils/version-check.js.map +1 -0
- package/dist/utils/windows-self-update.d.ts +3 -0
- package/dist/utils/windows-self-update.d.ts.map +1 -0
- package/dist/utils/windows-self-update.js +77 -0
- package/dist/utils/windows-self-update.js.map +1 -0
- package/docs/compaction.md +408 -0
- package/docs/custom-provider.md +714 -0
- package/docs/daemon-architecture.md +399 -0
- package/docs/daemon.md +110 -0
- package/docs/development.md +72 -0
- package/docs/docs.json +164 -0
- package/docs/extensions.md +2745 -0
- package/docs/hooks.md +85 -0
- package/docs/images/doom-extension.png +0 -0
- package/docs/images/exy.png +0 -0
- package/docs/images/interactive-mode.png +0 -0
- package/docs/images/tree-view.png +0 -0
- package/docs/index.md +81 -0
- package/docs/json.md +89 -0
- package/docs/keybindings.md +230 -0
- package/docs/lsp.md +499 -0
- package/docs/migrating-to-grip.md +18 -0
- package/docs/models.md +496 -0
- package/docs/packages.md +228 -0
- package/docs/prompt-templates.md +88 -0
- package/docs/providers.md +251 -0
- package/docs/quickstart.md +167 -0
- package/docs/rpc.md +1492 -0
- package/docs/rules.md +117 -0
- package/docs/sandbox.md +181 -0
- package/docs/sdk.md +360 -0
- package/docs/session-format.md +414 -0
- package/docs/sessions.md +137 -0
- package/docs/settings.md +371 -0
- package/docs/shell-aliases.md +13 -0
- package/docs/skills.md +246 -0
- package/docs/terminal-setup.md +112 -0
- package/docs/termux.md +129 -0
- package/docs/themes.md +295 -0
- package/docs/tmux.md +61 -0
- package/docs/tui.md +918 -0
- package/docs/usage.md +304 -0
- package/docs/windows.md +17 -0
- package/examples/README.md +31 -0
- package/examples/daemon-docker/Dockerfile +43 -0
- package/examples/daemon-docker/README.md +45 -0
- package/examples/extensions/README.md +208 -0
- package/examples/extensions/auto-commit-on-exit.ts +46 -0
- package/examples/extensions/bash-spawn-hook.ts +30 -0
- package/examples/extensions/bookmark.ts +50 -0
- package/examples/extensions/border-status-editor.ts +145 -0
- package/examples/extensions/built-in-tool-renderer.ts +259 -0
- package/examples/extensions/claude-rules.ts +86 -0
- package/examples/extensions/commands.ts +82 -0
- package/examples/extensions/confirm-destructive.ts +59 -0
- package/examples/extensions/custom-compaction.ts +131 -0
- package/examples/extensions/custom-footer.ts +79 -0
- package/examples/extensions/custom-header.ts +73 -0
- package/examples/extensions/custom-provider-anthropic/index.ts +707 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
- package/examples/extensions/custom-provider-anthropic/package.json +19 -0
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +402 -0
- package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
- package/examples/extensions/custom-provider-gitlab-duo/test.ts +104 -0
- package/examples/extensions/dirty-repo-guard.ts +59 -0
- package/examples/extensions/doom-overlay/README.md +46 -0
- package/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
- package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
- package/examples/extensions/doom-overlay/doom/build.sh +152 -0
- package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
- package/examples/extensions/doom-overlay/doom-component.ts +133 -0
- package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
- package/examples/extensions/doom-overlay/doom-keys.ts +104 -0
- package/examples/extensions/doom-overlay/index.ts +74 -0
- package/examples/extensions/doom-overlay/wad-finder.ts +51 -0
- package/examples/extensions/dynamic-resources/RULES.md +8 -0
- package/examples/extensions/dynamic-resources/SKILL.md +8 -0
- package/examples/extensions/dynamic-resources/dynamic.json +79 -0
- package/examples/extensions/dynamic-resources/dynamic.md +5 -0
- package/examples/extensions/dynamic-resources/index.ts +16 -0
- package/examples/extensions/dynamic-tools.ts +74 -0
- package/examples/extensions/event-bus.ts +43 -0
- package/examples/extensions/file-trigger.ts +41 -0
- package/examples/extensions/git-checkpoint.ts +53 -0
- package/examples/extensions/git-merge-and-resolve.ts +125 -0
- package/examples/extensions/github-issue-autocomplete.ts +191 -0
- package/examples/extensions/handoff.ts +191 -0
- package/examples/extensions/hello.ts +26 -0
- package/examples/extensions/hidden-thinking-label.ts +53 -0
- package/examples/extensions/inline-bash.ts +104 -0
- package/examples/extensions/input-transform.ts +43 -0
- package/examples/extensions/interactive-shell.ts +194 -0
- package/examples/extensions/mac-system-theme.ts +47 -0
- package/examples/extensions/message-renderer.ts +59 -0
- package/examples/extensions/minimal-mode.ts +428 -0
- package/examples/extensions/modal-editor.ts +86 -0
- package/examples/extensions/model-status.ts +31 -0
- package/examples/extensions/notify.ts +55 -0
- package/examples/extensions/overlay-qa-tests.ts +1374 -0
- package/examples/extensions/overlay-test.ts +171 -0
- package/examples/extensions/permission-gate.ts +34 -0
- package/examples/extensions/pirate.ts +47 -0
- package/examples/extensions/plan-mode/README.md +65 -0
- package/examples/extensions/plan-mode/index.ts +346 -0
- package/examples/extensions/plan-mode/utils.ts +172 -0
- package/examples/extensions/preset.ts +426 -0
- package/examples/extensions/prompt-customizer.ts +97 -0
- package/examples/extensions/protected-paths.ts +29 -0
- package/examples/extensions/provider-payload.ts +18 -0
- package/examples/extensions/qna.ts +125 -0
- package/examples/extensions/question.ts +294 -0
- package/examples/extensions/questionnaire.ts +459 -0
- package/examples/extensions/rainbow-editor.ts +88 -0
- package/examples/extensions/reload-runtime.ts +37 -0
- package/examples/extensions/rpc-demo.ts +118 -0
- package/examples/extensions/sandbox/index.ts +320 -0
- package/examples/extensions/sandbox/package-lock.json +92 -0
- package/examples/extensions/sandbox/package.json +19 -0
- package/examples/extensions/send-user-message.ts +97 -0
- package/examples/extensions/session-name.ts +27 -0
- package/examples/extensions/shutdown-command.ts +63 -0
- package/examples/extensions/snake.ts +381 -0
- package/examples/extensions/space-invaders.ts +597 -0
- package/examples/extensions/status-line.ts +32 -0
- package/examples/extensions/structured-output.ts +65 -0
- package/examples/extensions/subagent/README.md +175 -0
- package/examples/extensions/subagent/agents/planner.md +37 -0
- package/examples/extensions/subagent/agents/reviewer.md +35 -0
- package/examples/extensions/subagent/agents/scout.md +50 -0
- package/examples/extensions/subagent/agents/worker.md +24 -0
- package/examples/extensions/subagent/agents.ts +126 -0
- package/examples/extensions/subagent/index.ts +1083 -0
- package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
- package/examples/extensions/subagent/prompts/implement.md +10 -0
- package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
- package/examples/extensions/summarize.ts +186 -0
- package/examples/extensions/system-prompt-header.ts +17 -0
- package/examples/extensions/tic-tac-toe.ts +1091 -0
- package/examples/extensions/timed-confirm.ts +70 -0
- package/examples/extensions/titlebar-spinner.ts +58 -0
- package/examples/extensions/todo.ts +306 -0
- package/examples/extensions/tool-override.ts +144 -0
- package/examples/extensions/tools.ts +141 -0
- package/examples/extensions/trigger-compact.ts +50 -0
- package/examples/extensions/truncated-tool.ts +200 -0
- package/examples/extensions/widget-placement.ts +9 -0
- package/examples/extensions/with-deps/index.ts +32 -0
- package/examples/extensions/with-deps/package-lock.json +31 -0
- package/examples/extensions/with-deps/package.json +22 -0
- package/examples/extensions/working-indicator.ts +123 -0
- package/examples/extensions/working-message-test.ts +25 -0
- package/examples/remote-session-server/README.md +71 -0
- package/examples/remote-session-server/server.ts +353 -0
- package/examples/rpc-extension-ui.ts +642 -0
- package/examples/sandbox-docker/Dockerfile +274 -0
- package/examples/sandbox-docker/README.md +88 -0
- package/examples/sdk/01-minimal.ts +27 -0
- package/examples/sdk/02-custom-model.ts +54 -0
- package/examples/sdk/03-custom-prompt.ts +76 -0
- package/examples/sdk/04-skills.ts +60 -0
- package/examples/sdk/05-tools.ts +55 -0
- package/examples/sdk/06-extensions.ts +94 -0
- package/examples/sdk/07-context-files.ts +47 -0
- package/examples/sdk/08-prompt-templates.ts +56 -0
- package/examples/sdk/09-api-keys-and-oauth.ts +50 -0
- package/examples/sdk/10-settings.ts +58 -0
- package/examples/sdk/11-sessions.ts +54 -0
- package/examples/sdk/12-full-control.ts +79 -0
- package/examples/sdk/13-session-runtime.ts +49 -0
- package/examples/sdk/README.md +94 -0
- package/npm-shrinkwrap.json +1878 -0
- package/package.json +102 -5
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { createServer as createHttpServer, } from "node:http";
|
|
3
|
+
import { createServer as createHttpsServer } from "node:https";
|
|
4
|
+
import WebSocket, { WebSocketServer } from "ws";
|
|
5
|
+
import { RemoteWorkspaceServerProtocol, } from "../core/remote-workspace-protocol/session.js";
|
|
6
|
+
import { DAEMON_WEBSOCKET_PATH } from "./config.js";
|
|
7
|
+
import { createDaemonAuthorization, rejectDaemonUpgrade, validateDaemonNetworkPolicy, validateDaemonUpgrade, } from "./security.js";
|
|
8
|
+
import { createDaemonWorkspaceRuntime } from "./workspace-runtime.js";
|
|
9
|
+
function websocketPayload(data) {
|
|
10
|
+
if (Buffer.isBuffer(data))
|
|
11
|
+
return Uint8Array.from(data);
|
|
12
|
+
if (Array.isArray(data))
|
|
13
|
+
return Uint8Array.from(Buffer.concat(data));
|
|
14
|
+
return Uint8Array.from(new Uint8Array(data));
|
|
15
|
+
}
|
|
16
|
+
function websocketCloseCode(code) {
|
|
17
|
+
switch (code) {
|
|
18
|
+
case "normal":
|
|
19
|
+
return 1000;
|
|
20
|
+
case "protocol_error":
|
|
21
|
+
return 1002;
|
|
22
|
+
case "invalid_payload":
|
|
23
|
+
return 1007;
|
|
24
|
+
case "policy_violation":
|
|
25
|
+
return 1008;
|
|
26
|
+
case "message_too_large":
|
|
27
|
+
return 1009;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function waitForWebSocketClose(websocket) {
|
|
31
|
+
if (websocket.readyState === WebSocket.CLOSED)
|
|
32
|
+
return Promise.resolve();
|
|
33
|
+
return new Promise((resolve) => websocket.once("close", () => resolve()));
|
|
34
|
+
}
|
|
35
|
+
function waitWithin(promise, timeoutMs, forceSignal) {
|
|
36
|
+
if (forceSignal.aborted)
|
|
37
|
+
return Promise.resolve(false);
|
|
38
|
+
return new Promise((resolve) => {
|
|
39
|
+
let settled = false;
|
|
40
|
+
const finish = (value) => {
|
|
41
|
+
if (settled)
|
|
42
|
+
return;
|
|
43
|
+
settled = true;
|
|
44
|
+
clearTimeout(timer);
|
|
45
|
+
forceSignal.removeEventListener("abort", onForce);
|
|
46
|
+
resolve(value);
|
|
47
|
+
};
|
|
48
|
+
const timer = setTimeout(() => finish(false), timeoutMs);
|
|
49
|
+
const onForce = () => finish(false);
|
|
50
|
+
forceSignal.addEventListener("abort", onForce, { once: true });
|
|
51
|
+
promise.then(() => finish(true), () => finish(false));
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
function terminateDaemonConnections(connections) {
|
|
55
|
+
for (const connection of connections)
|
|
56
|
+
connection.websocket.terminate();
|
|
57
|
+
}
|
|
58
|
+
function beginDaemonConnectionDrain(connections, hostDisposal) {
|
|
59
|
+
return Promise.allSettled([...connections.map((connection) => connection.protocol.beginDrain()), hostDisposal]).then(() => undefined);
|
|
60
|
+
}
|
|
61
|
+
function disconnectDaemonConnections(connections) {
|
|
62
|
+
return Promise.allSettled(connections.map((connection) => connection.protocol.disconnect())).then(() => undefined);
|
|
63
|
+
}
|
|
64
|
+
function requestDaemonConnectionClose(connections) {
|
|
65
|
+
for (const connection of connections) {
|
|
66
|
+
if (connection.websocket.readyState === WebSocket.OPEN) {
|
|
67
|
+
connection.websocket.close(1001, "Daemon shutting down");
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function waitForDaemonConnectionsClosed(connections) {
|
|
72
|
+
return Promise.allSettled(connections.map((connection) => connection.closed)).then(() => undefined);
|
|
73
|
+
}
|
|
74
|
+
function destroyDaemonSockets(sockets) {
|
|
75
|
+
for (const socket of sockets)
|
|
76
|
+
socket.destroy();
|
|
77
|
+
}
|
|
78
|
+
function formatHostForUrl(host) {
|
|
79
|
+
return host.includes(":") && !host.startsWith("[") ? `[${host}]` : host;
|
|
80
|
+
}
|
|
81
|
+
export function createDaemonServer(configuration) {
|
|
82
|
+
validateDaemonNetworkPolicy(configuration);
|
|
83
|
+
const authorization = createDaemonAuthorization(configuration.token);
|
|
84
|
+
const workspaceId = randomBytes(18).toString("base64url");
|
|
85
|
+
const workspace = Object.freeze({
|
|
86
|
+
id: workspaceId,
|
|
87
|
+
root: configuration.workspaceRoot,
|
|
88
|
+
pathFlavor: process.platform === "win32" ? "windows" : "posix",
|
|
89
|
+
});
|
|
90
|
+
let runtime = createDaemonWorkspaceRuntime(configuration);
|
|
91
|
+
let runtimeHandler = runtime.createHandler(workspace);
|
|
92
|
+
const handler = {
|
|
93
|
+
handleRequest: (request, context) => runtimeHandler.handleRequest(request, context),
|
|
94
|
+
validateToolArguments: (toolName, value) => runtimeHandler.validateToolArguments(toolName, value),
|
|
95
|
+
};
|
|
96
|
+
const requestListener = (_request, response) => {
|
|
97
|
+
response.writeHead(404, { "content-type": "text/plain" });
|
|
98
|
+
response.end("Not found\n");
|
|
99
|
+
};
|
|
100
|
+
const server = configuration.tls
|
|
101
|
+
? createHttpsServer({
|
|
102
|
+
cert: configuration.tls.cert,
|
|
103
|
+
key: configuration.tls.key,
|
|
104
|
+
passphrase: configuration.tls.passphrase,
|
|
105
|
+
minVersion: "TLSv1.2",
|
|
106
|
+
}, requestListener)
|
|
107
|
+
: createHttpServer(requestListener);
|
|
108
|
+
const websocketServer = new WebSocketServer({
|
|
109
|
+
noServer: true,
|
|
110
|
+
clientTracking: false,
|
|
111
|
+
maxPayload: configuration.protocolLimits.maxMessageBytes,
|
|
112
|
+
perMessageDeflate: false,
|
|
113
|
+
allowSynchronousEvents: false,
|
|
114
|
+
skipUTF8Validation: false,
|
|
115
|
+
});
|
|
116
|
+
const sockets = new Set();
|
|
117
|
+
const pendingSockets = new Set();
|
|
118
|
+
const pendingSocketTimers = new Map();
|
|
119
|
+
const pendingSocketDeadlines = new Map();
|
|
120
|
+
const connections = new Set();
|
|
121
|
+
let catalog = runtime.catalog;
|
|
122
|
+
let reloadQueue = Promise.resolve();
|
|
123
|
+
const forceController = new AbortController();
|
|
124
|
+
let currentAddress;
|
|
125
|
+
let listenPromise;
|
|
126
|
+
let rejectListen;
|
|
127
|
+
let closePromise;
|
|
128
|
+
let serverState = "created";
|
|
129
|
+
const stopListener = () => {
|
|
130
|
+
if (!server.listening && !listenPromise)
|
|
131
|
+
return Promise.resolve();
|
|
132
|
+
return new Promise((resolve) => {
|
|
133
|
+
let settled = false;
|
|
134
|
+
const cleanup = () => {
|
|
135
|
+
server.off("listening", onListening);
|
|
136
|
+
server.off("error", onError);
|
|
137
|
+
server.off("close", onClose);
|
|
138
|
+
};
|
|
139
|
+
const finish = () => {
|
|
140
|
+
if (settled)
|
|
141
|
+
return;
|
|
142
|
+
settled = true;
|
|
143
|
+
cleanup();
|
|
144
|
+
resolve();
|
|
145
|
+
};
|
|
146
|
+
const closeListener = () => server.close(() => finish());
|
|
147
|
+
const onListening = () => closeListener();
|
|
148
|
+
const onError = () => finish();
|
|
149
|
+
const onClose = () => finish();
|
|
150
|
+
server.once("error", onError);
|
|
151
|
+
server.once("close", onClose);
|
|
152
|
+
if (server.listening)
|
|
153
|
+
closeListener();
|
|
154
|
+
else
|
|
155
|
+
server.once("listening", onListening);
|
|
156
|
+
});
|
|
157
|
+
};
|
|
158
|
+
server.on("connection", (socket) => {
|
|
159
|
+
if (serverState !== "listening" || pendingSockets.size >= configuration.maxPendingConnections) {
|
|
160
|
+
socket.destroy();
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
sockets.add(socket);
|
|
164
|
+
pendingSockets.add(socket);
|
|
165
|
+
const pendingTimer = setTimeout(() => socket.destroy(), configuration.handshakeTimeoutMs);
|
|
166
|
+
pendingTimer.unref?.();
|
|
167
|
+
pendingSocketTimers.set(socket, pendingTimer);
|
|
168
|
+
pendingSocketDeadlines.set(socket, performance.now() + configuration.handshakeTimeoutMs);
|
|
169
|
+
socket.once("close", () => {
|
|
170
|
+
sockets.delete(socket);
|
|
171
|
+
pendingSockets.delete(socket);
|
|
172
|
+
const timer = pendingSocketTimers.get(socket);
|
|
173
|
+
if (timer)
|
|
174
|
+
clearTimeout(timer);
|
|
175
|
+
pendingSocketTimers.delete(socket);
|
|
176
|
+
pendingSocketDeadlines.delete(socket);
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
server.on("upgrade", (request, socket, head) => {
|
|
180
|
+
const netSocket = socket;
|
|
181
|
+
const decision = validateDaemonUpgrade(request, configuration, authorization);
|
|
182
|
+
if (!decision.accepted) {
|
|
183
|
+
rejectDaemonUpgrade(netSocket, decision);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
if (serverState !== "listening" || connections.size >= configuration.maxConnections) {
|
|
187
|
+
rejectDaemonUpgrade(netSocket, { accepted: false, status: 503, message: "Service unavailable" });
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const handshakeDeadline = pendingSocketDeadlines.get(netSocket) ?? performance.now();
|
|
191
|
+
pendingSockets.delete(netSocket);
|
|
192
|
+
const pendingTimer = pendingSocketTimers.get(netSocket);
|
|
193
|
+
if (pendingTimer)
|
|
194
|
+
clearTimeout(pendingTimer);
|
|
195
|
+
pendingSocketTimers.delete(netSocket);
|
|
196
|
+
pendingSocketDeadlines.delete(netSocket);
|
|
197
|
+
websocketServer.handleUpgrade(request, socket, head, (websocket) => {
|
|
198
|
+
if (serverState !== "listening") {
|
|
199
|
+
websocket.terminate();
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
const remainingHandshakeMs = Math.max(0, handshakeDeadline - performance.now());
|
|
203
|
+
const handshakeTimer = setTimeout(() => {
|
|
204
|
+
websocket.terminate();
|
|
205
|
+
}, remainingHandshakeMs);
|
|
206
|
+
handshakeTimer.unref?.();
|
|
207
|
+
let protocol;
|
|
208
|
+
const transport = {
|
|
209
|
+
send(message) {
|
|
210
|
+
if (websocket.readyState !== WebSocket.OPEN)
|
|
211
|
+
return Promise.reject(new Error("WebSocket is not open"));
|
|
212
|
+
const serialized = JSON.stringify(message);
|
|
213
|
+
const bytes = Buffer.byteLength(serialized, "utf8");
|
|
214
|
+
if (websocket.bufferedAmount + bytes > configuration.protocolLimits.maxPendingOutboundBytes) {
|
|
215
|
+
return Promise.reject(new Error("WebSocket outbound buffer exceeds daemon limits"));
|
|
216
|
+
}
|
|
217
|
+
return new Promise((resolve, reject) => {
|
|
218
|
+
websocket.send(serialized, { binary: false, compress: false }, (error) => {
|
|
219
|
+
if (error)
|
|
220
|
+
reject(error);
|
|
221
|
+
else
|
|
222
|
+
resolve();
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
},
|
|
226
|
+
close(reason) {
|
|
227
|
+
if (websocket.readyState === WebSocket.CLOSED)
|
|
228
|
+
return Promise.resolve();
|
|
229
|
+
websocket.close(websocketCloseCode(reason.code), reason.message);
|
|
230
|
+
return waitForWebSocketClose(websocket);
|
|
231
|
+
},
|
|
232
|
+
};
|
|
233
|
+
protocol = new RemoteWorkspaceServerProtocol(transport, handler, {
|
|
234
|
+
workspace,
|
|
235
|
+
catalog,
|
|
236
|
+
capabilities: runtime.capabilities,
|
|
237
|
+
limits: configuration.protocolLimits,
|
|
238
|
+
backendLabel: "grip-workspace-daemon",
|
|
239
|
+
});
|
|
240
|
+
const connection = {
|
|
241
|
+
websocket,
|
|
242
|
+
protocol,
|
|
243
|
+
closed: Promise.resolve(),
|
|
244
|
+
};
|
|
245
|
+
connection.closed = waitForWebSocketClose(websocket).then(async () => {
|
|
246
|
+
clearTimeout(handshakeTimer);
|
|
247
|
+
connections.delete(connection);
|
|
248
|
+
await protocol.disconnect().catch(() => undefined);
|
|
249
|
+
});
|
|
250
|
+
connections.add(connection);
|
|
251
|
+
websocket.on("message", (data, isBinary) => {
|
|
252
|
+
if (isBinary) {
|
|
253
|
+
websocket.close(1003, "Text protocol required");
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
void protocol
|
|
257
|
+
.receive(websocketPayload(data))
|
|
258
|
+
.then(() => {
|
|
259
|
+
if (protocol.handshakeComplete)
|
|
260
|
+
clearTimeout(handshakeTimer);
|
|
261
|
+
})
|
|
262
|
+
.catch(() => undefined);
|
|
263
|
+
});
|
|
264
|
+
websocket.on("error", () => undefined);
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
const api = {
|
|
268
|
+
listen() {
|
|
269
|
+
if (serverState === "closing" || serverState === "closed")
|
|
270
|
+
return Promise.reject(new Error("Daemon server is closing"));
|
|
271
|
+
if (currentAddress)
|
|
272
|
+
return Promise.resolve(currentAddress);
|
|
273
|
+
if (listenPromise)
|
|
274
|
+
return listenPromise;
|
|
275
|
+
listenPromise = new Promise((resolve, reject) => {
|
|
276
|
+
rejectListen = reject;
|
|
277
|
+
const onError = (error) => {
|
|
278
|
+
server.off("listening", onListening);
|
|
279
|
+
listenPromise = undefined;
|
|
280
|
+
rejectListen = undefined;
|
|
281
|
+
reject(error);
|
|
282
|
+
};
|
|
283
|
+
const onListening = () => {
|
|
284
|
+
server.off("error", onError);
|
|
285
|
+
if (serverState !== "created") {
|
|
286
|
+
rejectListen = undefined;
|
|
287
|
+
reject(new Error("Daemon server closed before listening completed"));
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const address = server.address();
|
|
291
|
+
if (!address || typeof address === "string") {
|
|
292
|
+
rejectListen = undefined;
|
|
293
|
+
reject(new Error("Daemon listener did not return a TCP address"));
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
serverState = "listening";
|
|
297
|
+
const port = address.port;
|
|
298
|
+
currentAddress = Object.freeze({
|
|
299
|
+
host: configuration.host,
|
|
300
|
+
port,
|
|
301
|
+
secure: configuration.tls !== undefined,
|
|
302
|
+
url: `${configuration.tls ? "wss" : "ws"}://${formatHostForUrl(configuration.host)}:${port}${DAEMON_WEBSOCKET_PATH}`,
|
|
303
|
+
workspaceRoot: configuration.workspaceRoot,
|
|
304
|
+
workspaceId,
|
|
305
|
+
});
|
|
306
|
+
rejectListen = undefined;
|
|
307
|
+
resolve(currentAddress);
|
|
308
|
+
};
|
|
309
|
+
server.once("error", onError);
|
|
310
|
+
server.once("listening", onListening);
|
|
311
|
+
server.listen(configuration.port, configuration.host);
|
|
312
|
+
});
|
|
313
|
+
return listenPromise;
|
|
314
|
+
},
|
|
315
|
+
address() {
|
|
316
|
+
return currentAddress ? { ...currentAddress } : undefined;
|
|
317
|
+
},
|
|
318
|
+
state() {
|
|
319
|
+
return serverState;
|
|
320
|
+
},
|
|
321
|
+
reload() {
|
|
322
|
+
if (serverState !== "listening")
|
|
323
|
+
return Promise.reject(new Error("Daemon server is not listening"));
|
|
324
|
+
reloadQueue = reloadQueue.then(async () => {
|
|
325
|
+
if (serverState !== "listening")
|
|
326
|
+
throw new Error("Daemon server is not listening");
|
|
327
|
+
const candidate = createDaemonWorkspaceRuntime(configuration);
|
|
328
|
+
const candidateCatalog = { ...candidate.catalog, generation: catalog.generation + 1 };
|
|
329
|
+
const previous = runtime;
|
|
330
|
+
const previousCatalog = catalog;
|
|
331
|
+
runtime = candidate;
|
|
332
|
+
runtimeHandler = candidate.createHandler(workspace);
|
|
333
|
+
catalog = candidateCatalog;
|
|
334
|
+
try {
|
|
335
|
+
await Promise.all([...connections].map((connection) => connection.protocol.publishCatalog(catalog)));
|
|
336
|
+
}
|
|
337
|
+
catch (error) {
|
|
338
|
+
runtime = previous;
|
|
339
|
+
runtimeHandler = previous.createHandler(workspace);
|
|
340
|
+
catalog = previousCatalog;
|
|
341
|
+
await Promise.allSettled([...connections].map((connection) => connection.protocol.disconnect()));
|
|
342
|
+
await candidate.dispose();
|
|
343
|
+
throw error;
|
|
344
|
+
}
|
|
345
|
+
await previous.retire();
|
|
346
|
+
});
|
|
347
|
+
return reloadQueue;
|
|
348
|
+
},
|
|
349
|
+
close() {
|
|
350
|
+
if (closePromise)
|
|
351
|
+
return closePromise;
|
|
352
|
+
serverState = "closing";
|
|
353
|
+
rejectListen?.(new Error("Daemon server closed before listening completed"));
|
|
354
|
+
rejectListen = undefined;
|
|
355
|
+
const deadline = performance.now() + configuration.shutdownTimeoutMs;
|
|
356
|
+
const remainingMs = () => Math.max(0, deadline - performance.now());
|
|
357
|
+
closePromise = (async () => {
|
|
358
|
+
const listenerClose = stopListener();
|
|
359
|
+
const snapshot = [...connections];
|
|
360
|
+
await waitWithin(reloadQueue.catch(() => undefined), remainingMs(), forceController.signal);
|
|
361
|
+
const hostDisposal = runtime.dispose();
|
|
362
|
+
const drained = await waitWithin(beginDaemonConnectionDrain(snapshot, hostDisposal), remainingMs(), forceController.signal);
|
|
363
|
+
if (!drained)
|
|
364
|
+
terminateDaemonConnections(snapshot);
|
|
365
|
+
await waitWithin(disconnectDaemonConnections(snapshot), remainingMs(), forceController.signal);
|
|
366
|
+
requestDaemonConnectionClose(snapshot);
|
|
367
|
+
const socketsClosed = await waitWithin(waitForDaemonConnectionsClosed(snapshot), remainingMs(), forceController.signal);
|
|
368
|
+
if (!socketsClosed)
|
|
369
|
+
terminateDaemonConnections(snapshot);
|
|
370
|
+
destroyDaemonSockets(sockets);
|
|
371
|
+
await listenerClose;
|
|
372
|
+
connections.clear();
|
|
373
|
+
})().finally(() => {
|
|
374
|
+
terminateDaemonConnections(connections);
|
|
375
|
+
destroyDaemonSockets(sockets);
|
|
376
|
+
for (const timer of pendingSocketTimers.values())
|
|
377
|
+
clearTimeout(timer);
|
|
378
|
+
pendingSocketTimers.clear();
|
|
379
|
+
pendingSocketDeadlines.clear();
|
|
380
|
+
pendingSockets.clear();
|
|
381
|
+
connections.clear();
|
|
382
|
+
currentAddress = undefined;
|
|
383
|
+
serverState = "closed";
|
|
384
|
+
});
|
|
385
|
+
return closePromise;
|
|
386
|
+
},
|
|
387
|
+
forceClose() {
|
|
388
|
+
if (serverState === "closed")
|
|
389
|
+
return closePromise ?? Promise.resolve();
|
|
390
|
+
serverState = "closing";
|
|
391
|
+
forceController.abort();
|
|
392
|
+
currentAddress = undefined;
|
|
393
|
+
terminateDaemonConnections(connections);
|
|
394
|
+
destroyDaemonSockets(sockets);
|
|
395
|
+
return api.close();
|
|
396
|
+
},
|
|
397
|
+
};
|
|
398
|
+
return api;
|
|
399
|
+
}
|
|
400
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/daemon/server.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport {\n\tcreateServer as createHttpServer,\n\ttype Server as HttpServer,\n\ttype IncomingMessage,\n\ttype ServerResponse,\n} from \"node:http\";\nimport { createServer as createHttpsServer } from \"node:https\";\nimport type { AddressInfo, Socket } from \"node:net\";\nimport WebSocket, { type RawData, WebSocketServer } from \"ws\";\nimport type { RemoteWorkspaceServerMessage } from \"../core/remote-workspace-protocol/contract.ts\";\nimport {\n\ttype RemoteWorkspaceProtocolCloseCode,\n\ttype RemoteWorkspaceProtocolCloseReason,\n\ttype RemoteWorkspaceServerHandler,\n\tRemoteWorkspaceServerProtocol,\n} from \"../core/remote-workspace-protocol/session.ts\";\nimport { DAEMON_WEBSOCKET_PATH, type DaemonConfiguration } from \"./config.ts\";\nimport {\n\tcreateDaemonAuthorization,\n\trejectDaemonUpgrade,\n\tvalidateDaemonNetworkPolicy,\n\tvalidateDaemonUpgrade,\n} from \"./security.ts\";\nimport { createDaemonWorkspaceRuntime } from \"./workspace-runtime.ts\";\n\nexport interface DaemonServerAddress {\n\treadonly host: string;\n\treadonly port: number;\n\treadonly secure: boolean;\n\treadonly url: string;\n\treadonly workspaceRoot: string;\n\treadonly workspaceId: string;\n}\n\nexport type DaemonServerState = \"created\" | \"listening\" | \"closing\" | \"closed\";\n\nexport interface DaemonServer {\n\tlisten(): Promise<DaemonServerAddress>;\n\taddress(): DaemonServerAddress | undefined;\n\tstate(): DaemonServerState;\n\treload(): Promise<void>;\n\tclose(): Promise<void>;\n\tforceClose(): Promise<void>;\n}\n\ninterface DaemonConnection {\n\treadonly websocket: WebSocket;\n\treadonly protocol: RemoteWorkspaceServerProtocol;\n\tclosed: Promise<void>;\n}\n\nfunction websocketPayload(data: RawData): Uint8Array {\n\tif (Buffer.isBuffer(data)) return Uint8Array.from(data);\n\tif (Array.isArray(data)) return Uint8Array.from(Buffer.concat(data));\n\treturn Uint8Array.from(new Uint8Array(data));\n}\n\nfunction websocketCloseCode(code: RemoteWorkspaceProtocolCloseCode): number {\n\tswitch (code) {\n\t\tcase \"normal\":\n\t\t\treturn 1000;\n\t\tcase \"protocol_error\":\n\t\t\treturn 1002;\n\t\tcase \"invalid_payload\":\n\t\t\treturn 1007;\n\t\tcase \"policy_violation\":\n\t\t\treturn 1008;\n\t\tcase \"message_too_large\":\n\t\t\treturn 1009;\n\t}\n}\n\nfunction waitForWebSocketClose(websocket: WebSocket): Promise<void> {\n\tif (websocket.readyState === WebSocket.CLOSED) return Promise.resolve();\n\treturn new Promise((resolve) => websocket.once(\"close\", () => resolve()));\n}\n\nfunction waitWithin(promise: Promise<unknown>, timeoutMs: number, forceSignal: AbortSignal): Promise<boolean> {\n\tif (forceSignal.aborted) return Promise.resolve(false);\n\treturn new Promise((resolve) => {\n\t\tlet settled = false;\n\t\tconst finish = (value: boolean) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tclearTimeout(timer);\n\t\t\tforceSignal.removeEventListener(\"abort\", onForce);\n\t\t\tresolve(value);\n\t\t};\n\t\tconst timer = setTimeout(() => finish(false), timeoutMs);\n\t\tconst onForce = () => finish(false);\n\t\tforceSignal.addEventListener(\"abort\", onForce, { once: true });\n\t\tpromise.then(\n\t\t\t() => finish(true),\n\t\t\t() => finish(false),\n\t\t);\n\t});\n}\nfunction terminateDaemonConnections(connections: Iterable<DaemonConnection>): void {\n\tfor (const connection of connections) connection.websocket.terminate();\n}\n\nfunction beginDaemonConnectionDrain(\n\tconnections: readonly DaemonConnection[],\n\thostDisposal: Promise<void>,\n): Promise<void> {\n\treturn Promise.allSettled([...connections.map((connection) => connection.protocol.beginDrain()), hostDisposal]).then(\n\t\t() => undefined,\n\t);\n}\n\nfunction disconnectDaemonConnections(connections: readonly DaemonConnection[]): Promise<void> {\n\treturn Promise.allSettled(connections.map((connection) => connection.protocol.disconnect())).then(() => undefined);\n}\n\nfunction requestDaemonConnectionClose(connections: readonly DaemonConnection[]): void {\n\tfor (const connection of connections) {\n\t\tif (connection.websocket.readyState === WebSocket.OPEN) {\n\t\t\tconnection.websocket.close(1001, \"Daemon shutting down\");\n\t\t}\n\t}\n}\n\nfunction waitForDaemonConnectionsClosed(connections: readonly DaemonConnection[]): Promise<void> {\n\treturn Promise.allSettled(connections.map((connection) => connection.closed)).then(() => undefined);\n}\n\nfunction destroyDaemonSockets(sockets: ReadonlySet<Socket>): void {\n\tfor (const socket of sockets) socket.destroy();\n}\n\nfunction formatHostForUrl(host: string): string {\n\treturn host.includes(\":\") && !host.startsWith(\"[\") ? `[${host}]` : host;\n}\n\nexport function createDaemonServer(configuration: DaemonConfiguration): DaemonServer {\n\tvalidateDaemonNetworkPolicy(configuration);\n\tconst authorization = createDaemonAuthorization(configuration.token);\n\tconst workspaceId = randomBytes(18).toString(\"base64url\");\n\tconst workspace = Object.freeze({\n\t\tid: workspaceId,\n\t\troot: configuration.workspaceRoot,\n\t\tpathFlavor: process.platform === \"win32\" ? (\"windows\" as const) : (\"posix\" as const),\n\t});\n\tlet runtime = createDaemonWorkspaceRuntime(configuration);\n\tlet runtimeHandler = runtime.createHandler(workspace);\n\tconst handler: RemoteWorkspaceServerHandler = {\n\t\thandleRequest: (request, context) => runtimeHandler.handleRequest(request, context),\n\t\tvalidateToolArguments: (toolName, value) => runtimeHandler.validateToolArguments(toolName, value),\n\t};\n\tconst requestListener = (_request: IncomingMessage, response: ServerResponse) => {\n\t\tresponse.writeHead(404, { \"content-type\": \"text/plain\" });\n\t\tresponse.end(\"Not found\\n\");\n\t};\n\tconst server: HttpServer = configuration.tls\n\t\t? createHttpsServer(\n\t\t\t\t{\n\t\t\t\t\tcert: configuration.tls.cert,\n\t\t\t\t\tkey: configuration.tls.key,\n\t\t\t\t\tpassphrase: configuration.tls.passphrase,\n\t\t\t\t\tminVersion: \"TLSv1.2\",\n\t\t\t\t},\n\t\t\t\trequestListener,\n\t\t\t)\n\t\t: createHttpServer(requestListener);\n\tconst websocketServer = new WebSocketServer({\n\t\tnoServer: true,\n\t\tclientTracking: false,\n\t\tmaxPayload: configuration.protocolLimits.maxMessageBytes,\n\t\tperMessageDeflate: false,\n\t\tallowSynchronousEvents: false,\n\t\tskipUTF8Validation: false,\n\t});\n\tconst sockets = new Set<Socket>();\n\tconst pendingSockets = new Set<Socket>();\n\tconst pendingSocketTimers = new Map<Socket, NodeJS.Timeout>();\n\tconst pendingSocketDeadlines = new Map<Socket, number>();\n\tconst connections = new Set<DaemonConnection>();\n\tlet catalog = runtime.catalog;\n\tlet reloadQueue: Promise<void> = Promise.resolve();\n\tconst forceController = new AbortController();\n\tlet currentAddress: DaemonServerAddress | undefined;\n\tlet listenPromise: Promise<DaemonServerAddress> | undefined;\n\tlet rejectListen: ((error: Error) => void) | undefined;\n\tlet closePromise: Promise<void> | undefined;\n\tlet serverState: DaemonServerState = \"created\";\n\n\tconst stopListener = (): Promise<void> => {\n\t\tif (!server.listening && !listenPromise) return Promise.resolve();\n\t\treturn new Promise((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tconst cleanup = () => {\n\t\t\t\tserver.off(\"listening\", onListening);\n\t\t\t\tserver.off(\"error\", onError);\n\t\t\t\tserver.off(\"close\", onClose);\n\t\t\t};\n\t\t\tconst finish = () => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tcleanup();\n\t\t\t\tresolve();\n\t\t\t};\n\t\t\tconst closeListener = () => server.close(() => finish());\n\t\t\tconst onListening = () => closeListener();\n\t\t\tconst onError = () => finish();\n\t\t\tconst onClose = () => finish();\n\t\t\tserver.once(\"error\", onError);\n\t\t\tserver.once(\"close\", onClose);\n\t\t\tif (server.listening) closeListener();\n\t\t\telse server.once(\"listening\", onListening);\n\t\t});\n\t};\n\n\tserver.on(\"connection\", (socket: Socket) => {\n\t\tif (serverState !== \"listening\" || pendingSockets.size >= configuration.maxPendingConnections) {\n\t\t\tsocket.destroy();\n\t\t\treturn;\n\t\t}\n\t\tsockets.add(socket);\n\t\tpendingSockets.add(socket);\n\t\tconst pendingTimer = setTimeout(() => socket.destroy(), configuration.handshakeTimeoutMs);\n\t\tpendingTimer.unref?.();\n\t\tpendingSocketTimers.set(socket, pendingTimer);\n\t\tpendingSocketDeadlines.set(socket, performance.now() + configuration.handshakeTimeoutMs);\n\t\tsocket.once(\"close\", () => {\n\t\t\tsockets.delete(socket);\n\t\t\tpendingSockets.delete(socket);\n\t\t\tconst timer = pendingSocketTimers.get(socket);\n\t\t\tif (timer) clearTimeout(timer);\n\t\t\tpendingSocketTimers.delete(socket);\n\t\t\tpendingSocketDeadlines.delete(socket);\n\t\t});\n\t});\n\n\tserver.on(\"upgrade\", (request, socket, head) => {\n\t\tconst netSocket = socket as Socket;\n\t\tconst decision = validateDaemonUpgrade(request, configuration, authorization);\n\t\tif (!decision.accepted) {\n\t\t\trejectDaemonUpgrade(netSocket, decision);\n\t\t\treturn;\n\t\t}\n\t\tif (serverState !== \"listening\" || connections.size >= configuration.maxConnections) {\n\t\t\trejectDaemonUpgrade(netSocket, { accepted: false, status: 503, message: \"Service unavailable\" });\n\t\t\treturn;\n\t\t}\n\t\tconst handshakeDeadline = pendingSocketDeadlines.get(netSocket) ?? performance.now();\n\t\tpendingSockets.delete(netSocket);\n\t\tconst pendingTimer = pendingSocketTimers.get(netSocket);\n\t\tif (pendingTimer) clearTimeout(pendingTimer);\n\t\tpendingSocketTimers.delete(netSocket);\n\t\tpendingSocketDeadlines.delete(netSocket);\n\t\twebsocketServer.handleUpgrade(request, socket, head, (websocket) => {\n\t\t\tif (serverState !== \"listening\") {\n\t\t\t\twebsocket.terminate();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst remainingHandshakeMs = Math.max(0, handshakeDeadline - performance.now());\n\t\t\tconst handshakeTimer = setTimeout(() => {\n\t\t\t\twebsocket.terminate();\n\t\t\t}, remainingHandshakeMs);\n\t\t\thandshakeTimer.unref?.();\n\t\t\tlet protocol: RemoteWorkspaceServerProtocol;\n\t\t\tconst transport = {\n\t\t\t\tsend(message: RemoteWorkspaceServerMessage): Promise<void> {\n\t\t\t\t\tif (websocket.readyState !== WebSocket.OPEN) return Promise.reject(new Error(\"WebSocket is not open\"));\n\t\t\t\t\tconst serialized = JSON.stringify(message);\n\t\t\t\t\tconst bytes = Buffer.byteLength(serialized, \"utf8\");\n\t\t\t\t\tif (websocket.bufferedAmount + bytes > configuration.protocolLimits.maxPendingOutboundBytes) {\n\t\t\t\t\t\treturn Promise.reject(new Error(\"WebSocket outbound buffer exceeds daemon limits\"));\n\t\t\t\t\t}\n\t\t\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\t\t\twebsocket.send(serialized, { binary: false, compress: false }, (error) => {\n\t\t\t\t\t\t\tif (error) reject(error);\n\t\t\t\t\t\t\telse resolve();\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tclose(reason: RemoteWorkspaceProtocolCloseReason): Promise<void> {\n\t\t\t\t\tif (websocket.readyState === WebSocket.CLOSED) return Promise.resolve();\n\t\t\t\t\twebsocket.close(websocketCloseCode(reason.code), reason.message);\n\t\t\t\t\treturn waitForWebSocketClose(websocket);\n\t\t\t\t},\n\t\t\t};\n\t\t\tprotocol = new RemoteWorkspaceServerProtocol(transport, handler, {\n\t\t\t\tworkspace,\n\t\t\t\tcatalog,\n\t\t\t\tcapabilities: runtime.capabilities,\n\t\t\t\tlimits: configuration.protocolLimits,\n\t\t\t\tbackendLabel: \"grip-workspace-daemon\",\n\t\t\t});\n\t\t\tconst connection: DaemonConnection = {\n\t\t\t\twebsocket,\n\t\t\t\tprotocol,\n\t\t\t\tclosed: Promise.resolve(),\n\t\t\t};\n\t\t\tconnection.closed = waitForWebSocketClose(websocket).then(async () => {\n\t\t\t\tclearTimeout(handshakeTimer);\n\t\t\t\tconnections.delete(connection);\n\t\t\t\tawait protocol.disconnect().catch(() => undefined);\n\t\t\t});\n\t\t\tconnections.add(connection);\n\t\t\twebsocket.on(\"message\", (data, isBinary) => {\n\t\t\t\tif (isBinary) {\n\t\t\t\t\twebsocket.close(1003, \"Text protocol required\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tvoid protocol\n\t\t\t\t\t.receive(websocketPayload(data))\n\t\t\t\t\t.then(() => {\n\t\t\t\t\t\tif (protocol.handshakeComplete) clearTimeout(handshakeTimer);\n\t\t\t\t\t})\n\t\t\t\t\t.catch(() => undefined);\n\t\t\t});\n\t\t\twebsocket.on(\"error\", () => undefined);\n\t\t});\n\t});\n\n\tconst api: DaemonServer = {\n\t\tlisten(): Promise<DaemonServerAddress> {\n\t\t\tif (serverState === \"closing\" || serverState === \"closed\")\n\t\t\t\treturn Promise.reject(new Error(\"Daemon server is closing\"));\n\t\t\tif (currentAddress) return Promise.resolve(currentAddress);\n\t\t\tif (listenPromise) return listenPromise;\n\t\t\tlistenPromise = new Promise((resolve, reject) => {\n\t\t\t\trejectListen = reject;\n\t\t\t\tconst onError = (error: Error) => {\n\t\t\t\t\tserver.off(\"listening\", onListening);\n\t\t\t\t\tlistenPromise = undefined;\n\t\t\t\t\trejectListen = undefined;\n\t\t\t\t\treject(error);\n\t\t\t\t};\n\t\t\t\tconst onListening = () => {\n\t\t\t\t\tserver.off(\"error\", onError);\n\t\t\t\t\tif (serverState !== \"created\") {\n\t\t\t\t\t\trejectListen = undefined;\n\t\t\t\t\t\treject(new Error(\"Daemon server closed before listening completed\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst address = server.address();\n\t\t\t\t\tif (!address || typeof address === \"string\") {\n\t\t\t\t\t\trejectListen = undefined;\n\t\t\t\t\t\treject(new Error(\"Daemon listener did not return a TCP address\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tserverState = \"listening\";\n\t\t\t\t\tconst port = (address as AddressInfo).port;\n\t\t\t\t\tcurrentAddress = Object.freeze({\n\t\t\t\t\t\thost: configuration.host,\n\t\t\t\t\t\tport,\n\t\t\t\t\t\tsecure: configuration.tls !== undefined,\n\t\t\t\t\t\turl: `${configuration.tls ? \"wss\" : \"ws\"}://${formatHostForUrl(configuration.host)}:${port}${DAEMON_WEBSOCKET_PATH}`,\n\t\t\t\t\t\tworkspaceRoot: configuration.workspaceRoot,\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t});\n\t\t\t\t\trejectListen = undefined;\n\t\t\t\t\tresolve(currentAddress);\n\t\t\t\t};\n\t\t\t\tserver.once(\"error\", onError);\n\t\t\t\tserver.once(\"listening\", onListening);\n\t\t\t\tserver.listen(configuration.port, configuration.host);\n\t\t\t});\n\t\t\treturn listenPromise;\n\t\t},\n\t\taddress(): DaemonServerAddress | undefined {\n\t\t\treturn currentAddress ? { ...currentAddress } : undefined;\n\t\t},\n\t\tstate(): DaemonServerState {\n\t\t\treturn serverState;\n\t\t},\n\t\treload(): Promise<void> {\n\t\t\tif (serverState !== \"listening\") return Promise.reject(new Error(\"Daemon server is not listening\"));\n\t\t\treloadQueue = reloadQueue.then(async () => {\n\t\t\t\tif (serverState !== \"listening\") throw new Error(\"Daemon server is not listening\");\n\t\t\t\tconst candidate = createDaemonWorkspaceRuntime(configuration);\n\t\t\t\tconst candidateCatalog = { ...candidate.catalog, generation: catalog.generation + 1 };\n\t\t\t\tconst previous = runtime;\n\t\t\t\tconst previousCatalog = catalog;\n\t\t\t\truntime = candidate;\n\t\t\t\truntimeHandler = candidate.createHandler(workspace);\n\t\t\t\tcatalog = candidateCatalog;\n\t\t\t\ttry {\n\t\t\t\t\tawait Promise.all([...connections].map((connection) => connection.protocol.publishCatalog(catalog)));\n\t\t\t\t} catch (error) {\n\t\t\t\t\truntime = previous;\n\t\t\t\t\truntimeHandler = previous.createHandler(workspace);\n\t\t\t\t\tcatalog = previousCatalog;\n\t\t\t\t\tawait Promise.allSettled([...connections].map((connection) => connection.protocol.disconnect()));\n\t\t\t\t\tawait candidate.dispose();\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tawait previous.retire();\n\t\t\t});\n\t\t\treturn reloadQueue;\n\t\t},\n\t\tclose(): Promise<void> {\n\t\t\tif (closePromise) return closePromise;\n\t\t\tserverState = \"closing\";\n\t\t\trejectListen?.(new Error(\"Daemon server closed before listening completed\"));\n\t\t\trejectListen = undefined;\n\t\t\tconst deadline = performance.now() + configuration.shutdownTimeoutMs;\n\t\t\tconst remainingMs = () => Math.max(0, deadline - performance.now());\n\t\t\tclosePromise = (async () => {\n\t\t\t\tconst listenerClose = stopListener();\n\t\t\t\tconst snapshot = [...connections];\n\t\t\t\tawait waitWithin(\n\t\t\t\t\treloadQueue.catch(() => undefined),\n\t\t\t\t\tremainingMs(),\n\t\t\t\t\tforceController.signal,\n\t\t\t\t);\n\t\t\t\tconst hostDisposal = runtime.dispose();\n\t\t\t\tconst drained = await waitWithin(\n\t\t\t\t\tbeginDaemonConnectionDrain(snapshot, hostDisposal),\n\t\t\t\t\tremainingMs(),\n\t\t\t\t\tforceController.signal,\n\t\t\t\t);\n\t\t\t\tif (!drained) terminateDaemonConnections(snapshot);\n\t\t\t\tawait waitWithin(disconnectDaemonConnections(snapshot), remainingMs(), forceController.signal);\n\t\t\t\trequestDaemonConnectionClose(snapshot);\n\t\t\t\tconst socketsClosed = await waitWithin(\n\t\t\t\t\twaitForDaemonConnectionsClosed(snapshot),\n\t\t\t\t\tremainingMs(),\n\t\t\t\t\tforceController.signal,\n\t\t\t\t);\n\t\t\t\tif (!socketsClosed) terminateDaemonConnections(snapshot);\n\t\t\t\tdestroyDaemonSockets(sockets);\n\t\t\t\tawait listenerClose;\n\t\t\t\tconnections.clear();\n\t\t\t})().finally(() => {\n\t\t\t\tterminateDaemonConnections(connections);\n\t\t\t\tdestroyDaemonSockets(sockets);\n\t\t\t\tfor (const timer of pendingSocketTimers.values()) clearTimeout(timer);\n\t\t\t\tpendingSocketTimers.clear();\n\t\t\t\tpendingSocketDeadlines.clear();\n\t\t\t\tpendingSockets.clear();\n\t\t\t\tconnections.clear();\n\t\t\t\tcurrentAddress = undefined;\n\t\t\t\tserverState = \"closed\";\n\t\t\t});\n\t\t\treturn closePromise;\n\t\t},\n\t\tforceClose(): Promise<void> {\n\t\t\tif (serverState === \"closed\") return closePromise ?? Promise.resolve();\n\t\t\tserverState = \"closing\";\n\t\t\tforceController.abort();\n\t\t\tcurrentAddress = undefined;\n\t\t\tterminateDaemonConnections(connections);\n\t\t\tdestroyDaemonSockets(sockets);\n\t\t\treturn api.close();\n\t\t},\n\t};\n\treturn api;\n}\n"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type LspRuntimeState } from "../core/lsp/integration.ts";
|
|
2
|
+
import { type RemoteWorkspaceCapability, type RemoteWorkspaceCatalog, type RemoteWorkspaceIdentity } from "../core/remote-workspace-protocol/contract.ts";
|
|
3
|
+
import { type RemoteWorkspaceServerHandler } from "../core/remote-workspace-protocol/session.ts";
|
|
4
|
+
import { type ToolAccessMode, type ToolBackendInfo, type ToolExecOptions, type ToolExecResult, type ToolFileStat, type ToolGlobOptions, type ToolGrepOptions, type ToolGrepResult, type ToolMkdirOptions, type ToolOperations } from "../core/tools/operations.ts";
|
|
5
|
+
import { WorkspaceToolHost } from "../core/tools/workspace-tool-host.ts";
|
|
6
|
+
import type { DaemonConfiguration } from "./config.ts";
|
|
7
|
+
export declare class ConfinedDaemonToolOperations implements ToolOperations {
|
|
8
|
+
readonly cwd: string;
|
|
9
|
+
private readonly local;
|
|
10
|
+
private readonly allowedRoots;
|
|
11
|
+
private readonly allowProcessExec;
|
|
12
|
+
private readonly environment;
|
|
13
|
+
private readonly maxBufferedOutputBytes;
|
|
14
|
+
constructor(configuration: DaemonConfiguration);
|
|
15
|
+
createChildEnvironment(extra?: Record<string, string>): Record<string, string>;
|
|
16
|
+
private isWithinAllowedRoot;
|
|
17
|
+
private lexicalPath;
|
|
18
|
+
private existingPath;
|
|
19
|
+
private existingWritablePath;
|
|
20
|
+
private ensureConfinedWritableParent;
|
|
21
|
+
private writablePath;
|
|
22
|
+
private atomicWriteFile;
|
|
23
|
+
exec(command: string, options: ToolExecOptions): Promise<ToolExecResult>;
|
|
24
|
+
access(path: string, mode?: ToolAccessMode): Promise<void>;
|
|
25
|
+
readFile(path: string): Promise<Buffer>;
|
|
26
|
+
writeFile(path: string, content: string | Buffer): Promise<void>;
|
|
27
|
+
mkdir(path: string, options?: ToolMkdirOptions): Promise<void>;
|
|
28
|
+
stat(path: string): Promise<ToolFileStat>;
|
|
29
|
+
readdir(path: string): Promise<string[]>;
|
|
30
|
+
glob(pattern: string, cwd: string, options: ToolGlobOptions): Promise<string[]>;
|
|
31
|
+
grep(options: ToolGrepOptions): Promise<ToolGrepResult>;
|
|
32
|
+
detectImageMimeType(path: string): Promise<string | null | undefined>;
|
|
33
|
+
getBackendInfo(): ToolBackendInfo;
|
|
34
|
+
}
|
|
35
|
+
export interface DaemonWorkspaceRuntime {
|
|
36
|
+
readonly operations: ConfinedDaemonToolOperations;
|
|
37
|
+
readonly host: WorkspaceToolHost;
|
|
38
|
+
readonly lspRuntime?: LspRuntimeState;
|
|
39
|
+
readonly catalog: RemoteWorkspaceCatalog;
|
|
40
|
+
readonly capabilities: readonly RemoteWorkspaceCapability[];
|
|
41
|
+
createHandler(workspace: RemoteWorkspaceIdentity): RemoteWorkspaceServerHandler;
|
|
42
|
+
retire(): Promise<void>;
|
|
43
|
+
dispose(): Promise<void>;
|
|
44
|
+
}
|
|
45
|
+
export declare function createDaemonWorkspaceRuntime(configuration: DaemonConfiguration): DaemonWorkspaceRuntime;
|
|
46
|
+
//# sourceMappingURL=workspace-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-runtime.d.ts","sourceRoot":"","sources":["../../src/daemon/workspace-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { mkdir as fsMkdir, lstat, open, readFile, realpath, rename, rm } from \"node:fs/promises\";\nimport { basename, isAbsolute, relative, resolve, sep } from \"node:path\";\nimport type { AgentToolResult } from \"@greppleai/grip-agent-core\";\nimport { createLspRuntimeState, createLspToolDefinitions, type LspRuntimeState } from \"../core/lsp/integration.ts\";\nimport type { LspServerStatus } from \"../core/lsp/manager.ts\";\nimport { createManagedStdioConnectionFactory, resolveLspConnectionFactory } from \"../core/lsp/transport.ts\";\nimport {\n\thashRemoteWorkspaceJson,\n\ttype RemoteWorkspaceCapability,\n\ttype RemoteWorkspaceCatalog,\n\ttype RemoteWorkspaceIdentity,\n\ttype RemoteWorkspaceMethod,\n\ttype RemoteWorkspaceOperationKind,\n} from \"../core/remote-workspace-protocol/contract.ts\";\nimport {\n\tRemoteWorkspaceRequestError,\n\ttype RemoteWorkspaceServerHandler,\n\ttype RemoteWorkspaceServerRequestContext,\n\ttype RemoteWorkspaceTypedRequest,\n} from \"../core/remote-workspace-protocol/session.ts\";\nimport { withFileMutationQueue } from \"../core/tools/file-mutation-queue.ts\";\nimport {\n\tGRIP_SESSION_ENVIRONMENT_NAMES,\n\tLocalToolOperations,\n\ttype ToolAccessMode,\n\ttype ToolBackendInfo,\n\ttype ToolExecOptions,\n\ttype ToolExecResult,\n\ttype ToolFileStat,\n\ttype ToolGlobOptions,\n\ttype ToolGrepMatch,\n\ttype ToolGrepOptions,\n\ttype ToolGrepResult,\n\ttype ToolMkdirOptions,\n\ttype ToolOperations,\n\ttype WorkspaceToolExecutionOptions,\n} from \"../core/tools/operations.ts\";\nimport { WorkspaceToolHost, type WorkspaceToolName } from \"../core/tools/workspace-tool-host.ts\";\nimport type { DaemonConfiguration } from \"./config.ts\";\nimport { loadDaemonLspConfiguration } from \"./lsp-config.ts\";\nimport { redactDaemonText } from \"./security.ts\";\n\nconst PRIMITIVE_OPERATIONS: RemoteWorkspaceMethod[] = [\n\t\"workspace.access\",\n\t\"workspace.read\",\n\t\"workspace.write\",\n\t\"workspace.mkdir\",\n\t\"workspace.stat\",\n\t\"workspace.readdir\",\n\t\"workspace.glob\",\n\t\"workspace.grep\",\n\t\"workspace.detect_image_mime\",\n\t\"workspace.exec\",\n];\n\nconst SECRET_ENVIRONMENT_SUFFIX = /_(?:API_KEY|TOKEN|SECRET|PASSWORD|PRIVATE_KEY|CREDENTIALS)$/iu;\nconst BASELINE_ENVIRONMENT =\n\tprocess.platform === \"win32\"\n\t\t? [\"PATH\", \"PATHEXT\", \"SYSTEMROOT\", \"COMSPEC\", \"TEMP\", \"TMP\", \"USER\", \"USERNAME\"]\n\t\t: [\"PATH\", \"HOME\", \"USER\", \"LOGNAME\", \"SHELL\", \"LANG\", \"TERM\", \"COLORTERM\", \"NO_COLOR\", \"TMPDIR\"];\n\nfunction isSecretEnvironmentName(name: string): boolean {\n\tconst upper = name.toUpperCase();\n\treturn (\n\t\tupper === \"GRIP_DAEMON_TOKEN\" ||\n\t\tupper === \"PI_DAEMON_TOKEN\" ||\n\t\tupper === \"GRIP_REMOTE_TOKEN\" ||\n\t\tupper.startsWith(\"GRIP_DAEMON_TLS_\") ||\n\t\tupper.startsWith(\"PI_DAEMON_TLS_\") ||\n\t\tSECRET_ENVIRONMENT_SUFFIX.test(upper)\n\t);\n}\nprocess.platform === \"win32\"\n\t? [\"PATH\", \"PATHEXT\", \"SYSTEMROOT\", \"TEMP\", \"TMP\"]\n\t: [\"PATH\", \"HOME\", \"LANG\", \"LC_ALL\", \"TERM\", \"TMPDIR\"];\n\nfunction isMissingPath(error: unknown): boolean {\n\treturn error instanceof Error && \"code\" in error && error.code === \"ENOENT\";\n}\n\nfunction sanitizeLspStatus(\n\tstatus: LspServerStatus,\n\tconfiguration: DaemonConfiguration,\n): Omit<LspServerStatus, \"capabilities\"> {\n\tconst { capabilities: _capabilities, ...safe } = status;\n\tconst secrets = [configuration.token, configuration.tls?.passphrase];\n\tconst redact = (value: string | undefined) => (value ? redactDaemonText(value, secrets) : undefined);\n\treturn {\n\t\t...safe,\n\t\tserverId: redact(safe.serverId)!,\n\t\tlanguageIds: safe.languageIds.map((value) => redact(value)!),\n\t\ttransport: redact(safe.transport)!,\n\t\t...(safe.instanceKey ? { instanceKey: redact(safe.instanceKey) } : {}),\n\t\t...(safe.workspaceRoot ? { workspaceRoot: redact(safe.workspaceRoot) } : {}),\n\t\t...(safe.rootUri ? { rootUri: redact(safe.rootUri) } : {}),\n\t\t...(safe.endpoint ? { endpoint: redact(safe.endpoint) } : {}),\n\t\t...(safe.lastError ? { lastError: redact(safe.lastError) } : {}),\n\t\t...(safe.lastRequestError ? { lastRequestError: redact(safe.lastRequestError) } : {}),\n\t\t...(safe.stderr ? { stderr: redact(safe.stderr) } : {}),\n\t\t...(safe.synchronizationError ? { synchronizationError: redact(safe.synchronizationError) } : {}),\n\t};\n}\n\nfunction portableToolResult(result: AgentToolResult<unknown>): AgentToolResult<unknown> {\n\tconst clone = JSON.parse(JSON.stringify(result)) as AgentToolResult<unknown>;\n\tconst details = clone.details;\n\tif (!details || typeof details !== \"object\" || !(\"fullOutputPath\" in details)) return clone;\n\tconst fullOutputPath = (details as { fullOutputPath?: unknown }).fullOutputPath;\n\tif (typeof fullOutputPath !== \"string\") return clone;\n\tdelete (details as { fullOutputPath?: unknown }).fullOutputPath;\n\tfor (const content of clone.content) {\n\t\tif (content.type === \"text\") {\n\t\t\tcontent.text = content.text.replaceAll(fullOutputPath, \"[remote full output is not transferable]\");\n\t\t}\n\t}\n\treturn clone;\n}\n\nfunction operationKind(name: string): RemoteWorkspaceOperationKind {\n\tif (name.startsWith(\"lsp_\")) return \"service\";\n\tswitch (name) {\n\t\tcase \"read\":\n\t\tcase \"grep\":\n\t\tcase \"find\":\n\t\tcase \"ls\":\n\t\t\treturn \"read\";\n\t\tcase \"edit\":\n\t\tcase \"write\":\n\t\t\treturn \"mutation\";\n\t\tcase \"bash\":\n\t\t\treturn \"process\";\n\t}\n\tthrow new Error(`Unknown daemon tool: ${name}`);\n}\n\nfunction runCommand(\n\tcommand: string,\n\targs: string[],\n\tenvironment: NodeJS.ProcessEnv,\n\tmaxBufferedBytes: number,\n): Promise<Buffer> {\n\treturn new Promise((resolvePromise, reject) => {\n\t\tconst child = spawn(command, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"], windowsHide: true, env: environment });\n\t\tconst stdout: Buffer[] = [];\n\t\tconst stderr: Buffer[] = [];\n\t\tlet bufferedBytes = 0;\n\t\tlet settled = false;\n\t\tconst append = (target: Buffer[], chunk: Buffer) => {\n\t\t\tif (settled) return;\n\t\t\tbufferedBytes += chunk.byteLength;\n\t\t\tif (bufferedBytes > maxBufferedBytes) {\n\t\t\t\tsettled = true;\n\t\t\t\tchild.kill();\n\t\t\t\treject(new Error(`${command} output exceeded the daemon buffered-output limit`));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttarget.push(Buffer.from(chunk));\n\t\t};\n\t\tchild.stdout.on(\"data\", (chunk: Buffer) => append(stdout, chunk));\n\t\tchild.stderr.on(\"data\", (chunk: Buffer) => append(stderr, chunk));\n\t\tchild.once(\"error\", (error) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\treject(error);\n\t\t});\n\t\tchild.once(\"close\", (code) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tif (code === 0 || (command === \"rg\" && code === 1)) {\n\t\t\t\tresolvePromise(Buffer.concat(stdout));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treject(new Error(Buffer.concat(stderr).toString(\"utf8\").trim() || `${command} exited with code ${code}`));\n\t\t});\n\t});\n}\n\nfunction isUnknownRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction nestedText(record: Record<string, unknown> | undefined, key: string): string | undefined {\n\tconst nested = record?.[key];\n\treturn isUnknownRecord(nested) && typeof nested.text === \"string\" ? nested.text : undefined;\n}\n\nfunction parseDaemonGrepMatch(line: string): ToolGrepMatch | undefined {\n\tif (!line) return undefined;\n\tlet event: unknown;\n\ttry {\n\t\tevent = JSON.parse(line) as unknown;\n\t} catch {\n\t\treturn undefined;\n\t}\n\tconst eventRecord = isUnknownRecord(event) ? event : undefined;\n\tif (eventRecord?.type !== \"match\") return undefined;\n\tconst data = isUnknownRecord(eventRecord.data) ? eventRecord.data : undefined;\n\tconst filePath = nestedText(data, \"path\");\n\tconst lineNumber = data?.line_number;\n\tif (!filePath || typeof lineNumber !== \"number\") return undefined;\n\tconst lineText = nestedText(data, \"lines\");\n\treturn { filePath, lineNumber, ...(lineText === undefined ? {} : { lineText }) };\n}\n\nexport class ConfinedDaemonToolOperations implements ToolOperations {\n\treadonly cwd: string;\n\tprivate readonly local: LocalToolOperations;\n\tprivate readonly allowedRoots: readonly string[];\n\tprivate readonly allowProcessExec: boolean;\n\tprivate readonly environment: NodeJS.ProcessEnv;\n\tprivate readonly maxBufferedOutputBytes: number;\n\n\tconstructor(configuration: DaemonConfiguration) {\n\t\tthis.cwd = configuration.workspaceRoot;\n\t\tthis.local = new LocalToolOperations(this.cwd);\n\t\tthis.allowedRoots = Object.freeze([\n\t\t\tthis.cwd,\n\t\t\t...(configuration.temporaryRoot ? [configuration.temporaryRoot] : []),\n\t\t]);\n\t\tthis.allowProcessExec = configuration.allowProcessExec;\n\t\tthis.maxBufferedOutputBytes = configuration.maxBufferedOutputBytes;\n\t\tconst localeNames = Object.keys(process.env).filter((name) => /^LC_/iu.test(name));\n\t\tconst names = new Set([...BASELINE_ENVIRONMENT, ...localeNames, ...configuration.forwardedEnvironment]);\n\t\tthis.environment = {};\n\t\tfor (const name of names) {\n\t\t\tif (isSecretEnvironmentName(name)) continue;\n\t\t\tconst value = process.env[name];\n\t\t\tif (value !== undefined) this.environment[name] = value;\n\t\t}\n\t}\n\n\tcreateChildEnvironment(extra: Record<string, string> = {}): Record<string, string> {\n\t\tconst environment: Record<string, string> = {};\n\t\tfor (const [name, value] of Object.entries(this.environment)) {\n\t\t\tif (value !== undefined) environment[name] = value;\n\t\t}\n\t\tObject.assign(environment, extra);\n\t\tfor (const name of Object.keys(environment)) {\n\t\t\tif (isSecretEnvironmentName(name)) delete environment[name];\n\t\t}\n\t\treturn environment;\n\t}\n\tprivate isWithinAllowedRoot(candidate: string, root: string): boolean {\n\t\tconst pathRelative = relative(root, candidate);\n\t\treturn pathRelative !== \"..\" && !pathRelative.startsWith(`..${sep}`) && !isAbsolute(pathRelative);\n\t}\n\n\tprivate lexicalPath(path: string): string {\n\t\tconst candidate = resolve(this.cwd, path);\n\t\tif (!this.allowedRoots.some((root) => this.isWithinAllowedRoot(candidate, root))) {\n\t\t\tthrow new Error(`Path escapes the daemon workspace and allowed temporary root: ${path}`);\n\t\t}\n\t\treturn candidate;\n\t}\n\n\tprivate async existingPath(path: string): Promise<string> {\n\t\tconst candidate = this.lexicalPath(path);\n\t\tconst canonical = await realpath(candidate);\n\t\treturn this.lexicalPath(canonical);\n\t}\n\n\tprivate async existingWritablePath(candidate: string, path: string): Promise<string | undefined> {\n\t\ttry {\n\t\t\tconst stat = await lstat(candidate);\n\t\t\tif (stat.isSymbolicLink()) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.lexicalPath(await realpath(candidate));\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (isMissingPath(error)) throw new Error(`Writable path uses a broken symbolic link: ${path}`);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tthrow new Error(`Writable path uses a symbolic link: ${path}`);\n\t\t\t}\n\t\t\tconst canonical = await realpath(candidate);\n\t\t\tthis.lexicalPath(canonical);\n\t\t\treturn this.lexicalPath(canonical);\n\t\t} catch (error) {\n\t\t\tif (isMissingPath(error)) return undefined;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate async ensureConfinedWritableParent(candidate: string, path: string): Promise<void> {\n\t\tlet parent = resolve(candidate, \"..\");\n\t\twhile (true) {\n\t\t\ttry {\n\t\t\t\tconst parentStat = await lstat(parent);\n\t\t\t\tif (parentStat.isSymbolicLink()) {\n\t\t\t\t\tthis.lexicalPath(await realpath(parent));\n\t\t\t\t\tthrow new Error(`Writable parent uses a symbolic link: ${path}`);\n\t\t\t\t}\n\t\t\t\tconst canonicalParent = await realpath(parent);\n\t\t\t\tthis.lexicalPath(canonicalParent);\n\t\t\t\treturn;\n\t\t\t} catch (error) {\n\t\t\t\tif (!isMissingPath(error)) throw error;\n\t\t\t\tconst next = resolve(parent, \"..\");\n\t\t\t\tif (next === parent) throw new Error(`No confined parent exists for path: ${path}`);\n\t\t\t\tparent = next;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async writablePath(path: string): Promise<string> {\n\t\tconst candidate = this.lexicalPath(path);\n\t\tconst existing = await this.existingWritablePath(candidate, path);\n\t\tif (existing) return existing;\n\t\tawait this.ensureConfinedWritableParent(candidate, path);\n\t\treturn candidate;\n\t}\n\n\tprivate async atomicWriteFile(path: string, content: string | Buffer): Promise<void> {\n\t\tconst target = await this.writablePath(path);\n\t\tconst parent = resolve(target, \"..\");\n\t\tconst temporary = resolve(parent, `.grip-remote-write-${process.pid}-${randomUUID()}-${basename(target)}.tmp`);\n\t\tthis.lexicalPath(temporary);\n\t\tlet wroteTemporary = false;\n\t\ttry {\n\t\t\tconst handle = await open(temporary, \"wx\", 0o600);\n\t\t\ttry {\n\t\t\t\tawait handle.writeFile(content, typeof content === \"string\" ? \"utf8\" : undefined);\n\t\t\t} finally {\n\t\t\t\tawait handle.close();\n\t\t\t}\n\t\t\twroteTemporary = true;\n\t\t\tthis.lexicalPath(await realpath(temporary));\n\t\t\ttry {\n\t\t\t\tif ((await lstat(target)).isSymbolicLink()) throw new Error(`Writable path uses a symbolic link: ${path}`);\n\t\t\t} catch (error) {\n\t\t\t\tif (!isMissingPath(error)) throw error;\n\t\t\t}\n\t\t\tawait rename(temporary, target);\n\t\t\twroteTemporary = false;\n\t\t\tthis.lexicalPath(await realpath(target));\n\t\t} finally {\n\t\t\tif (wroteTemporary) await rm(temporary, { force: true });\n\t\t}\n\t}\n\n\tasync exec(command: string, options: ToolExecOptions): Promise<ToolExecResult> {\n\t\tif (!this.allowProcessExec) throw new Error(\"Process execution is disabled by daemon policy\");\n\t\tconst cwd = await this.existingPath(options.cwd ?? this.cwd);\n\t\tconst environment = { ...this.environment };\n\t\tfor (const name of GRIP_SESSION_ENVIRONMENT_NAMES) {\n\t\t\tconst value = options.env?.[name];\n\t\t\tif (value !== undefined) environment[name] = value;\n\t\t}\n\t\treturn this.local.exec(command, { ...options, cwd, env: environment });\n\t}\n\n\tasync access(path: string, mode?: ToolAccessMode): Promise<void> {\n\t\tawait this.local.access(await this.existingPath(path), mode);\n\t}\n\n\tasync readFile(path: string): Promise<Buffer> {\n\t\treturn this.local.readFile(await this.existingPath(path));\n\t}\n\n\tasync writeFile(path: string, content: string | Buffer): Promise<void> {\n\t\tawait this.atomicWriteFile(path, content);\n\t}\n\n\tasync mkdir(path: string, options?: ToolMkdirOptions): Promise<void> {\n\t\tawait fsMkdir(await this.writablePath(path), options);\n\t}\n\n\tasync stat(path: string): Promise<ToolFileStat> {\n\t\treturn this.local.stat(await this.existingPath(path));\n\t}\n\n\tasync readdir(path: string): Promise<string[]> {\n\t\treturn this.local.readdir(await this.existingPath(path));\n\t}\n\n\tasync glob(pattern: string, cwd: string, options: ToolGlobOptions): Promise<string[]> {\n\t\tconst searchRoot = await this.existingPath(cwd);\n\t\tconst args = [\"--glob\", \"--color=never\", \"--hidden\", \"--no-require-git\", \"--max-results\", String(options.limit)];\n\t\tfor (const ignored of options.ignore) args.push(\"--exclude\", ignored);\n\t\tlet effectivePattern = pattern;\n\t\tif (pattern.includes(\"/\")) {\n\t\t\targs.push(\"--full-path\");\n\t\t\tif (!pattern.startsWith(\"/\") && !pattern.startsWith(\"**/\") && pattern !== \"**\")\n\t\t\t\teffectivePattern = `**/${pattern}`;\n\t\t}\n\t\targs.push(\"--\", effectivePattern, searchRoot);\n\t\tconst output = await runCommand(\"fd\", args, this.environment, this.maxBufferedOutputBytes);\n\t\tconst results: string[] = [];\n\t\tfor (const entry of output.toString(\"utf8\").split(\"\\n\")) {\n\t\t\tif (!entry) continue;\n\t\t\ttry {\n\t\t\t\tresults.push(await this.existingPath(entry));\n\t\t\t} catch {\n\t\t\t\t// Symlinks escaping the workspace are deliberately omitted.\n\t\t\t}\n\t\t}\n\t\treturn results;\n\t}\n\n\tasync grep(options: ToolGrepOptions): Promise<ToolGrepResult> {\n\t\tconst searchPath = await this.existingPath(options.path);\n\t\tconst isDirectory = (await this.local.stat(searchPath)).isDirectory();\n\t\tconst args = [\"--json\", \"--line-number\", \"--color=never\", \"--hidden\"];\n\t\tif (options.ignoreCase) args.push(\"--ignore-case\");\n\t\tif (options.literal) args.push(\"--fixed-strings\");\n\t\tif (options.glob) args.push(\"--glob\", options.glob);\n\t\targs.push(\"--\", options.pattern, searchPath);\n\t\tconst output = await runCommand(\"rg\", args, this.environment, this.maxBufferedOutputBytes);\n\t\tconst matches: ToolGrepMatch[] = [];\n\t\tfor (const line of output.toString(\"utf8\").split(\"\\n\")) {\n\t\t\tif (matches.length >= options.limit) continue;\n\t\t\tconst match = parseDaemonGrepMatch(line);\n\t\t\tif (!match) continue;\n\t\t\ttry {\n\t\t\t\tawait this.existingPath(match.filePath);\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tmatches.push(match);\n\t\t}\n\t\treturn { isDirectory, matches };\n\t}\n\n\tasync detectImageMimeType(path: string): Promise<string | null | undefined> {\n\t\treturn this.local.detectImageMimeType(await this.existingPath(path));\n\t}\n\n\tgetBackendInfo(): ToolBackendInfo {\n\t\treturn { type: \"local\", cwd: this.cwd };\n\t}\n}\n\nexport interface DaemonWorkspaceRuntime {\n\treadonly operations: ConfinedDaemonToolOperations;\n\treadonly host: WorkspaceToolHost;\n\treadonly lspRuntime?: LspRuntimeState;\n\treadonly catalog: RemoteWorkspaceCatalog;\n\treadonly capabilities: readonly RemoteWorkspaceCapability[];\n\tcreateHandler(workspace: RemoteWorkspaceIdentity): RemoteWorkspaceServerHandler;\n\tretire(): Promise<void>;\n\tdispose(): Promise<void>;\n}\n\ntype DaemonRequestInterruptionCode = \"cancelled\" | \"deadline_exceeded\";\ntype DaemonInterruptedExecutionState = \"not_started\" | \"indeterminate\";\n\nfunction requestError(code: DaemonRequestInterruptionCode, message: string, state: DaemonInterruptedExecutionState) {\n\treturn new RemoteWorkspaceRequestError({ code, message, executionState: state, retryable: false });\n}\ninterface DaemonRequestRuntime {\n\tconfiguration: DaemonConfiguration;\n\toperations: ConfinedDaemonToolOperations;\n\thost: WorkspaceToolHost;\n\tlspRuntime: LspRuntimeState | undefined;\n\tworkspace: RemoteWorkspaceIdentity;\n}\n\nfunction withDaemonWorkspace<T extends Record<string, unknown>>(result: T, workspace: RemoteWorkspaceIdentity) {\n\treturn { ...result, workspace };\n}\n\nasync function synchronizeDaemonToolFile(\n\ttoolName: string,\n\tinvocationArguments: unknown,\n\truntime: DaemonRequestRuntime,\n): Promise<void> {\n\tif (!runtime.lspRuntime) return;\n\tconst args = invocationArguments as { path?: unknown };\n\tif (typeof args.path !== \"string\") return;\n\ttry {\n\t\tif (toolName === \"read\") {\n\t\t\tawait runtime.lspRuntime.fileSync.handleFileRead(args.path, runtime.operations);\n\t\t} else if (toolName === \"write\" || toolName === \"edit\") {\n\t\t\tawait runtime.lspRuntime.fileSync.handleFileWrite(args.path, runtime.operations);\n\t\t}\n\t} catch {\n\t\t// Synchronization remains best-effort, matching local AgentSession behavior.\n\t}\n}\n\nasync function invokeDaemonTool(\n\trequest: RemoteWorkspaceTypedRequest,\n\tparams: Record<string, unknown>,\n\tcontext: RemoteWorkspaceServerRequestContext,\n\truntime: DaemonRequestRuntime,\n): Promise<AgentToolResult<unknown>> {\n\tconst toolName = params.toolName as string;\n\tconst kind = operationKind(toolName);\n\tif (kind !== \"read\") context.markSideEffectStarted();\n\tlet updateQueue = Promise.resolve();\n\ttry {\n\t\tconst result = await runtime.host.executePrepared(toolName, {\n\t\t\ttoolCallId: request.id,\n\t\t\targuments: params.arguments,\n\t\t\tsignal: context.signal,\n\t\t\texecutionOptions: params.executionOptions as WorkspaceToolExecutionOptions,\n\t\t\tonUpdate: (update) => {\n\t\t\t\tupdateQueue = updateQueue.then(() => context.sendUpdate(portableToolResult(update)));\n\t\t\t},\n\t\t});\n\t\tawait updateQueue;\n\t\tawait synchronizeDaemonToolFile(toolName, params.arguments, runtime);\n\t\tif (kind !== \"read\") context.markCommitted();\n\t\treturn portableToolResult(result);\n\t} catch (error) {\n\t\tawait updateQueue.catch(() => undefined);\n\t\tif (context.signal.aborted) {\n\t\t\tthrow requestError(\n\t\t\t\t\"cancelled\",\n\t\t\t\t\"Remote workspace tool invocation was cancelled\",\n\t\t\t\tkind === \"read\" ? \"not_started\" : \"indeterminate\",\n\t\t\t);\n\t\t}\n\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\tcode: \"internal_error\",\n\t\t\tmessage: error instanceof Error ? error.message.slice(0, 4096) : \"Workspace tool failed\",\n\t\t\texecutionState: kind === \"read\" ? \"not_started\" : \"indeterminate\",\n\t\t\tretryable: false,\n\t\t});\n\t}\n}\n\nasync function executeDaemonWorkspaceProcess(\n\tparams: Record<string, unknown>,\n\tcontext: RemoteWorkspaceServerRequestContext,\n\truntime: DaemonRequestRuntime,\n): Promise<ToolExecResult> {\n\tcontext.markSideEffectStarted();\n\tlet updateQueue = Promise.resolve();\n\tlet pendingOutputBytes = 0;\n\tlet outputLimitExceeded = false;\n\tconst outputController = new AbortController();\n\tconst signal = AbortSignal.any([context.signal, outputController.signal]);\n\tlet result: ToolExecResult;\n\ttry {\n\t\tresult = await runtime.operations.exec(params.command as string, {\n\t\t\tcwd: params.cwd as string,\n\t\t\tsignal,\n\t\t\tonData: (data) => {\n\t\t\t\tif (outputLimitExceeded) return;\n\t\t\t\tconst chunk = Buffer.from(data);\n\t\t\t\tpendingOutputBytes += chunk.byteLength;\n\t\t\t\tif (pendingOutputBytes > runtime.configuration.maxBufferedOutputBytes) {\n\t\t\t\t\toutputLimitExceeded = true;\n\t\t\t\t\toutputController.abort();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tupdateQueue = updateQueue\n\t\t\t\t\t.then(() => context.sendUpdate({ dataBase64: chunk.toString(\"base64\") }))\n\t\t\t\t\t.finally(() => {\n\t\t\t\t\t\tpendingOutputBytes -= chunk.byteLength;\n\t\t\t\t\t});\n\t\t\t},\n\t\t});\n\t} catch (error) {\n\t\tif (outputLimitExceeded) throw new Error(\"Process output exceeded the daemon buffered-output limit\");\n\t\tthrow error;\n\t}\n\tawait updateQueue;\n\tcontext.markCommitted();\n\treturn result;\n}\n\nasync function readDaemonResource(\n\tparams: Record<string, unknown>,\n\truntime: DaemonRequestRuntime,\n): Promise<Record<string, unknown>> {\n\tconst path = params.path as string;\n\tconst resourcePath =\n\t\tpath === \"SANDBOX.md\"\n\t\t\t? runtime.configuration.sandboxInstructionsPath\n\t\t\t: path === \"AGENTS.md\"\n\t\t\t\t? runtime.configuration.userAgentsPath\n\t\t\t\t: undefined;\n\tif (!resourcePath) {\n\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\tcode: \"not_available\",\n\t\t\tmessage: \"Requested daemon resource is not available\",\n\t\t\texecutionState: \"not_started\",\n\t\t\tretryable: false,\n\t\t});\n\t}\n\treturn withDaemonWorkspace({ contentBase64: (await readFile(resourcePath)).toString(\"base64\") }, runtime.workspace);\n}\n\nfunction getDaemonLspStatus(runtime: DaemonRequestRuntime): Record<string, unknown> {\n\tif (!runtime.lspRuntime) {\n\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\tcode: \"not_available\",\n\t\t\tmessage: \"Daemon LSP is not configured\",\n\t\t\texecutionState: \"not_started\",\n\t\t\tretryable: false,\n\t\t});\n\t}\n\treturn {\n\t\tenabled: true,\n\t\tservers: runtime.lspRuntime.manager.getStatus().map((status) => sanitizeLspStatus(status, runtime.configuration)),\n\t};\n}\n\nasync function dispatchDaemonWorkspaceRequest(\n\trequest: RemoteWorkspaceTypedRequest,\n\tcontext: RemoteWorkspaceServerRequestContext,\n\truntime: DaemonRequestRuntime,\n): Promise<unknown> {\n\tconst params = request.params as Record<string, unknown>;\n\tswitch (request.method) {\n\t\tcase \"tool.invoke\":\n\t\t\treturn invokeDaemonTool(request, params, context, runtime);\n\t\tcase \"workspace.access\":\n\t\t\tawait runtime.operations.access(params.path as string, params.mode as ToolAccessMode | undefined);\n\t\t\treturn {};\n\t\tcase \"workspace.read\":\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{ contentBase64: (await runtime.operations.readFile(params.path as string)).toString(\"base64\") },\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\tcase \"workspace.write\":\n\t\t\tcontext.markSideEffectStarted();\n\t\t\tawait withFileMutationQueue(resolve(runtime.configuration.workspaceRoot, params.path as string), () =>\n\t\t\t\truntime.operations.writeFile(params.path as string, Buffer.from(params.contentBase64 as string, \"base64\")),\n\t\t\t);\n\t\t\tcontext.markCommitted();\n\t\t\treturn {};\n\t\tcase \"workspace.mkdir\":\n\t\t\tcontext.markSideEffectStarted();\n\t\t\tawait withFileMutationQueue(resolve(runtime.configuration.workspaceRoot, params.path as string), () =>\n\t\t\t\truntime.operations.mkdir(params.path as string, { recursive: params.recursive === true }),\n\t\t\t);\n\t\t\tcontext.markCommitted();\n\t\t\treturn {};\n\t\tcase \"workspace.stat\": {\n\t\t\tconst value = await runtime.operations.stat(params.path as string);\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{ kind: value.isDirectory() ? \"directory\" : value.isFile() ? \"file\" : \"other\" },\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\t}\n\t\tcase \"workspace.readdir\":\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{ entries: await runtime.operations.readdir(params.path as string) },\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\tcase \"workspace.glob\":\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{\n\t\t\t\t\tmatches: await runtime.operations.glob(params.pattern as string, params.cwd as string, {\n\t\t\t\t\t\tignore: params.ignore as string[],\n\t\t\t\t\t\tlimit: params.limit as number,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\tcase \"workspace.grep\": {\n\t\t\tconst result = await runtime.operations.grep(params as unknown as ToolGrepOptions);\n\t\t\treturn withDaemonWorkspace(result as unknown as Record<string, unknown>, runtime.workspace);\n\t\t}\n\t\tcase \"workspace.detect_image_mime\":\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{ mimeType: (await runtime.operations.detectImageMimeType(params.path as string)) ?? null },\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\tcase \"workspace.exec\":\n\t\t\treturn executeDaemonWorkspaceProcess(params, context, runtime);\n\t\tcase \"resource.read\":\n\t\t\treturn readDaemonResource(params, runtime);\n\t\tcase \"lsp.status\":\n\t\t\treturn getDaemonLspStatus(runtime);\n\t\tdefault:\n\t\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\t\tcode: \"method_not_supported\",\n\t\t\t\tmessage: `Workspace operation is not implemented: ${request.method}`,\n\t\t\t\texecutionState: \"not_started\",\n\t\t\t\tretryable: false,\n\t\t\t});\n\t}\n}\n\nexport function createDaemonWorkspaceRuntime(configuration: DaemonConfiguration): DaemonWorkspaceRuntime {\n\tconst operations = new ConfinedDaemonToolOperations(configuration);\n\tconst toolNames: WorkspaceToolName[] = [\"read\", \"edit\", \"write\", \"grep\", \"find\", \"ls\"];\n\tif (configuration.allowProcessExec) toolNames.splice(1, 0, \"bash\");\n\tconst lspConfiguration = loadDaemonLspConfiguration(configuration);\n\tconst lspRuntime = lspConfiguration.enabled\n\t\t? createLspRuntimeState(configuration.workspaceRoot, {\n\t\t\t\tconfiguration: lspConfiguration,\n\t\t\t\tgetToolBackendInfo: () => operations.getBackendInfo(),\n\t\t\t\tgetToolOperations: () => operations,\n\t\t\t\tresolveConnectionFactory: (transport) =>\n\t\t\t\t\ttransport.type === \"spawn\"\n\t\t\t\t\t\t? createManagedStdioConnectionFactory({\n\t\t\t\t\t\t\t\t...transport,\n\t\t\t\t\t\t\t\tenv: operations.createChildEnvironment(transport.env),\n\t\t\t\t\t\t\t\tinheritEnvironment: false,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: resolveLspConnectionFactory(transport),\n\t\t\t})\n\t\t: undefined;\n\tconst host = new WorkspaceToolHost({\n\t\tcwd: configuration.workspaceRoot,\n\t\toperations,\n\t\ttoolNames,\n\t\tadditionalDefinitions: lspRuntime\n\t\t\t? createLspToolDefinitions(\n\t\t\t\t\t() => lspRuntime,\n\t\t\t\t\t() => operations,\n\t\t\t\t)\n\t\t\t: undefined,\n\t\tdisposeTimeoutMs: Math.min(configuration.shutdownTimeoutMs, 60_000),\n\t});\n\tconst catalog: RemoteWorkspaceCatalog = {\n\t\tgeneration: 1,\n\t\ttools: host.getCatalog().map((entry) => ({\n\t\t\tname: entry.name,\n\t\t\texecutionMode: operationKind(entry.name),\n\t\t\tparameterSchema: structuredClone(entry.parameters) as Record<string, unknown>,\n\t\t\tschemaHash: hashRemoteWorkspaceJson(entry.parameters),\n\t\t\tfeatureFlags: [],\n\t\t})),\n\t\toperations: [\n\t\t\t...PRIMITIVE_OPERATIONS.filter((method) => method !== \"workspace.exec\" || configuration.allowProcessExec),\n\t\t\t...(configuration.sandboxInstructionsPath || configuration.userAgentsPath ? ([\"resource.read\"] as const) : []),\n\t\t\t...(lspRuntime ? ([\"lsp.status\"] as const) : []),\n\t\t],\n\t};\n\tconst capabilities: RemoteWorkspaceCapability[] = [\n\t\t\"catalog_refresh\",\n\t\t\"primitive_operations\",\n\t\t\"tool_updates\",\n\t\t...(lspRuntime ? ([\"lsp_status\"] as const) : []),\n\t];\n\tlet activeRequests = 0;\n\n\treturn {\n\t\toperations,\n\t\thost,\n\t\tlspRuntime,\n\t\tcatalog,\n\t\tcapabilities,\n\t\tcreateHandler(workspace) {\n\t\t\tconst requestRuntime: DaemonRequestRuntime = { configuration, operations, host, lspRuntime, workspace };\n\t\t\treturn {\n\t\t\t\tvalidateToolArguments: (toolName, value) => host.validatePreparedArguments(toolName, value),\n\t\t\t\tasync handleRequest(request, context) {\n\t\t\t\t\tif (activeRequests >= configuration.maxGlobalRequests) {\n\t\t\t\t\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\t\t\t\t\tcode: \"limit_exceeded\",\n\t\t\t\t\t\t\tmessage: \"Daemon global active request limit reached\",\n\t\t\t\t\t\t\texecutionState: \"not_started\",\n\t\t\t\t\t\t\tretryable: true,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tactiveRequests++;\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn await dispatchDaemonWorkspaceRequest(request, context, requestRuntime);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tactiveRequests--;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tretire: async () => {\n\t\t\tawait host.waitForIdle(configuration.shutdownTimeoutMs);\n\t\t\tawait lspRuntime?.manager.shutdownAll();\n\t\t\tawait host.dispose();\n\t\t},\n\t\tdispose: async () => {\n\t\t\tawait Promise.all([lspRuntime?.manager.shutdownAll(), host.dispose()]);\n\t\t},\n\t};\n}\n"]}
|