@abot-ai/runtime 1.6.0 → 1.8.0
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/README.md +2 -0
- package/dist/src/bridge/request-steering.js +60 -15
- package/dist/src/capabilities/normal-invocation/contracts.d.ts +3 -0
- package/dist/src/capabilities/normal-invocation/output-channels.d.ts +10 -0
- package/dist/src/capabilities/normal-invocation/output-channels.js +29 -0
- package/dist/src/capabilities/normal-invocation/validator.js +4 -2
- package/dist/src/capabilities/tool-request-resources.d.ts +3 -0
- package/dist/src/capabilities/tool-types.d.ts +1 -1
- package/dist/src/cli/abot.js +2 -0
- package/dist/src/cli/host-companion-bundle.mjs +8003 -6796
- package/dist/src/cli/host-companion-entry.js +5 -22
- package/dist/src/cli/host-companion-input.d.ts +3 -0
- package/dist/src/cli/host-companion-input.js +21 -0
- package/dist/src/cli/host-companion-lifecycle.d.ts +11 -0
- package/dist/src/cli/host-companion-lifecycle.js +32 -0
- package/dist/src/cli/host-companion-setup-target.d.ts +4 -0
- package/dist/src/cli/host-companion-setup-target.js +17 -0
- package/dist/src/cli/host-companion-startup.d.ts +2 -0
- package/dist/src/cli/host-companion-startup.js +7 -2
- package/dist/src/cli/host-companion.d.ts +6 -0
- package/dist/src/cli/host-companion.js +30 -27
- package/dist/src/cli/windows-companion-store-entry.d.ts +9 -0
- package/dist/src/cli/windows-companion-store-entry.js +67 -0
- package/dist/src/computer-access/collection-consent.d.ts +9 -0
- package/dist/src/computer-access/collection-consent.js +47 -0
- package/dist/src/computer-access/command-output-capture.d.ts +48 -0
- package/dist/src/computer-access/command-output-capture.js +202 -0
- package/dist/src/computer-access/command-output-protection.d.ts +17 -0
- package/dist/src/computer-access/command-output-protection.js +59 -0
- package/dist/src/computer-access/command-output-retention.d.ts +5 -0
- package/dist/src/computer-access/command-output-retention.js +90 -0
- package/dist/src/computer-access/command-output.d.ts +7 -0
- package/dist/src/computer-access/command-output.js +1 -0
- package/dist/src/computer-access/commands.d.ts +1 -0
- package/dist/src/computer-access/commands.js +1 -1
- package/dist/src/computer-access/companion/command-output-protocol.d.ts +12 -0
- package/dist/src/computer-access/companion/command-output-protocol.js +28 -0
- package/dist/src/computer-access/companion/command-output.d.ts +14 -0
- package/dist/src/computer-access/companion/command-output.js +127 -0
- package/dist/src/computer-access/companion/install-link-macos.d.ts +7 -0
- package/dist/src/computer-access/companion/install-link-macos.js +49 -0
- package/dist/src/computer-access/companion/install-link-registration.d.ts +4 -0
- package/dist/src/computer-access/companion/install-link-registration.js +184 -0
- package/dist/src/computer-access/companion/install-link-windows.d.ts +4 -0
- package/dist/src/computer-access/companion/install-link-windows.js +65 -0
- package/dist/src/computer-access/companion/install-link.d.ts +9 -0
- package/dist/src/computer-access/companion/install-link.js +54 -0
- package/dist/src/computer-access/companion/native-messages.js +3 -0
- package/dist/src/computer-access/companion/native-notifications.js +3 -2
- package/dist/src/computer-access/companion/native-session.d.ts +1 -0
- package/dist/src/computer-access/companion/native-session.js +20 -4
- package/dist/src/computer-access/companion/native-supervisor.js +1 -0
- package/dist/src/computer-access/companion/notification-windows.d.ts +1 -1
- package/dist/src/computer-access/companion/notification-windows.js +8 -3
- package/dist/src/computer-access/companion/observation-filter.js +2 -26
- package/dist/src/computer-access/companion/observation-process.d.ts +2 -0
- package/dist/src/computer-access/companion/observation-process.js +51 -25
- package/dist/src/computer-access/companion/observation-redaction.d.ts +2 -7
- package/dist/src/computer-access/companion/observation-redaction.js +2 -111
- package/dist/src/computer-access/companion/protocol.d.ts +1 -1
- package/dist/src/computer-access/companion/protocol.js +6 -0
- package/dist/src/computer-access/companion/release-version.d.ts +1 -1
- package/dist/src/computer-access/companion/release-version.js +1 -1
- package/dist/src/computer-access/companion/secret-protection-protocol.d.ts +6 -0
- package/dist/src/computer-access/companion/secret-protection-protocol.js +6 -0
- package/dist/src/computer-access/companion/windows-store/connection-error.d.ts +7 -0
- package/dist/src/computer-access/companion/windows-store/connection-error.js +19 -0
- package/dist/src/computer-access/companion/windows-store/connection-link.d.ts +13 -0
- package/dist/src/computer-access/companion/windows-store/connection-link.js +109 -0
- package/dist/src/computer-access/companion/windows-store/identity.d.ts +13 -0
- package/dist/src/computer-access/companion/windows-store/identity.js +13 -0
- package/dist/src/computer-access/companion/windows-store/lifecycle.d.ts +5 -0
- package/dist/src/computer-access/companion/windows-store/lifecycle.js +90 -0
- package/dist/src/computer-access/computer/companion-sessions.js +7 -6
- package/dist/src/computer-access/computer/unix-native-process.js +23 -11
- package/dist/src/computer-access/contracts.d.ts +1 -1
- package/dist/src/computer-access/handlers.d.ts +3 -1
- package/dist/src/computer-access/handlers.js +83 -11
- package/dist/src/computer-access/host-observation.d.ts +3 -3
- package/dist/src/computer-access/native-observation-connection.d.ts +12 -0
- package/dist/src/computer-access/native-observation-connection.js +78 -0
- package/dist/src/computer-access/native-observation-ownership.d.ts +6 -0
- package/dist/src/computer-access/native-observation-ownership.js +55 -0
- package/dist/src/computer-access/native-observation-shutdown.d.ts +7 -0
- package/dist/src/computer-access/native-observation-shutdown.js +58 -0
- package/dist/src/computer-access/observation-source.d.ts +6 -0
- package/dist/src/computer-access/observation-source.js +10 -0
- package/dist/src/computer-access/process-capture.d.ts +6 -0
- package/dist/src/computer-access/process-capture.js +1 -0
- package/dist/src/computer-access/process-result.d.ts +2 -0
- package/dist/src/computer-access/process-result.js +14 -6
- package/dist/src/computer-access/process-runner.d.ts +2 -1
- package/dist/src/computer-access/process-runner.js +21 -13
- package/dist/src/computer-access/security/desktop-result.d.ts +8 -0
- package/dist/src/computer-access/security/desktop-result.js +146 -0
- package/dist/src/computer-access/security/observed-error.d.ts +2 -0
- package/dist/src/computer-access/security/observed-error.js +10 -0
- package/dist/src/computer-access/security/secret-text.d.ts +7 -0
- package/dist/src/computer-access/security/secret-text.js +111 -0
- package/dist/src/computer-access/security/system-results.d.ts +2 -0
- package/dist/src/computer-access/security/system-results.js +53 -0
- package/dist/src/computer-access/system-result-protection.d.ts +11 -0
- package/dist/src/computer-access/system-result-protection.js +1 -0
- package/dist/src/model-gateway/observability/provider-response-capture.d.ts +60 -0
- package/dist/src/model-gateway/observability/provider-response-capture.js +68 -0
- package/dist/src/model-gateway/observability/provider-response-prefix.d.ts +7 -0
- package/dist/src/model-gateway/observability/provider-response-prefix.js +14 -0
- package/dist/src/model-gateway/observability/provider-response-tail.d.ts +8 -0
- package/dist/src/model-gateway/observability/provider-response-tail.js +28 -0
- package/dist/src/model-gateway/observability/provider-sse-diagnostics.d.ts +30 -0
- package/dist/src/model-gateway/observability/provider-sse-diagnostics.js +119 -0
- package/dist/src/model-gateway/observability/provider-trace.js +30 -8
- package/dist/src/model-gateway/providers/ollama/adapter.js +8 -2
- package/dist/src/model-gateway/providers/ollama/stream-normalizer.js +70 -50
- package/dist/src/model-gateway/providers/ollama/stream-termination.d.ts +6 -0
- package/dist/src/model-gateway/providers/ollama/stream-termination.js +20 -0
- package/dist/src/model-gateway/providers/openai/adapter.js +9 -7
- package/dist/src/model-gateway/providers/openai/diagnostics.d.ts +0 -1
- package/dist/src/model-gateway/providers/openai/diagnostics.js +0 -9
- package/dist/src/model-gateway/providers/openai/function-output.d.ts +11 -0
- package/dist/src/model-gateway/providers/openai/function-output.js +37 -0
- package/dist/src/model-gateway/providers/openai/function-result.d.ts +7 -0
- package/dist/src/model-gateway/providers/openai/function-result.js +35 -0
- package/dist/src/model-gateway/providers/openai/message-output-policy.d.ts +3 -0
- package/dist/src/model-gateway/providers/openai/message-output-policy.js +16 -0
- package/dist/src/model-gateway/providers/openai/payload.d.ts +0 -2
- package/dist/src/model-gateway/providers/openai/payload.js +6 -23
- package/dist/src/model-gateway/providers/openai/response-lifetime.d.ts +2 -0
- package/dist/src/model-gateway/providers/openai/response-lifetime.js +64 -0
- package/dist/src/model-gateway/providers/openai/sse-data.d.ts +9 -0
- package/dist/src/model-gateway/providers/openai/sse-data.js +67 -0
- package/dist/src/model-gateway/providers/openai/stream-normalizer.d.ts +10 -22
- package/dist/src/model-gateway/providers/openai/stream-normalizer.js +78 -79
- package/dist/src/model-gateway/providers/openai/stream.js +13 -41
- package/dist/src/model-gateway/providers/openai/structured-message-output.d.ts +42 -0
- package/dist/src/model-gateway/providers/openai/structured-message-output.js +175 -0
- package/dist/src/model-gateway/server/configuration.d.ts +2 -0
- package/dist/src/model-gateway/server/configuration.js +73 -21
- package/dist/src/model-gateway/server.js +5 -1
- package/dist/src/plugin-contract/index.d.ts +1 -0
- package/dist/src/plugin-contract/index.js +1 -0
- package/dist/src/plugin-contract/install-source.d.ts +13 -0
- package/dist/src/plugin-contract/install-source.js +99 -0
- package/dist/src/plugin-contract/manifest.d.ts +4 -1
- package/dist/src/plugin-contract/manifest.js +1 -0
- package/dist/src/plugin-contract/platform-compatibility.d.ts +16 -0
- package/dist/src/plugin-contract/platform-compatibility.js +3 -0
- package/dist/src/plugin-sdk/computer-access.d.ts +12 -0
- package/dist/src/plugin-sdk/computer-access.js +6 -0
- package/dist/src/plugin-sdk/files-windows/process.d.ts +3 -0
- package/dist/src/plugin-sdk/files-windows/process.js +93 -0
- package/dist/src/plugin-sdk/files-windows/read-script.d.ts +1 -0
- package/dist/src/plugin-sdk/files-windows/read-script.js +43 -0
- package/dist/src/plugin-sdk/files-windows/read.d.ts +6 -0
- package/dist/src/plugin-sdk/files-windows/read.js +56 -0
- package/dist/src/plugin-sdk/files-windows/result.d.ts +4 -0
- package/dist/src/plugin-sdk/files-windows/result.js +67 -0
- package/dist/src/plugin-sdk/files.js +4 -0
- package/dist/src/plugin-sdk/index.d.ts +1 -0
- package/dist/src/plugin-sdk/index.js +1 -0
- package/dist/src/plugin-sdk/mutation-result.d.ts +7 -0
- package/dist/src/plugin-sdk/mutation-result.js +11 -0
- package/dist/src/runtime/adapters/in-memory-session-store.js +6 -16
- package/dist/src/runtime/adapters/long-term-memory/file-lock/acquisition.js +20 -3
- package/dist/src/runtime/adapters/long-term-memory/file-lock/owner-record.js +3 -1
- package/dist/src/runtime/adapters/long-term-memory/file-lock/path-observation.d.ts +3 -0
- package/dist/src/runtime/adapters/long-term-memory/file-lock/path-observation.js +20 -0
- package/dist/src/runtime/adapters/long-term-memory/file-lock/snapshot.js +7 -3
- package/dist/src/runtime/adapters/passive-learning-runtime.d.ts +1 -1
- package/dist/src/runtime/adapters/passive-learning-runtime.js +3 -3
- package/dist/src/runtime/adapters/runtime-observation-connection.d.ts +5 -0
- package/dist/src/runtime/adapters/runtime-observation-connection.js +13 -0
- package/dist/src/runtime/admin/config-control.js +2 -1
- package/dist/src/runtime/automations/catalog.d.ts +3 -0
- package/dist/src/runtime/automations/catalog.js +1 -0
- package/dist/src/runtime/automations/model-dependency-projection.d.ts +2 -0
- package/dist/src/runtime/automations/service.d.ts +2 -0
- package/dist/src/runtime/capabilities/automation-builder/authoring-reference.d.ts +10 -5
- package/dist/src/runtime/capabilities/automation-builder/authoring-reference.js +8 -7
- package/dist/src/runtime/capabilities/automation-builder/payload-instructions.d.ts +2 -2
- package/dist/src/runtime/capabilities/automation-builder/payload-instructions.js +2 -2
- package/dist/src/runtime/capabilities/automation-builder/tool-contract.d.ts +2 -2
- package/dist/src/runtime/capabilities/automations/authoring-catalog.js +1 -1
- package/dist/src/runtime/capabilities/automations/authoring-preparation.d.ts +11 -5
- package/dist/src/runtime/capabilities/automations/tool-module.js +1 -1
- package/dist/src/runtime/capabilities/request-permission-catalog.d.ts +3 -1
- package/dist/src/runtime/capabilities/request-permission-catalog.js +21 -2
- package/dist/src/runtime/capabilities/request-permission-tool-registry.d.ts +2 -1
- package/dist/src/runtime/capabilities/request-permission-tool-registry.js +18 -10
- package/dist/src/runtime/capabilities/request-runtime-tool-registry.d.ts +2 -0
- package/dist/src/runtime/capabilities/request-runtime-tool-registry.js +1 -1
- package/dist/src/runtime/capabilities/scheduling/create-operations.d.ts +6 -0
- package/dist/src/runtime/config/builders.js +6 -5
- package/dist/src/runtime/config/effective-model-config-validation.js +4 -35
- package/dist/src/runtime/config/fields.js +15 -0
- package/dist/src/runtime/config/model-context-capacity.d.ts +20 -0
- package/dist/src/runtime/config/model-context-capacity.js +55 -0
- package/dist/src/runtime/config/model-execution-policy.d.ts +5 -1
- package/dist/src/runtime/config/model-execution-policy.js +16 -0
- package/dist/src/runtime/config/model-plugin-config.d.ts +8 -0
- package/dist/src/runtime/config/model-plugin-config.js +40 -0
- package/dist/src/runtime/config/schema.js +5 -1
- package/dist/src/runtime/config/validation/model-profile-validation.js +2 -0
- package/dist/src/runtime/config/validation/runtime-config-validation-contract.d.ts +3 -1
- package/dist/src/runtime/config/validation/runtime-config-validation-contract.js +3 -1
- package/dist/src/runtime/config/validation/runtime-root-section-validation.js +11 -4
- package/dist/src/runtime/config/validation/web-ui-config-validation.js +3 -2
- package/dist/src/runtime/config/web-ui.d.ts +5 -0
- package/dist/src/runtime/config/web-ui.js +5 -0
- package/dist/src/runtime/config.js +2 -0
- package/dist/src/runtime/local-application.d.ts +2 -0
- package/dist/src/runtime/local-host/app-owner.js +50 -6
- package/dist/src/runtime/local-host/app-request-control.d.ts +3 -1
- package/dist/src/runtime/local-host/app-request-control.js +91 -11
- package/dist/src/runtime/local-host/client-requests.js +32 -5
- package/dist/src/runtime/local-host/client-services.d.ts +2 -0
- package/dist/src/runtime/local-host/local-request-diagnostics.d.ts +9 -0
- package/dist/src/runtime/local-host/local-request-diagnostics.js +47 -0
- package/dist/src/runtime/local-host/saved-approvals.js +23 -2
- package/dist/src/runtime/local-host/windows-private-access.js +2 -0
- package/dist/src/runtime/model/model-selection.js +4 -1
- package/dist/src/runtime/observability/request-control-diagnostics.d.ts +6 -0
- package/dist/src/runtime/observability/request-control-diagnostics.js +52 -0
- package/dist/src/runtime/passive-learning/application-catalog.js +3 -1
- package/dist/src/runtime/passive-learning/collection-source.js +7 -0
- package/dist/src/runtime/passive-learning/service.js +2 -3
- package/dist/src/runtime/passive-learning/status-projection.d.ts +2 -0
- package/dist/src/runtime/passive-learning/status-projection.js +9 -0
- package/dist/src/runtime/plugins/configuration-context.d.ts +9 -0
- package/dist/src/runtime/plugins/configuration-context.js +42 -0
- package/dist/src/runtime/plugins/configuration-settings.d.ts +2 -0
- package/dist/src/runtime/plugins/configuration-settings.js +26 -0
- package/dist/src/runtime/plugins/configuration-store.d.ts +23 -0
- package/dist/src/runtime/plugins/configuration-store.js +100 -0
- package/dist/src/runtime/plugins/configuration-write.d.ts +5 -0
- package/dist/src/runtime/plugins/configuration-write.js +58 -0
- package/dist/src/runtime/plugins/installation/archive.d.ts +2 -0
- package/dist/src/runtime/plugins/installation/archive.js +107 -0
- package/dist/src/runtime/plugins/installation/github-download.d.ts +9 -0
- package/dist/src/runtime/plugins/installation/github-download.js +72 -0
- package/dist/src/runtime/plugins/installation/installed-package.d.ts +9 -0
- package/dist/src/runtime/plugins/installation/installed-package.js +66 -0
- package/dist/src/runtime/plugins/installation/package.d.ts +53 -0
- package/dist/src/runtime/plugins/installation/package.js +81 -0
- package/dist/src/runtime/plugins/installation/portable-path.d.ts +2 -0
- package/dist/src/runtime/plugins/installation/portable-path.js +10 -0
- package/dist/src/runtime/plugins/installation/publication.d.ts +10 -0
- package/dist/src/runtime/plugins/installation/publication.js +17 -0
- package/dist/src/runtime/plugins/installation/service.d.ts +48 -0
- package/dist/src/runtime/plugins/installation/service.js +80 -0
- package/dist/src/runtime/plugins/loader.js +34 -38
- package/dist/src/runtime/plugins/manifest-platform-compatibility.d.ts +2 -0
- package/dist/src/runtime/plugins/manifest-platform-compatibility.js +39 -0
- package/dist/src/runtime/plugins/manifest-projection.js +1 -0
- package/dist/src/runtime/plugins/manifest-validator.js +12 -1
- package/dist/src/runtime/plugins/module-cache.d.ts +2 -0
- package/dist/src/runtime/plugins/module-cache.js +19 -0
- package/dist/src/runtime/plugins/platform-compatibility.d.ts +4 -0
- package/dist/src/runtime/plugins/platform-compatibility.js +44 -0
- package/dist/src/runtime/plugins/selection.d.ts +2 -0
- package/dist/src/runtime/plugins/selection.js +16 -11
- package/dist/src/runtime/ports.d.ts +6 -4
- package/dist/src/runtime/request/approval-wait/activation-events.js +19 -7
- package/dist/src/runtime/request/approval-wait/execution-compaction-restore.d.ts +20 -0
- package/dist/src/runtime/request/approval-wait/execution-compaction-restore.js +118 -0
- package/dist/src/runtime/request/approval-wait/super-compaction-restore.js +2 -1
- package/dist/src/runtime/request/dependencies.d.ts +2 -1
- package/dist/src/runtime/request/execution-payload-compacted-evidence.d.ts +1 -1
- package/dist/src/runtime/request/handler.js +8 -0
- package/dist/src/runtime/request/prepared-execution.js +9 -1
- package/dist/src/runtime/request/request-steering.d.ts +4 -0
- package/dist/src/runtime/request/request-steering.js +37 -12
- package/dist/src/runtime/request/worker-capability-composition.d.ts +2 -0
- package/dist/src/runtime/request/worker-capability-composition.js +4 -1
- package/dist/src/runtime/scheduler/journal-index-state.d.ts +1 -1
- package/dist/src/runtime/steps/execution-agent/capability-result-context.d.ts +6 -0
- package/dist/src/runtime/steps/execution-agent/capability-result-context.js +29 -0
- package/dist/src/runtime/steps/execution-agent/format.js +2 -3
- package/dist/src/runtime/steps/execution-agent/input.js +1 -1
- package/dist/src/runtime/steps/execution-agent/prompt.js +5 -5
- package/dist/src/runtime/steps/execution-agent/response-prompt.js +1 -0
- package/dist/src/runtime/steps/execution-agent/state-context.d.ts +2 -3
- package/dist/src/runtime/steps/execution-agent/state-context.js +26 -35
- package/dist/src/runtime/steps/execution-agent/work-plan-contract.d.ts +1 -3
- package/dist/src/runtime/steps/execution-agent/work-plan-contract.js +0 -55
- package/dist/src/runtime/steps/execution-agent/work-plan-schema.d.ts +3 -0
- package/dist/src/runtime/steps/execution-agent/work-plan-schema.js +61 -0
- package/dist/src/sessions/assistant-initiative-message.d.ts +3 -0
- package/dist/src/sessions/assistant-initiative-message.js +12 -0
- package/dist/src/sessions/assistant-initiative.d.ts +2 -2
- package/dist/src/sessions/assistant-initiative.js +1 -7
- package/dist/src/sessions/durable-session-commit.d.ts +2 -1
- package/dist/src/sessions/durable-session-commit.js +9 -4
- package/dist/src/sessions/metadata/projection.d.ts +15 -0
- package/dist/src/sessions/metadata/projection.js +55 -0
- package/dist/src/sessions/metadata/publication.d.ts +12 -0
- package/dist/src/sessions/metadata/publication.js +78 -0
- package/dist/src/sessions/metadata/source-receipt.d.ts +5 -0
- package/dist/src/sessions/metadata/source-receipt.js +42 -0
- package/dist/src/sessions/metadata/store.d.ts +7 -0
- package/dist/src/sessions/metadata/store.js +119 -0
- package/dist/src/sessions/prepared-session-replacement.d.ts +6 -0
- package/dist/src/sessions/prepared-session-replacement.js +46 -0
- package/dist/src/sessions/record/projection.d.ts +3 -1
- package/dist/src/sessions/record/projection.js +26 -18
- package/dist/src/sessions/request-lifecycle/service.js +3 -3
- package/dist/src/sessions/session-service.d.ts +2 -4
- package/dist/src/sessions/session-service.js +4 -16
- package/dist/src/sessions/session-store.d.ts +2 -1
- package/dist/src/sessions/session-store.js +11 -5
- package/dist/src/sessions/snapshot.d.ts +17 -0
- package/dist/src/sessions/snapshot.js +105 -0
- package/dist/src/sessions/types.d.ts +2 -0
- package/dist/src/shared/passive-observation-self-exclusion.d.ts +5 -0
- package/dist/src/shared/passive-observation-self-exclusion.js +37 -0
- package/dist/src/shared/tool-selection.d.ts +2 -0
- package/dist/src/shared/tool-selection.js +7 -0
- package/dist/src/shared/windows-file-io/authority-script.d.ts +1 -0
- package/dist/src/shared/windows-file-io/authority-script.js +94 -0
- package/dist/src/shared/windows-file-io/native-script.d.ts +2 -0
- package/dist/src/shared/windows-file-io/native-script.js +120 -0
- package/dist/src/shared/windows-file-io/read-bytes-script.d.ts +1 -0
- package/dist/src/shared/windows-file-io/read-bytes-script.js +18 -0
- package/dist/src/shared/windows-job-object.d.ts +2 -0
- package/dist/src/shared/windows-job-object.js +66 -0
- package/dist/src/web-ui/app/ARCHITECTURE.md +14 -0
- package/dist/src/web-ui/app/app-bootstrap.js +14 -1
- package/dist/src/web-ui/app/app-state.js +0 -7
- package/dist/src/web-ui/app/app.js +59 -159
- package/dist/src/web-ui/app/components/automations/node-inspector.js +3 -2
- package/dist/src/web-ui/app/components/automations/step-editor-dialog.js +3 -0
- package/dist/src/web-ui/app/components/composer-submission-notice.js +50 -0
- package/dist/src/web-ui/app/components/config-workspace/config-model.js +2 -0
- package/dist/src/web-ui/app/components/config-workspace/model-plugin-permissions.js +136 -0
- package/dist/src/web-ui/app/components/config-workspace/model-plugin-selection.js +180 -0
- package/dist/src/web-ui/app/components/config-workspace/model-plugin-view-state.js +114 -0
- package/dist/src/web-ui/app/components/config-workspace/model-rendering.js +3 -0
- package/dist/src/web-ui/app/components/config-workspace/model-summary.js +39 -0
- package/dist/src/web-ui/app/components/config-workspace/summary-rendering.js +30 -0
- package/dist/src/web-ui/app/components/config-workspace/workspace-events.js +37 -0
- package/dist/src/web-ui/app/components/config-workspace/workspace-mutations.js +24 -2
- package/dist/src/web-ui/app/components/config-workspace/workspace-persistence.js +9 -1
- package/dist/src/web-ui/app/components/config-workspace/workspace-view.js +23 -67
- package/dist/src/web-ui/app/components/config-workspace.js +11 -2
- package/dist/src/web-ui/app/components/conversation-view.js +36 -5
- package/dist/src/web-ui/app/components/dashboard/recent-conversations.js +2 -1
- package/dist/src/web-ui/app/components/dashboard/workspace.js +2 -1
- package/dist/src/web-ui/app/components/home-guidance/daily-review.js +2 -2
- package/dist/src/web-ui/app/components/home-guidance/home-guidance.js +20 -6
- package/dist/src/web-ui/app/components/model-setup/context-window-feedback.js +53 -0
- package/dist/src/web-ui/app/components/model-setup/save-flow.js +3 -1
- package/dist/src/web-ui/app/components/model-setup/save-outcome.js +1 -0
- package/dist/src/web-ui/app/components/model-setup/wizard.js +12 -0
- package/dist/src/web-ui/app/components/operations-summary.js +105 -0
- package/dist/src/web-ui/app/components/passive-learning/activity-controls.js +4 -0
- package/dist/src/web-ui/app/components/passive-learning/collection-access.js +35 -0
- package/dist/src/web-ui/app/components/passive-learning/collection-consent-dialog.js +59 -0
- package/dist/src/web-ui/app/components/passive-learning/collection-consent-gate.js +94 -0
- package/dist/src/web-ui/app/components/passive-learning/computer-update-notice.js +6 -0
- package/dist/src/web-ui/app/components/passive-learning/failure-copy.js +1 -0
- package/dist/src/web-ui/app/components/passive-learning/home.js +8 -11
- package/dist/src/web-ui/app/components/passive-learning/macos-collection-restart-notice.js +1 -0
- package/dist/src/web-ui/app/components/passive-learning/memory.js +2 -4
- package/dist/src/web-ui/app/components/passive-learning/workspace-view.js +2 -2
- package/dist/src/web-ui/app/components/plugins/compatibility.js +13 -0
- package/dist/src/web-ui/app/components/plugins/configuration-draft.js +34 -0
- package/dist/src/web-ui/app/components/plugins/configuration-editor.js +147 -0
- package/dist/src/web-ui/app/components/plugins/configuration-fields.js +103 -0
- package/dist/src/web-ui/app/components/plugins/configuration-retained-secrets.js +20 -0
- package/dist/src/web-ui/app/components/plugins/configuration-settings.js +108 -0
- package/dist/src/web-ui/app/components/plugins/discovery-rendering.js +45 -0
- package/dist/src/web-ui/app/components/plugins/installation-compatibility.js +7 -0
- package/dist/src/web-ui/app/components/plugins/installation.js +213 -0
- package/dist/src/web-ui/app/components/plugins/manager.js +160 -6
- package/dist/src/web-ui/app/components/plugins/removal.js +130 -0
- package/dist/src/web-ui/app/components/plugins/rendering.js +17 -2
- package/dist/src/web-ui/app/components/plugins/summary.js +54 -0
- package/dist/src/web-ui/app/components/plugins/tabs.js +31 -0
- package/dist/src/web-ui/app/components/plugins/view-state.js +3 -1
- package/dist/src/web-ui/app/components/reasoning-override-prompt.js +82 -0
- package/dist/src/web-ui/app/components/runtime-config-activation.js +22 -8
- package/dist/src/web-ui/app/components/runtime-setup/connection-form.js +5 -2
- package/dist/src/web-ui/app/components/runtime-setup/connection-state.js +9 -1
- package/dist/src/web-ui/app/components/runtime-setup/context-window-feedback.js +71 -0
- package/dist/src/web-ui/app/components/runtime-setup/optional-steps.js +9 -4
- package/dist/src/web-ui/app/components/runtime-setup/plugins.js +3 -1
- package/dist/src/web-ui/app/components/runtime-setup/rendering.js +6 -4
- package/dist/src/web-ui/app/components/runtime-setup-guide.d.ts +1 -0
- package/dist/src/web-ui/app/components/runtime-setup-guide.js +15 -3
- package/dist/src/web-ui/app/components/schedules/form.js +10 -8
- package/dist/src/web-ui/app/components/schedules/workspace.js +23 -4
- package/dist/src/web-ui/app/components/session-sidebar-sections.js +2 -2
- package/dist/src/web-ui/app/components/spark-chat/empty-state.js +1 -0
- package/dist/src/web-ui/app/components/spark-chat/handoff-actions.js +9 -3
- package/dist/src/web-ui/app/components/spark-chat/panel.js +1 -0
- package/dist/src/web-ui/app/components/spark-chat/placement.js +4 -7
- package/dist/src/web-ui/app/components/spark-chat/settings.js +7 -3
- package/dist/src/web-ui/app/components/system-host/connection-card.js +35 -0
- package/dist/src/web-ui/app/components/system-host/macos-permissions.js +2 -0
- package/dist/src/web-ui/app/components/system-host/macos-setup.js +1 -1
- package/dist/src/web-ui/app/components/system-host/manager.js +45 -12
- package/dist/src/web-ui/app/components/system-host/native-windows-access.js +50 -0
- package/dist/src/web-ui/app/components/system-host/rendering.js +114 -106
- package/dist/src/web-ui/app/components/system-host/windows-store-setup.js +293 -0
- package/dist/src/web-ui/app/components/workspace-shell.js +6 -0
- package/dist/src/web-ui/app/components/workspace-storage-notice.js +37 -0
- package/dist/src/web-ui/app/computer-access-feature.js +22 -5
- package/dist/src/web-ui/app/configuration-environment-refresh.js +27 -34
- package/dist/src/web-ui/app/configuration-feature.js +44 -3
- package/dist/src/web-ui/app/controllers/app-event-bindings.js +41 -105
- package/dist/src/web-ui/app/controllers/chat-request-controller.d.ts +28 -0
- package/dist/src/web-ui/app/controllers/chat-request-controller.js +34 -66
- package/dist/src/web-ui/app/controllers/composer-attachments-controller.d.ts +15 -40
- package/dist/src/web-ui/app/controllers/composer-attachments-controller.js +26 -69
- package/dist/src/web-ui/app/controllers/composer-draft-view.d.ts +27 -0
- package/dist/src/web-ui/app/controllers/composer-draft-view.js +48 -0
- package/dist/src/web-ui/app/controllers/composer-drafts.d.ts +55 -0
- package/dist/src/web-ui/app/controllers/composer-drafts.js +120 -0
- package/dist/src/web-ui/app/controllers/composer-feature.d.ts +65 -0
- package/dist/src/web-ui/app/controllers/composer-feature.js +124 -0
- package/dist/src/web-ui/app/controllers/composer-queue-controller.d.ts +33 -94
- package/dist/src/web-ui/app/controllers/composer-queue-controller.js +185 -251
- package/dist/src/web-ui/app/controllers/composer-submission-lifecycle.d.ts +48 -0
- package/dist/src/web-ui/app/controllers/composer-submission-lifecycle.js +97 -0
- package/dist/src/web-ui/app/controllers/composer-submit-controller.d.ts +30 -61
- package/dist/src/web-ui/app/controllers/composer-submit-controller.js +56 -138
- package/dist/src/web-ui/app/controllers/composer-surface-controller.js +6 -0
- package/dist/src/web-ui/app/controllers/composer-workspace-controller.d.ts +22 -40
- package/dist/src/web-ui/app/controllers/composer-workspace-controller.js +49 -165
- package/dist/src/web-ui/app/controllers/conversation-navigation-intent.js +15 -0
- package/dist/src/web-ui/app/controllers/conversation-read-state-controller.d.ts +1 -0
- package/dist/src/web-ui/app/controllers/conversation-read-state-controller.js +7 -3
- package/dist/src/web-ui/app/controllers/conversation-request-hydration.js +91 -0
- package/dist/src/web-ui/app/controllers/conversation-session-controller.d.ts +10 -5
- package/dist/src/web-ui/app/controllers/conversation-session-controller.js +97 -162
- package/dist/src/web-ui/app/controllers/conversation-workspace-activation.js +27 -0
- package/dist/src/web-ui/app/controllers/daily-memory-review.js +15 -16
- package/dist/src/web-ui/app/controllers/environment-transition.js +126 -0
- package/dist/src/web-ui/app/controllers/environment-workspace-preparation.js +18 -0
- package/dist/src/web-ui/app/controllers/history-pagination.js +111 -0
- package/dist/src/web-ui/app/controllers/home-composer-feature.d.ts +14 -36
- package/dist/src/web-ui/app/controllers/home-composer-feature.js +17 -114
- package/dist/src/web-ui/app/controllers/home-conversation-activation.js +6 -8
- package/dist/src/web-ui/app/controllers/operations-controller.d.ts +12 -0
- package/dist/src/web-ui/app/controllers/operations-controller.js +28 -21
- package/dist/src/web-ui/app/controllers/passive-learning-controller.js +56 -0
- package/dist/src/web-ui/app/controllers/projects-controller.d.ts +1 -1
- package/dist/src/web-ui/app/controllers/projects-controller.js +6 -1
- package/dist/src/web-ui/app/controllers/reasoning-mode-controller.js +174 -0
- package/dist/src/web-ui/app/controllers/runtime-onboarding-controller.d.ts +1 -0
- package/dist/src/web-ui/app/controllers/runtime-onboarding-controller.js +11 -0
- package/dist/src/web-ui/app/controllers/runtime-selection-controller.d.ts +7 -0
- package/dist/src/web-ui/app/controllers/runtime-selection-controller.js +20 -155
- package/dist/src/web-ui/app/controllers/session-controller.js +43 -19
- package/dist/src/web-ui/app/controllers/session-list-pagination.js +71 -0
- package/dist/src/web-ui/app/controllers/session-pin-updates.js +14 -0
- package/dist/src/web-ui/app/controllers/session-sidebar-controller.js +17 -17
- package/dist/src/web-ui/app/controllers/spark-chat-reading.js +1 -0
- package/dist/src/web-ui/app/controllers/spark-chat-sync.js +26 -7
- package/dist/src/web-ui/app/controllers/steer-controller.js +9 -7
- package/dist/src/web-ui/app/controllers/tool-permission-mode-controller.js +1 -1
- package/dist/src/web-ui/app/controllers/workspace-conversation-opener.js +34 -0
- package/dist/src/web-ui/app/controllers/workspace-route-controller.js +21 -19
- package/dist/src/web-ui/app/dashboard-feature.js +4 -3
- package/dist/src/web-ui/app/index.html +6 -2
- package/dist/src/web-ui/app/lib/history-page-messages.js +49 -0
- package/dist/src/web-ui/app/lib/reasoning-controls.js +35 -0
- package/dist/src/web-ui/app/lib/request-lifecycle-view.js +8 -0
- package/dist/src/web-ui/app/lib/session-composer-queue-ownership.js +58 -0
- package/dist/src/web-ui/app/lib/session-composer-queue.d.ts +12 -0
- package/dist/src/web-ui/app/lib/session-composer-queue.js +25 -6
- package/dist/src/web-ui/app/lib/workspace-route.d.ts +3 -0
- package/dist/src/web-ui/app/lib/workspace-route.js +4 -0
- package/dist/src/web-ui/app/passive-learning-feature.js +16 -4
- package/dist/src/web-ui/app/runtime-onboarding-feature.js +3 -0
- package/dist/src/web-ui/app/schedules-feature.js +5 -3
- package/dist/src/web-ui/app/services/client-preferences.d.ts +18 -10
- package/dist/src/web-ui/app/services/client-preferences.js +25 -16
- package/dist/src/web-ui/app/services/home-guidance-preferences.js +13 -13
- package/dist/src/web-ui/app/services/reasoning-override.js +12 -0
- package/dist/src/web-ui/app/services/runtime-web-client/automations.js +10 -2
- package/dist/src/web-ui/app/services/runtime-web-client/configuration.js +20 -0
- package/dist/src/web-ui/app/services/runtime-web-client/memory.js +7 -2
- package/dist/src/web-ui/app/services/runtime-web-client/plugin-configuration.js +19 -0
- package/dist/src/web-ui/app/services/runtime-web-client/spark-chat.js +4 -4
- package/dist/src/web-ui/app/services/runtime-web-client/system-host.js +4 -0
- package/dist/src/web-ui/app/services/runtime-web-client.d.ts +8 -1
- package/dist/src/web-ui/app/services/runtime-web-client.js +14 -3
- package/dist/src/web-ui/app/services/server-composer-queue.js +32 -0
- package/dist/src/web-ui/app/services/session-sidebar-preferences.js +5 -5
- package/dist/src/web-ui/app/services/workspace-state-storage.js +116 -0
- package/dist/src/web-ui/app/services/workspace-state.js +27 -0
- package/dist/src/web-ui/app/spark-chat-conversation.js +34 -45
- package/dist/src/web-ui/app/spark-chat-feature.js +84 -21
- package/dist/src/web-ui/app/styles/11-product-links.css +30 -0
- package/dist/src/web-ui/app/styles/21-composer-controls.css +16 -0
- package/dist/src/web-ui/app/styles/41-plugin-configuration.css +79 -0
- package/dist/src/web-ui/app/styles/41-plugin-discovery.css +132 -0
- package/dist/src/web-ui/app/styles/41-plugin-management.css +14 -0
- package/dist/src/web-ui/app/styles/42-model-plugin-permissions.css +174 -0
- package/dist/src/web-ui/app/styles/46-system-host.css +61 -107
- package/dist/src/web-ui/app/styles/47-config-controls.css +13 -1
- package/dist/src/web-ui/app/styles/49-collection-consent.css +30 -0
- package/dist/src/web-ui/app/styles/54-spark-chat.css +33 -1
- package/dist/src/web-ui/app/styles/64-workspace-storage.css +23 -0
- package/dist/src/web-ui/app/styles.css +6 -0
- package/dist/src/web-ui/client-state/contracts.d.ts +15 -0
- package/dist/src/web-ui/client-state/contracts.js +13 -0
- package/dist/src/web-ui/client-state/preference-shapes.d.ts +2 -0
- package/dist/src/web-ui/client-state/preference-shapes.js +80 -0
- package/dist/src/web-ui/client-state/preferences.d.ts +3 -0
- package/dist/src/web-ui/client-state/preferences.js +84 -0
- package/dist/src/web-ui/client-state/queue.d.ts +3 -0
- package/dist/src/web-ui/client-state/queue.js +43 -0
- package/dist/src/web-ui/client-state/routes.d.ts +7 -0
- package/dist/src/web-ui/client-state/routes.js +58 -0
- package/dist/src/web-ui/client-state/store.d.ts +14 -0
- package/dist/src/web-ui/client-state/store.js +88 -0
- package/dist/src/web-ui/local-runtime/api-router.js +11 -6
- package/dist/src/web-ui/local-runtime/approval-request-attachment.js +14 -5
- package/dist/src/web-ui/local-runtime/configuration-activation-source.d.ts +1 -1
- package/dist/src/web-ui/local-runtime/configuration-activation-source.js +11 -3
- package/dist/src/web-ui/local-runtime/contracts.d.ts +4 -3
- package/dist/src/web-ui/local-runtime/environment-registry.d.ts +5 -1
- package/dist/src/web-ui/local-runtime/environment-registry.js +53 -11
- package/dist/src/web-ui/local-runtime/history-pagination.d.ts +16 -0
- package/dist/src/web-ui/local-runtime/history-pagination.js +20 -0
- package/dist/src/web-ui/local-runtime/http.js +11 -2
- package/dist/src/web-ui/local-runtime/model-context-capacity-error.d.ts +14 -0
- package/dist/src/web-ui/local-runtime/model-context-capacity-error.js +28 -0
- package/dist/src/web-ui/local-runtime/model-setup-context-window.d.ts +15 -0
- package/dist/src/web-ui/local-runtime/model-setup-context-window.js +25 -0
- package/dist/src/web-ui/local-runtime/model-setup-routes.js +2 -0
- package/dist/src/web-ui/local-runtime/model-setup-service.js +5 -2
- package/dist/src/web-ui/local-runtime/model-setup-validation.d.ts +1 -0
- package/dist/src/web-ui/local-runtime/model-setup-validation.js +14 -7
- package/dist/src/web-ui/local-runtime/plugin-configuration-routes.d.ts +16 -0
- package/dist/src/web-ui/local-runtime/plugin-configuration-routes.js +68 -0
- package/dist/src/web-ui/local-runtime/plugin-installation-routes.d.ts +16 -0
- package/dist/src/web-ui/local-runtime/plugin-installation-routes.js +96 -0
- package/dist/src/web-ui/local-runtime/plugin-management-routes.d.ts +8 -1
- package/dist/src/web-ui/local-runtime/plugin-management-routes.js +17 -0
- package/dist/src/web-ui/local-runtime/plugin-mutation-admission.d.ts +7 -0
- package/dist/src/web-ui/local-runtime/plugin-mutation-admission.js +17 -0
- package/dist/src/web-ui/local-runtime/plugin-removal-routes.d.ts +18 -0
- package/dist/src/web-ui/local-runtime/plugin-removal-routes.js +60 -0
- package/dist/src/web-ui/local-runtime/realtime-controller.js +41 -2
- package/dist/src/web-ui/local-runtime/request-body-error.d.ts +11 -0
- package/dist/src/web-ui/local-runtime/request-body-error.js +14 -0
- package/dist/src/web-ui/local-runtime/request-cancellation-route.js +28 -1
- package/dist/src/web-ui/local-runtime/request-control-observation.d.ts +19 -0
- package/dist/src/web-ui/local-runtime/request-control-observation.js +80 -0
- package/dist/src/web-ui/local-runtime/request-execution.js +66 -34
- package/dist/src/web-ui/local-runtime/runtime-setup-connection-edit.d.ts +2 -0
- package/dist/src/web-ui/local-runtime/runtime-setup-connection-edit.js +35 -22
- package/dist/src/web-ui/local-runtime/runtime-setup-context-window.d.ts +13 -0
- package/dist/src/web-ui/local-runtime/runtime-setup-context-window.js +21 -0
- package/dist/src/web-ui/local-runtime/runtime-setup-credentials.d.ts +15 -1
- package/dist/src/web-ui/local-runtime/runtime-setup-credentials.js +30 -11
- package/dist/src/web-ui/local-runtime/runtime-setup-edit-files.d.ts +20 -0
- package/dist/src/web-ui/local-runtime/runtime-setup-edit-files.js +104 -0
- package/dist/src/web-ui/local-runtime/runtime-setup-edit-journal.d.ts +29 -0
- package/dist/src/web-ui/local-runtime/runtime-setup-edit-journal.js +151 -0
- package/dist/src/web-ui/local-runtime/runtime-setup-edit-recovery.d.ts +7 -0
- package/dist/src/web-ui/local-runtime/runtime-setup-edit-recovery.js +87 -0
- package/dist/src/web-ui/local-runtime/runtime-setup-edit-transaction.d.ts +3 -0
- package/dist/src/web-ui/local-runtime/runtime-setup-edit-transaction.js +37 -0
- package/dist/src/web-ui/local-runtime/runtime-setup-routes.js +2 -0
- package/dist/src/web-ui/local-runtime/runtime-setup-service.js +4 -0
- package/dist/src/web-ui/local-runtime/runtime-setup-validation.js +9 -2
- package/dist/src/web-ui/local-runtime/session-routes.d.ts +1 -0
- package/dist/src/web-ui/local-runtime/session-routes.js +16 -4
- package/dist/src/web-ui/local-runtime/spark-chat-routes.js +4 -3
- package/dist/src/web-ui/local-runtime-backend.js +14 -0
- package/dist/src/web-ui/plugin-capability-selection.js +4 -1
- package/dist/src/web-ui/plugin-configuration-input.d.ts +12 -0
- package/dist/src/web-ui/plugin-configuration-input.js +68 -0
- package/dist/src/web-ui/plugin-configuration-retained-secrets.d.ts +9 -0
- package/dist/src/web-ui/plugin-configuration-retained-secrets.js +48 -0
- package/dist/src/web-ui/plugin-configuration-service.d.ts +52 -0
- package/dist/src/web-ui/plugin-configuration-service.js +66 -0
- package/dist/src/web-ui/plugin-configuration-view.d.ts +25 -0
- package/dist/src/web-ui/plugin-configuration-view.js +45 -0
- package/dist/src/web-ui/plugin-disabled-selection.d.ts +7 -0
- package/dist/src/web-ui/plugin-disabled-selection.js +17 -0
- package/dist/src/web-ui/plugin-management-catalog.d.ts +5 -1
- package/dist/src/web-ui/plugin-management-catalog.js +13 -1
- package/dist/src/web-ui/plugin-management-selection.js +22 -9
- package/dist/src/web-ui/plugin-management-service.d.ts +6 -1
- package/dist/src/web-ui/plugin-management-service.js +11 -7
- package/dist/src/web-ui/plugin-removal-error.d.ts +7 -0
- package/dist/src/web-ui/plugin-removal-error.js +16 -0
- package/dist/src/web-ui/plugin-removal-service.d.ts +31 -0
- package/dist/src/web-ui/plugin-removal-service.js +109 -0
- package/dist/src/web-ui/runtime-setup-gateway.d.ts +6 -2
- package/dist/src/web-ui/runtime-setup-gateway.js +30 -10
- package/dist/src/web-ui/server-readiness.d.ts +3 -0
- package/dist/src/web-ui/server-readiness.js +36 -0
- package/dist/src/web-ui/server.d.ts +2 -0
- package/dist/src/web-ui/server.js +29 -3
- package/dist/src/web-ui/session-read-state/overview.d.ts +42 -0
- package/dist/src/web-ui/session-read-state/overview.js +16 -0
- package/dist/src/web-ui/session-read-state/pagination.d.ts +15 -0
- package/dist/src/web-ui/session-read-state/pagination.js +42 -0
- package/dist/src/web-ui/session-read-state/projection.d.ts +4 -3
- package/dist/src/web-ui/session-read-state/service.d.ts +213 -20
- package/dist/src/web-ui/session-read-state/service.js +25 -23
- package/dist/src/web-ui/session-read-state/visible-messages.d.ts +3 -3
- package/dist/src/web-ui/system-host-service.js +13 -2
- package/dist/src/web-ui/system-host-setup/collection-consent-route.d.ts +3 -0
- package/dist/src/web-ui/system-host-setup/collection-consent-route.js +30 -0
- package/dist/src/web-ui/system-host-setup/companion-linux.js +1 -1
- package/dist/src/web-ui/system-host-setup/installer-contract.d.ts +1 -1
- package/dist/src/web-ui/system-host-setup/installer-contract.js +2 -2
- package/dist/src/web-ui/system-host-setup/installers.js +0 -7
- package/dist/src/web-ui/system-host-setup/local-connection.d.ts +4 -1
- package/dist/src/web-ui/system-host-setup/local-connection.js +10 -17
- package/dist/src/web-ui/system-host-setup/routes.d.ts +2 -0
- package/dist/src/web-ui/system-host-setup/routes.js +32 -9
- package/dist/src/web-ui/system-host-setup/setup-mutation.d.ts +9 -0
- package/dist/src/web-ui/system-host-setup/setup-mutation.js +27 -0
- package/dist/src/web-ui/system-host-setup/windows-store-route.d.ts +13 -0
- package/dist/src/web-ui/system-host-setup/windows-store-route.js +68 -0
- package/docs/configuration.md +46 -0
- package/docs/installation.md +88 -28
- package/docs/plugins.md +310 -6
- package/docs/projects-and-full-plus.md +2 -6
- package/docs/runtime-library.md +0 -1
- package/docs/tool-execution-result-evidence-contract.md +57 -0
- package/docs/windows-companion-store.md +132 -0
- package/package.json +6 -4
- package/plugins/capability-brief/plugin.json +4 -0
- package/plugins/code-outline/README.md +20 -0
- package/plugins/code-outline/plugin.json +1 -0
- package/plugins/code-outline/source/index.ts +16 -20
- package/plugins/code-outline/source/read-failure.ts +40 -0
- package/plugins/code-outline/src/index.cjs +614 -29
- package/plugins/document-reader/README.md +33 -0
- package/plugins/document-reader/plugin.json +2 -0
- package/plugins/document-reader/source/pdf-contract.ts +57 -0
- package/plugins/document-reader/source/pdf-parser.ts +139 -0
- package/plugins/document-reader/source/pdf-process-main.ts +56 -0
- package/plugins/document-reader/source/pdf-process.ts +207 -0
- package/plugins/document-reader/source/pdf-result.ts +79 -0
- package/plugins/document-reader/source/pdf-worker.ts +39 -303
- package/plugins/document-reader/source/pdf.ts +4 -1
- package/plugins/document-reader/source/read-failure.ts +37 -0
- package/plugins/document-reader/source/reader.ts +3 -19
- package/plugins/document-reader/src/index.cjs +995 -211
- package/plugins/exec/README.md +19 -0
- package/plugins/exec/plugin.json +7 -3
- package/plugins/exec/skills/exec_skill/SKILL.md +3 -2
- package/plugins/exec/source/filesystem-file-observer.ts +98 -0
- package/plugins/exec/source/filesystem-observer.ts +8 -79
- package/plugins/exec/source/output-files.ts +12 -6
- package/plugins/exec/source/paths.ts +3 -1
- package/plugins/exec/source/process-manager.ts +8 -24
- package/plugins/exec/source/shell-platform.ts +19 -3
- package/plugins/exec/source/shell-process.ts +55 -0
- package/plugins/exec/source/windows-job-source.ts +1 -0
- package/plugins/exec/source/windows-shell-bootstrap.ts +20 -0
- package/plugins/exec/src/index.cjs +252 -96
- package/plugins/filesystem/README.md +65 -0
- package/plugins/filesystem/plugin.json +8 -2
- package/plugins/filesystem/source/atomic-write.ts +2 -0
- package/plugins/filesystem/source/bounded-io.ts +80 -306
- package/plugins/filesystem/source/directory-sample.ts +2 -0
- package/plugins/filesystem/source/errors.ts +14 -0
- package/plugins/filesystem/source/file-observation.ts +151 -0
- package/plugins/filesystem/source/file-version.ts +41 -0
- package/plugins/filesystem/source/index.ts +6 -0
- package/plugins/filesystem/source/mutation-coordinator.ts +1 -0
- package/plugins/filesystem/source/windows/authority-script.ts +1 -0
- package/plugins/filesystem/source/windows/native-script.ts +1 -0
- package/plugins/filesystem/source/windows/operations.ts +197 -0
- package/plugins/filesystem/source/windows/process.ts +214 -0
- package/plugins/filesystem/source/windows/publication-script.ts +29 -0
- package/plugins/filesystem/source/windows/read-script.ts +63 -0
- package/plugins/filesystem/source/windows/request-availability.ts +67 -0
- package/plugins/filesystem/source/windows/source.ts +42 -0
- package/plugins/filesystem/source/windows/storage-script.ts +11 -0
- package/plugins/filesystem/source/windows/streams-script.ts +24 -0
- package/plugins/filesystem/source/windows/write-script.ts +86 -0
- package/plugins/filesystem/src/index.cjs +1208 -322
- package/plugins/json-inspector/README.md +18 -0
- package/plugins/json-inspector/plugin.json +1 -0
- package/plugins/json-inspector/source/index.ts +16 -19
- package/plugins/json-inspector/source/read-failure.ts +42 -0
- package/plugins/json-inspector/src/index.cjs +612 -27
- package/plugins/local-search/README.md +29 -0
- package/plugins/local-search/plugin.json +2 -0
- package/plugins/local-search/source/errors.ts +2 -0
- package/plugins/local-search/source/paths.ts +3 -0
- package/plugins/local-search/source/ripgrep-process.ts +31 -5
- package/plugins/local-search/source/ripgrep.ts +3 -3
- package/plugins/local-search/source/windows-authority.ts +99 -0
- package/plugins/local-search/source/windows-search-lease.ts +49 -0
- package/plugins/local-search/source/windows-search-process.ts +91 -0
- package/plugins/local-search/source/windows-search-script.ts +52 -0
- package/plugins/local-search/src/index.cjs +595 -26
- package/plugins/memory/plugin.json +4 -0
- package/plugins/memory/source/lock-directory-claim.ts +56 -0
- package/plugins/memory/source/lock-owner-file.ts +71 -0
- package/plugins/memory/source/lock-path-observation.ts +26 -0
- package/plugins/memory/source/prepared-memory-replacement.ts +40 -0
- package/plugins/memory/source/store-lock.ts +12 -7
- package/plugins/memory/source/store.ts +3 -2
- package/plugins/memory/src/index.cjs +174 -25
- package/plugins/project-orientation/README.md +23 -0
- package/plugins/project-orientation/plugin.json +1 -0
- package/plugins/project-orientation/source/index.ts +12 -9
- package/plugins/project-orientation/source/inspection-failure.ts +70 -0
- package/plugins/project-orientation/source/manifest-summary.ts +9 -2
- package/plugins/project-orientation/source/tree.ts +6 -0
- package/plugins/project-orientation/src/index.cjs +647 -31
- package/plugins/system/README.md +81 -5
- package/plugins/system/plugin.json +10 -1
- package/plugins/system/skills/system_actions/SKILL.md +1 -1
- package/plugins/system/source/command-working-directory.ts +47 -0
- package/plugins/system/source/companion-command-output.ts +82 -0
- package/plugins/system/source/computer/handlers.ts +13 -9
- package/plugins/system/source/computer/observation-result.ts +10 -5
- package/plugins/system/source/computer/request-computers.ts +10 -3
- package/plugins/system/source/computer/request-modules.ts +3 -6
- package/plugins/system/source/computer/runtime-platform.ts +18 -0
- package/plugins/system/source/host-dispatch.ts +21 -1
- package/plugins/system/source/index.ts +14 -6
- package/plugins/system/source/local-command-output-retention.ts +16 -0
- package/plugins/system/source/local-command-output.ts +69 -0
- package/plugins/system/source/request-system-modules.ts +14 -2
- package/plugins/system/source/request-target-snapshot.ts +2 -1
- package/plugins/system/source/security/desktop-result.ts +177 -0
- package/plugins/system/source/security/observed-error.ts +10 -0
- package/plugins/system/source/security/secret-text.ts +118 -0
- package/plugins/system/source/security/system-results.ts +62 -0
- package/plugins/system/source/security/windows-output-directory.ts +82 -0
- package/plugins/system/src/index.cjs +1207 -86
- package/plugins/system-probe/plugin.json +8 -2
- package/plugins/system-probe/source/disk-path.ts +8 -0
- package/plugins/system-probe/source/index.ts +10 -5
- package/plugins/system-probe/source/machine-load.ts +33 -0
- package/plugins/system-probe/source/metrics.ts +6 -8
- package/plugins/system-probe/src/index.cjs +49 -16
- package/plugins/web/README.md +2 -2
- package/plugins/web/plugin.json +8 -0
- package/runtime.config.schema.json +25 -1
- package/src/runtime/README.md +12 -2
- package/dist/src/web-ui/system-host-setup/companion-windows.d.ts +0 -2
- package/dist/src/web-ui/system-host-setup/companion-windows.js +0 -108
- package/docs/publishing.md +0 -167
|
@@ -6,6 +6,14 @@ var __defProp = Object.defineProperty;
|
|
|
6
6
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
7
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __esm = (fn, res, err) => function __init() {
|
|
10
|
+
if (err) throw err[0];
|
|
11
|
+
try {
|
|
12
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
13
|
+
} catch (e) {
|
|
14
|
+
throw err = [e], e;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
9
17
|
var __export = (target, all) => {
|
|
10
18
|
for (var name in all)
|
|
11
19
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -20,6 +28,261 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
20
28
|
};
|
|
21
29
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
22
30
|
|
|
31
|
+
// src/shared/windows-file-io/read-bytes-script.ts
|
|
32
|
+
var WINDOWS_FILE_READ_BYTES;
|
|
33
|
+
var init_read_bytes_script = __esm({
|
|
34
|
+
"src/shared/windows-file-io/read-bytes-script.ts"() {
|
|
35
|
+
"use strict";
|
|
36
|
+
WINDOWS_FILE_READ_BYTES = String.raw`
|
|
37
|
+
public static partial class AbotFilesystem {
|
|
38
|
+
static byte[] ReadBytes(SafeFileHandle file, long position, int length) {
|
|
39
|
+
long actual; Check(SetFilePointerEx(file, position, out actual, 0));
|
|
40
|
+
if (actual != position) throw new FsFault("filesystem_read_incomplete");
|
|
41
|
+
var bytes = new byte[length];
|
|
42
|
+
int offset = 0;
|
|
43
|
+
while (offset < length) {
|
|
44
|
+
var chunk = new byte[Math.Min(65536, length-offset)];
|
|
45
|
+
uint read; Check(ReadFile(file, chunk, (uint)chunk.Length, out read, IntPtr.Zero));
|
|
46
|
+
if (read == 0 || read > chunk.Length) throw new FsFault("filesystem_read_incomplete");
|
|
47
|
+
Buffer.BlockCopy(chunk, 0, bytes, offset, (int)read);
|
|
48
|
+
offset += (int)read;
|
|
49
|
+
}
|
|
50
|
+
return bytes;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
`;
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// src/shared/windows-file-io/native-script.ts
|
|
58
|
+
var WINDOWS_FILESYSTEM_NATIVE;
|
|
59
|
+
var init_native_script = __esm({
|
|
60
|
+
"src/shared/windows-file-io/native-script.ts"() {
|
|
61
|
+
"use strict";
|
|
62
|
+
WINDOWS_FILESYSTEM_NATIVE = String.raw`
|
|
63
|
+
using System;
|
|
64
|
+
using System.IO;
|
|
65
|
+
using System.Text;
|
|
66
|
+
using System.Linq;
|
|
67
|
+
using System.Collections.Generic;
|
|
68
|
+
using System.ComponentModel;
|
|
69
|
+
using System.Runtime.InteropServices;
|
|
70
|
+
using System.Security.AccessControl;
|
|
71
|
+
using System.Security.Principal;
|
|
72
|
+
using System.Web.Script.Serialization;
|
|
73
|
+
using Microsoft.Win32.SafeHandles;
|
|
74
|
+
|
|
75
|
+
public sealed class FsFault : Exception {
|
|
76
|
+
public readonly string Code;
|
|
77
|
+
public FsFault(string code) : base(code) { Code = code; }
|
|
78
|
+
}
|
|
79
|
+
public static partial class AbotFilesystem {
|
|
80
|
+
[StructLayout(LayoutKind.Sequential)] struct UnicodeString { public ushort Length, MaximumLength; public IntPtr Buffer; }
|
|
81
|
+
[StructLayout(LayoutKind.Sequential)] struct ObjectAttributes {
|
|
82
|
+
public int Length; public IntPtr Root, Name; public uint Attributes; public IntPtr Security, Qos;
|
|
83
|
+
}
|
|
84
|
+
[StructLayout(LayoutKind.Sequential)] struct IoStatus { public IntPtr Status, Information; }
|
|
85
|
+
[StructLayout(LayoutKind.Sequential)] struct BasicInfo {
|
|
86
|
+
public long Created, Accessed, Modified, Changed; public uint Attributes;
|
|
87
|
+
}
|
|
88
|
+
[StructLayout(LayoutKind.Sequential)] struct FileInfo {
|
|
89
|
+
public uint Attributes; public System.Runtime.InteropServices.ComTypes.FILETIME Created, Accessed, Modified;
|
|
90
|
+
public uint Volume, SizeHigh, SizeLow, Links, IndexHigh, IndexLow;
|
|
91
|
+
}
|
|
92
|
+
[DllImport("ntdll.dll")] static extern int NtCreateFile(out SafeFileHandle file, uint access,
|
|
93
|
+
ref ObjectAttributes attributes, out IoStatus status, IntPtr allocation, uint fileAttributes,
|
|
94
|
+
uint share, uint disposition, uint options, IntPtr ea, uint eaLength);
|
|
95
|
+
[DllImport("ntdll.dll")] static extern uint RtlNtStatusToDosError(int status);
|
|
96
|
+
[DllImport("ntdll.dll")] static extern int NtSetInformationFile(SafeFileHandle file,
|
|
97
|
+
out IoStatus status, IntPtr info, uint length, int kind);
|
|
98
|
+
[DllImport("kernel32.dll", SetLastError=true)] static extern bool GetFileInformationByHandle(SafeFileHandle file, out FileInfo info);
|
|
99
|
+
[DllImport("kernel32.dll", SetLastError=true)] static extern bool GetFileInformationByHandleEx(SafeFileHandle file, int kind, IntPtr data, uint length);
|
|
100
|
+
[DllImport("kernel32.dll", SetLastError=true)] static extern bool SetFileInformationByHandle(SafeFileHandle file, int kind, ref BasicInfo info, uint length);
|
|
101
|
+
[DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)] static extern uint GetFinalPathNameByHandle(SafeFileHandle file, StringBuilder name, uint length, uint flags);
|
|
102
|
+
[DllImport("kernel32.dll", SetLastError=true)] static extern bool SetFilePointerEx(SafeFileHandle file, long position, out long result, uint method);
|
|
103
|
+
[DllImport("kernel32.dll", SetLastError=true)] static extern bool ReadFile(SafeFileHandle file, byte[] bytes, uint count, out uint read, IntPtr overlapped);
|
|
104
|
+
[DllImport("kernel32.dll", SetLastError=true)] static extern bool WriteFile(SafeFileHandle file, byte[] bytes, uint count, out uint written, IntPtr overlapped);
|
|
105
|
+
[DllImport("kernel32.dll", SetLastError=true)] static extern bool FlushFileBuffers(SafeFileHandle file);
|
|
106
|
+
[DllImport("advapi32.dll")] static extern uint GetSecurityInfo(SafeFileHandle file, int kind, uint information,
|
|
107
|
+
out IntPtr owner, out IntPtr group, out IntPtr dacl, out IntPtr sacl, out IntPtr descriptor);
|
|
108
|
+
[DllImport("advapi32.dll")] static extern uint SetSecurityInfo(SafeFileHandle file, int kind, uint information,
|
|
109
|
+
IntPtr owner, IntPtr group, IntPtr dacl, IntPtr sacl);
|
|
110
|
+
[DllImport("advapi32.dll", SetLastError=true)] static extern bool GetSecurityDescriptorControl(IntPtr descriptor, out ushort control, out uint revision);
|
|
111
|
+
[DllImport("kernel32.dll")] static extern IntPtr LocalFree(IntPtr value);
|
|
112
|
+
|
|
113
|
+
static void Check(bool success) { if (!success) NativeFailure((uint)Marshal.GetLastWin32Error()); }
|
|
114
|
+
static bool IsNotDirectoryError(uint code) { return code == 267; } // ERROR_DIRECTORY
|
|
115
|
+
static void NativeFailure(uint code) {
|
|
116
|
+
if (IsNotDirectoryError(code)) throw new FsFault("not_a_directory");
|
|
117
|
+
if (code == 2 || code == 3) throw new FsFault("file_not_found");
|
|
118
|
+
if (code == 80 || code == 183) throw new FsFault("filesystem_target_changed");
|
|
119
|
+
if (code == 5 || code == 32 || code == 33) throw new FsFault("filesystem_access_denied");
|
|
120
|
+
throw new FsFault("filesystem_native_operation_failed");
|
|
121
|
+
}
|
|
122
|
+
static void CheckNt(int status) { if (status < 0) NativeFailure(RtlNtStatusToDosError(status)); }
|
|
123
|
+
static SafeFileHandle OpenHandle(SafeFileHandle root, string name, bool directory,
|
|
124
|
+
uint disposition, uint access, uint share, byte[] securityDescriptor = null, bool deleteOnClose = false) {
|
|
125
|
+
IntPtr text = Marshal.StringToHGlobalUni(name), unicodePointer = IntPtr.Zero, securityPointer = IntPtr.Zero;
|
|
126
|
+
try {
|
|
127
|
+
int length = Encoding.Unicode.GetByteCount(name);
|
|
128
|
+
if (length > 65532) throw new FsFault("filesystem_invalid_path");
|
|
129
|
+
UnicodeString unicode = new UnicodeString { Length=(ushort)length, MaximumLength=(ushort)(length+2), Buffer=text };
|
|
130
|
+
unicodePointer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(UnicodeString)));
|
|
131
|
+
Marshal.StructureToPtr(unicode, unicodePointer, false);
|
|
132
|
+
if (securityDescriptor != null) {
|
|
133
|
+
securityPointer = Marshal.AllocHGlobal(securityDescriptor.Length);
|
|
134
|
+
Marshal.Copy(securityDescriptor, 0, securityPointer, securityDescriptor.Length);
|
|
135
|
+
}
|
|
136
|
+
ObjectAttributes attributes = new ObjectAttributes {
|
|
137
|
+
Length=Marshal.SizeOf(typeof(ObjectAttributes)), Root=root == null ? IntPtr.Zero : root.DangerousGetHandle(),
|
|
138
|
+
Name=unicodePointer, Attributes=0x40, Security=securityPointer
|
|
139
|
+
};
|
|
140
|
+
SafeFileHandle file;
|
|
141
|
+
IoStatus status;
|
|
142
|
+
int result = NtCreateFile(out file, access | 0x100000, ref attributes, out status,
|
|
143
|
+
IntPtr.Zero, 0x80, share, disposition, 0x200020u | (directory ? 1u : 0x40u) | (deleteOnClose ? 0x1000u : 0u), IntPtr.Zero, 0);
|
|
144
|
+
if (result < 0) { if (file != null) file.Dispose(); CheckNt(result); }
|
|
145
|
+
try {
|
|
146
|
+
FileInfo info; Check(GetFileInformationByHandle(file, out info));
|
|
147
|
+
if ((info.Attributes & 0x400) != 0) throw new FsFault("filesystem_path_changed");
|
|
148
|
+
if (((info.Attributes & 0x10) != 0) != directory) throw new FsFault("filesystem_path_changed");
|
|
149
|
+
return file;
|
|
150
|
+
} catch { file.Dispose(); throw; }
|
|
151
|
+
} finally {
|
|
152
|
+
if (securityPointer != IntPtr.Zero) Marshal.FreeHGlobal(securityPointer);
|
|
153
|
+
if (unicodePointer != IntPtr.Zero) Marshal.FreeHGlobal(unicodePointer);
|
|
154
|
+
Marshal.FreeHGlobal(text);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
static BasicInfo Basic(SafeFileHandle file) {
|
|
158
|
+
IntPtr buffer = Marshal.AllocHGlobal(40);
|
|
159
|
+
try { Check(GetFileInformationByHandleEx(file, 0, buffer, 40)); return (BasicInfo)Marshal.PtrToStructure(buffer, typeof(BasicInfo)); }
|
|
160
|
+
finally { Marshal.FreeHGlobal(buffer); }
|
|
161
|
+
}
|
|
162
|
+
static Dictionary<string,object> Record(params object[] pairs) {
|
|
163
|
+
var result = new Dictionary<string,object>();
|
|
164
|
+
for (int i=0;i<pairs.Length;i+=2) result.Add((string)pairs[i], pairs[i+1]);
|
|
165
|
+
return result;
|
|
166
|
+
}
|
|
167
|
+
static string Text(Dictionary<string,object> request, string key) {
|
|
168
|
+
object value;
|
|
169
|
+
if (!request.TryGetValue(key, out value) || !(value is string)) throw new FsFault("filesystem_invalid_request");
|
|
170
|
+
return (string)value;
|
|
171
|
+
}
|
|
172
|
+
static int Limit(Dictionary<string,object> request, string key, int maximum) {
|
|
173
|
+
object value;
|
|
174
|
+
if (!request.TryGetValue(key, out value) || !(value is int)) throw new FsFault("filesystem_invalid_request");
|
|
175
|
+
int number = (int)value;
|
|
176
|
+
if (number < 0 || number > maximum) throw new FsFault("filesystem_invalid_request");
|
|
177
|
+
return number;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
`;
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// src/shared/windows-file-io/authority-script.ts
|
|
185
|
+
var WINDOWS_FILESYSTEM_AUTHORITY;
|
|
186
|
+
var init_authority_script = __esm({
|
|
187
|
+
"src/shared/windows-file-io/authority-script.ts"() {
|
|
188
|
+
"use strict";
|
|
189
|
+
WINDOWS_FILESYSTEM_AUTHORITY = String.raw`
|
|
190
|
+
public static partial class AbotFilesystem {
|
|
191
|
+
static string NativePath(string path) {
|
|
192
|
+
string full = Path.GetFullPath(path);
|
|
193
|
+
if (full.StartsWith(@"\\?\") || full.StartsWith(@"\\.\")) throw new FsFault("filesystem_invalid_path");
|
|
194
|
+
if (full.StartsWith(@"\\")) return @"\??\UNC\" + full.Substring(2);
|
|
195
|
+
if (full.Length < 3 || full[1] != ':' || full[2] != '\\') throw new FsFault("filesystem_invalid_path");
|
|
196
|
+
return @"\??\" + full;
|
|
197
|
+
}
|
|
198
|
+
static string FinalPath(SafeFileHandle handle) {
|
|
199
|
+
var value = new StringBuilder(32768);
|
|
200
|
+
uint length = GetFinalPathNameByHandle(handle, value, (uint)value.Capacity, 0);
|
|
201
|
+
Check(length != 0);
|
|
202
|
+
if (length >= value.Capacity) throw new FsFault("filesystem_invalid_path");
|
|
203
|
+
string path = value.ToString();
|
|
204
|
+
if (path.StartsWith(@"\\?\UNC\")) return @"\\" + path.Substring(8);
|
|
205
|
+
if (path.StartsWith(@"\\?\")) return path.Substring(4);
|
|
206
|
+
throw new FsFault("filesystem_path_changed");
|
|
207
|
+
}
|
|
208
|
+
static SafeFileHandle OpenRoot(Dictionary<string,object> request) {
|
|
209
|
+
string path = Path.GetFullPath(Text(request, "rootPath"));
|
|
210
|
+
SafeFileHandle root = OpenHandle(null, NativePath(path), true, 1, 0x80000000, 7);
|
|
211
|
+
try {
|
|
212
|
+
if (!String.Equals(FinalPath(root).TrimEnd('\\'), path.TrimEnd('\\'), StringComparison.OrdinalIgnoreCase))
|
|
213
|
+
throw new FsFault("filesystem_path_changed");
|
|
214
|
+
var expected = request["rootIdentity"] as Dictionary<string,object>;
|
|
215
|
+
if (expected == null || !MatchesIdentity(Identity(root), expected)) throw new FsFault("filesystem_path_changed");
|
|
216
|
+
return root;
|
|
217
|
+
} catch { root.Dispose(); throw; }
|
|
218
|
+
}
|
|
219
|
+
static string[] Components(Dictionary<string,object> request) {
|
|
220
|
+
string relative = Text(request, "relativePath");
|
|
221
|
+
if (relative == "") return new string[0];
|
|
222
|
+
string[] parts = relative.Split('/');
|
|
223
|
+
foreach (string part in parts) ValidateComponent(part);
|
|
224
|
+
return parts;
|
|
225
|
+
}
|
|
226
|
+
static void ValidateComponent(string name) {
|
|
227
|
+
if (name.Length == 0 || name == "." || name == "..") throw new FsFault("filesystem_invalid_path");
|
|
228
|
+
if (name.EndsWith(".") || name.EndsWith(" ")) throw new FsFault("filesystem_invalid_path");
|
|
229
|
+
foreach (char c in name) {
|
|
230
|
+
if (c < 32 || "\\/:*?\"<>|".IndexOf(c) >= 0) throw new FsFault("filesystem_invalid_path");
|
|
231
|
+
}
|
|
232
|
+
string stem = name.Split('.')[0].ToUpperInvariant();
|
|
233
|
+
if (stem == "CON" || stem == "PRN" || stem == "AUX" || stem == "NUL" ||
|
|
234
|
+
stem == "CONIN$" || stem == "CONOUT$") throw new FsFault("filesystem_invalid_path");
|
|
235
|
+
if (stem.Length == 4 && (stem.StartsWith("COM") || stem.StartsWith("LPT")) &&
|
|
236
|
+
"123456789\u00b9\u00b2\u00b3".IndexOf(stem[3]) >= 0) throw new FsFault("filesystem_invalid_path");
|
|
237
|
+
}
|
|
238
|
+
sealed class DirectoryChain : IDisposable {
|
|
239
|
+
public readonly SafeFileHandle Root;
|
|
240
|
+
readonly List<SafeFileHandle> children = new List<SafeFileHandle>();
|
|
241
|
+
public SafeFileHandle Current { get { return children.Count == 0 ? Root : children[children.Count-1]; } }
|
|
242
|
+
public DirectoryChain(Dictionary<string,object> request) { Root = OpenRoot(request); }
|
|
243
|
+
public void Walk(string[] parts, int count, bool create) {
|
|
244
|
+
for (int i=0;i<count;i++) children.Add(OpenHandle(Current, parts[i], true, create ? 3u : 1u, 0x80000000, 7));
|
|
245
|
+
}
|
|
246
|
+
public void Dispose() { for (int i=children.Count-1;i>=0;i--) children[i].Dispose(); Root.Dispose(); }
|
|
247
|
+
}
|
|
248
|
+
static ulong FileId(FileInfo info) {
|
|
249
|
+
ulong id=((ulong)info.IndexHigh << 32) | info.IndexLow;
|
|
250
|
+
if (id == 0) throw new FsFault("filesystem_safe_io_unsupported");
|
|
251
|
+
return id;
|
|
252
|
+
}
|
|
253
|
+
static Dictionary<string,object> Identity(SafeFileHandle file) {
|
|
254
|
+
FileInfo info; Check(GetFileInformationByHandle(file, out info));
|
|
255
|
+
BasicInfo basic = Basic(file);
|
|
256
|
+
return Record("device", info.Volume.ToString(), "inode", FileId(info).ToString(),
|
|
257
|
+
"birthtimeNs", ((basic.Created - 116444736000000000L) * 100L).ToString());
|
|
258
|
+
}
|
|
259
|
+
static bool MatchesIdentity(Dictionary<string,object> left, Dictionary<string,object> right) {
|
|
260
|
+
foreach (string key in new [] {"device", "inode", "birthtimeNs"}) {
|
|
261
|
+
if (!right.ContainsKey(key) || !Object.Equals(left[key], right[key])) return false;
|
|
262
|
+
}
|
|
263
|
+
return true;
|
|
264
|
+
}
|
|
265
|
+
static Dictionary<string,object> Metadata(SafeFileHandle file) {
|
|
266
|
+
FileInfo info; Check(GetFileInformationByHandle(file, out info));
|
|
267
|
+
BasicInfo basic = Basic(file);
|
|
268
|
+
ulong size = ((ulong)info.SizeHigh << 32) | info.SizeLow;
|
|
269
|
+
if (size > 9007199254740991UL) throw new FsFault("file_too_large");
|
|
270
|
+
return Record("device", info.Volume.ToString(), "inode", FileId(info).ToString(),
|
|
271
|
+
"size", (long)size, "mode", (basic.Attributes & 1) != 0 ? 292 : 438,
|
|
272
|
+
"modifiedNs", ((basic.Modified - 116444736000000000L) * 100L).ToString(),
|
|
273
|
+
"changedNs", ((basic.Changed - 116444736000000000L) * 100L).ToString());
|
|
274
|
+
}
|
|
275
|
+
static bool SameMetadata(Dictionary<string,object> left, Dictionary<string,object> right) {
|
|
276
|
+
foreach (string key in new [] {"device", "inode", "size", "mode", "modifiedNs", "changedNs"}) {
|
|
277
|
+
if (!right.ContainsKey(key) || Convert.ToString(left[key]) != Convert.ToString(right[key])) return false;
|
|
278
|
+
}
|
|
279
|
+
return true;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
`;
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
|
|
23
286
|
// plugins/filesystem/source/index.ts
|
|
24
287
|
var index_exports = {};
|
|
25
288
|
__export(index_exports, {
|
|
@@ -27,6 +290,9 @@ __export(index_exports, {
|
|
|
27
290
|
});
|
|
28
291
|
module.exports = __toCommonJS(index_exports);
|
|
29
292
|
|
|
293
|
+
// plugins/filesystem/source/windows/request-availability.ts
|
|
294
|
+
var import_node_async_hooks = require("node:async_hooks");
|
|
295
|
+
|
|
30
296
|
// src/plugin-sdk/bounds.ts
|
|
31
297
|
function boundText(value, options) {
|
|
32
298
|
if (!Number.isSafeInteger(options.maxChars) || options.maxChars < 0) {
|
|
@@ -270,6 +536,557 @@ function failureFromError(error, options) {
|
|
|
270
536
|
// src/capabilities/tool-media.ts
|
|
271
537
|
var TOOL_IMAGE_MAX_BYTES = 10 * 1024 * 1024;
|
|
272
538
|
|
|
539
|
+
// plugins/filesystem/source/windows/process.ts
|
|
540
|
+
var import_node_child_process = require("node:child_process");
|
|
541
|
+
var import_node_path = require("node:path");
|
|
542
|
+
|
|
543
|
+
// plugins/filesystem/source/errors.ts
|
|
544
|
+
var FilesystemToolError = class extends Error {
|
|
545
|
+
code;
|
|
546
|
+
data;
|
|
547
|
+
constructor(code, message = code, data) {
|
|
548
|
+
super(message);
|
|
549
|
+
this.name = "FilesystemToolError";
|
|
550
|
+
this.code = code;
|
|
551
|
+
this.data = data;
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
function fail(code, message = code, data) {
|
|
555
|
+
throw new FilesystemToolError(code, message, data);
|
|
556
|
+
}
|
|
557
|
+
function isNodeErrorCode(error, code) {
|
|
558
|
+
return error instanceof Error && typeof error.code === "string" && error.code === code;
|
|
559
|
+
}
|
|
560
|
+
function isDirectoryTypeFailure(code) {
|
|
561
|
+
return code === "not_a_directory" || code === "ENOTDIR";
|
|
562
|
+
}
|
|
563
|
+
function failNotDirectory() {
|
|
564
|
+
fail(
|
|
565
|
+
"not_a_directory",
|
|
566
|
+
"A component of the requested path is not a directory. An existing file cannot contain child files. Inspect the path and choose a file target under a directory; do not repeat the same operation unchanged or overwrite the blocking file to turn it into a directory."
|
|
567
|
+
);
|
|
568
|
+
}
|
|
569
|
+
function rethrowFilesystemError(error, operation, logicalPath) {
|
|
570
|
+
if (isRuntimeToolPathError(error) || error instanceof FilesystemToolError) {
|
|
571
|
+
throw error;
|
|
572
|
+
}
|
|
573
|
+
if (isNodeErrorCode(error, "ENOENT")) {
|
|
574
|
+
fail("file_not_found", `Path does not exist: ${logicalPath}`);
|
|
575
|
+
}
|
|
576
|
+
if (error instanceof Error && isDirectoryTypeFailure(error.code)) {
|
|
577
|
+
failNotDirectory();
|
|
578
|
+
}
|
|
579
|
+
if (isNodeErrorCode(error, "EACCES") || isNodeErrorCode(error, "EPERM")) {
|
|
580
|
+
fail(
|
|
581
|
+
"filesystem_access_denied",
|
|
582
|
+
`Access was denied while attempting to ${operation}: ${logicalPath}`
|
|
583
|
+
);
|
|
584
|
+
}
|
|
585
|
+
if (isNodeErrorCode(error, "EISDIR")) {
|
|
586
|
+
fail("not_a_file", `Expected a regular file: ${logicalPath}`);
|
|
587
|
+
}
|
|
588
|
+
fail(
|
|
589
|
+
`filesystem_${operation}_failed`,
|
|
590
|
+
`Filesystem ${operation} failed for ${logicalPath}.`
|
|
591
|
+
);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// plugins/filesystem/source/windows/source.ts
|
|
595
|
+
init_read_bytes_script();
|
|
596
|
+
|
|
597
|
+
// plugins/filesystem/source/windows/native-script.ts
|
|
598
|
+
init_native_script();
|
|
599
|
+
|
|
600
|
+
// plugins/filesystem/source/windows/authority-script.ts
|
|
601
|
+
init_authority_script();
|
|
602
|
+
|
|
603
|
+
// plugins/filesystem/source/windows/read-script.ts
|
|
604
|
+
var WINDOWS_FILESYSTEM_READ = String.raw`
|
|
605
|
+
public static partial class AbotFilesystem {
|
|
606
|
+
static object ReadSlices(Dictionary<string,object> request) {
|
|
607
|
+
int headLimit=Limit(request, "headBytes", 1048576), tailLimit=Limit(request, "tailBytes", 1048576);
|
|
608
|
+
int maximum=Limit(request, "maximumFileBytes", 1048576);
|
|
609
|
+
string[] parts=Components(request);
|
|
610
|
+
if (parts.Length == 0) throw new FsFault("not_a_file");
|
|
611
|
+
using (var chain=new DirectoryChain(request)) {
|
|
612
|
+
chain.Walk(parts, parts.Length-1, false);
|
|
613
|
+
using (var file=OpenHandle(chain.Current, parts[parts.Length-1], false, 1, 0x80000000, 1)) {
|
|
614
|
+
var before=Metadata(file);
|
|
615
|
+
long size=Convert.ToInt64(before["size"]);
|
|
616
|
+
if (maximum > 0 && size > maximum) throw new FsFault("file_too_large");
|
|
617
|
+
bool complete=size <= (long)headLimit+tailLimit;
|
|
618
|
+
var head=ReadBytes(file, 0, complete ? (int)size : headLimit);
|
|
619
|
+
var tail=complete ? new byte[0] : ReadBytes(file, size-tailLimit, tailLimit);
|
|
620
|
+
if (!SameMetadata(before, Metadata(file))) throw new FsFault("filesystem_read_changed");
|
|
621
|
+
return Record("metadata", before, "head", Convert.ToBase64String(head), "tail", Convert.ToBase64String(tail));
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
static object SampleDirectory(Dictionary<string,object> request) {
|
|
626
|
+
int maximum=Limit(request, "maxEntries", 160);
|
|
627
|
+
string[] parts=Components(request);
|
|
628
|
+
using (var chain=new DirectoryChain(request)) {
|
|
629
|
+
chain.Walk(parts, parts.Length, false);
|
|
630
|
+
var before=Basic(chain.Current);
|
|
631
|
+
var entries=new List<string>();
|
|
632
|
+
bool truncated=false, complete=false;
|
|
633
|
+
IntPtr buffer=Marshal.AllocHGlobal(16384);
|
|
634
|
+
try {
|
|
635
|
+
int kind=11;
|
|
636
|
+
while (!complete) {
|
|
637
|
+
if (!GetFileInformationByHandleEx(chain.Current, kind, buffer, 16384)) {
|
|
638
|
+
uint error=(uint)Marshal.GetLastWin32Error();
|
|
639
|
+
if (error == 18) break;
|
|
640
|
+
NativeFailure(error);
|
|
641
|
+
}
|
|
642
|
+
kind=10;
|
|
643
|
+
int offset=0;
|
|
644
|
+
for (;;) {
|
|
645
|
+
int next=Marshal.ReadInt32(buffer, offset), attributes=Marshal.ReadInt32(buffer, offset+56);
|
|
646
|
+
int nameLength=Marshal.ReadInt32(buffer, offset+60);
|
|
647
|
+
if (nameLength < 0 || nameLength % 2 != 0 || offset+104+nameLength > 16384)
|
|
648
|
+
throw new FsFault("filesystem_native_operation_failed");
|
|
649
|
+
string name=Marshal.PtrToStringUni(IntPtr.Add(buffer, offset+104), nameLength/2);
|
|
650
|
+
if (name != "." && name != "..") {
|
|
651
|
+
if (entries.Count == maximum) { truncated=true; complete=true; break; }
|
|
652
|
+
entries.Add(name + ((attributes & 0x410) == 0x10 ? "/" : ""));
|
|
653
|
+
}
|
|
654
|
+
if (next == 0) break;
|
|
655
|
+
if (next < 104 || offset+next >= 16384) throw new FsFault("filesystem_native_operation_failed");
|
|
656
|
+
offset+=next;
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
} finally { Marshal.FreeHGlobal(buffer); }
|
|
660
|
+
var after=Basic(chain.Current);
|
|
661
|
+
if (before.Modified != after.Modified || before.Changed != after.Changed) throw new FsFault("filesystem_read_changed");
|
|
662
|
+
return Record("entries", entries, "truncated", truncated);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
`;
|
|
667
|
+
|
|
668
|
+
// plugins/filesystem/source/windows/streams-script.ts
|
|
669
|
+
var WINDOWS_FILESYSTEM_STREAMS = String.raw`
|
|
670
|
+
public static partial class AbotFilesystem {
|
|
671
|
+
static void RequireUnnamedDataStreamOnly(SafeFileHandle file) {
|
|
672
|
+
// One unnamed data stream fits in 40 bytes. Extra entries/names must not
|
|
673
|
+
// be silently discarded by replacement; only a bounded header is needed.
|
|
674
|
+
const int capacity=64;
|
|
675
|
+
IntPtr buffer=Marshal.AllocHGlobal(capacity);
|
|
676
|
+
try {
|
|
677
|
+
if (!GetFileInformationByHandleEx(file, 7, buffer, capacity)) {
|
|
678
|
+
uint error=(uint)Marshal.GetLastWin32Error();
|
|
679
|
+
if (error == 122 || error == 234)
|
|
680
|
+
throw new FsFault("filesystem_named_streams_unsupported");
|
|
681
|
+
NativeFailure(error);
|
|
682
|
+
}
|
|
683
|
+
int next=Marshal.ReadInt32(buffer, 0), length=Marshal.ReadInt32(buffer, 4);
|
|
684
|
+
if (next != 0 || length != 14)
|
|
685
|
+
throw new FsFault("filesystem_named_streams_unsupported");
|
|
686
|
+
string name=Marshal.PtrToStringUni(IntPtr.Add(buffer, 24), length/2);
|
|
687
|
+
if (name != "::$DATA") throw new FsFault("filesystem_named_streams_unsupported");
|
|
688
|
+
} finally { Marshal.FreeHGlobal(buffer); }
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
`;
|
|
692
|
+
|
|
693
|
+
// plugins/filesystem/source/windows/storage-script.ts
|
|
694
|
+
var WINDOWS_FILESYSTEM_STORAGE = String.raw`
|
|
695
|
+
public static partial class AbotFilesystem {
|
|
696
|
+
static void RequireReplaceableStorage(SafeFileHandle file) {
|
|
697
|
+
const uint encrypted=0x4000, compressed=0x800;
|
|
698
|
+
if ((Basic(file).Attributes & (encrypted | compressed)) != 0)
|
|
699
|
+
throw new FsFault("filesystem_storage_attributes_unsupported");
|
|
700
|
+
RequireUnnamedDataStreamOnly(file);
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
`;
|
|
704
|
+
|
|
705
|
+
// plugins/filesystem/source/windows/publication-script.ts
|
|
706
|
+
var WINDOWS_FILESYSTEM_PUBLICATION = String.raw`
|
|
707
|
+
public static partial class AbotFilesystem {
|
|
708
|
+
static void CheckLinkPublication(int status) {
|
|
709
|
+
if (status >= 0) return;
|
|
710
|
+
uint error=RtlNtStatusToDosError(status);
|
|
711
|
+
if (error == 1 || error == 50 || error == 87)
|
|
712
|
+
throw new FsFault("filesystem_windows_publication_unsupported");
|
|
713
|
+
NativeFailure(error);
|
|
714
|
+
}
|
|
715
|
+
static void PublishLinkRelative(SafeFileHandle file, SafeFileHandle parent, string name, bool replace) {
|
|
716
|
+
byte[] bytes=Encoding.Unicode.GetBytes(name);
|
|
717
|
+
int rootOffset=IntPtr.Size == 8 ? 8 : 4;
|
|
718
|
+
int lengthOffset=rootOffset+IntPtr.Size, nameOffset=lengthOffset+4;
|
|
719
|
+
IntPtr buffer=Marshal.AllocHGlobal(nameOffset+bytes.Length);
|
|
720
|
+
try {
|
|
721
|
+
for (int i=0;i<nameOffset;i++) Marshal.WriteByte(buffer, i, 0);
|
|
722
|
+
// FileLinkInformationEx: replace the destination atomically, retaining
|
|
723
|
+
// existing observations. Closing this handle deletes only its temporary name.
|
|
724
|
+
Marshal.WriteInt32(buffer, 0, replace ? 3 : 0);
|
|
725
|
+
Marshal.WriteIntPtr(buffer, rootOffset, parent.DangerousGetHandle());
|
|
726
|
+
Marshal.WriteInt32(buffer, lengthOffset, bytes.Length);
|
|
727
|
+
Marshal.Copy(bytes, 0, IntPtr.Add(buffer, nameOffset), bytes.Length);
|
|
728
|
+
IoStatus status;
|
|
729
|
+
CheckLinkPublication(NtSetInformationFile(file, out status, buffer, (uint)(nameOffset+bytes.Length), 72));
|
|
730
|
+
} finally { Marshal.FreeHGlobal(buffer); }
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
`;
|
|
734
|
+
|
|
735
|
+
// plugins/filesystem/source/windows/write-script.ts
|
|
736
|
+
var WINDOWS_FILESYSTEM_WRITE = String.raw`
|
|
737
|
+
public static partial class AbotFilesystem {
|
|
738
|
+
static string Digest(byte[] bytes) {
|
|
739
|
+
using (var hash=System.Security.Cryptography.SHA256.Create())
|
|
740
|
+
return BitConverter.ToString(hash.ComputeHash(bytes)).Replace("-", "").ToLowerInvariant();
|
|
741
|
+
}
|
|
742
|
+
static SafeFileHandle ObserveExisting(SafeFileHandle parent, string name, Dictionary<string,object> expected) {
|
|
743
|
+
SafeFileHandle file=null;
|
|
744
|
+
try {
|
|
745
|
+
try { file=OpenHandle(parent, name, false, 1, 0x80020000, 7); }
|
|
746
|
+
catch (FsFault error) {
|
|
747
|
+
if (error.Code != "file_not_found") throw;
|
|
748
|
+
if (Text(expected, "kind") != "absent") throw new FsFault("filesystem_target_changed");
|
|
749
|
+
return null;
|
|
750
|
+
}
|
|
751
|
+
if (Text(expected, "kind") != "file") throw new FsFault("filesystem_target_changed");
|
|
752
|
+
var before=Metadata(file);
|
|
753
|
+
if (!SameMetadata(before, expected)) throw new FsFault("filesystem_target_changed");
|
|
754
|
+
long size=Convert.ToInt64(before["size"]);
|
|
755
|
+
if (size > 1048576) throw new FsFault("filesystem_target_changed");
|
|
756
|
+
byte[] bytes=ReadBytes(file, 0, (int)size);
|
|
757
|
+
if (!SameMetadata(before, Metadata(file)) || Digest(bytes) != Text(expected, "digest"))
|
|
758
|
+
throw new FsFault("filesystem_target_changed");
|
|
759
|
+
RequireReplaceableStorage(file);
|
|
760
|
+
return file;
|
|
761
|
+
} catch { if (file != null) file.Dispose(); throw; }
|
|
762
|
+
}
|
|
763
|
+
static byte[] PrivateFileSecurityDescriptor() {
|
|
764
|
+
var acl=new FileSecurity();
|
|
765
|
+
acl.SetAccessRuleProtection(true, false);
|
|
766
|
+
acl.AddAccessRule(new FileSystemAccessRule(WindowsIdentity.GetCurrent().User,
|
|
767
|
+
FileSystemRights.FullControl, AccessControlType.Allow));
|
|
768
|
+
return acl.GetSecurityDescriptorBinaryForm();
|
|
769
|
+
}
|
|
770
|
+
static void PreserveAccess(SafeFileHandle original, SafeFileHandle replacement) {
|
|
771
|
+
IntPtr owner, group, dacl, sacl, descriptor;
|
|
772
|
+
uint error=GetSecurityInfo(original, 1, 4, out owner, out group, out dacl, out sacl, out descriptor);
|
|
773
|
+
if (error != 0) NativeFailure(error);
|
|
774
|
+
try {
|
|
775
|
+
ushort control; uint revision;
|
|
776
|
+
Check(GetSecurityDescriptorControl(descriptor, out control, out revision));
|
|
777
|
+
uint protection=(control & 0x1000) != 0 ? 0x80000000u : 0x20000000u;
|
|
778
|
+
error=SetSecurityInfo(replacement, 1, 4 | protection, IntPtr.Zero, IntPtr.Zero, dacl, IntPtr.Zero);
|
|
779
|
+
if (error != 0) NativeFailure(error);
|
|
780
|
+
var basic=new BasicInfo { Attributes=Basic(original).Attributes & 0x27u };
|
|
781
|
+
if (basic.Attributes == 0) basic.Attributes=0x80;
|
|
782
|
+
Check(SetFileInformationByHandle(replacement, 0, ref basic, 40));
|
|
783
|
+
} finally { LocalFree(descriptor); }
|
|
784
|
+
}
|
|
785
|
+
static void WritePreparedContent(SafeFileHandle file, byte[] bytes) {
|
|
786
|
+
int offset=0;
|
|
787
|
+
while (offset < bytes.Length) {
|
|
788
|
+
var chunk=new byte[Math.Min(65536, bytes.Length-offset)];
|
|
789
|
+
Buffer.BlockCopy(bytes, offset, chunk, 0, chunk.Length);
|
|
790
|
+
uint written;
|
|
791
|
+
Check(WriteFile(file, chunk, (uint)chunk.Length, out written, IntPtr.Zero));
|
|
792
|
+
if (written == 0 || written > chunk.Length) throw new FsFault("filesystem_native_operation_failed");
|
|
793
|
+
offset+=(int)written;
|
|
794
|
+
}
|
|
795
|
+
Check(FlushFileBuffers(file));
|
|
796
|
+
}
|
|
797
|
+
static object CommitWrite(Dictionary<string,object> request) {
|
|
798
|
+
string[] parts=Components(request);
|
|
799
|
+
if (parts.Length == 0) throw new FsFault("not_a_file");
|
|
800
|
+
byte[] bytes=Convert.FromBase64String(Text(request, "content"));
|
|
801
|
+
if (bytes.Length > 1048576) throw new FsFault("file_too_large");
|
|
802
|
+
var expected=request["expected"] as Dictionary<string,object>;
|
|
803
|
+
if (expected == null) throw new FsFault("filesystem_invalid_request");
|
|
804
|
+
string name=parts[parts.Length-1];
|
|
805
|
+
using (var chain=new DirectoryChain(request)) {
|
|
806
|
+
chain.Walk(parts, parts.Length-1, true);
|
|
807
|
+
using (var previous=ObserveExisting(chain.Current, name, expected)) {
|
|
808
|
+
string temporary=".abot-"+Guid.NewGuid().ToString("N")+".tmp";
|
|
809
|
+
using (var file=OpenHandle(chain.Current, temporary, false, 2, 0xC0070000, 0, PrivateFileSecurityDescriptor(), true)) {
|
|
810
|
+
WritePreparedContent(file, bytes);
|
|
811
|
+
using (var current=ObserveExisting(chain.Current, name, expected)) {
|
|
812
|
+
if (current != null) PreserveAccess(current, file);
|
|
813
|
+
PublishLinkRelative(file, chain.Current, name, current != null);
|
|
814
|
+
}
|
|
815
|
+
return Record("committed", true);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
`;
|
|
822
|
+
|
|
823
|
+
// plugins/filesystem/source/windows/source.ts
|
|
824
|
+
var ENTRYPOINT = String.raw`
|
|
825
|
+
public static partial class AbotFilesystem {
|
|
826
|
+
public static string Run(string input) {
|
|
827
|
+
var json=new JavaScriptSerializer { MaxJsonLength=2097152 };
|
|
828
|
+
try {
|
|
829
|
+
var request=json.Deserialize<Dictionary<string,object>>(input);
|
|
830
|
+
string operation=Text(request, "operation");
|
|
831
|
+
object result;
|
|
832
|
+
switch (operation) {
|
|
833
|
+
case "probe": result=Record("available", true); break;
|
|
834
|
+
case "read": result=ReadSlices(request); break;
|
|
835
|
+
case "sample": result=SampleDirectory(request); break;
|
|
836
|
+
case "write": result=CommitWrite(request); break;
|
|
837
|
+
default: throw new FsFault("filesystem_invalid_request");
|
|
838
|
+
}
|
|
839
|
+
return json.Serialize(Record("ok", true, "result", result));
|
|
840
|
+
} catch (FsFault error) { return json.Serialize(Record("ok", false, "code", error.Code)); }
|
|
841
|
+
catch { return json.Serialize(Record("ok", false, "code", "filesystem_native_operation_failed")); }
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
`;
|
|
845
|
+
var WINDOWS_FILESYSTEM_SOURCE = [
|
|
846
|
+
WINDOWS_FILESYSTEM_NATIVE,
|
|
847
|
+
WINDOWS_FILESYSTEM_AUTHORITY,
|
|
848
|
+
WINDOWS_FILE_READ_BYTES,
|
|
849
|
+
WINDOWS_FILESYSTEM_READ,
|
|
850
|
+
WINDOWS_FILESYSTEM_STREAMS,
|
|
851
|
+
WINDOWS_FILESYSTEM_STORAGE,
|
|
852
|
+
WINDOWS_FILESYSTEM_PUBLICATION,
|
|
853
|
+
WINDOWS_FILESYSTEM_WRITE,
|
|
854
|
+
ENTRYPOINT
|
|
855
|
+
].join("\n");
|
|
856
|
+
|
|
857
|
+
// plugins/filesystem/source/windows/process.ts
|
|
858
|
+
var MAX_MESSAGE_BYTES = 2 * 1024 * 1024;
|
|
859
|
+
var BOOTSTRAP = [
|
|
860
|
+
"$ErrorActionPreference='Stop'",
|
|
861
|
+
`if ($ExecutionContext.SessionState.LanguageMode -ne 'FullLanguage') { Write-Output '{"ok":false,"code":"filesystem_windows_policy_blocked"}'; exit 0 }`,
|
|
862
|
+
"$env:PSModulePath=[IO.Path]::Combine($PSHOME,'Modules')",
|
|
863
|
+
"[Console]::InputEncoding=[Text.UTF8Encoding]::new($false)",
|
|
864
|
+
"[Console]::OutputEncoding=[Text.UTF8Encoding]::new($false)",
|
|
865
|
+
"$started=$false",
|
|
866
|
+
"try {",
|
|
867
|
+
"$envelope=[Console]::In.ReadToEnd() | ConvertFrom-Json",
|
|
868
|
+
"Add-Type -ReferencedAssemblies @('System.Web.Extensions') -TypeDefinition $envelope.source",
|
|
869
|
+
"$started=$true",
|
|
870
|
+
"[Console]::Write([AbotFilesystem]::Run($envelope.request))",
|
|
871
|
+
`} catch { if ($started) { [Console]::Write('{"ok":false,"code":"filesystem_windows_operation_unreported"}') } else { [Console]::Write('{"ok":false,"code":"filesystem_windows_helper_unavailable"}') } }`
|
|
872
|
+
].join(";");
|
|
873
|
+
var NATIVE_CODES = /* @__PURE__ */ new Set([
|
|
874
|
+
"file_not_found",
|
|
875
|
+
"file_too_large",
|
|
876
|
+
"not_a_file",
|
|
877
|
+
"not_a_directory",
|
|
878
|
+
"filesystem_access_denied",
|
|
879
|
+
"filesystem_safe_io_unsupported",
|
|
880
|
+
"filesystem_storage_attributes_unsupported",
|
|
881
|
+
"filesystem_named_streams_unsupported",
|
|
882
|
+
"filesystem_windows_publication_unsupported",
|
|
883
|
+
"filesystem_path_changed",
|
|
884
|
+
"filesystem_target_changed",
|
|
885
|
+
"filesystem_invalid_path",
|
|
886
|
+
"filesystem_read_changed",
|
|
887
|
+
"filesystem_read_incomplete",
|
|
888
|
+
"filesystem_invalid_request",
|
|
889
|
+
"filesystem_native_operation_failed",
|
|
890
|
+
"filesystem_windows_policy_blocked",
|
|
891
|
+
"filesystem_windows_helper_unavailable"
|
|
892
|
+
]);
|
|
893
|
+
function isWindowsHelperBlocked(error) {
|
|
894
|
+
if (!(error instanceof FilesystemToolError)) return false;
|
|
895
|
+
return error.code === "filesystem_windows_policy_blocked" || error.code === "filesystem_windows_helper_unavailable";
|
|
896
|
+
}
|
|
897
|
+
function helperFailure(code, mutation) {
|
|
898
|
+
if (code === "filesystem_windows_publication_unsupported")
|
|
899
|
+
return new FilesystemToolError(
|
|
900
|
+
code,
|
|
901
|
+
"Windows cannot safely publish this file. Writes require Windows 10 version 1809 or newer and a filesystem supporting hard links, such as NTFS. The destination was left unchanged. Do not retry this write on the same unsupported target.",
|
|
902
|
+
{
|
|
903
|
+
retryable: false,
|
|
904
|
+
blockedBy: "filesystem_publication_support",
|
|
905
|
+
targetUnchanged: true
|
|
906
|
+
}
|
|
907
|
+
);
|
|
908
|
+
if (code === "filesystem_named_streams_unsupported")
|
|
909
|
+
return new FilesystemToolError(
|
|
910
|
+
code,
|
|
911
|
+
"This file has Windows named data streams, which may include download-origin security information. Editing it is not supported; the original file and its streams were left unchanged. Do not retry this edit or remove the streams to bypass the restriction.",
|
|
912
|
+
{
|
|
913
|
+
retryable: false,
|
|
914
|
+
blockedBy: "file_named_streams",
|
|
915
|
+
targetUnchanged: true
|
|
916
|
+
}
|
|
917
|
+
);
|
|
918
|
+
if (code === "filesystem_storage_attributes_unsupported")
|
|
919
|
+
return new FilesystemToolError(
|
|
920
|
+
code,
|
|
921
|
+
"This file uses EFS encryption or NTFS compression. Editing it is not supported; the original file was left unchanged. Do not retry this edit or remove its storage attributes to bypass the restriction.",
|
|
922
|
+
{
|
|
923
|
+
retryable: false,
|
|
924
|
+
blockedBy: "file_storage_attributes",
|
|
925
|
+
targetUnchanged: true
|
|
926
|
+
}
|
|
927
|
+
);
|
|
928
|
+
if (code === "filesystem_windows_policy_blocked")
|
|
929
|
+
return new FilesystemToolError(
|
|
930
|
+
code,
|
|
931
|
+
"Windows policy blocks the filesystem helper. No file operation ran. Retrying cannot resolve this restriction; ask the user to contact their administrator. Do not bypass the restriction.",
|
|
932
|
+
{
|
|
933
|
+
retryable: false,
|
|
934
|
+
blockedBy: "system_policy",
|
|
935
|
+
operationOutcome: "not_started"
|
|
936
|
+
}
|
|
937
|
+
);
|
|
938
|
+
if (code === "filesystem_windows_helper_unavailable")
|
|
939
|
+
return new FilesystemToolError(
|
|
940
|
+
code,
|
|
941
|
+
"The Windows filesystem helper is unavailable. No file operation ran. Do not retry in this request; the user must resolve helper availability first.",
|
|
942
|
+
{
|
|
943
|
+
retryable: false,
|
|
944
|
+
blockedBy: "helper_availability",
|
|
945
|
+
operationOutcome: "not_started"
|
|
946
|
+
}
|
|
947
|
+
);
|
|
948
|
+
return new FilesystemToolError(
|
|
949
|
+
code,
|
|
950
|
+
mutation ? "The filesystem helper did not report a completed operation. The file state is unknown; do not repeat the write automatically." : "The Windows filesystem helper did not complete the read.",
|
|
951
|
+
{
|
|
952
|
+
retryable: false,
|
|
953
|
+
operationOutcome: mutation ? "unknown" : "not_started"
|
|
954
|
+
}
|
|
955
|
+
);
|
|
956
|
+
}
|
|
957
|
+
async function runWindowsFilesystem(request, signal, spawnProcess = import_node_child_process.spawn) {
|
|
958
|
+
const mutation = request.operation === "write";
|
|
959
|
+
if (signal?.aborted)
|
|
960
|
+
throw helperFailure("filesystem_windows_interrupted", false);
|
|
961
|
+
const input = JSON.stringify({
|
|
962
|
+
source: WINDOWS_FILESYSTEM_SOURCE,
|
|
963
|
+
request: JSON.stringify(request)
|
|
964
|
+
});
|
|
965
|
+
if (Buffer.byteLength(input) > MAX_MESSAGE_BYTES)
|
|
966
|
+
throw new FilesystemToolError(
|
|
967
|
+
"filesystem_invalid_request",
|
|
968
|
+
"Filesystem helper input exceeds its byte limit."
|
|
969
|
+
);
|
|
970
|
+
const executable = (0, import_node_path.join)(
|
|
971
|
+
process.env.SystemRoot ?? "C:\\Windows",
|
|
972
|
+
"System32",
|
|
973
|
+
"WindowsPowerShell",
|
|
974
|
+
"v1.0",
|
|
975
|
+
"powershell.exe"
|
|
976
|
+
);
|
|
977
|
+
const raw = await new Promise((resolve, reject) => {
|
|
978
|
+
const child = spawnProcess(
|
|
979
|
+
executable,
|
|
980
|
+
["-NoLogo", "-NoProfile", "-NonInteractive", "-Command", BOOTSTRAP],
|
|
981
|
+
{ windowsHide: true, stdio: ["pipe", "pipe", "pipe"] }
|
|
982
|
+
);
|
|
983
|
+
const chunks = [];
|
|
984
|
+
let bytes = 0;
|
|
985
|
+
let failure;
|
|
986
|
+
const stop = (code2) => {
|
|
987
|
+
failure ??= helperFailure(code2, mutation);
|
|
988
|
+
child.kill("SIGKILL");
|
|
989
|
+
};
|
|
990
|
+
const abort = () => stop("filesystem_windows_interrupted");
|
|
991
|
+
const timer = setTimeout(() => stop("filesystem_windows_timeout"), 15e3);
|
|
992
|
+
timer.unref();
|
|
993
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
994
|
+
child.stdout.on("data", (chunk) => {
|
|
995
|
+
bytes += chunk.length;
|
|
996
|
+
if (bytes > MAX_MESSAGE_BYTES) {
|
|
997
|
+
stop("filesystem_windows_output_limit");
|
|
998
|
+
return;
|
|
999
|
+
}
|
|
1000
|
+
chunks.push(chunk);
|
|
1001
|
+
});
|
|
1002
|
+
child.stderr.resume();
|
|
1003
|
+
child.stdin.on("error", () => stop("filesystem_windows_transport_failed"));
|
|
1004
|
+
child.once("error", () => {
|
|
1005
|
+
failure ??= child.pid === void 0 ? helperFailure("filesystem_windows_helper_unavailable", false) : helperFailure("filesystem_windows_transport_failed", mutation);
|
|
1006
|
+
});
|
|
1007
|
+
child.once("close", (code2) => {
|
|
1008
|
+
clearTimeout(timer);
|
|
1009
|
+
signal?.removeEventListener("abort", abort);
|
|
1010
|
+
if (failure) {
|
|
1011
|
+
reject(failure);
|
|
1012
|
+
return;
|
|
1013
|
+
}
|
|
1014
|
+
if (code2 !== 0) {
|
|
1015
|
+
reject(helperFailure("filesystem_windows_transport_failed", mutation));
|
|
1016
|
+
return;
|
|
1017
|
+
}
|
|
1018
|
+
resolve(Buffer.concat(chunks).toString("utf8"));
|
|
1019
|
+
});
|
|
1020
|
+
if (signal?.aborted) {
|
|
1021
|
+
abort();
|
|
1022
|
+
return;
|
|
1023
|
+
}
|
|
1024
|
+
child.stdin.end(input, "utf8");
|
|
1025
|
+
});
|
|
1026
|
+
let envelope;
|
|
1027
|
+
try {
|
|
1028
|
+
envelope = JSON.parse(raw);
|
|
1029
|
+
} catch {
|
|
1030
|
+
throw helperFailure("filesystem_windows_response_invalid", mutation);
|
|
1031
|
+
}
|
|
1032
|
+
if (envelope?.ok === true) return envelope.result;
|
|
1033
|
+
const code = typeof envelope?.code === "string" ? envelope.code : "";
|
|
1034
|
+
if (!NATIVE_CODES.has(code))
|
|
1035
|
+
throw helperFailure("filesystem_windows_response_invalid", mutation);
|
|
1036
|
+
if (isDirectoryTypeFailure(code)) failNotDirectory();
|
|
1037
|
+
if (code === "filesystem_storage_attributes_unsupported" || code === "filesystem_named_streams_unsupported")
|
|
1038
|
+
throw helperFailure(code, mutation);
|
|
1039
|
+
if (code.startsWith("filesystem_windows_")) throw helperFailure(code, false);
|
|
1040
|
+
throw new FilesystemToolError(
|
|
1041
|
+
code,
|
|
1042
|
+
"The filesystem operation was rejected: " + code + "."
|
|
1043
|
+
);
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
// plugins/filesystem/source/windows/request-availability.ts
|
|
1047
|
+
var currentRequest = new import_node_async_hooks.AsyncLocalStorage();
|
|
1048
|
+
async function executeWindowsFilesystem(request) {
|
|
1049
|
+
const scope = currentRequest.getStore();
|
|
1050
|
+
if (scope?.availability.blocked) throw scope.availability.blocked;
|
|
1051
|
+
try {
|
|
1052
|
+
return await runWindowsFilesystem(request, scope?.signal);
|
|
1053
|
+
} catch (error) {
|
|
1054
|
+
if (scope && isWindowsHelperBlocked(error))
|
|
1055
|
+
scope.availability.blocked = error;
|
|
1056
|
+
throw error;
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
var prepareFilesystemRequest = async (modules) => {
|
|
1060
|
+
if (process.platform !== "win32" || modules.length === 0) return modules;
|
|
1061
|
+
try {
|
|
1062
|
+
const result = await runWindowsFilesystem({ operation: "probe" });
|
|
1063
|
+
if (!result || typeof result !== "object" || !("available" in result) || result.available !== true)
|
|
1064
|
+
return Object.freeze([]);
|
|
1065
|
+
} catch {
|
|
1066
|
+
return Object.freeze([]);
|
|
1067
|
+
}
|
|
1068
|
+
const availability = {};
|
|
1069
|
+
return Object.freeze(
|
|
1070
|
+
modules.map((module2) => ({
|
|
1071
|
+
...module2,
|
|
1072
|
+
implementation: (params, context) => {
|
|
1073
|
+
if (availability.blocked)
|
|
1074
|
+
return Promise.resolve(
|
|
1075
|
+
failureResult({
|
|
1076
|
+
errorCode: availability.blocked.code,
|
|
1077
|
+
message: availability.blocked.message,
|
|
1078
|
+
data: availability.blocked.data
|
|
1079
|
+
})
|
|
1080
|
+
);
|
|
1081
|
+
return currentRequest.run(
|
|
1082
|
+
{ availability, signal: context?.abortSignal },
|
|
1083
|
+
() => module2.implementation(params, context)
|
|
1084
|
+
);
|
|
1085
|
+
}
|
|
1086
|
+
}))
|
|
1087
|
+
);
|
|
1088
|
+
};
|
|
1089
|
+
|
|
273
1090
|
// plugins/filesystem/source/adapters.ts
|
|
274
1091
|
function invalidStrings(params, names) {
|
|
275
1092
|
return names.filter((name) => {
|
|
@@ -295,70 +1112,288 @@ var writeFileAdapter = Object.freeze({
|
|
|
295
1112
|
repairHint: "Set path to exactly one non-empty logical target path."
|
|
296
1113
|
};
|
|
297
1114
|
}
|
|
298
|
-
if (target.split("|").filter((part) => part.trim()).length > 1) {
|
|
299
|
-
return {
|
|
300
|
-
error: "single_target_path_required",
|
|
301
|
-
repairHint: "Set path to exactly one target. Invoke write_file separately for each file."
|
|
302
|
-
};
|
|
1115
|
+
if (target.split("|").filter((part) => part.trim()).length > 1) {
|
|
1116
|
+
return {
|
|
1117
|
+
error: "single_target_path_required",
|
|
1118
|
+
repairHint: "Set path to exactly one target. Invoke write_file separately for each file."
|
|
1119
|
+
};
|
|
1120
|
+
}
|
|
1121
|
+
return null;
|
|
1122
|
+
}
|
|
1123
|
+
});
|
|
1124
|
+
|
|
1125
|
+
// plugins/filesystem/source/dev-view.ts
|
|
1126
|
+
var import_promises4 = require("node:fs/promises");
|
|
1127
|
+
|
|
1128
|
+
// plugins/filesystem/source/bounded-io.ts
|
|
1129
|
+
var import_node_crypto = require("node:crypto");
|
|
1130
|
+
var import_node_string_decoder = require("node:string_decoder");
|
|
1131
|
+
var import_node_util = require("node:util");
|
|
1132
|
+
|
|
1133
|
+
// plugins/filesystem/source/file-observation.ts
|
|
1134
|
+
var import_node_fs = require("node:fs");
|
|
1135
|
+
var import_promises2 = require("node:fs/promises");
|
|
1136
|
+
var import_node_path3 = require("node:path");
|
|
1137
|
+
|
|
1138
|
+
// plugins/filesystem/source/file-version.ts
|
|
1139
|
+
function metadataFromStat(info, logicalPath) {
|
|
1140
|
+
if (info.size > BigInt(Number.MAX_SAFE_INTEGER))
|
|
1141
|
+
fail("file_too_large", `File is too large to read safely: ${logicalPath}`);
|
|
1142
|
+
return Object.freeze({
|
|
1143
|
+
device: info.dev,
|
|
1144
|
+
inode: info.ino,
|
|
1145
|
+
size: Number(info.size),
|
|
1146
|
+
mode: Number(info.mode) & 4095,
|
|
1147
|
+
modifiedNs: info.mtimeNs,
|
|
1148
|
+
changedNs: info.ctimeNs
|
|
1149
|
+
});
|
|
1150
|
+
}
|
|
1151
|
+
function sameMetadata(left, right) {
|
|
1152
|
+
return left.device === right.device && left.inode === right.inode && left.size === right.size && left.mode === right.mode && left.modifiedNs === right.modifiedNs && left.changedNs === right.changedNs;
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
// plugins/filesystem/source/windows/operations.ts
|
|
1156
|
+
var import_promises = require("node:fs/promises");
|
|
1157
|
+
var import_node_path2 = require("node:path");
|
|
1158
|
+
async function withTarget(target, run) {
|
|
1159
|
+
const expectedPath = import_node_path2.win32.resolve(target.rootPath, target.relativePath);
|
|
1160
|
+
if (import_node_path2.win32.relative(expectedPath, target.absolutePath) !== "")
|
|
1161
|
+
fail(
|
|
1162
|
+
"filesystem_path_changed",
|
|
1163
|
+
"The resolved file target no longer matches its root."
|
|
1164
|
+
);
|
|
1165
|
+
const relative4 = import_node_path2.win32.relative(target.rootPath, expectedPath);
|
|
1166
|
+
if (import_node_path2.win32.isAbsolute(relative4) || relative4 === ".." || relative4.startsWith("..\\"))
|
|
1167
|
+
fail(
|
|
1168
|
+
"filesystem_path_changed",
|
|
1169
|
+
"The file target is outside its configured root."
|
|
1170
|
+
);
|
|
1171
|
+
let root;
|
|
1172
|
+
try {
|
|
1173
|
+
root = await (0, import_promises.open)(target.rootPath, "r");
|
|
1174
|
+
const identity = await root.stat({ bigint: true });
|
|
1175
|
+
if (!identity.isDirectory())
|
|
1176
|
+
fail("not_a_directory", "The configured root is not a directory.");
|
|
1177
|
+
if (identity.ino <= 0n)
|
|
1178
|
+
fail(
|
|
1179
|
+
"filesystem_safe_io_unsupported",
|
|
1180
|
+
"The configured filesystem does not provide a stable file identity."
|
|
1181
|
+
);
|
|
1182
|
+
return await run(
|
|
1183
|
+
{
|
|
1184
|
+
rootPath: target.rootPath,
|
|
1185
|
+
relativePath: target.relativePath,
|
|
1186
|
+
rootIdentity: {
|
|
1187
|
+
device: String(identity.dev),
|
|
1188
|
+
inode: String(identity.ino),
|
|
1189
|
+
birthtimeNs: String(identity.birthtimeNs)
|
|
1190
|
+
}
|
|
1191
|
+
},
|
|
1192
|
+
root
|
|
1193
|
+
);
|
|
1194
|
+
} catch (error) {
|
|
1195
|
+
return rethrowFilesystemError(error, "inspect", target.logicalPath);
|
|
1196
|
+
} finally {
|
|
1197
|
+
await root?.close().catch(() => void 0);
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
function decodeMetadata(value) {
|
|
1201
|
+
const validSize = Number.isSafeInteger(value?.size) && value.size >= 0;
|
|
1202
|
+
if (!validSize || !Number.isSafeInteger(value?.mode))
|
|
1203
|
+
fail(
|
|
1204
|
+
"filesystem_windows_response_invalid",
|
|
1205
|
+
"The filesystem helper returned invalid file metadata."
|
|
1206
|
+
);
|
|
1207
|
+
const fields = [value.device, value.inode, value.modifiedNs, value.changedNs];
|
|
1208
|
+
if (!fields.every(
|
|
1209
|
+
(field) => typeof field === "string" && /^-?\d{1,30}$/u.test(field)
|
|
1210
|
+
))
|
|
1211
|
+
fail(
|
|
1212
|
+
"filesystem_windows_response_invalid",
|
|
1213
|
+
"The filesystem helper returned invalid file identity."
|
|
1214
|
+
);
|
|
1215
|
+
return Object.freeze({
|
|
1216
|
+
device: BigInt(value.device),
|
|
1217
|
+
inode: BigInt(value.inode),
|
|
1218
|
+
size: value.size,
|
|
1219
|
+
mode: value.mode,
|
|
1220
|
+
modifiedNs: BigInt(value.modifiedNs),
|
|
1221
|
+
changedNs: BigInt(value.changedNs)
|
|
1222
|
+
});
|
|
1223
|
+
}
|
|
1224
|
+
async function readWindowsFileSlices(target, options) {
|
|
1225
|
+
return withTarget(target, async (request) => {
|
|
1226
|
+
const result = await executeWindowsFilesystem({
|
|
1227
|
+
...request,
|
|
1228
|
+
operation: "read",
|
|
1229
|
+
...options,
|
|
1230
|
+
maximumFileBytes: options.maximumFileBytes ?? 0
|
|
1231
|
+
});
|
|
1232
|
+
const metadata = decodeMetadata(result?.metadata);
|
|
1233
|
+
if (typeof result.head !== "string" || typeof result.tail !== "string")
|
|
1234
|
+
fail(
|
|
1235
|
+
"filesystem_windows_response_invalid",
|
|
1236
|
+
"The filesystem helper returned invalid file bytes."
|
|
1237
|
+
);
|
|
1238
|
+
const head = Buffer.from(result.head, "base64"), tail = Buffer.from(result.tail, "base64");
|
|
1239
|
+
const complete = metadata.size <= options.headBytes + options.tailBytes;
|
|
1240
|
+
const expectedHead = complete ? metadata.size : options.headBytes;
|
|
1241
|
+
const expectedTail = complete ? 0 : options.tailBytes;
|
|
1242
|
+
if (head.length !== expectedHead || tail.length !== expectedTail)
|
|
1243
|
+
fail(
|
|
1244
|
+
"filesystem_read_incomplete",
|
|
1245
|
+
"The filesystem helper returned incomplete file bytes."
|
|
1246
|
+
);
|
|
1247
|
+
return Object.freeze({ metadata, head, tail });
|
|
1248
|
+
});
|
|
1249
|
+
}
|
|
1250
|
+
async function sampleWindowsDirectory(target, maxEntries) {
|
|
1251
|
+
return withTarget(target, async (request) => {
|
|
1252
|
+
const result = await executeWindowsFilesystem({
|
|
1253
|
+
...request,
|
|
1254
|
+
operation: "sample",
|
|
1255
|
+
maxEntries
|
|
1256
|
+
});
|
|
1257
|
+
if (!Array.isArray(result?.entries) || result.entries.length > maxEntries || !result.entries.every((entry) => typeof entry === "string") || typeof result.truncated !== "boolean")
|
|
1258
|
+
fail(
|
|
1259
|
+
"filesystem_windows_response_invalid",
|
|
1260
|
+
"The filesystem helper returned an invalid directory sample."
|
|
1261
|
+
);
|
|
1262
|
+
return Object.freeze({
|
|
1263
|
+
entries: Object.freeze(result.entries.sort((a, b) => a.localeCompare(b))),
|
|
1264
|
+
truncated: result.truncated
|
|
1265
|
+
});
|
|
1266
|
+
});
|
|
1267
|
+
}
|
|
1268
|
+
async function writeWindowsFile(input) {
|
|
1269
|
+
await withTarget(input.target, async (request, root) => {
|
|
1270
|
+
const expected = Object.fromEntries(
|
|
1271
|
+
Object.entries(input.expectedVersion).map(([key, value]) => [
|
|
1272
|
+
key,
|
|
1273
|
+
typeof value === "bigint" ? String(value) : value
|
|
1274
|
+
])
|
|
1275
|
+
);
|
|
1276
|
+
const result = await executeWindowsFilesystem({
|
|
1277
|
+
...request,
|
|
1278
|
+
operation: "write",
|
|
1279
|
+
content: Buffer.from(input.content, "utf8").toString("base64"),
|
|
1280
|
+
expected
|
|
1281
|
+
});
|
|
1282
|
+
if (result?.committed !== true)
|
|
1283
|
+
fail(
|
|
1284
|
+
"filesystem_windows_response_invalid",
|
|
1285
|
+
"The filesystem helper did not confirm the write; do not repeat it automatically."
|
|
1286
|
+
);
|
|
1287
|
+
try {
|
|
1288
|
+
input.onCommitted?.(root);
|
|
1289
|
+
} catch {
|
|
1290
|
+
}
|
|
1291
|
+
});
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
// plugins/filesystem/source/file-observation.ts
|
|
1295
|
+
async function readExactBytes(reader, buffer, position, logicalPath) {
|
|
1296
|
+
let offset = 0;
|
|
1297
|
+
while (offset < buffer.length) {
|
|
1298
|
+
const result = await reader.read(
|
|
1299
|
+
buffer,
|
|
1300
|
+
offset,
|
|
1301
|
+
buffer.length - offset,
|
|
1302
|
+
position + offset
|
|
1303
|
+
);
|
|
1304
|
+
if (result.bytesRead <= 0 || result.bytesRead > buffer.length - offset) {
|
|
1305
|
+
fail(
|
|
1306
|
+
"filesystem_read_incomplete",
|
|
1307
|
+
`File changed or ended before a complete read: ${logicalPath}`
|
|
1308
|
+
);
|
|
1309
|
+
}
|
|
1310
|
+
offset += result.bytesRead;
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
async function openRegularFile(target) {
|
|
1314
|
+
let handle;
|
|
1315
|
+
try {
|
|
1316
|
+
if (typeof import_node_fs.constants.O_NOFOLLOW !== "number") {
|
|
1317
|
+
fail(
|
|
1318
|
+
"filesystem_safe_io_unsupported",
|
|
1319
|
+
"This platform does not provide the no-follow operation required for a safe read."
|
|
1320
|
+
);
|
|
1321
|
+
}
|
|
1322
|
+
handle = await (0, import_promises2.open)(
|
|
1323
|
+
target.absolutePath,
|
|
1324
|
+
import_node_fs.constants.O_RDONLY | import_node_fs.constants.O_NOFOLLOW
|
|
1325
|
+
);
|
|
1326
|
+
const info = await handle.stat({ bigint: true });
|
|
1327
|
+
if (!info.isFile()) {
|
|
1328
|
+
fail("not_a_file", `Expected a regular file: ${target.logicalPath}`);
|
|
1329
|
+
}
|
|
1330
|
+
const metadata = metadataFromStat(info, target.logicalPath);
|
|
1331
|
+
const [canonicalRoot, canonicalTarget] = await Promise.all([
|
|
1332
|
+
(0, import_promises2.realpath)(target.rootPath),
|
|
1333
|
+
(0, import_promises2.realpath)(target.absolutePath)
|
|
1334
|
+
]);
|
|
1335
|
+
const rootRelative = (0, import_node_path3.relative)(canonicalRoot, canonicalTarget);
|
|
1336
|
+
if (rootRelative === ".." || rootRelative.startsWith(`..${import_node_path3.sep}`) || rootRelative.startsWith(import_node_path3.sep)) {
|
|
1337
|
+
fail(
|
|
1338
|
+
"filesystem_path_changed",
|
|
1339
|
+
`File changed outside its configured root: ${target.logicalPath}`
|
|
1340
|
+
);
|
|
303
1341
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
var import_node_path3 = require("node:path");
|
|
316
|
-
var import_node_string_decoder = require("node:string_decoder");
|
|
317
|
-
var import_node_util = require("node:util");
|
|
318
|
-
|
|
319
|
-
// plugins/filesystem/source/errors.ts
|
|
320
|
-
var FilesystemToolError = class extends Error {
|
|
321
|
-
code;
|
|
322
|
-
data;
|
|
323
|
-
constructor(code, message = code, data) {
|
|
324
|
-
super(message);
|
|
325
|
-
this.name = "FilesystemToolError";
|
|
326
|
-
this.code = code;
|
|
327
|
-
this.data = data;
|
|
1342
|
+
const pathIdentity = await (0, import_promises2.stat)(canonicalTarget, { bigint: true });
|
|
1343
|
+
if (!pathIdentity.isFile() || pathIdentity.dev !== info.dev || pathIdentity.ino !== info.ino) {
|
|
1344
|
+
fail(
|
|
1345
|
+
"filesystem_path_changed",
|
|
1346
|
+
`File changed while it was being opened: ${target.logicalPath}`
|
|
1347
|
+
);
|
|
1348
|
+
}
|
|
1349
|
+
return Object.freeze({ handle, size: metadata.size, metadata });
|
|
1350
|
+
} catch (error) {
|
|
1351
|
+
await handle?.close().catch(() => void 0);
|
|
1352
|
+
rethrowFilesystemError(error, "inspect", target.logicalPath);
|
|
328
1353
|
}
|
|
329
|
-
};
|
|
330
|
-
function fail(code, message = code, data) {
|
|
331
|
-
throw new FilesystemToolError(code, message, data);
|
|
332
1354
|
}
|
|
333
|
-
function
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
1355
|
+
async function observeFileSlices(target, options) {
|
|
1356
|
+
if (process.platform === "win32")
|
|
1357
|
+
return readWindowsFileSlices(target, options);
|
|
1358
|
+
const file = await openRegularFile(target);
|
|
1359
|
+
try {
|
|
1360
|
+
if (options.maximumFileBytes !== void 0 && file.size > options.maximumFileBytes)
|
|
1361
|
+
fail(
|
|
1362
|
+
"file_too_large",
|
|
1363
|
+
`File exceeds the mutation byte limit: ${target.logicalPath}`,
|
|
1364
|
+
{ byteCount: file.size, maxBytes: options.maximumFileBytes }
|
|
1365
|
+
);
|
|
1366
|
+
const complete = file.size <= options.headBytes + options.tailBytes;
|
|
1367
|
+
const head = Buffer.alloc(complete ? file.size : options.headBytes);
|
|
1368
|
+
const tail = Buffer.alloc(complete ? 0 : options.tailBytes);
|
|
1369
|
+
await readExactBytes(file.handle, head, 0, target.logicalPath);
|
|
1370
|
+
await readExactBytes(
|
|
1371
|
+
file.handle,
|
|
1372
|
+
tail,
|
|
1373
|
+
file.size - tail.length,
|
|
1374
|
+
target.logicalPath
|
|
347
1375
|
);
|
|
1376
|
+
const after = metadataFromStat(
|
|
1377
|
+
await file.handle.stat({ bigint: true }),
|
|
1378
|
+
target.logicalPath
|
|
1379
|
+
);
|
|
1380
|
+
if (!sameMetadata(file.metadata, after))
|
|
1381
|
+
fail(
|
|
1382
|
+
"filesystem_read_changed",
|
|
1383
|
+
`File changed while it was being read: ${target.logicalPath}`
|
|
1384
|
+
);
|
|
1385
|
+
return Object.freeze({ metadata: file.metadata, head, tail });
|
|
1386
|
+
} catch (error) {
|
|
1387
|
+
return rethrowFilesystemError(error, "read", target.logicalPath);
|
|
1388
|
+
} finally {
|
|
1389
|
+
await file.handle.close().catch(() => void 0);
|
|
348
1390
|
}
|
|
349
|
-
if (isNodeErrorCode(error, "EISDIR")) {
|
|
350
|
-
fail("not_a_file", `Expected a regular file: ${logicalPath}`);
|
|
351
|
-
}
|
|
352
|
-
fail(
|
|
353
|
-
`filesystem_${operation}_failed`,
|
|
354
|
-
`Filesystem ${operation} failed for ${logicalPath}.`
|
|
355
|
-
);
|
|
356
1391
|
}
|
|
357
1392
|
|
|
358
1393
|
// plugins/filesystem/source/directory-sample.ts
|
|
359
|
-
var
|
|
360
|
-
var
|
|
361
|
-
var
|
|
1394
|
+
var import_node_fs2 = require("node:fs");
|
|
1395
|
+
var import_promises3 = require("node:fs/promises");
|
|
1396
|
+
var import_node_path5 = require("node:path");
|
|
362
1397
|
|
|
363
1398
|
// src/shared/directory-authority/bootstrap.ts
|
|
364
1399
|
function directoryAuthorityBootstrap(mode, messageLimit, task) {
|
|
@@ -433,9 +1468,9 @@ function directoryAuthorityBootstrap(mode, messageLimit, task) {
|
|
|
433
1468
|
writeResponse(1, encoded);
|
|
434
1469
|
}
|
|
435
1470
|
function runCommand(input) {
|
|
436
|
-
const { spawn:
|
|
1471
|
+
const { spawn: spawn3 } = require("node:child_process");
|
|
437
1472
|
const command = input;
|
|
438
|
-
const child =
|
|
1473
|
+
const child = spawn3(command.command, command.args, {
|
|
439
1474
|
stdio: ["ignore", "inherit", "inherit"],
|
|
440
1475
|
env: process.env
|
|
441
1476
|
});
|
|
@@ -467,7 +1502,7 @@ function directoryAuthorityScript(mode, messageLimit, task) {
|
|
|
467
1502
|
}
|
|
468
1503
|
|
|
469
1504
|
// src/shared/directory-authority/protocol.ts
|
|
470
|
-
var
|
|
1505
|
+
var import_node_path4 = require("node:path");
|
|
471
1506
|
|
|
472
1507
|
// src/shared/directory-authority/errors.ts
|
|
473
1508
|
var DirectoryAuthorityError = class extends Error {
|
|
@@ -486,7 +1521,7 @@ var AUTHORITY_MESSAGE_LIMIT = 8 * 1024 * 1024;
|
|
|
486
1521
|
var AUTHORITY_STDERR_LIMIT = 16 * 1024;
|
|
487
1522
|
var AUTHORITY_TASK_TIMEOUT_MS = 3e4;
|
|
488
1523
|
function assertDirectoryAuthorityLocation(location) {
|
|
489
|
-
if (!(0,
|
|
1524
|
+
if (!(0, import_node_path4.isAbsolute)(location.directoryPath)) {
|
|
490
1525
|
throw new DirectoryAuthorityError(
|
|
491
1526
|
"directory_authority_invalid_path",
|
|
492
1527
|
"The directory authority requires an absolute starting path."
|
|
@@ -574,7 +1609,7 @@ function decodeAuthorityResult(output) {
|
|
|
574
1609
|
}
|
|
575
1610
|
|
|
576
1611
|
// src/shared/directory-authority/task.ts
|
|
577
|
-
var
|
|
1612
|
+
var import_node_child_process2 = require("node:child_process");
|
|
578
1613
|
async function runDirectoryAuthorityTask(input) {
|
|
579
1614
|
assertDirectoryAuthorityLocation(input);
|
|
580
1615
|
const request = encodeAuthorityRequest(input.input);
|
|
@@ -592,7 +1627,7 @@ async function runDirectoryAuthorityTask(input) {
|
|
|
592
1627
|
"The directory operation was cancelled before it started."
|
|
593
1628
|
);
|
|
594
1629
|
}
|
|
595
|
-
const child = (0,
|
|
1630
|
+
const child = (0, import_node_child_process2.spawn)(
|
|
596
1631
|
process.execPath,
|
|
597
1632
|
[
|
|
598
1633
|
"--input-type=commonjs",
|
|
@@ -721,35 +1756,36 @@ async function sampleDirectoryTask(input) {
|
|
|
721
1756
|
// plugins/filesystem/source/directory-sample.ts
|
|
722
1757
|
var DIRECTORY_ENTRY_LIMIT = 160;
|
|
723
1758
|
async function readDirectorySample(target) {
|
|
1759
|
+
if (process.platform === "win32") return sampleWindowsDirectory(target, DIRECTORY_ENTRY_LIMIT);
|
|
724
1760
|
const entries = [];
|
|
725
1761
|
let handle;
|
|
726
1762
|
try {
|
|
727
|
-
if (typeof
|
|
1763
|
+
if (typeof import_node_fs2.constants.O_DIRECTORY !== "number" || typeof import_node_fs2.constants.O_NOFOLLOW !== "number") {
|
|
728
1764
|
fail(
|
|
729
1765
|
"filesystem_safe_io_unsupported",
|
|
730
1766
|
"This platform does not provide the no-follow directory operation required for a safe read."
|
|
731
1767
|
);
|
|
732
1768
|
}
|
|
733
|
-
handle = await (0,
|
|
1769
|
+
handle = await (0, import_promises3.open)(
|
|
734
1770
|
target.absolutePath,
|
|
735
|
-
|
|
1771
|
+
import_node_fs2.constants.O_RDONLY | import_node_fs2.constants.O_DIRECTORY | import_node_fs2.constants.O_NOFOLLOW
|
|
736
1772
|
);
|
|
737
1773
|
const before = await handle.stat({ bigint: true });
|
|
738
1774
|
if (!before.isDirectory()) {
|
|
739
1775
|
fail("not_a_directory", `Expected a directory: ${target.logicalPath}`);
|
|
740
1776
|
}
|
|
741
1777
|
const [canonicalRoot, canonicalTarget] = await Promise.all([
|
|
742
|
-
(0,
|
|
743
|
-
(0,
|
|
1778
|
+
(0, import_promises3.realpath)(target.rootPath),
|
|
1779
|
+
(0, import_promises3.realpath)(target.absolutePath)
|
|
744
1780
|
]);
|
|
745
|
-
const rootRelative = (0,
|
|
746
|
-
if (rootRelative === ".." || rootRelative.startsWith(`..${
|
|
1781
|
+
const rootRelative = (0, import_node_path5.relative)(canonicalRoot, canonicalTarget);
|
|
1782
|
+
if (rootRelative === ".." || rootRelative.startsWith(`..${import_node_path5.sep}`) || rootRelative.startsWith(import_node_path5.sep)) {
|
|
747
1783
|
fail(
|
|
748
1784
|
"filesystem_path_changed",
|
|
749
1785
|
`Directory changed outside its configured root: ${target.logicalPath}`
|
|
750
1786
|
);
|
|
751
1787
|
}
|
|
752
|
-
const pathIdentity = await (0,
|
|
1788
|
+
const pathIdentity = await (0, import_promises3.stat)(canonicalTarget, { bigint: true });
|
|
753
1789
|
if (!pathIdentity.isDirectory() || pathIdentity.dev !== before.dev || pathIdentity.ino !== before.ino) {
|
|
754
1790
|
fail(
|
|
755
1791
|
"filesystem_path_changed",
|
|
@@ -766,7 +1802,7 @@ async function readDirectorySample(target) {
|
|
|
766
1802
|
await assertDirectoryStable(handle, before, target.logicalPath);
|
|
767
1803
|
return sample;
|
|
768
1804
|
}
|
|
769
|
-
const directory = await (0,
|
|
1805
|
+
const directory = await (0, import_promises3.opendir)(`/proc/self/fd/${handle.fd}`);
|
|
770
1806
|
for await (const entry of directory) {
|
|
771
1807
|
if (entries.length >= DIRECTORY_ENTRY_LIMIT) {
|
|
772
1808
|
await assertDirectoryStable(handle, before, target.logicalPath);
|
|
@@ -811,32 +1847,13 @@ var MAX_MUTATION_BYTES = 1048576;
|
|
|
811
1847
|
var READ_HEAD_BYTES = 24576;
|
|
812
1848
|
var READ_TAIL_BYTES = 12288;
|
|
813
1849
|
var DEV_SCAN_BYTES = 1048576;
|
|
814
|
-
async function readExactBytes(reader, buffer, position, logicalPath) {
|
|
815
|
-
let offset = 0;
|
|
816
|
-
while (offset < buffer.length) {
|
|
817
|
-
const result = await reader.read(
|
|
818
|
-
buffer,
|
|
819
|
-
offset,
|
|
820
|
-
buffer.length - offset,
|
|
821
|
-
position + offset
|
|
822
|
-
);
|
|
823
|
-
if (result.bytesRead <= 0 || result.bytesRead > buffer.length - offset) {
|
|
824
|
-
fail(
|
|
825
|
-
"filesystem_read_incomplete",
|
|
826
|
-
`File changed or ended before a complete read: ${logicalPath}`
|
|
827
|
-
);
|
|
828
|
-
}
|
|
829
|
-
offset += result.bytesRead;
|
|
830
|
-
}
|
|
831
|
-
}
|
|
832
1850
|
function decodeCompletePrefix(buffer) {
|
|
833
1851
|
return new import_node_string_decoder.StringDecoder("utf8").write(buffer);
|
|
834
1852
|
}
|
|
835
1853
|
function decodeSuffix(buffer) {
|
|
836
1854
|
let start = 0;
|
|
837
|
-
while (start < Math.min(4, buffer.length) && (buffer[start] & 192) === 128)
|
|
1855
|
+
while (start < Math.min(4, buffer.length) && (buffer[start] & 192) === 128)
|
|
838
1856
|
start += 1;
|
|
839
|
-
}
|
|
840
1857
|
return buffer.subarray(start).toString("utf8");
|
|
841
1858
|
}
|
|
842
1859
|
function decodeMutationText(buffer, logicalPath) {
|
|
@@ -849,194 +1866,88 @@ function decodeMutationText(buffer, logicalPath) {
|
|
|
849
1866
|
);
|
|
850
1867
|
}
|
|
851
1868
|
}
|
|
852
|
-
async function openRegularFile(target) {
|
|
853
|
-
let handle;
|
|
854
|
-
try {
|
|
855
|
-
if (typeof import_node_fs2.constants.O_NOFOLLOW !== "number") {
|
|
856
|
-
fail(
|
|
857
|
-
"filesystem_safe_io_unsupported",
|
|
858
|
-
"This platform does not provide the no-follow operation required for a safe read."
|
|
859
|
-
);
|
|
860
|
-
}
|
|
861
|
-
handle = await (0, import_promises2.open)(
|
|
862
|
-
target.absolutePath,
|
|
863
|
-
import_node_fs2.constants.O_RDONLY | import_node_fs2.constants.O_NOFOLLOW
|
|
864
|
-
);
|
|
865
|
-
const info = await handle.stat({ bigint: true });
|
|
866
|
-
if (!info.isFile()) {
|
|
867
|
-
fail("not_a_file", `Expected a regular file: ${target.logicalPath}`);
|
|
868
|
-
}
|
|
869
|
-
const metadata = metadataFromStat(info, target.logicalPath);
|
|
870
|
-
const [canonicalRoot, canonicalTarget] = await Promise.all([
|
|
871
|
-
(0, import_promises2.realpath)(target.rootPath),
|
|
872
|
-
(0, import_promises2.realpath)(target.absolutePath)
|
|
873
|
-
]);
|
|
874
|
-
const rootRelative = (0, import_node_path3.relative)(canonicalRoot, canonicalTarget);
|
|
875
|
-
if (rootRelative === ".." || rootRelative.startsWith(`..${import_node_path3.sep}`) || rootRelative.startsWith(import_node_path3.sep)) {
|
|
876
|
-
fail(
|
|
877
|
-
"filesystem_path_changed",
|
|
878
|
-
`File changed outside its configured root: ${target.logicalPath}`
|
|
879
|
-
);
|
|
880
|
-
}
|
|
881
|
-
const pathIdentity = await (0, import_promises2.stat)(canonicalTarget, { bigint: true });
|
|
882
|
-
if (!pathIdentity.isFile() || pathIdentity.dev !== info.dev || pathIdentity.ino !== info.ino) {
|
|
883
|
-
fail(
|
|
884
|
-
"filesystem_path_changed",
|
|
885
|
-
`File changed while it was being opened: ${target.logicalPath}`
|
|
886
|
-
);
|
|
887
|
-
}
|
|
888
|
-
return Object.freeze({ handle, size: metadata.size, metadata });
|
|
889
|
-
} catch (error) {
|
|
890
|
-
await handle?.close().catch(() => void 0);
|
|
891
|
-
rethrowFilesystemError(error, "inspect", target.logicalPath);
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
1869
|
async function readBoundedText(target, options = {}) {
|
|
895
|
-
const
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
await Promise.all([
|
|
916
|
-
readExactBytes(file.handle, head, 0, target.logicalPath),
|
|
917
|
-
readExactBytes(
|
|
918
|
-
file.handle,
|
|
919
|
-
tail,
|
|
920
|
-
Math.max(0, file.size - tailBytes),
|
|
921
|
-
target.logicalPath
|
|
922
|
-
)
|
|
923
|
-
]);
|
|
924
|
-
await assertFileStable(file, target.logicalPath);
|
|
925
|
-
rejectBinary(head, target.logicalPath);
|
|
926
|
-
rejectBinary(tail, target.logicalPath);
|
|
927
|
-
const omittedBytes = Math.max(0, file.size - head.length - tail.length);
|
|
928
|
-
return Object.freeze({
|
|
929
|
-
text: [
|
|
930
|
-
decodeCompletePrefix(head),
|
|
931
|
-
`[${omittedBytes} bytes omitted from the middle]`,
|
|
932
|
-
decodeSuffix(tail)
|
|
933
|
-
].join("\n"),
|
|
934
|
-
byteCount: file.size,
|
|
935
|
-
bytesRead: head.length + tail.length,
|
|
936
|
-
omittedBytes,
|
|
937
|
-
truncated: true
|
|
938
|
-
});
|
|
939
|
-
} catch (error) {
|
|
940
|
-
return rethrowFilesystemError(error, "read", target.logicalPath);
|
|
941
|
-
} finally {
|
|
942
|
-
await file.handle.close().catch(() => void 0);
|
|
943
|
-
}
|
|
1870
|
+
const observed = await observeFileSlices(target, {
|
|
1871
|
+
headBytes: options.headBytes ?? READ_HEAD_BYTES,
|
|
1872
|
+
tailBytes: options.tailBytes ?? READ_TAIL_BYTES
|
|
1873
|
+
});
|
|
1874
|
+
rejectBinary(observed.head, target.logicalPath);
|
|
1875
|
+
rejectBinary(observed.tail, target.logicalPath);
|
|
1876
|
+
const bytesRead = observed.head.length + observed.tail.length;
|
|
1877
|
+
const omittedBytes = observed.metadata.size - bytesRead;
|
|
1878
|
+
const text = omittedBytes === 0 ? decodeCompletePrefix(observed.head) : [
|
|
1879
|
+
decodeCompletePrefix(observed.head),
|
|
1880
|
+
`[${omittedBytes} bytes omitted from the middle]`,
|
|
1881
|
+
decodeSuffix(observed.tail)
|
|
1882
|
+
].join("\n");
|
|
1883
|
+
return Object.freeze({
|
|
1884
|
+
text,
|
|
1885
|
+
byteCount: observed.metadata.size,
|
|
1886
|
+
bytesRead,
|
|
1887
|
+
omittedBytes,
|
|
1888
|
+
truncated: omittedBytes > 0
|
|
1889
|
+
});
|
|
944
1890
|
}
|
|
945
1891
|
async function readPrefixText(target, maxBytes = DEV_SCAN_BYTES) {
|
|
946
|
-
const
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
truncated: length < file.size
|
|
959
|
-
});
|
|
960
|
-
} catch (error) {
|
|
961
|
-
rethrowFilesystemError(error, "read", target.logicalPath);
|
|
962
|
-
} finally {
|
|
963
|
-
await file.handle.close().catch(() => void 0);
|
|
964
|
-
}
|
|
1892
|
+
const observed = await observeFileSlices(target, {
|
|
1893
|
+
headBytes: maxBytes,
|
|
1894
|
+
tailBytes: 0
|
|
1895
|
+
});
|
|
1896
|
+
rejectBinary(observed.head, target.logicalPath);
|
|
1897
|
+
return Object.freeze({
|
|
1898
|
+
text: decodeCompletePrefix(observed.head),
|
|
1899
|
+
byteCount: observed.metadata.size,
|
|
1900
|
+
bytesRead: observed.head.length,
|
|
1901
|
+
omittedBytes: observed.metadata.size - observed.head.length,
|
|
1902
|
+
truncated: observed.head.length < observed.metadata.size
|
|
1903
|
+
});
|
|
965
1904
|
}
|
|
966
1905
|
async function readMutationSnapshot(target) {
|
|
967
|
-
let file;
|
|
968
1906
|
try {
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
{ byteCount, maxBytes: MAX_MUTATION_BYTES }
|
|
976
|
-
);
|
|
977
|
-
}
|
|
978
|
-
const buffer = Buffer.alloc(byteCount);
|
|
979
|
-
await readExactBytes(file.handle, buffer, 0, target.logicalPath);
|
|
980
|
-
const afterRead = metadataFromStat(
|
|
981
|
-
await file.handle.stat({ bigint: true }),
|
|
982
|
-
target.logicalPath
|
|
983
|
-
);
|
|
984
|
-
if (!sameMetadata(file.metadata, afterRead)) {
|
|
985
|
-
failTargetChanged(target.logicalPath, "file", "file");
|
|
986
|
-
}
|
|
987
|
-
rejectBinary(buffer, target.logicalPath);
|
|
1907
|
+
const observed = await observeFileSlices(target, {
|
|
1908
|
+
headBytes: MAX_MUTATION_BYTES,
|
|
1909
|
+
tailBytes: 0,
|
|
1910
|
+
maximumFileBytes: MAX_MUTATION_BYTES
|
|
1911
|
+
});
|
|
1912
|
+
rejectBinary(observed.head, target.logicalPath);
|
|
988
1913
|
return Object.freeze({
|
|
989
|
-
content: decodeMutationText(
|
|
1914
|
+
content: decodeMutationText(observed.head, target.logicalPath),
|
|
990
1915
|
version: Object.freeze({
|
|
991
1916
|
kind: "file",
|
|
992
|
-
...
|
|
993
|
-
digest: digest(
|
|
1917
|
+
...observed.metadata,
|
|
1918
|
+
digest: digest(observed.head)
|
|
994
1919
|
})
|
|
995
1920
|
});
|
|
996
1921
|
} catch (error) {
|
|
997
|
-
if (error instanceof FilesystemToolError && error.code === "file_not_found")
|
|
1922
|
+
if (error instanceof FilesystemToolError && error.code === "file_not_found")
|
|
998
1923
|
return Object.freeze({
|
|
999
1924
|
content: null,
|
|
1000
1925
|
version: Object.freeze({ kind: "absent" })
|
|
1001
1926
|
});
|
|
1002
|
-
|
|
1927
|
+
if (error instanceof FilesystemToolError && error.code === "filesystem_read_changed")
|
|
1928
|
+
failTargetChanged(target.logicalPath, "file", "file");
|
|
1003
1929
|
return rethrowFilesystemError(error, "read", target.logicalPath);
|
|
1004
|
-
} finally {
|
|
1005
|
-
await file?.handle.close().catch(() => void 0);
|
|
1006
1930
|
}
|
|
1007
1931
|
}
|
|
1008
1932
|
async function assertMutationTargetUnchanged(target, expected) {
|
|
1009
|
-
let
|
|
1933
|
+
let current;
|
|
1010
1934
|
try {
|
|
1011
|
-
|
|
1935
|
+
current = await readMutationSnapshot(target);
|
|
1012
1936
|
} catch (error) {
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1937
|
+
const changedContents = error instanceof FilesystemToolError && [
|
|
1938
|
+
"file_too_large",
|
|
1939
|
+
"binary_file_unsupported",
|
|
1940
|
+
"filesystem_invalid_encoding"
|
|
1941
|
+
].includes(error.code);
|
|
1942
|
+
if (changedContents)
|
|
1943
|
+
failTargetChanged(target.logicalPath, expected.kind, "file");
|
|
1017
1944
|
throw error;
|
|
1018
1945
|
}
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
failTargetChanged(target.logicalPath, "file", "file");
|
|
1025
|
-
}
|
|
1026
|
-
const buffer = Buffer.alloc(file.size);
|
|
1027
|
-
await readExactBytes(file.handle, buffer, 0, target.logicalPath);
|
|
1028
|
-
const afterRead = metadataFromStat(
|
|
1029
|
-
await file.handle.stat({ bigint: true }),
|
|
1030
|
-
target.logicalPath
|
|
1031
|
-
);
|
|
1032
|
-
if (!sameMetadata(file.metadata, afterRead) || digest(buffer) !== expected.digest) {
|
|
1033
|
-
failTargetChanged(target.logicalPath, "file", "file");
|
|
1034
|
-
}
|
|
1035
|
-
} catch (error) {
|
|
1036
|
-
return rethrowFilesystemError(error, "inspect", target.logicalPath);
|
|
1037
|
-
} finally {
|
|
1038
|
-
await file.handle.close().catch(() => void 0);
|
|
1039
|
-
}
|
|
1946
|
+
if (current.version.kind !== expected.kind)
|
|
1947
|
+
failTargetChanged(target.logicalPath, expected.kind, current.version.kind);
|
|
1948
|
+
if (current.version.kind === "absent" || expected.kind === "absent") return;
|
|
1949
|
+
if (!sameMetadata(expected, current.version) || expected.digest !== current.version.digest)
|
|
1950
|
+
failTargetChanged(target.logicalPath, "file", "file");
|
|
1040
1951
|
}
|
|
1041
1952
|
function assertMutationContentSize(content) {
|
|
1042
1953
|
const byteCount = Buffer.byteLength(content, "utf8");
|
|
@@ -1050,40 +1961,11 @@ function assertMutationContentSize(content) {
|
|
|
1050
1961
|
return byteCount;
|
|
1051
1962
|
}
|
|
1052
1963
|
function rejectBinary(buffer, logicalPath) {
|
|
1053
|
-
if (buffer.includes(0))
|
|
1964
|
+
if (buffer.includes(0))
|
|
1054
1965
|
fail(
|
|
1055
1966
|
"binary_file_unsupported",
|
|
1056
1967
|
`Binary file is not supported: ${logicalPath}`
|
|
1057
1968
|
);
|
|
1058
|
-
}
|
|
1059
|
-
}
|
|
1060
|
-
function metadataFromStat(info, logicalPath) {
|
|
1061
|
-
if (info.size > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
1062
|
-
fail("file_too_large", `File is too large to read safely: ${logicalPath}`);
|
|
1063
|
-
}
|
|
1064
|
-
return Object.freeze({
|
|
1065
|
-
device: info.dev,
|
|
1066
|
-
inode: info.ino,
|
|
1067
|
-
size: Number(info.size),
|
|
1068
|
-
mode: Number(info.mode) & 4095,
|
|
1069
|
-
modifiedNs: info.mtimeNs,
|
|
1070
|
-
changedNs: info.ctimeNs
|
|
1071
|
-
});
|
|
1072
|
-
}
|
|
1073
|
-
function sameMetadata(left, right) {
|
|
1074
|
-
return left.device === right.device && left.inode === right.inode && left.size === right.size && left.mode === right.mode && left.modifiedNs === right.modifiedNs && left.changedNs === right.changedNs;
|
|
1075
|
-
}
|
|
1076
|
-
async function assertFileStable(file, logicalPath) {
|
|
1077
|
-
const afterRead = metadataFromStat(
|
|
1078
|
-
await file.handle.stat({ bigint: true }),
|
|
1079
|
-
logicalPath
|
|
1080
|
-
);
|
|
1081
|
-
if (!sameMetadata(file.metadata, afterRead)) {
|
|
1082
|
-
fail(
|
|
1083
|
-
"filesystem_read_changed",
|
|
1084
|
-
`File changed while it was being read: ${logicalPath}`
|
|
1085
|
-
);
|
|
1086
|
-
}
|
|
1087
1969
|
}
|
|
1088
1970
|
function digest(buffer) {
|
|
1089
1971
|
return (0, import_node_crypto.createHash)("sha256").update(buffer).digest("hex");
|
|
@@ -1249,7 +2131,7 @@ function createDevViewHandler(paths) {
|
|
|
1249
2131
|
const target = paths.resolve(pathRange.path, context);
|
|
1250
2132
|
let info;
|
|
1251
2133
|
try {
|
|
1252
|
-
info = await (0,
|
|
2134
|
+
info = await (0, import_promises4.stat)(target.absolutePath);
|
|
1253
2135
|
} catch (error) {
|
|
1254
2136
|
rethrowFilesystemError(error, "inspect", target.logicalPath);
|
|
1255
2137
|
}
|
|
@@ -1449,16 +2331,16 @@ async function viewFile(input) {
|
|
|
1449
2331
|
|
|
1450
2332
|
// plugins/filesystem/source/atomic-write.ts
|
|
1451
2333
|
var import_node_crypto2 = require("node:crypto");
|
|
1452
|
-
var
|
|
1453
|
-
var
|
|
2334
|
+
var import_promises6 = require("node:fs/promises");
|
|
2335
|
+
var import_node_path7 = require("node:path");
|
|
1454
2336
|
|
|
1455
2337
|
// plugins/filesystem/source/mutation-parent.ts
|
|
1456
2338
|
var import_node_fs3 = require("node:fs");
|
|
1457
|
-
var
|
|
1458
|
-
var
|
|
2339
|
+
var import_promises5 = require("node:fs/promises");
|
|
2340
|
+
var import_node_path6 = require("node:path");
|
|
1459
2341
|
function isWithinRoot(target, root) {
|
|
1460
|
-
const rel = (0,
|
|
1461
|
-
return rel === "" || rel !== ".." && !rel.startsWith(`..${
|
|
2342
|
+
const rel = (0, import_node_path6.relative)(root, target);
|
|
2343
|
+
return rel === "" || rel !== ".." && !rel.startsWith(`..${import_node_path6.sep}`);
|
|
1462
2344
|
}
|
|
1463
2345
|
function sameIdentity(left, right) {
|
|
1464
2346
|
return left.dev === right.dev && left.ino === right.ino;
|
|
@@ -1472,7 +2354,7 @@ async function openDirectory(path, rootPath, logicalPath, allowMissing = false)
|
|
|
1472
2354
|
}
|
|
1473
2355
|
let handle;
|
|
1474
2356
|
try {
|
|
1475
|
-
handle = await (0,
|
|
2357
|
+
handle = await (0, import_promises5.open)(
|
|
1476
2358
|
path,
|
|
1477
2359
|
import_node_fs3.constants.O_RDONLY | import_node_fs3.constants.O_DIRECTORY | import_node_fs3.constants.O_NOFOLLOW
|
|
1478
2360
|
);
|
|
@@ -1481,8 +2363,8 @@ async function openDirectory(path, rootPath, logicalPath, allowMissing = false)
|
|
|
1481
2363
|
fail("not_a_directory", `Expected a directory: ${logicalPath}`);
|
|
1482
2364
|
}
|
|
1483
2365
|
const [canonicalRoot, canonicalDirectory] = await Promise.all([
|
|
1484
|
-
(0,
|
|
1485
|
-
(0,
|
|
2366
|
+
(0, import_promises5.realpath)(rootPath),
|
|
2367
|
+
(0, import_promises5.realpath)(path)
|
|
1486
2368
|
]);
|
|
1487
2369
|
if (!isWithinRoot(canonicalDirectory, canonicalRoot)) {
|
|
1488
2370
|
fail(
|
|
@@ -1490,7 +2372,7 @@ async function openDirectory(path, rootPath, logicalPath, allowMissing = false)
|
|
|
1490
2372
|
`Directory changed outside its configured root: ${logicalPath}`
|
|
1491
2373
|
);
|
|
1492
2374
|
}
|
|
1493
|
-
const pathIdentity = await (0,
|
|
2375
|
+
const pathIdentity = await (0, import_promises5.stat)(canonicalDirectory, { bigint: true });
|
|
1494
2376
|
if (!pathIdentity.isDirectory() || !sameIdentity(opened, pathIdentity)) {
|
|
1495
2377
|
fail(
|
|
1496
2378
|
"filesystem_path_changed",
|
|
@@ -1499,7 +2381,7 @@ async function openDirectory(path, rootPath, logicalPath, allowMissing = false)
|
|
|
1499
2381
|
}
|
|
1500
2382
|
if (usesIsolatedDirectoryAuthority()) return handle;
|
|
1501
2383
|
const procPath = `/proc/self/fd/${handle.fd}`;
|
|
1502
|
-
const procIdentity = await (0,
|
|
2384
|
+
const procIdentity = await (0, import_promises5.stat)(procPath, { bigint: true });
|
|
1503
2385
|
if (!procIdentity.isDirectory() || !sameIdentity(opened, procIdentity)) {
|
|
1504
2386
|
fail(
|
|
1505
2387
|
"filesystem_safe_io_unsupported",
|
|
@@ -1526,7 +2408,7 @@ async function openChildDirectory(parent, name, logicalPath) {
|
|
|
1526
2408
|
if (!isNodeErrorCode(error, "ENOENT")) throw error;
|
|
1527
2409
|
}
|
|
1528
2410
|
try {
|
|
1529
|
-
await (0,
|
|
2411
|
+
await (0, import_promises5.mkdir)(anchoredPath);
|
|
1530
2412
|
} catch (error) {
|
|
1531
2413
|
if (!isNodeErrorCode(error, "EEXIST")) {
|
|
1532
2414
|
rethrowFilesystemError(error, "write", logicalPath);
|
|
@@ -1791,6 +2673,7 @@ async function writeWithDirectoryAuthority(input) {
|
|
|
1791
2673
|
// plugins/filesystem/source/atomic-write.ts
|
|
1792
2674
|
async function atomicWriteText(input) {
|
|
1793
2675
|
assertMutationContentSize(input.content);
|
|
2676
|
+
if (process.platform === "win32") return writeWindowsFile(input);
|
|
1794
2677
|
if (requiresIsolatedDirectoryAuthority()) {
|
|
1795
2678
|
await writeWithDirectoryAuthority(input);
|
|
1796
2679
|
return;
|
|
@@ -1803,12 +2686,12 @@ async function atomicWriteText(input) {
|
|
|
1803
2686
|
absolutePath: targetPath,
|
|
1804
2687
|
relativePath: parent.targetName
|
|
1805
2688
|
});
|
|
1806
|
-
const temporaryName = `.abot-${
|
|
2689
|
+
const temporaryName = `.abot-${import_node_path7.posix.basename(parent.targetName)}-${(0, import_node_crypto2.randomUUID)()}.tmp`;
|
|
1807
2690
|
const temporaryPath = `${parent.procPath}/${temporaryName}`;
|
|
1808
2691
|
const existingMode = input.expectedVersion.kind === "file" ? input.expectedVersion.mode : void 0;
|
|
1809
2692
|
let temporaryCreated = false;
|
|
1810
2693
|
try {
|
|
1811
|
-
const temporaryHandle = await (0,
|
|
2694
|
+
const temporaryHandle = await (0, import_promises6.open)(temporaryPath, "wx");
|
|
1812
2695
|
temporaryCreated = true;
|
|
1813
2696
|
try {
|
|
1814
2697
|
await temporaryHandle.writeFile(input.content, "utf8");
|
|
@@ -1830,7 +2713,7 @@ async function atomicWriteText(input) {
|
|
|
1830
2713
|
if (input.expectedVersion.kind === "file") {
|
|
1831
2714
|
temporaryCreated = false;
|
|
1832
2715
|
} else {
|
|
1833
|
-
const removed = await (0,
|
|
2716
|
+
const removed = await (0, import_promises6.rm)(temporaryPath, { force: true }).then(() => true).catch(() => false);
|
|
1834
2717
|
temporaryCreated = !removed;
|
|
1835
2718
|
}
|
|
1836
2719
|
await syncDirectoryBestEffort(parent.handle);
|
|
@@ -1839,7 +2722,7 @@ async function atomicWriteText(input) {
|
|
|
1839
2722
|
rethrowFilesystemError(error, "write", input.target.logicalPath);
|
|
1840
2723
|
} finally {
|
|
1841
2724
|
if (temporaryCreated) {
|
|
1842
|
-
await (0,
|
|
2725
|
+
await (0, import_promises6.rm)(temporaryPath, { force: true }).catch(() => void 0);
|
|
1843
2726
|
}
|
|
1844
2727
|
await closeMutationParent(parent);
|
|
1845
2728
|
}
|
|
@@ -1848,11 +2731,11 @@ async function installPreparedFile(input) {
|
|
|
1848
2731
|
const temporaryPath = `${input.parentProcPath}/${input.temporaryName}`;
|
|
1849
2732
|
const targetPath = `${input.parentProcPath}/${input.targetName}`;
|
|
1850
2733
|
if (input.expectedKind === "file") {
|
|
1851
|
-
await (0,
|
|
2734
|
+
await (0, import_promises6.rename)(temporaryPath, targetPath);
|
|
1852
2735
|
return;
|
|
1853
2736
|
}
|
|
1854
2737
|
try {
|
|
1855
|
-
await (0,
|
|
2738
|
+
await (0, import_promises6.link)(temporaryPath, targetPath);
|
|
1856
2739
|
} catch (error) {
|
|
1857
2740
|
if (isNodeErrorCode(error, "EEXIST")) {
|
|
1858
2741
|
fail(
|
|
@@ -1875,7 +2758,7 @@ function requiresIsolatedDirectoryAuthority() {
|
|
|
1875
2758
|
|
|
1876
2759
|
// plugins/filesystem/source/draft/grounding.ts
|
|
1877
2760
|
var import_node_crypto3 = require("node:crypto");
|
|
1878
|
-
var
|
|
2761
|
+
var import_node_path8 = require("node:path");
|
|
1879
2762
|
var GROUNDING_MAX_CHARS = 32768;
|
|
1880
2763
|
var SNAPSHOT_MAX_CHARS = 3e4;
|
|
1881
2764
|
var SNAPSHOT_SEGMENT_CHARS = Math.floor(SNAPSHOT_MAX_CHARS / 2);
|
|
@@ -1884,7 +2767,7 @@ function buildMutationGrounding(input) {
|
|
|
1884
2767
|
const byteCount = Buffer.byteLength(input.content, "utf8");
|
|
1885
2768
|
const lineCount = input.content.length ? input.content.split(/\r?\n/u).length : 0;
|
|
1886
2769
|
const sha256 = (0, import_node_crypto3.createHash)("sha256").update(input.content).digest("hex");
|
|
1887
|
-
const extension = (0,
|
|
2770
|
+
const extension = (0, import_node_path8.extname)(input.logicalPath).toLowerCase() || "none";
|
|
1888
2771
|
const snapshot = projectSnapshot(input.content, input.previousContent);
|
|
1889
2772
|
const summary = bound(
|
|
1890
2773
|
[
|
|
@@ -2128,7 +3011,7 @@ function scopeError(message) {
|
|
|
2128
3011
|
// plugins/filesystem/source/draft/validators.ts
|
|
2129
3012
|
var import_parser = require("@babel/parser");
|
|
2130
3013
|
var import_postcss = require("postcss");
|
|
2131
|
-
var
|
|
3014
|
+
var import_node_path9 = require("node:path");
|
|
2132
3015
|
var SCRIPT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
2133
3016
|
".js",
|
|
2134
3017
|
".jsx",
|
|
@@ -2168,7 +3051,7 @@ function lineColumnAt(content, offset) {
|
|
|
2168
3051
|
});
|
|
2169
3052
|
}
|
|
2170
3053
|
function scriptOptions(targetPath) {
|
|
2171
|
-
const extension = (0,
|
|
3054
|
+
const extension = (0, import_node_path9.extname)(targetPath).toLowerCase();
|
|
2172
3055
|
const plugins = [];
|
|
2173
3056
|
if ([".js", ".jsx", ".mjs", ".cjs", ".tsx"].includes(extension)) {
|
|
2174
3057
|
plugins.push("jsx");
|
|
@@ -2231,7 +3114,7 @@ function foreignScriptWrapper(content, targetPath, originalError) {
|
|
|
2231
3114
|
return parseScript(projected.join("\n"), targetPath) === void 0;
|
|
2232
3115
|
};
|
|
2233
3116
|
if (opening && closing && first < last && parsesWithout(first, last)) {
|
|
2234
|
-
const extension = (0,
|
|
3117
|
+
const extension = (0, import_node_path9.extname)(targetPath).toLowerCase();
|
|
2235
3118
|
if (!originalError && [".jsx", ".tsx"].includes(extension))
|
|
2236
3119
|
return void 0;
|
|
2237
3120
|
return wrapperDiagnostic(lines[first], first, "opening", 2);
|
|
@@ -2249,14 +3132,14 @@ var validators = Object.freeze([
|
|
|
2249
3132
|
id: "json",
|
|
2250
3133
|
label: "strict JSON",
|
|
2251
3134
|
authoritativeStructure: true,
|
|
2252
|
-
matchesTarget: (targetPath) => (0,
|
|
3135
|
+
matchesTarget: (targetPath) => (0, import_node_path9.extname)(targetPath).toLowerCase() === ".json",
|
|
2253
3136
|
validate: (content) => validateJson(content)
|
|
2254
3137
|
}),
|
|
2255
3138
|
Object.freeze({
|
|
2256
3139
|
id: "css",
|
|
2257
3140
|
label: "CSS",
|
|
2258
3141
|
authoritativeStructure: true,
|
|
2259
|
-
matchesTarget: (targetPath) => (0,
|
|
3142
|
+
matchesTarget: (targetPath) => (0, import_node_path9.extname)(targetPath).toLowerCase() === ".css",
|
|
2260
3143
|
validate(content, targetPath) {
|
|
2261
3144
|
try {
|
|
2262
3145
|
(0, import_postcss.parse)(content, { from: targetPath });
|
|
@@ -2276,7 +3159,7 @@ var validators = Object.freeze([
|
|
|
2276
3159
|
id: "script",
|
|
2277
3160
|
label: "JavaScript/TypeScript",
|
|
2278
3161
|
authoritativeStructure: true,
|
|
2279
|
-
matchesTarget: (targetPath) => SCRIPT_EXTENSIONS.has((0,
|
|
3162
|
+
matchesTarget: (targetPath) => SCRIPT_EXTENSIONS.has((0, import_node_path9.extname)(targetPath).toLowerCase()),
|
|
2280
3163
|
validate(content, targetPath) {
|
|
2281
3164
|
const error = parseScript(content, targetPath);
|
|
2282
3165
|
return foreignScriptWrapper(content, targetPath, error) ?? (error ? scriptDiagnostic(error) : void 0);
|
|
@@ -2626,17 +3509,17 @@ function delimiterRegressions(previous, updated) {
|
|
|
2626
3509
|
["square", "[", "]"],
|
|
2627
3510
|
["paren", "(", ")"]
|
|
2628
3511
|
];
|
|
2629
|
-
return delimiters.flatMap(([name,
|
|
2630
|
-
if (!previous.includes(
|
|
2631
|
-
const before = balance(previous,
|
|
2632
|
-
const after = balance(updated,
|
|
3512
|
+
return delimiters.flatMap(([name, open6, close]) => {
|
|
3513
|
+
if (!previous.includes(open6) || !previous.includes(close)) return [];
|
|
3514
|
+
const before = balance(previous, open6, close);
|
|
3515
|
+
const after = balance(updated, open6, close);
|
|
2633
3516
|
return before === 0 && after !== 0 ? [`${name} delimiter balance changed from 0 to ${after}`] : [];
|
|
2634
3517
|
});
|
|
2635
3518
|
}
|
|
2636
|
-
function balance(content,
|
|
3519
|
+
function balance(content, open6, close) {
|
|
2637
3520
|
let count = 0;
|
|
2638
3521
|
for (const character of content) {
|
|
2639
|
-
if (character ===
|
|
3522
|
+
if (character === open6) count += 1;
|
|
2640
3523
|
else if (character === close) count -= 1;
|
|
2641
3524
|
}
|
|
2642
3525
|
return count;
|
|
@@ -2660,6 +3543,7 @@ function createFilesystemMutationCoordinator() {
|
|
|
2660
3543
|
const tails = /* @__PURE__ */ new Map();
|
|
2661
3544
|
return Object.freeze({
|
|
2662
3545
|
async runExclusive(targetKey, task) {
|
|
3546
|
+
if (process.platform === "win32") targetKey = targetKey.toUpperCase();
|
|
2663
3547
|
const previous = tails.get(targetKey) ?? Promise.resolve();
|
|
2664
3548
|
let release;
|
|
2665
3549
|
const current = new Promise((resolve) => {
|
|
@@ -2682,7 +3566,7 @@ function getProcessFilesystemMutationCoordinator() {
|
|
|
2682
3566
|
}
|
|
2683
3567
|
|
|
2684
3568
|
// plugins/filesystem/source/path-service.ts
|
|
2685
|
-
var
|
|
3569
|
+
var import_node_path10 = require("node:path");
|
|
2686
3570
|
var FILESYSTEM_LOCATIONS = Object.freeze([
|
|
2687
3571
|
"agent_work",
|
|
2688
3572
|
"workspace"
|
|
@@ -2700,7 +3584,7 @@ function logicalParent(logicalPath) {
|
|
|
2700
3584
|
if (logicalPath === "." || logicalPath === "workspace") {
|
|
2701
3585
|
return logicalPath;
|
|
2702
3586
|
}
|
|
2703
|
-
return
|
|
3587
|
+
return import_node_path10.posix.dirname(logicalPath);
|
|
2704
3588
|
}
|
|
2705
3589
|
function createFilesystemPathService(fallbackResolver) {
|
|
2706
3590
|
return Object.freeze({
|
|
@@ -2715,7 +3599,7 @@ function createFilesystemPathService(fallbackResolver) {
|
|
|
2715
3599
|
},
|
|
2716
3600
|
sibling(target, name, context) {
|
|
2717
3601
|
const parent = logicalParent(target.logicalPath);
|
|
2718
|
-
const logicalPath = parent === "." ? name :
|
|
3602
|
+
const logicalPath = parent === "." ? name : import_node_path10.posix.join(parent, name);
|
|
2719
3603
|
return resolveWith(resolverFor(fallbackResolver, context), logicalPath);
|
|
2720
3604
|
}
|
|
2721
3605
|
});
|
|
@@ -2910,7 +3794,8 @@ function settle(handler, operation) {
|
|
|
2910
3794
|
return failureResult({
|
|
2911
3795
|
errorCode: error.code,
|
|
2912
3796
|
message: error.message,
|
|
2913
|
-
data: error.data
|
|
3797
|
+
data: error.data,
|
|
3798
|
+
...error.code === "filesystem_windows_interrupted" && context?.abortSignal?.aborted ? { interruption: "aborted" } : {}
|
|
2914
3799
|
});
|
|
2915
3800
|
}
|
|
2916
3801
|
return failureFromError(error, {
|
|
@@ -2925,6 +3810,7 @@ var index_default = defineRuntimePlugin((context) => {
|
|
|
2925
3810
|
const paths = createFilesystemPathService(context.runtimePathResolver);
|
|
2926
3811
|
const mutations = getProcessFilesystemMutationCoordinator();
|
|
2927
3812
|
return Object.freeze({
|
|
3813
|
+
prepareRequest: prepareFilesystemRequest,
|
|
2928
3814
|
handlers: Object.freeze({
|
|
2929
3815
|
dev_view: settle(createDevViewHandler(paths), "dev_view"),
|
|
2930
3816
|
edit_file: settle(createEditFileHandler(paths, mutations), "edit_file"),
|