@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
|
@@ -234,9 +234,27 @@ function failureFromError(error, options) {
|
|
|
234
234
|
});
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
+
// src/plugin-sdk/context-text-result.ts
|
|
238
|
+
function deliverPluginTextResult(result, fields, budget) {
|
|
239
|
+
const assessed = enforcePluginResultByteBudget(result, budget);
|
|
240
|
+
if (!canHandOffContextText(result, assessed, budget)) return assessed;
|
|
241
|
+
return enforcePluginResultByteBudget(
|
|
242
|
+
{ ...result, contextTextFields: Object.freeze([...fields]) },
|
|
243
|
+
budget
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
function canHandOffContextText(original, assessed, budget) {
|
|
247
|
+
if (budget?.acceptsContextText !== true) return false;
|
|
248
|
+
if (assessed === original) return false;
|
|
249
|
+
return assessed.errorCode === "plugin_result_too_large";
|
|
250
|
+
}
|
|
251
|
+
|
|
237
252
|
// src/capabilities/tool-media.ts
|
|
238
253
|
var TOOL_IMAGE_MAX_BYTES = 10 * 1024 * 1024;
|
|
239
254
|
|
|
255
|
+
// src/computer-access/companion/secret-protection-protocol.ts
|
|
256
|
+
var HOST_SECRET_PROTECTION_CAPABILITY = "host_secret_protection_v1";
|
|
257
|
+
|
|
240
258
|
// src/computer-access/companion/broker-client.ts
|
|
241
259
|
var import_node_net = require("node:net");
|
|
242
260
|
|
|
@@ -255,25 +273,25 @@ function hostStateDirectory(rootDir) {
|
|
|
255
273
|
}
|
|
256
274
|
function ensureHostStateDirectory(directory) {
|
|
257
275
|
(0, import_node_fs.mkdirSync)(directory, { recursive: true, mode: 448 });
|
|
258
|
-
const
|
|
259
|
-
if (!
|
|
276
|
+
const stat3 = (0, import_node_fs.lstatSync)(directory);
|
|
277
|
+
if (!stat3.isDirectory()) throw new Error("host_state_directory_invalid");
|
|
260
278
|
if (process.platform === "win32") return;
|
|
261
|
-
if (
|
|
279
|
+
if (stat3.uid !== process.getuid?.())
|
|
262
280
|
throw new Error("host_state_owner_invalid");
|
|
263
|
-
if ((
|
|
281
|
+
if ((stat3.mode & 63) !== 0)
|
|
264
282
|
throw new Error("host_state_directory_not_private");
|
|
265
283
|
}
|
|
266
284
|
function readHostPrivateJson(path) {
|
|
267
285
|
try {
|
|
268
|
-
const
|
|
269
|
-
if (!
|
|
286
|
+
const stat3 = (0, import_node_fs.lstatSync)(path);
|
|
287
|
+
if (!stat3.isFile()) throw new Error("host_state_file_invalid");
|
|
270
288
|
if (process.platform !== "win32") {
|
|
271
|
-
if (
|
|
289
|
+
if (stat3.uid !== process.getuid?.())
|
|
272
290
|
throw new Error("host_state_owner_invalid");
|
|
273
|
-
if ((
|
|
291
|
+
if ((stat3.mode & 63) !== 0)
|
|
274
292
|
throw new Error("host_state_file_not_private");
|
|
275
293
|
}
|
|
276
|
-
if (
|
|
294
|
+
if (stat3.size > 16384) throw new Error("host_state_file_too_large");
|
|
277
295
|
return JSON.parse((0, import_node_fs.readFileSync)(path, "utf8"));
|
|
278
296
|
} catch (error) {
|
|
279
297
|
if (error.code === "ENOENT") return void 0;
|
|
@@ -2124,7 +2142,7 @@ function createUnixNativeProcess(options) {
|
|
|
2124
2142
|
let failedReason;
|
|
2125
2143
|
let buffer = Buffer.alloc(0);
|
|
2126
2144
|
let queue = Promise.resolve();
|
|
2127
|
-
let
|
|
2145
|
+
let lastDesktop;
|
|
2128
2146
|
function interruptedResult(reason) {
|
|
2129
2147
|
const dispatch = pending?.request.operation === "act" ? pending.dispatch ?? {
|
|
2130
2148
|
status: "unknown",
|
|
@@ -2132,12 +2150,8 @@ function createUnixNativeProcess(options) {
|
|
|
2132
2150
|
reason
|
|
2133
2151
|
} : void 0;
|
|
2134
2152
|
const result = unavailableUnixDesktop(options.platform, reason, dispatch);
|
|
2135
|
-
if (!
|
|
2136
|
-
return {
|
|
2137
|
-
...result,
|
|
2138
|
-
desktop: { ...lastResult.desktop, available: false, reason },
|
|
2139
|
-
windows: lastResult.windows
|
|
2140
|
-
};
|
|
2153
|
+
if (!lastDesktop) return result;
|
|
2154
|
+
return { ...result, desktop: { ...result.desktop, ...lastDesktop } };
|
|
2141
2155
|
}
|
|
2142
2156
|
function terminate(reason) {
|
|
2143
2157
|
failedReason = reason;
|
|
@@ -2150,6 +2164,7 @@ function createUnixNativeProcess(options) {
|
|
|
2150
2164
|
retiring.once("exit", () => clearTimeout(hardStop));
|
|
2151
2165
|
}
|
|
2152
2166
|
child = void 0;
|
|
2167
|
+
buffer.fill(0);
|
|
2153
2168
|
buffer = Buffer.alloc(0);
|
|
2154
2169
|
}
|
|
2155
2170
|
function receiveLine(line) {
|
|
@@ -2165,7 +2180,17 @@ function createUnixNativeProcess(options) {
|
|
|
2165
2180
|
}
|
|
2166
2181
|
if (message.type !== "result") throw new Error("native_protocol_invalid");
|
|
2167
2182
|
const result = readUnixNativeResult(message.result, options.platform);
|
|
2168
|
-
|
|
2183
|
+
lastDesktop = {
|
|
2184
|
+
binding: result.desktop.binding,
|
|
2185
|
+
bounds: {
|
|
2186
|
+
x: result.desktop.bounds.x,
|
|
2187
|
+
y: result.desktop.bounds.y,
|
|
2188
|
+
width: result.desktop.bounds.width,
|
|
2189
|
+
height: result.desktop.bounds.height
|
|
2190
|
+
},
|
|
2191
|
+
coordinateSpace: result.desktop.coordinateSpace,
|
|
2192
|
+
targetingGuarantee: result.desktop.targetingGuarantee
|
|
2193
|
+
};
|
|
2169
2194
|
pending.finish(result);
|
|
2170
2195
|
}
|
|
2171
2196
|
function ensureHelper() {
|
|
@@ -2178,15 +2203,19 @@ function createUnixNativeProcess(options) {
|
|
|
2178
2203
|
child.stderr.resume();
|
|
2179
2204
|
child.stdout.on("data", (chunk) => {
|
|
2180
2205
|
if (closed || failedReason) return;
|
|
2181
|
-
|
|
2206
|
+
const previous = buffer;
|
|
2207
|
+
buffer = Buffer.concat([previous, chunk]);
|
|
2208
|
+
previous.fill(0);
|
|
2182
2209
|
if (buffer.length > NATIVE_JSON_LIMIT) {
|
|
2183
2210
|
terminate("computer_native_result_limit");
|
|
2184
2211
|
return;
|
|
2185
2212
|
}
|
|
2186
2213
|
let boundary = buffer.indexOf(10);
|
|
2187
2214
|
while (boundary >= 0) {
|
|
2188
|
-
const
|
|
2189
|
-
|
|
2215
|
+
const received = buffer;
|
|
2216
|
+
const line = received.subarray(0, boundary).toString("utf8");
|
|
2217
|
+
buffer = Buffer.from(received.subarray(boundary + 1));
|
|
2218
|
+
received.fill(0);
|
|
2190
2219
|
try {
|
|
2191
2220
|
receiveLine(line);
|
|
2192
2221
|
} catch {
|
|
@@ -4259,7 +4288,7 @@ var import_node_path4 = require("node:path");
|
|
|
4259
4288
|
// src/computer-access/process-runner.ts
|
|
4260
4289
|
var import_node_child_process4 = require("node:child_process");
|
|
4261
4290
|
var STREAM_MAX_CHARS = 16e3;
|
|
4262
|
-
function runSystemProcess(input) {
|
|
4291
|
+
function runSystemProcess(input, capture) {
|
|
4263
4292
|
if (input.abortSignal?.aborted)
|
|
4264
4293
|
return Promise.resolve({
|
|
4265
4294
|
exitCode: null,
|
|
@@ -4287,6 +4316,7 @@ function runSystemProcess(input) {
|
|
|
4287
4316
|
if (timeout) clearTimeout(timeout);
|
|
4288
4317
|
if (stopGrace) clearTimeout(stopGrace);
|
|
4289
4318
|
input.abortSignal?.removeEventListener("abort", abort);
|
|
4319
|
+
capture?.end();
|
|
4290
4320
|
resolve(
|
|
4291
4321
|
Object.freeze({
|
|
4292
4322
|
exitCode,
|
|
@@ -4330,18 +4360,25 @@ function runSystemProcess(input) {
|
|
|
4330
4360
|
stopGrace.unref();
|
|
4331
4361
|
};
|
|
4332
4362
|
const abort = () => stop("aborted");
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
stdout
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4363
|
+
const attachOutput = () => {
|
|
4364
|
+
if (capture) {
|
|
4365
|
+
capture.attach(child.stdout, child.stderr, () => stop("output_failed"));
|
|
4366
|
+
return;
|
|
4367
|
+
}
|
|
4368
|
+
child.stdout.setEncoding("utf8");
|
|
4369
|
+
child.stderr.setEncoding("utf8");
|
|
4370
|
+
child.stdout.on("data", (chunk) => {
|
|
4371
|
+
const remaining = streamMaxChars - stdout.length;
|
|
4372
|
+
truncated ||= chunk.length > remaining;
|
|
4373
|
+
stdout += chunk.slice(0, remaining);
|
|
4374
|
+
});
|
|
4375
|
+
child.stderr.on("data", (chunk) => {
|
|
4376
|
+
const remaining = streamMaxChars - stderr.length;
|
|
4377
|
+
truncated ||= chunk.length > remaining;
|
|
4378
|
+
stderr += chunk.slice(0, remaining);
|
|
4379
|
+
});
|
|
4380
|
+
};
|
|
4381
|
+
attachOutput();
|
|
4345
4382
|
child.once("error", (error) => {
|
|
4346
4383
|
status = "spawn_failed";
|
|
4347
4384
|
stderr = error.message.slice(0, STREAM_MAX_CHARS);
|
|
@@ -4963,7 +5000,7 @@ async function executeSystemCommand(input) {
|
|
|
4963
5000
|
);
|
|
4964
5001
|
await requireNativeWorkingDirectory(target, cwd);
|
|
4965
5002
|
const plan = params.elevated === true ? await elevatedSystemCommand({ target, command, cwd, run }) : unprivilegedSystemCommand(target, command, cwd);
|
|
4966
|
-
return run({
|
|
5003
|
+
return (input.runCommand ?? run)({
|
|
4967
5004
|
...plan,
|
|
4968
5005
|
timeoutMs,
|
|
4969
5006
|
...input.abortSignal ? { abortSignal: input.abortSignal } : {}
|
|
@@ -5007,6 +5044,11 @@ var LEGACY_EVIDENCE_LABELS = {
|
|
|
5007
5044
|
launch_request_dispatch: "application launch request dispatch"
|
|
5008
5045
|
};
|
|
5009
5046
|
function systemProcessResult(target, result, evidenceScope, application) {
|
|
5047
|
+
return enforcePluginResultByteBudget(
|
|
5048
|
+
buildSystemProcessResult(target, result, evidenceScope, application)
|
|
5049
|
+
);
|
|
5050
|
+
}
|
|
5051
|
+
function buildSystemProcessResult(target, result, evidenceScope, application) {
|
|
5010
5052
|
const stdoutOmittedChars = Math.max(
|
|
5011
5053
|
0,
|
|
5012
5054
|
result.stdout.length - STREAM_EXCERPT_CHARS
|
|
@@ -5049,24 +5091,28 @@ function systemProcessResult(target, result, evidenceScope, application) {
|
|
|
5049
5091
|
`Summary omitted characters: stdout=${stdoutOmittedChars}, stderr=${stderrOmittedChars}. Raw stream capture truncated: ${result.outputTruncated}.`
|
|
5050
5092
|
].join("\n");
|
|
5051
5093
|
if (hasSuccessfulSystemObservation(result)) {
|
|
5052
|
-
return
|
|
5094
|
+
return {
|
|
5095
|
+
ok: true,
|
|
5096
|
+
producedNewInformation: true,
|
|
5053
5097
|
output,
|
|
5054
5098
|
stdout: result.stdout,
|
|
5055
5099
|
stderr: result.stderr,
|
|
5056
5100
|
exitCode: 0,
|
|
5057
5101
|
data
|
|
5058
|
-
}
|
|
5102
|
+
};
|
|
5059
5103
|
}
|
|
5060
5104
|
const errorCode = result.status === "completed" ? "system_command_failed" : `system_${result.status}`;
|
|
5061
|
-
return
|
|
5105
|
+
return {
|
|
5106
|
+
ok: false,
|
|
5107
|
+
producedNewInformation: false,
|
|
5062
5108
|
errorCode,
|
|
5063
|
-
|
|
5109
|
+
error: hasUncertainDescendantState(result) ? "System command observation stopped. External or detached descendants may remain; inspect the target before retrying." : "The target did not report successful command completion.",
|
|
5064
5110
|
output,
|
|
5065
5111
|
stdout: result.stdout,
|
|
5066
5112
|
stderr: result.stderr,
|
|
5067
5113
|
...result.exitCode !== null ? { exitCode: result.exitCode } : {},
|
|
5068
5114
|
data
|
|
5069
|
-
}
|
|
5115
|
+
};
|
|
5070
5116
|
}
|
|
5071
5117
|
function hasSuccessfulSystemObservation(result) {
|
|
5072
5118
|
if (result.status !== "completed") return false;
|
|
@@ -5082,15 +5128,60 @@ function identityExcerpt(identity) {
|
|
|
5082
5128
|
}
|
|
5083
5129
|
|
|
5084
5130
|
// src/computer-access/handlers.ts
|
|
5085
|
-
|
|
5131
|
+
var PROTECTION_FAILURE = "The system result could not be protected for delivery.";
|
|
5132
|
+
function protectSystemResult(operation) {
|
|
5133
|
+
try {
|
|
5134
|
+
return operation();
|
|
5135
|
+
} catch {
|
|
5136
|
+
throw new SystemOperationError("system_result_protection_failed", PROTECTION_FAILURE);
|
|
5137
|
+
}
|
|
5138
|
+
}
|
|
5139
|
+
function failedSystemProtectionReceipt(target, result, evidenceScope) {
|
|
5140
|
+
const safeProcess = {
|
|
5141
|
+
status: result.status,
|
|
5142
|
+
exitCode: result.exitCode,
|
|
5143
|
+
outputTruncated: result.outputTruncated,
|
|
5144
|
+
stdout: "[UNAVAILABLE: result protection failed]",
|
|
5145
|
+
stderr: "[UNAVAILABLE: result protection failed]",
|
|
5146
|
+
...result.spawnedProcess ? {
|
|
5147
|
+
spawnedProcess: {
|
|
5148
|
+
pid: result.spawnedProcess.pid,
|
|
5149
|
+
pidNamespace: result.spawnedProcess.pidNamespace,
|
|
5150
|
+
identitySource: result.spawnedProcess.identitySource,
|
|
5151
|
+
executable: "[REDACTED]"
|
|
5152
|
+
}
|
|
5153
|
+
} : {}
|
|
5154
|
+
};
|
|
5155
|
+
const receipt = systemProcessResult(target, safeProcess, evidenceScope);
|
|
5156
|
+
return failureResult({
|
|
5157
|
+
errorCode: "system_result_protection_failed",
|
|
5158
|
+
message: PROTECTION_FAILURE,
|
|
5159
|
+
output: "The operation was dispatched. Inspect the process receipt before another action; the command was not replayed.\n" + receipt.output,
|
|
5160
|
+
stdout: safeProcess.stdout,
|
|
5161
|
+
stderr: safeProcess.stderr,
|
|
5162
|
+
...result.exitCode !== null ? { exitCode: result.exitCode } : {},
|
|
5163
|
+
data: receipt.data
|
|
5164
|
+
});
|
|
5165
|
+
}
|
|
5166
|
+
function withSystemOperationErrors(operation, protection) {
|
|
5086
5167
|
return async (params, context) => {
|
|
5087
5168
|
try {
|
|
5088
5169
|
return await operation(params, context);
|
|
5089
5170
|
} catch (error) {
|
|
5171
|
+
let message = error instanceof Error ? error.message : void 0;
|
|
5172
|
+
try {
|
|
5173
|
+
if (protection && message !== void 0)
|
|
5174
|
+
message = protection.protectMessage(message);
|
|
5175
|
+
} catch {
|
|
5176
|
+
return failureResult({
|
|
5177
|
+
errorCode: "system_result_protection_failed",
|
|
5178
|
+
message: PROTECTION_FAILURE
|
|
5179
|
+
});
|
|
5180
|
+
}
|
|
5090
5181
|
if (error instanceof SystemOperationError)
|
|
5091
5182
|
return failureResult({
|
|
5092
5183
|
errorCode: error.code,
|
|
5093
|
-
message
|
|
5184
|
+
message,
|
|
5094
5185
|
data: {
|
|
5095
5186
|
humanActionRequired: error.code === "system_authorization_required"
|
|
5096
5187
|
}
|
|
@@ -5103,9 +5194,10 @@ function withSystemOperationErrors(operation) {
|
|
|
5103
5194
|
}
|
|
5104
5195
|
};
|
|
5105
5196
|
}
|
|
5106
|
-
function createSystemHandlers(run = runSystemProcess, resolveTarget = (id) => resolveSystemTarget(id, run)) {
|
|
5197
|
+
function createSystemHandlers(run = runSystemProcess, resolveTarget = (id) => resolveSystemTarget(id, run), commandOutput, protection) {
|
|
5107
5198
|
const targets = async () => {
|
|
5108
|
-
const
|
|
5199
|
+
const observed = await observeSystemTargets(run);
|
|
5200
|
+
const observation = protection ? protectSystemResult(() => protection.protectTargets(observed)) : observed;
|
|
5109
5201
|
return successResult({
|
|
5110
5202
|
output: JSON.stringify(observation),
|
|
5111
5203
|
data: {
|
|
@@ -5116,12 +5208,21 @@ function createSystemHandlers(run = runSystemProcess, resolveTarget = (id) => re
|
|
|
5116
5208
|
};
|
|
5117
5209
|
const command = async (params, context) => {
|
|
5118
5210
|
const target = await resolveTarget(readSystemTargetId(params.target));
|
|
5119
|
-
const
|
|
5211
|
+
const output = commandOutput?.(context);
|
|
5212
|
+
const observed = await executeSystemCommand({
|
|
5120
5213
|
target,
|
|
5121
5214
|
params,
|
|
5122
5215
|
run,
|
|
5216
|
+
...output ? { runCommand: output.run } : {},
|
|
5123
5217
|
...context?.abortSignal ? { abortSignal: context.abortSignal } : {}
|
|
5124
5218
|
});
|
|
5219
|
+
let result = observed;
|
|
5220
|
+
try {
|
|
5221
|
+
if (protection) result = protection.protectProcess(observed);
|
|
5222
|
+
} catch {
|
|
5223
|
+
return failedSystemProtectionReceipt(target, observed, "command_process_completion");
|
|
5224
|
+
}
|
|
5225
|
+
if (output) return output.present(target, result);
|
|
5125
5226
|
return systemProcessResult(target, result, "command_process_completion");
|
|
5126
5227
|
};
|
|
5127
5228
|
const applications = async (params) => {
|
|
@@ -5132,7 +5233,8 @@ function createSystemHandlers(run = runSystemProcess, resolveTarget = (id) => re
|
|
|
5132
5233
|
minimum: 1,
|
|
5133
5234
|
maximum: 100
|
|
5134
5235
|
});
|
|
5135
|
-
const
|
|
5236
|
+
const observed = await readSystemApplications(target, run);
|
|
5237
|
+
const catalog = protection ? protectSystemResult(() => protection.protectCatalog(observed)) : observed;
|
|
5136
5238
|
const { output, data } = systemApplicationObservation(
|
|
5137
5239
|
target,
|
|
5138
5240
|
catalog,
|
|
@@ -5155,20 +5257,447 @@ function createSystemHandlers(run = runSystemProcess, resolveTarget = (id) => re
|
|
|
5155
5257
|
run,
|
|
5156
5258
|
...context?.abortSignal ? { abortSignal: context.abortSignal } : {}
|
|
5157
5259
|
});
|
|
5260
|
+
let process2 = result.process;
|
|
5261
|
+
let application = result.application;
|
|
5262
|
+
try {
|
|
5263
|
+
if (protection) {
|
|
5264
|
+
process2 = protection.protectProcess(result.process);
|
|
5265
|
+
application = protection.protectApplication(result.application);
|
|
5266
|
+
}
|
|
5267
|
+
} catch {
|
|
5268
|
+
return failedSystemProtectionReceipt(target, result.process, "launch_request_dispatch");
|
|
5269
|
+
}
|
|
5158
5270
|
return systemProcessResult(
|
|
5159
5271
|
target,
|
|
5160
|
-
|
|
5272
|
+
process2,
|
|
5161
5273
|
"launch_request_dispatch",
|
|
5162
|
-
|
|
5274
|
+
application
|
|
5163
5275
|
);
|
|
5164
5276
|
};
|
|
5165
5277
|
return {
|
|
5166
|
-
system_targets: withSystemOperationErrors(targets),
|
|
5167
|
-
system_command: withSystemOperationErrors(command),
|
|
5168
|
-
system_applications: withSystemOperationErrors(applications),
|
|
5169
|
-
system_launch: withSystemOperationErrors(launch)
|
|
5278
|
+
system_targets: withSystemOperationErrors(targets, protection),
|
|
5279
|
+
system_command: withSystemOperationErrors(command, protection),
|
|
5280
|
+
system_applications: withSystemOperationErrors(applications, protection),
|
|
5281
|
+
system_launch: withSystemOperationErrors(launch, protection)
|
|
5282
|
+
};
|
|
5283
|
+
}
|
|
5284
|
+
|
|
5285
|
+
// src/computer-access/command-output-capture.ts
|
|
5286
|
+
var import_node_crypto6 = require("node:crypto");
|
|
5287
|
+
var import_node_events = require("node:events");
|
|
5288
|
+
var import_node_fs5 = require("node:fs");
|
|
5289
|
+
var import_promises7 = require("node:fs/promises");
|
|
5290
|
+
var import_node_path8 = require("node:path");
|
|
5291
|
+
var import_promises8 = require("node:stream/promises");
|
|
5292
|
+
|
|
5293
|
+
// src/computer-access/command-output-protection.ts
|
|
5294
|
+
var import_promises5 = require("node:fs/promises");
|
|
5295
|
+
var CapturedOutputProtectionError = class extends Error {
|
|
5296
|
+
constructor(reason) {
|
|
5297
|
+
super(reason);
|
|
5298
|
+
this.reason = reason;
|
|
5299
|
+
}
|
|
5300
|
+
reason;
|
|
5301
|
+
};
|
|
5302
|
+
async function protectCapturedOutput(paths, redact) {
|
|
5303
|
+
let stdout, stderr;
|
|
5304
|
+
try {
|
|
5305
|
+
stdout = await protectStream(paths.stdout, redact);
|
|
5306
|
+
stderr = await protectStream(paths.stderr, redact);
|
|
5307
|
+
const writes = await Promise.allSettled([
|
|
5308
|
+
(0, import_promises5.writeFile)(paths.stdout, stdout, { flag: "w", mode: 384, flush: true }),
|
|
5309
|
+
(0, import_promises5.writeFile)(paths.stderr, stderr, { flag: "w", mode: 384, flush: true })
|
|
5310
|
+
]);
|
|
5311
|
+
if (hasRejectedOutputWrite(writes)) throw new CapturedOutputProtectionError("output_storage_failed");
|
|
5312
|
+
return { stdout, stderr };
|
|
5313
|
+
} catch (error) {
|
|
5314
|
+
stdout?.fill(0);
|
|
5315
|
+
stderr?.fill(0);
|
|
5316
|
+
throw error;
|
|
5317
|
+
}
|
|
5318
|
+
}
|
|
5319
|
+
async function protectStream(path, redact) {
|
|
5320
|
+
let bytes;
|
|
5321
|
+
try {
|
|
5322
|
+
bytes = await (0, import_promises5.readFile)(path);
|
|
5323
|
+
} catch {
|
|
5324
|
+
throw new CapturedOutputProtectionError("output_storage_failed");
|
|
5325
|
+
}
|
|
5326
|
+
try {
|
|
5327
|
+
const text = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes);
|
|
5328
|
+
const protectedText = redact(text);
|
|
5329
|
+
if (!isProtectedOutputText(protectedText)) throw new Error("output_protection_failed");
|
|
5330
|
+
return Buffer.from(protectedText, "utf8");
|
|
5331
|
+
} catch {
|
|
5332
|
+
throw new CapturedOutputProtectionError("output_protection_failed");
|
|
5333
|
+
} finally {
|
|
5334
|
+
bytes.fill(0);
|
|
5335
|
+
}
|
|
5336
|
+
}
|
|
5337
|
+
async function discardCapturedOutput(paths) {
|
|
5338
|
+
const removed = await Promise.allSettled(Object.values(paths).map((path) => (0, import_promises5.rm)(path, { force: true })));
|
|
5339
|
+
return removed.every((entry) => entry.status === "fulfilled");
|
|
5340
|
+
}
|
|
5341
|
+
function isProtectedOutputText(value) {
|
|
5342
|
+
return typeof value === "string";
|
|
5343
|
+
}
|
|
5344
|
+
function hasRejectedOutputWrite(writes) {
|
|
5345
|
+
return writes.some((entry) => entry.status === "rejected");
|
|
5346
|
+
}
|
|
5347
|
+
|
|
5348
|
+
// src/computer-access/command-output-retention.ts
|
|
5349
|
+
var import_promises6 = require("node:fs/promises");
|
|
5350
|
+
var import_node_path7 = require("node:path");
|
|
5351
|
+
var DEFAULT_SYSTEM_OUTPUT_RETENTION_MS = 7 * 24 * 60 * 6e4;
|
|
5352
|
+
var activeSystemCaptures = /* @__PURE__ */ new Set();
|
|
5353
|
+
var jobs = /* @__PURE__ */ new Map();
|
|
5354
|
+
var CAPTURE_ID = /^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/;
|
|
5355
|
+
async function cleanupSystemOutput(root, retentionMs) {
|
|
5356
|
+
const entries = await (0, import_promises6.readdir)(root, { withFileTypes: true }).catch((error) => {
|
|
5357
|
+
if (error.code === "ENOENT") return [];
|
|
5358
|
+
throw error;
|
|
5359
|
+
});
|
|
5360
|
+
let removed = 0;
|
|
5361
|
+
for (const entry of entries) {
|
|
5362
|
+
if (!entry.isDirectory() || !CAPTURE_ID.test(entry.name)) continue;
|
|
5363
|
+
const directory = (0, import_node_path7.join)(root, entry.name);
|
|
5364
|
+
if (activeSystemCaptures.has(directory)) continue;
|
|
5365
|
+
const files = await (0, import_promises6.readdir)(directory);
|
|
5366
|
+
const times = await Promise.all(files.map(async (file) => (await (0, import_promises6.stat)((0, import_node_path7.join)(directory, file))).mtimeMs));
|
|
5367
|
+
const completedAt = Math.max((await (0, import_promises6.stat)(directory)).mtimeMs, ...times);
|
|
5368
|
+
const captureRetentionMs = await readCaptureRetention(directory, entry.name, retentionMs);
|
|
5369
|
+
if (Date.now() - completedAt < captureRetentionMs) continue;
|
|
5370
|
+
if (activeSystemCaptures.has(directory)) continue;
|
|
5371
|
+
await (0, import_promises6.rm)(directory, { recursive: true });
|
|
5372
|
+
removed += 1;
|
|
5373
|
+
}
|
|
5374
|
+
return removed;
|
|
5375
|
+
}
|
|
5376
|
+
async function readCaptureRetention(directory, id, fallbackMs) {
|
|
5377
|
+
let receipt;
|
|
5378
|
+
try {
|
|
5379
|
+
receipt = JSON.parse(await (0, import_promises6.readFile)((0, import_node_path7.join)(directory, "receipt.json"), "utf8"));
|
|
5380
|
+
} catch (error) {
|
|
5381
|
+
if (error.code === "ENOENT") return fallbackMs;
|
|
5382
|
+
if (error instanceof SyntaxError) return fallbackMs;
|
|
5383
|
+
throw error;
|
|
5384
|
+
}
|
|
5385
|
+
if (receipt === null || typeof receipt !== "object") return fallbackMs;
|
|
5386
|
+
if (!("kind" in receipt) || receipt.kind !== "system_command_output_v1") return fallbackMs;
|
|
5387
|
+
if (!("id" in receipt) || receipt.id !== id) return fallbackMs;
|
|
5388
|
+
if (!("retentionMs" in receipt) || typeof receipt.retentionMs !== "number") return fallbackMs;
|
|
5389
|
+
if (!Number.isSafeInteger(receipt.retentionMs) || receipt.retentionMs < 1) return fallbackMs;
|
|
5390
|
+
return receipt.retentionMs;
|
|
5391
|
+
}
|
|
5392
|
+
function scheduleSystemOutputCleanup(root, retentionMs) {
|
|
5393
|
+
const previous = jobs.get(root);
|
|
5394
|
+
if (previous) {
|
|
5395
|
+
previous.retentionMs = retentionMs;
|
|
5396
|
+
previous.requested = true;
|
|
5397
|
+
return;
|
|
5398
|
+
}
|
|
5399
|
+
const job = { retentionMs, requested: false };
|
|
5400
|
+
jobs.set(root, job);
|
|
5401
|
+
const sweep = async () => {
|
|
5402
|
+
job.requested = false;
|
|
5403
|
+
let empty = false;
|
|
5404
|
+
try {
|
|
5405
|
+
await cleanupSystemOutput(root, job.retentionMs);
|
|
5406
|
+
empty = (await (0, import_promises6.readdir)(root).catch((error) => {
|
|
5407
|
+
if (error.code === "ENOENT") return [];
|
|
5408
|
+
throw error;
|
|
5409
|
+
})).length === 0;
|
|
5410
|
+
} catch {
|
|
5411
|
+
process.emitWarning("SYSTEM output cleanup failed; retained output was not confirmed removed.", { code: "SYSTEM_OUTPUT_CLEANUP_FAILED" });
|
|
5412
|
+
}
|
|
5413
|
+
if (empty && !job.requested) {
|
|
5414
|
+
jobs.delete(root);
|
|
5415
|
+
return;
|
|
5416
|
+
}
|
|
5417
|
+
const timer = setTimeout(() => {
|
|
5418
|
+
void sweep();
|
|
5419
|
+
}, Math.max(1, Math.min(job.retentionMs, 60 * 6e4)));
|
|
5420
|
+
timer.unref();
|
|
5421
|
+
};
|
|
5422
|
+
void sweep();
|
|
5423
|
+
}
|
|
5424
|
+
|
|
5425
|
+
// src/computer-access/command-output-capture.ts
|
|
5426
|
+
var STREAMS = ["stdout", "stderr"];
|
|
5427
|
+
var OUTPUT_IO_CHUNK_BYTES = 64 * 1024;
|
|
5428
|
+
async function createSystemOutputCapture(root, retentionMs, redact) {
|
|
5429
|
+
if (!hasOutputProtection(redact))
|
|
5430
|
+
throw new SystemOperationError("system_output_protection_failed", "Command output protection is unavailable. The command was not dispatched.");
|
|
5431
|
+
const id = (0, import_node_crypto6.randomUUID)();
|
|
5432
|
+
const directory = (0, import_node_path8.join)(root, id);
|
|
5433
|
+
activeSystemCaptures.add(directory);
|
|
5434
|
+
try {
|
|
5435
|
+
await (0, import_promises7.mkdir)(directory, { recursive: true, mode: 448 });
|
|
5436
|
+
} catch {
|
|
5437
|
+
activeSystemCaptures.delete(directory);
|
|
5438
|
+
throw new SystemOperationError("system_output_storage_failed", "Output storage could not be prepared. The command was not dispatched.");
|
|
5439
|
+
}
|
|
5440
|
+
let storageFailure, securityFailure;
|
|
5441
|
+
let stop;
|
|
5442
|
+
let ended = false, retained = false, admitted = false;
|
|
5443
|
+
let receipt;
|
|
5444
|
+
let processResult;
|
|
5445
|
+
let finishing;
|
|
5446
|
+
const sources = [];
|
|
5447
|
+
const completeStreams = /* @__PURE__ */ new Set();
|
|
5448
|
+
const paths = { stdout: (0, import_node_path8.join)(directory, "stdout.bytes"), stderr: (0, import_node_path8.join)(directory, "stderr.bytes") };
|
|
5449
|
+
const streams = STREAMS.map((name) => {
|
|
5450
|
+
const sink = (0, import_node_fs5.createWriteStream)(paths[name], { flags: "wx", mode: 384, highWaterMark: OUTPUT_IO_CHUNK_BYTES, flush: true });
|
|
5451
|
+
const completion = (0, import_promises8.finished)(sink).catch(() => {
|
|
5452
|
+
storageFailure ??= "write_failed";
|
|
5453
|
+
stop?.();
|
|
5454
|
+
});
|
|
5455
|
+
return { sink, completion };
|
|
5456
|
+
});
|
|
5457
|
+
try {
|
|
5458
|
+
await Promise.all(streams.map(({ sink }) => (0, import_node_events.once)(sink, "open")));
|
|
5459
|
+
} catch {
|
|
5460
|
+
for (const { sink } of streams) sink.destroy();
|
|
5461
|
+
await Promise.all(streams.map(({ completion }) => completion));
|
|
5462
|
+
activeSystemCaptures.delete(directory);
|
|
5463
|
+
scheduleSystemOutputCleanup(root, retentionMs);
|
|
5464
|
+
throw new SystemOperationError("system_output_storage_failed", "Output files could not be opened. The command was not dispatched.");
|
|
5465
|
+
}
|
|
5466
|
+
scheduleSystemOutputCleanup(root, retentionMs);
|
|
5467
|
+
const failure = () => storageFailure ?? securityFailure;
|
|
5468
|
+
const capture = {
|
|
5469
|
+
attach(stdout, stderr, onFailure) {
|
|
5470
|
+
if (!canAttachCapture()) {
|
|
5471
|
+
securityFailure ??= "output_protection_failed";
|
|
5472
|
+
onFailure();
|
|
5473
|
+
return;
|
|
5474
|
+
}
|
|
5475
|
+
stop = onFailure;
|
|
5476
|
+
sources.push(stdout, stderr);
|
|
5477
|
+
for (const [index, source] of sources.entries()) {
|
|
5478
|
+
source.once("end", () => completeStreams.add(STREAMS[index]));
|
|
5479
|
+
source.once("error", () => {
|
|
5480
|
+
securityFailure ??= "output_incomplete";
|
|
5481
|
+
stop?.();
|
|
5482
|
+
});
|
|
5483
|
+
source.pipe(streams[index].sink);
|
|
5484
|
+
}
|
|
5485
|
+
if (failure()) onFailure();
|
|
5486
|
+
},
|
|
5487
|
+
end() {
|
|
5488
|
+
if (ended) return;
|
|
5489
|
+
ended = true;
|
|
5490
|
+
if (!hasCompleteStreams()) securityFailure ??= "output_incomplete";
|
|
5491
|
+
for (const source of sources) {
|
|
5492
|
+
source.unpipe();
|
|
5493
|
+
source.destroy();
|
|
5494
|
+
}
|
|
5495
|
+
for (const { sink } of streams) if (!sink.destroyed && !sink.writableEnded) sink.end();
|
|
5496
|
+
}
|
|
5497
|
+
};
|
|
5498
|
+
function canAttachCapture() {
|
|
5499
|
+
return sources.length === 0 && !ended;
|
|
5500
|
+
}
|
|
5501
|
+
function hasCompleteStreams() {
|
|
5502
|
+
return completeStreams.size === 2;
|
|
5503
|
+
}
|
|
5504
|
+
function protectProcess2(result) {
|
|
5505
|
+
if (!result) return;
|
|
5506
|
+
let spawnedProcess = result.spawnedProcess;
|
|
5507
|
+
if (spawnedProcess) {
|
|
5508
|
+
let executable = "[REDACTED]";
|
|
5509
|
+
try {
|
|
5510
|
+
executable = redact(spawnedProcess.executable);
|
|
5511
|
+
if (!hasProtectedIdentity(executable)) throw new Error("output_protection_failed");
|
|
5512
|
+
} catch {
|
|
5513
|
+
securityFailure ??= "output_protection_failed";
|
|
5514
|
+
executable = "[REDACTED]";
|
|
5515
|
+
}
|
|
5516
|
+
spawnedProcess = { ...spawnedProcess, executable };
|
|
5517
|
+
}
|
|
5518
|
+
processResult = {
|
|
5519
|
+
exitCode: result.exitCode,
|
|
5520
|
+
status: result.status,
|
|
5521
|
+
outputTruncated: result.outputTruncated,
|
|
5522
|
+
stdout: "",
|
|
5523
|
+
stderr: "",
|
|
5524
|
+
...spawnedProcess ? { spawnedProcess } : {}
|
|
5525
|
+
};
|
|
5526
|
+
}
|
|
5527
|
+
async function finish(result, materialize = true) {
|
|
5528
|
+
capture.end();
|
|
5529
|
+
await Promise.all(streams.map(({ completion }) => completion));
|
|
5530
|
+
protectProcess2(result);
|
|
5531
|
+
let protectedBytes;
|
|
5532
|
+
try {
|
|
5533
|
+
if (!failure()) {
|
|
5534
|
+
try {
|
|
5535
|
+
protectedBytes = await protectCapturedOutput(paths, redact);
|
|
5536
|
+
} catch (error) {
|
|
5537
|
+
if (isOutputStorageFailure(error)) storageFailure ??= "write_failed";
|
|
5538
|
+
else securityFailure ??= "output_protection_failed";
|
|
5539
|
+
}
|
|
5540
|
+
}
|
|
5541
|
+
if (failure() && !await discardCapturedOutput(paths)) storageFailure = "capture_purge_failed";
|
|
5542
|
+
receipt = {
|
|
5543
|
+
id,
|
|
5544
|
+
stdoutBytes: protectedBytes?.stdout.length ?? 0,
|
|
5545
|
+
stderrBytes: protectedBytes?.stderr.length ?? 0,
|
|
5546
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5547
|
+
retentionMs,
|
|
5548
|
+
complete: !failure(),
|
|
5549
|
+
...!materialize && protectedBytes ? {
|
|
5550
|
+
stdoutSha256: (0, import_node_crypto6.createHash)("sha256").update(protectedBytes.stdout).digest("hex"),
|
|
5551
|
+
stderrSha256: (0, import_node_crypto6.createHash)("sha256").update(protectedBytes.stderr).digest("hex")
|
|
5552
|
+
} : {}
|
|
5553
|
+
};
|
|
5554
|
+
try {
|
|
5555
|
+
const temporary = (0, import_node_path8.join)(directory, "receipt.tmp");
|
|
5556
|
+
await (0, import_promises7.writeFile)(
|
|
5557
|
+
temporary,
|
|
5558
|
+
JSON.stringify({
|
|
5559
|
+
kind: "system_command_output_v1",
|
|
5560
|
+
...receipt,
|
|
5561
|
+
processStatus: processResult?.status,
|
|
5562
|
+
exitCode: processResult?.exitCode,
|
|
5563
|
+
spawnedProcess: processResult?.spawnedProcess,
|
|
5564
|
+
...securityFailure ? { securityFailure } : {},
|
|
5565
|
+
...storageFailure ? { storageFailure } : {}
|
|
5566
|
+
}),
|
|
5567
|
+
{ flag: "wx", mode: 384, flush: true }
|
|
5568
|
+
);
|
|
5569
|
+
await (0, import_promises7.rename)(temporary, (0, import_node_path8.join)(directory, "receipt.json"));
|
|
5570
|
+
} catch {
|
|
5571
|
+
storageFailure ??= "receipt_write_failed";
|
|
5572
|
+
receipt = { ...receipt, complete: false };
|
|
5573
|
+
}
|
|
5574
|
+
admitted = receipt.complete;
|
|
5575
|
+
if (!admitted || !materialize || !protectedBytes) return { stdout: "", stderr: "" };
|
|
5576
|
+
return { stdout: protectedBytes.stdout.toString("utf8"), stderr: protectedBytes.stderr.toString("utf8") };
|
|
5577
|
+
} finally {
|
|
5578
|
+
protectedBytes?.stdout.fill(0);
|
|
5579
|
+
protectedBytes?.stderr.fill(0);
|
|
5580
|
+
if (!retained) activeSystemCaptures.delete(directory);
|
|
5581
|
+
}
|
|
5582
|
+
}
|
|
5583
|
+
return {
|
|
5584
|
+
capture,
|
|
5585
|
+
get receipt() {
|
|
5586
|
+
return receipt;
|
|
5587
|
+
},
|
|
5588
|
+
get failure() {
|
|
5589
|
+
return failure();
|
|
5590
|
+
},
|
|
5591
|
+
get failureKind() {
|
|
5592
|
+
if (storageFailure) return "storage";
|
|
5593
|
+
return securityFailure ? "security" : void 0;
|
|
5594
|
+
},
|
|
5595
|
+
get processResult() {
|
|
5596
|
+
return processResult;
|
|
5597
|
+
},
|
|
5598
|
+
retain() {
|
|
5599
|
+
retained = true;
|
|
5600
|
+
activeSystemCaptures.add(directory);
|
|
5601
|
+
},
|
|
5602
|
+
release() {
|
|
5603
|
+
retained = false;
|
|
5604
|
+
activeSystemCaptures.delete(directory);
|
|
5605
|
+
},
|
|
5606
|
+
async read(stream, offset, length) {
|
|
5607
|
+
if (!admitted) throw new Error("system_output_unavailable");
|
|
5608
|
+
if (!isAdmittedOutputRead(stream, offset, length, receipt)) throw new Error("system_output_reference_invalid");
|
|
5609
|
+
const file = await (0, import_promises7.open)(paths[stream], "r");
|
|
5610
|
+
try {
|
|
5611
|
+
const size = stream === "stdout" ? receipt.stdoutBytes : receipt.stderrBytes;
|
|
5612
|
+
const bytes = Buffer.alloc(Math.min(length, size - offset));
|
|
5613
|
+
const { bytesRead } = await file.read(bytes, 0, bytes.length, offset);
|
|
5614
|
+
return bytes.subarray(0, bytesRead);
|
|
5615
|
+
} finally {
|
|
5616
|
+
await file.close();
|
|
5617
|
+
}
|
|
5618
|
+
},
|
|
5619
|
+
finish(result, materialize = true) {
|
|
5620
|
+
finishing ??= finish(result, materialize);
|
|
5621
|
+
return finishing;
|
|
5622
|
+
}
|
|
5623
|
+
};
|
|
5624
|
+
}
|
|
5625
|
+
function hasOutputProtection(value) {
|
|
5626
|
+
return typeof value === "function";
|
|
5627
|
+
}
|
|
5628
|
+
function hasProtectedIdentity(value) {
|
|
5629
|
+
return typeof value === "string";
|
|
5630
|
+
}
|
|
5631
|
+
function isOutputStorageFailure(error) {
|
|
5632
|
+
return error instanceof CapturedOutputProtectionError && error.reason === "output_storage_failed";
|
|
5633
|
+
}
|
|
5634
|
+
function isAdmittedOutputRead(stream, offset, length, receipt) {
|
|
5635
|
+
if (stream !== "stdout" && stream !== "stderr") return false;
|
|
5636
|
+
if (!Number.isSafeInteger(offset) || offset < 0) return false;
|
|
5637
|
+
if (!Number.isSafeInteger(length) || length < 0) return false;
|
|
5638
|
+
const size = stream === "stdout" ? receipt.stdoutBytes : receipt.stderrBytes;
|
|
5639
|
+
return offset <= size;
|
|
5640
|
+
}
|
|
5641
|
+
|
|
5642
|
+
// src/computer-access/companion/command-output-protocol.ts
|
|
5643
|
+
var SYSTEM_OUTPUT_CAPABILITY = "system_command_output_v1";
|
|
5644
|
+
var SYSTEM_OUTPUT_CHUNK_BYTES = 64 * 1024;
|
|
5645
|
+
function isStreamByteCount(value) {
|
|
5646
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
5647
|
+
}
|
|
5648
|
+
function isStreamDigest(value) {
|
|
5649
|
+
return typeof value === "string" && /^[a-f0-9]{64}$/.test(value);
|
|
5650
|
+
}
|
|
5651
|
+
function readSystemOutputTransfer(value) {
|
|
5652
|
+
if (!isHostRecord(value)) throw new Error("system_output_receipt_invalid");
|
|
5653
|
+
if (value.kind !== SYSTEM_OUTPUT_CAPABILITY) throw new Error("system_output_receipt_invalid");
|
|
5654
|
+
if (!isHostIdentifier(value.id)) throw new Error("system_output_receipt_invalid");
|
|
5655
|
+
if (!isStreamByteCount(value.stdoutBytes)) throw new Error("system_output_receipt_invalid");
|
|
5656
|
+
if (!isStreamByteCount(value.stderrBytes)) throw new Error("system_output_receipt_invalid");
|
|
5657
|
+
if (!isStreamDigest(value.stdoutSha256)) throw new Error("system_output_receipt_invalid");
|
|
5658
|
+
if (!isStreamDigest(value.stderrSha256)) throw new Error("system_output_receipt_invalid");
|
|
5659
|
+
return {
|
|
5660
|
+
kind: SYSTEM_OUTPUT_CAPABILITY,
|
|
5661
|
+
id: value.id,
|
|
5662
|
+
stdoutBytes: value.stdoutBytes,
|
|
5663
|
+
stderrBytes: value.stderrBytes,
|
|
5664
|
+
stdoutSha256: value.stdoutSha256,
|
|
5665
|
+
stderrSha256: value.stderrSha256
|
|
5666
|
+
};
|
|
5667
|
+
}
|
|
5668
|
+
|
|
5669
|
+
// plugins/system/source/command-working-directory.ts
|
|
5670
|
+
var import_node_path9 = require("node:path");
|
|
5671
|
+
function createSystemCommandPathAdapter(adapter, snapshot, resolver) {
|
|
5672
|
+
if (!resolver) return adapter;
|
|
5673
|
+
return {
|
|
5674
|
+
...adapter,
|
|
5675
|
+
normalizeCall(input) {
|
|
5676
|
+
const call = adapter?.normalizeCall?.(input) ?? input;
|
|
5677
|
+
if (!hasNativeWindowsRelativeDirectory(call, snapshot)) return call;
|
|
5678
|
+
const directory = resolver.resolve(call.params.cwd, {
|
|
5679
|
+
requirePath: true,
|
|
5680
|
+
allowedLocations: ["agent_work", "workspace"]
|
|
5681
|
+
});
|
|
5682
|
+
return {
|
|
5683
|
+
...call,
|
|
5684
|
+
params: { ...call.params, cwd: directory.absolutePath }
|
|
5685
|
+
};
|
|
5686
|
+
}
|
|
5170
5687
|
};
|
|
5171
5688
|
}
|
|
5689
|
+
function hasNativeWindowsRelativeDirectory(call, snapshot) {
|
|
5690
|
+
if (call.tool !== "system_command") return false;
|
|
5691
|
+
if (call.params.target !== "windows") return false;
|
|
5692
|
+
if (typeof call.params.cwd !== "string") return false;
|
|
5693
|
+
if (import_node_path9.win32.isAbsolute(call.params.cwd.trim())) return false;
|
|
5694
|
+
const route = snapshot.find((entry) => {
|
|
5695
|
+
if (entry.kind !== "native") return false;
|
|
5696
|
+
if (entry.target.id !== "windows") return false;
|
|
5697
|
+
return entry.target.transport === "native";
|
|
5698
|
+
});
|
|
5699
|
+
return route !== void 0;
|
|
5700
|
+
}
|
|
5172
5701
|
|
|
5173
5702
|
// plugins/system/source/computer/public-action.ts
|
|
5174
5703
|
function readPublicComputerAction(params) {
|
|
@@ -5331,8 +5860,115 @@ function fits(value) {
|
|
|
5331
5860
|
return Buffer.byteLength(value, "utf8") <= COMPUTER_OBSERVATION_OUTPUT_MAX_BYTES;
|
|
5332
5861
|
}
|
|
5333
5862
|
|
|
5863
|
+
// plugins/system/source/security/secret-text.ts
|
|
5864
|
+
var REDACTED = "[REDACTED]";
|
|
5865
|
+
var CREDENTIAL_KEY_SOURCE = String.raw`(?:[A-Za-z][A-Za-z0-9_-]*\.)*(?:[A-Za-z][A-Za-z0-9]*[-_])*(?:password|passwd|pwd|api[_ -]?key|access[_ -]?token|refresh[_ -]?token|client[_ -]?secret|secret[_ -]?access[_ -]?key|recovery[_ -]?code)`;
|
|
5866
|
+
var credentialIndicator = new RegExp(
|
|
5867
|
+
String.raw`(?<![\p{L}\p{N}_.-])(?:-{1,2})?(?:${CREDENTIAL_KEY_SOURCE}|(?:proxy-)?authorization)[\s"'\\]*[:=]`,
|
|
5868
|
+
"iu"
|
|
5869
|
+
);
|
|
5870
|
+
function detectionText(input) {
|
|
5871
|
+
const percentDecoded = input.replace(
|
|
5872
|
+
/%([0-7][0-9a-f])/giu,
|
|
5873
|
+
(_, hex) => String.fromCharCode(Number.parseInt(hex, 16))
|
|
5874
|
+
);
|
|
5875
|
+
return percentDecoded.replace(
|
|
5876
|
+
/\\(?:u00|x|U000000)([0-7][0-9a-fA-F])/gu,
|
|
5877
|
+
(_, hex) => String.fromCharCode(Number.parseInt(hex, 16))
|
|
5878
|
+
);
|
|
5879
|
+
}
|
|
5880
|
+
function hasPrivateKeyIndicator(text) {
|
|
5881
|
+
return /-----BEGIN (?:[A-Z0-9]+ )*PRIVATE KEY(?: BLOCK)?-----/u.test(text);
|
|
5882
|
+
}
|
|
5883
|
+
function hasUrlCredentials(text) {
|
|
5884
|
+
return /\b[a-z][a-z0-9+.-]*(?::|%3a)(?:\/|%2f){2}[^\s/?#<>]*(?:@|%40)/iu.test(text);
|
|
5885
|
+
}
|
|
5886
|
+
function hasAuthorizationCredentials(text) {
|
|
5887
|
+
for (const match of text.matchAll(
|
|
5888
|
+
/\b(Bearer|Basic)[ \t]+([A-Za-z0-9._~+/-]+={0,2})/giu
|
|
5889
|
+
)) {
|
|
5890
|
+
if (match[1].toLowerCase() === "bearer") return true;
|
|
5891
|
+
const value = match[2];
|
|
5892
|
+
if (!/^[A-Za-z0-9+/]+={0,2}$/u.test(value)) continue;
|
|
5893
|
+
if (value.length < 8) continue;
|
|
5894
|
+
if (Buffer.from(value, "base64").toString("utf8").includes(":")) return true;
|
|
5895
|
+
}
|
|
5896
|
+
return false;
|
|
5897
|
+
}
|
|
5898
|
+
function isAwsAccessKeyValue(value, atEnd) {
|
|
5899
|
+
if (/^[A-Z0-9]{16}$/u.test(value)) return true;
|
|
5900
|
+
if (!atEnd) return false;
|
|
5901
|
+
return /^[A-Z0-9]{4,15}$/u.test(value);
|
|
5902
|
+
}
|
|
5903
|
+
function isRecognizedProviderToken(prefix, value, atEnd) {
|
|
5904
|
+
if (prefix === "AKIA" || prefix === "ASIA")
|
|
5905
|
+
return isAwsAccessKeyValue(value, atEnd);
|
|
5906
|
+
if (value.length >= 20) return true;
|
|
5907
|
+
const partialMinimum = prefix === "sk-" ? 8 : 1;
|
|
5908
|
+
return atEnd && value.length >= partialMinimum;
|
|
5909
|
+
}
|
|
5910
|
+
function hasProviderToken(text) {
|
|
5911
|
+
const provider = /\b(sk-(?:proj-|svcacct-)?|gh[pousr]_|github_pat_|xox[baprs]-|AKIA|ASIA)([A-Za-z0-9_-]+)/gu;
|
|
5912
|
+
for (const match of text.matchAll(provider)) {
|
|
5913
|
+
const atEnd = match.index + match[0].length === text.length;
|
|
5914
|
+
if (isRecognizedProviderToken(match[1], match[2], atEnd)) return true;
|
|
5915
|
+
}
|
|
5916
|
+
return false;
|
|
5917
|
+
}
|
|
5918
|
+
function compactJoseSegmentCount(header) {
|
|
5919
|
+
try {
|
|
5920
|
+
const value = JSON.parse(
|
|
5921
|
+
Buffer.from(header, "base64url").toString("utf8")
|
|
5922
|
+
);
|
|
5923
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
5924
|
+
return void 0;
|
|
5925
|
+
const fields = value;
|
|
5926
|
+
if (typeof fields.alg !== "string") return void 0;
|
|
5927
|
+
return typeof fields.enc === "string" ? 5 : 3;
|
|
5928
|
+
} catch {
|
|
5929
|
+
return void 0;
|
|
5930
|
+
}
|
|
5931
|
+
}
|
|
5932
|
+
function hasCompactJoseToken(text) {
|
|
5933
|
+
const jose = /\b([A-Za-z0-9_-]+)(?:\.[A-Za-z0-9_-]*)+/gu;
|
|
5934
|
+
for (const match of text.matchAll(jose)) {
|
|
5935
|
+
const parts = match[0].split(".");
|
|
5936
|
+
const capturedAtEnd = match.index + match[0].length === text.length;
|
|
5937
|
+
for (let index = 0; index < parts.length - 1; index += 1) {
|
|
5938
|
+
const expected = compactJoseSegmentCount(parts[index]);
|
|
5939
|
+
if (expected === void 0) continue;
|
|
5940
|
+
if (expected === 3 && parts[index + 1] === "") continue;
|
|
5941
|
+
if (parts.length - index >= expected) return true;
|
|
5942
|
+
if (capturedAtEnd) return true;
|
|
5943
|
+
}
|
|
5944
|
+
}
|
|
5945
|
+
return false;
|
|
5946
|
+
}
|
|
5947
|
+
function hasSecretIndicator(text) {
|
|
5948
|
+
if (credentialIndicator.test(text)) return true;
|
|
5949
|
+
if (hasPrivateKeyIndicator(text)) return true;
|
|
5950
|
+
if (hasUrlCredentials(text)) return true;
|
|
5951
|
+
if (hasAuthorizationCredentials(text)) return true;
|
|
5952
|
+
if (hasProviderToken(text)) return true;
|
|
5953
|
+
return hasCompactJoseToken(text);
|
|
5954
|
+
}
|
|
5955
|
+
function redactSecretText(input) {
|
|
5956
|
+
if (hasSecretIndicator(input)) return REDACTED;
|
|
5957
|
+
if (hasSecretIndicator(detectionText(input))) return REDACTED;
|
|
5958
|
+
return input;
|
|
5959
|
+
}
|
|
5960
|
+
|
|
5961
|
+
// plugins/system/source/security/observed-error.ts
|
|
5962
|
+
function protectObservedError(error, fallback) {
|
|
5963
|
+
try {
|
|
5964
|
+
return redactSecretText(error instanceof Error ? error.message : fallback);
|
|
5965
|
+
} catch {
|
|
5966
|
+
return "Observed error details withheld because the protection check failed.";
|
|
5967
|
+
}
|
|
5968
|
+
}
|
|
5969
|
+
|
|
5334
5970
|
// plugins/system/source/computer/request-computers.ts
|
|
5335
|
-
var
|
|
5971
|
+
var import_node_crypto8 = require("node:crypto");
|
|
5336
5972
|
|
|
5337
5973
|
// plugins/system/source/request-target-snapshot.ts
|
|
5338
5974
|
async function captureSystemTargetSnapshot(input) {
|
|
@@ -5420,7 +6056,7 @@ function systemRouteMetadata(route) {
|
|
|
5420
6056
|
return {
|
|
5421
6057
|
displayTarget: route.target,
|
|
5422
6058
|
transport: "host_companion",
|
|
5423
|
-
computerName: route.identity.name
|
|
6059
|
+
computerName: redactSecretText(route.identity.name)
|
|
5424
6060
|
};
|
|
5425
6061
|
}
|
|
5426
6062
|
function observeCapturedSystemTargets(snapshot) {
|
|
@@ -5449,14 +6085,14 @@ function modelSafeRouteObservation(route) {
|
|
|
5449
6085
|
}
|
|
5450
6086
|
|
|
5451
6087
|
// plugins/system/source/computer/desktop-bindings.ts
|
|
5452
|
-
var
|
|
6088
|
+
var import_node_crypto7 = require("node:crypto");
|
|
5453
6089
|
var DesktopBindings = class {
|
|
5454
6090
|
current;
|
|
5455
6091
|
windows = /* @__PURE__ */ new Map();
|
|
5456
6092
|
observe(result) {
|
|
5457
6093
|
this.windows.clear();
|
|
5458
6094
|
const windows = result.windows.map((window) => {
|
|
5459
|
-
const id2 = (0,
|
|
6095
|
+
const id2 = (0, import_node_crypto7.randomUUID)();
|
|
5460
6096
|
this.windows.set(id2, window.binding);
|
|
5461
6097
|
const { binding: _binding, ...details } = window;
|
|
5462
6098
|
return {
|
|
@@ -5472,7 +6108,7 @@ var DesktopBindings = class {
|
|
|
5472
6108
|
observation_ref: void 0,
|
|
5473
6109
|
coordinateSpace: result.desktop.coordinateSpace ?? "native_desktop"
|
|
5474
6110
|
};
|
|
5475
|
-
const id = (0,
|
|
6111
|
+
const id = (0, import_node_crypto7.randomUUID)();
|
|
5476
6112
|
this.current = {
|
|
5477
6113
|
id,
|
|
5478
6114
|
issuedAt: Date.now(),
|
|
@@ -5567,7 +6203,7 @@ var DesktopBindings = class {
|
|
|
5567
6203
|
this.current = void 0;
|
|
5568
6204
|
this.windows.clear();
|
|
5569
6205
|
}
|
|
5570
|
-
regionalObservation(observationRef,
|
|
6206
|
+
regionalObservation(observationRef, rectangle2) {
|
|
5571
6207
|
const current = this.current;
|
|
5572
6208
|
if (!current || current.id !== observationRef)
|
|
5573
6209
|
throw new SystemOperationError(
|
|
@@ -5575,7 +6211,7 @@ var DesktopBindings = class {
|
|
|
5575
6211
|
"Use a current observation to select a smaller region."
|
|
5576
6212
|
);
|
|
5577
6213
|
const observation = current.observation;
|
|
5578
|
-
if (!isRegionInsideImage(
|
|
6214
|
+
if (!isRegionInsideImage(rectangle2, observation))
|
|
5579
6215
|
throw new SystemOperationError(
|
|
5580
6216
|
"computer_region_outside_image",
|
|
5581
6217
|
"Select a region inside the returned image."
|
|
@@ -5587,10 +6223,10 @@ var DesktopBindings = class {
|
|
|
5587
6223
|
desktopBinding: current.result.desktop.binding,
|
|
5588
6224
|
expectedGeometry: current.result.desktop.bounds,
|
|
5589
6225
|
region: {
|
|
5590
|
-
x: Math.round(observation.region.x +
|
|
5591
|
-
y: Math.round(observation.region.y +
|
|
5592
|
-
width: Math.max(1, Math.floor(
|
|
5593
|
-
height: Math.max(1, Math.floor(
|
|
6226
|
+
x: Math.round(observation.region.x + rectangle2.x * scaleX),
|
|
6227
|
+
y: Math.round(observation.region.y + rectangle2.y * scaleY),
|
|
6228
|
+
width: Math.max(1, Math.floor(rectangle2.width * scaleX)),
|
|
6229
|
+
height: Math.max(1, Math.floor(rectangle2.height * scaleY))
|
|
5594
6230
|
}
|
|
5595
6231
|
};
|
|
5596
6232
|
}
|
|
@@ -5622,10 +6258,10 @@ function imageRectangle(bounds, observation) {
|
|
|
5622
6258
|
height: bounds.height * scaleY
|
|
5623
6259
|
};
|
|
5624
6260
|
}
|
|
5625
|
-
function isRegionInsideImage(
|
|
5626
|
-
if (
|
|
5627
|
-
if (
|
|
5628
|
-
return
|
|
6261
|
+
function isRegionInsideImage(rectangle2, observation) {
|
|
6262
|
+
if (rectangle2.x < 0 || rectangle2.y < 0) return false;
|
|
6263
|
+
if (rectangle2.x + rectangle2.width > observation.imageWidth) return false;
|
|
6264
|
+
return rectangle2.y + rectangle2.height <= observation.imageHeight;
|
|
5629
6265
|
}
|
|
5630
6266
|
function translateAction(action, observation) {
|
|
5631
6267
|
const point = (value) => {
|
|
@@ -5650,6 +6286,131 @@ function translateAction(action, observation) {
|
|
|
5650
6286
|
return action;
|
|
5651
6287
|
}
|
|
5652
6288
|
|
|
6289
|
+
// plugins/system/source/security/desktop-result.ts
|
|
6290
|
+
function rectangle(value) {
|
|
6291
|
+
return { x: value.x, y: value.y, width: value.width, height: value.height };
|
|
6292
|
+
}
|
|
6293
|
+
function projectDesktopFields(result, text) {
|
|
6294
|
+
const capability = (value) => ({
|
|
6295
|
+
supported: value.supported,
|
|
6296
|
+
available: value.available,
|
|
6297
|
+
...value.reason === void 0 ? {} : { reason: text(value.reason) }
|
|
6298
|
+
});
|
|
6299
|
+
const desktop = result.desktop;
|
|
6300
|
+
return {
|
|
6301
|
+
desktop: {
|
|
6302
|
+
platform: desktop.platform,
|
|
6303
|
+
binding: desktop.binding,
|
|
6304
|
+
name: text(desktop.name),
|
|
6305
|
+
available: desktop.available,
|
|
6306
|
+
...desktop.reason === void 0 ? {} : { reason: text(desktop.reason) },
|
|
6307
|
+
bounds: rectangle(desktop.bounds),
|
|
6308
|
+
...desktop.coordinateSpace === void 0 ? {} : { coordinateSpace: desktop.coordinateSpace },
|
|
6309
|
+
capabilities: {
|
|
6310
|
+
capture: capability(desktop.capabilities.capture),
|
|
6311
|
+
accessibility: capability(desktop.capabilities.accessibility),
|
|
6312
|
+
input: capability(desktop.capabilities.input),
|
|
6313
|
+
windows: capability(desktop.capabilities.windows)
|
|
6314
|
+
},
|
|
6315
|
+
targetingGuarantee: desktop.targetingGuarantee
|
|
6316
|
+
},
|
|
6317
|
+
windows: result.windows.map((window) => ({
|
|
6318
|
+
binding: window.binding,
|
|
6319
|
+
title: text(window.title),
|
|
6320
|
+
...window.application === void 0 ? {} : { application: text(window.application) },
|
|
6321
|
+
bounds: rectangle(window.bounds),
|
|
6322
|
+
focused: window.focused
|
|
6323
|
+
})),
|
|
6324
|
+
...result.focusedWindow === void 0 ? {} : { focusedWindow: result.focusedWindow },
|
|
6325
|
+
...result.observation ? {
|
|
6326
|
+
observation: {
|
|
6327
|
+
capturedAt: text(result.observation.capturedAt),
|
|
6328
|
+
region: rectangle(result.observation.region),
|
|
6329
|
+
imageWidth: result.observation.imageWidth,
|
|
6330
|
+
imageHeight: result.observation.imageHeight,
|
|
6331
|
+
accessibility: result.observation.accessibility.map((node) => ({
|
|
6332
|
+
role: text(node.role),
|
|
6333
|
+
...node.name === void 0 ? {} : { name: text(node.name) },
|
|
6334
|
+
...node.value === void 0 ? {} : { value: text(node.value) },
|
|
6335
|
+
...node.bounds === void 0 ? {} : { bounds: rectangle(node.bounds) },
|
|
6336
|
+
...node.focused === void 0 ? {} : { focused: node.focused }
|
|
6337
|
+
})),
|
|
6338
|
+
accessibilityTruncated: result.observation.accessibilityTruncated
|
|
6339
|
+
}
|
|
6340
|
+
} : {},
|
|
6341
|
+
...result.dispatch ? {
|
|
6342
|
+
dispatch: {
|
|
6343
|
+
status: result.dispatch.status,
|
|
6344
|
+
requestedInputCount: result.dispatch.requestedInputCount,
|
|
6345
|
+
...result.dispatch.acceptedInputCount === void 0 ? {} : { acceptedInputCount: result.dispatch.acceptedInputCount },
|
|
6346
|
+
...result.dispatch.reason === void 0 ? {} : { reason: text(result.dispatch.reason) }
|
|
6347
|
+
}
|
|
6348
|
+
} : {},
|
|
6349
|
+
...result.error ? {
|
|
6350
|
+
error: {
|
|
6351
|
+
code: text(result.error.code),
|
|
6352
|
+
message: text(result.error.message)
|
|
6353
|
+
}
|
|
6354
|
+
} : {}
|
|
6355
|
+
};
|
|
6356
|
+
}
|
|
6357
|
+
function protectDesktopResult(result, scan = redactSecretText) {
|
|
6358
|
+
let suspected = false;
|
|
6359
|
+
try {
|
|
6360
|
+
const protectedResult = projectDesktopFields(result, (input) => {
|
|
6361
|
+
const output = scan(input);
|
|
6362
|
+
if (typeof output !== "string")
|
|
6363
|
+
throw new Error("desktop_text_scan_failed");
|
|
6364
|
+
suspected ||= output !== input;
|
|
6365
|
+
return output;
|
|
6366
|
+
});
|
|
6367
|
+
if (!suspected)
|
|
6368
|
+
return {
|
|
6369
|
+
...protectedResult,
|
|
6370
|
+
...result.image ? {
|
|
6371
|
+
image: {
|
|
6372
|
+
mimeType: result.image.mimeType,
|
|
6373
|
+
bytes: result.image.bytes
|
|
6374
|
+
}
|
|
6375
|
+
} : {}
|
|
6376
|
+
};
|
|
6377
|
+
result.image?.bytes.fill(0);
|
|
6378
|
+
return {
|
|
6379
|
+
...protectedResult,
|
|
6380
|
+
...result.image && !protectedResult.error ? {
|
|
6381
|
+
error: {
|
|
6382
|
+
code: "computer_image_secret_blocked",
|
|
6383
|
+
message: "Image withheld because desktop text contained a suspected secret. The dispatch receipt is unchanged."
|
|
6384
|
+
}
|
|
6385
|
+
} : {}
|
|
6386
|
+
};
|
|
6387
|
+
} catch {
|
|
6388
|
+
result.image?.bytes.fill(0);
|
|
6389
|
+
const safe = projectDesktopFields(result, () => "[REDACTED]");
|
|
6390
|
+
return {
|
|
6391
|
+
desktop: {
|
|
6392
|
+
...safe.desktop,
|
|
6393
|
+
reason: "Desktop content withheld because its protection check failed."
|
|
6394
|
+
},
|
|
6395
|
+
windows: [],
|
|
6396
|
+
...safe.focusedWindow === void 0 ? {} : { focusedWindow: safe.focusedWindow },
|
|
6397
|
+
...safe.dispatch ? { dispatch: safe.dispatch } : {},
|
|
6398
|
+
error: {
|
|
6399
|
+
code: "computer_observation_protection_failed",
|
|
6400
|
+
message: "Desktop content withheld because its protection check failed. The dispatch receipt is unchanged."
|
|
6401
|
+
}
|
|
6402
|
+
};
|
|
6403
|
+
}
|
|
6404
|
+
}
|
|
6405
|
+
function protectNativeDesktopBackend(backend) {
|
|
6406
|
+
return {
|
|
6407
|
+
async execute(request, signal) {
|
|
6408
|
+
return protectDesktopResult(await backend.execute(request, signal));
|
|
6409
|
+
},
|
|
6410
|
+
close: () => backend.close()
|
|
6411
|
+
};
|
|
6412
|
+
}
|
|
6413
|
+
|
|
5653
6414
|
// plugins/system/source/computer/request-computers.ts
|
|
5654
6415
|
var RequestComputers = class {
|
|
5655
6416
|
constructor(rootDir, routes, connection, nativeFactory = createNativeComputerBackend, snapshot) {
|
|
@@ -5657,7 +6418,7 @@ var RequestComputers = class {
|
|
|
5657
6418
|
this.connection = connection;
|
|
5658
6419
|
this.nativeFactory = nativeFactory;
|
|
5659
6420
|
this.entries = snapshot === void 0 ? routes.map((route) => ({
|
|
5660
|
-
ref: (0,
|
|
6421
|
+
ref: (0, import_node_crypto8.randomUUID)(),
|
|
5661
6422
|
route,
|
|
5662
6423
|
bindings: new DesktopBindings()
|
|
5663
6424
|
})) : restoreComputers(routes, snapshot);
|
|
@@ -5704,7 +6465,7 @@ var RequestComputers = class {
|
|
|
5704
6465
|
"Install the companion from this Runtime build to enable desktop observation and input."
|
|
5705
6466
|
);
|
|
5706
6467
|
if (entry.backend) return entry.backend;
|
|
5707
|
-
entry.backend = entry.route.kind === "native" ? this.nativeFactory(entry.route.target) : createCompanionComputerBackend(
|
|
6468
|
+
entry.backend = entry.route.kind === "native" ? protectNativeDesktopBackend(this.nativeFactory(entry.route.target)) : createCompanionComputerBackend(
|
|
5708
6469
|
this.rootDir,
|
|
5709
6470
|
entry.route,
|
|
5710
6471
|
this.connection
|
|
@@ -5731,7 +6492,7 @@ function computerQueueIdentity(entry) {
|
|
|
5731
6492
|
}
|
|
5732
6493
|
function supportsComputerRoute(route) {
|
|
5733
6494
|
if (route.kind === "native") return true;
|
|
5734
|
-
return route.capabilities?.includes(COMPUTER_CAPABILITY) === true;
|
|
6495
|
+
return route.capabilities?.includes(COMPUTER_CAPABILITY) === true && route.capabilities.includes(HOST_SECRET_PROTECTION_CAPABILITY);
|
|
5735
6496
|
}
|
|
5736
6497
|
function restoreComputers(routes, value) {
|
|
5737
6498
|
if (!value || typeof value !== "object" || !("kind" in value) || value.kind !== "request_computers_v1" || !("entries" in value) || !Array.isArray(value.entries))
|
|
@@ -5780,7 +6541,7 @@ async function projectComputerResult(entry, result, context) {
|
|
|
5780
6541
|
);
|
|
5781
6542
|
media.push(image);
|
|
5782
6543
|
} catch (error) {
|
|
5783
|
-
imageFailure = error
|
|
6544
|
+
imageFailure = protectObservedError(error, "Image admission failed.");
|
|
5784
6545
|
} finally {
|
|
5785
6546
|
result.image.bytes.fill(0);
|
|
5786
6547
|
}
|
|
@@ -5791,7 +6552,10 @@ async function projectComputerResult(entry, result, context) {
|
|
|
5791
6552
|
description.observation_ref = void 0;
|
|
5792
6553
|
}
|
|
5793
6554
|
const hasPartialInputDispatch = result.dispatch?.status === "partial";
|
|
5794
|
-
const operationError = result.error ?? (hasPartialInputDispatch ? {
|
|
6555
|
+
const operationError = result.error ?? (hasPartialInputDispatch ? {
|
|
6556
|
+
code: "computer_input_partial",
|
|
6557
|
+
message: "Only part of the input was accepted."
|
|
6558
|
+
} : void 0);
|
|
5795
6559
|
const data = {
|
|
5796
6560
|
desktop_ref: entry.ref,
|
|
5797
6561
|
...description.observation_ref ? { observation_ref: description.observation_ref } : {},
|
|
@@ -5870,7 +6634,10 @@ function createComputerHandlers(computers) {
|
|
|
5870
6634
|
} catch (error) {
|
|
5871
6635
|
return failureResult({
|
|
5872
6636
|
errorCode: error instanceof SystemOperationError ? error.code : "computer_operation_interrupted",
|
|
5873
|
-
message:
|
|
6637
|
+
message: protectObservedError(
|
|
6638
|
+
error,
|
|
6639
|
+
"Computer operation interrupted; effects may be partial. Observe before another action."
|
|
6640
|
+
)
|
|
5874
6641
|
});
|
|
5875
6642
|
}
|
|
5876
6643
|
};
|
|
@@ -5891,7 +6658,10 @@ function createComputerHandlers(computers) {
|
|
|
5891
6658
|
return {
|
|
5892
6659
|
...computerRouteLabel(entry),
|
|
5893
6660
|
available: false,
|
|
5894
|
-
reason:
|
|
6661
|
+
reason: protectObservedError(
|
|
6662
|
+
error,
|
|
6663
|
+
"Desktop inspection failed."
|
|
6664
|
+
)
|
|
5895
6665
|
};
|
|
5896
6666
|
}
|
|
5897
6667
|
}
|
|
@@ -5960,20 +6730,34 @@ function requireMedia(context) {
|
|
|
5960
6730
|
);
|
|
5961
6731
|
}
|
|
5962
6732
|
|
|
6733
|
+
// plugins/system/source/computer/runtime-platform.ts
|
|
6734
|
+
function supportsRuntimeDesktopTools(platform = process.platform) {
|
|
6735
|
+
return platform !== "win32";
|
|
6736
|
+
}
|
|
6737
|
+
function unboundComputerFailure() {
|
|
6738
|
+
if (!supportsRuntimeDesktopTools())
|
|
6739
|
+
return failureResult({
|
|
6740
|
+
errorCode: "computer_runtime_platform_unsupported",
|
|
6741
|
+
message: "Desktop observation and control are unavailable on Windows Runtime. System commands and applications remain available."
|
|
6742
|
+
});
|
|
6743
|
+
return failureResult({
|
|
6744
|
+
errorCode: "computer_request_binding_required",
|
|
6745
|
+
message: "Computer control requires a prepared request."
|
|
6746
|
+
});
|
|
6747
|
+
}
|
|
6748
|
+
|
|
5963
6749
|
// plugins/system/source/computer/request-modules.ts
|
|
5964
6750
|
function unboundComputerHandlers() {
|
|
5965
6751
|
return Object.fromEntries(
|
|
5966
6752
|
COMPUTER_TOOLS.map((name) => [
|
|
5967
6753
|
name,
|
|
5968
|
-
async () =>
|
|
5969
|
-
errorCode: "computer_request_binding_required",
|
|
5970
|
-
message: "Computer control requires a prepared request."
|
|
5971
|
-
})
|
|
6754
|
+
async () => unboundComputerFailure()
|
|
5972
6755
|
])
|
|
5973
6756
|
);
|
|
5974
6757
|
}
|
|
5975
6758
|
function prepareComputerModules(rootDir, modules, routes, connection, preparation) {
|
|
5976
6759
|
if (modules.length === 0) return [];
|
|
6760
|
+
if (!supportsRuntimeDesktopTools()) return [];
|
|
5977
6761
|
const computers = new RequestComputers(
|
|
5978
6762
|
rootDir,
|
|
5979
6763
|
routes,
|
|
@@ -6026,6 +6810,77 @@ function prepareComputerModules(rootDir, modules, routes, connection, preparatio
|
|
|
6026
6810
|
}));
|
|
6027
6811
|
}
|
|
6028
6812
|
|
|
6813
|
+
// plugins/system/source/companion-command-output.ts
|
|
6814
|
+
var import_node_crypto9 = require("node:crypto");
|
|
6815
|
+
var import_node_string_decoder = require("node:string_decoder");
|
|
6816
|
+
function supportsCompanionCommandOutput(route) {
|
|
6817
|
+
return route.capabilities?.includes(SYSTEM_OUTPUT_CAPABILITY) === true;
|
|
6818
|
+
}
|
|
6819
|
+
async function executeCompanionCommand(input) {
|
|
6820
|
+
const { route, context } = input;
|
|
6821
|
+
const call = (operation, params, signal) => input.connection.executeHostOperation(input.rootDir, {
|
|
6822
|
+
hostId: route.hostId,
|
|
6823
|
+
connectionId: route.connectionId,
|
|
6824
|
+
operation,
|
|
6825
|
+
params: { ...params, target: route.target },
|
|
6826
|
+
...signal ? { abortSignal: signal } : {}
|
|
6827
|
+
});
|
|
6828
|
+
const receipt = await call("system_command_capture", {
|
|
6829
|
+
...input.params,
|
|
6830
|
+
...input.outputRetentionMs !== void 0 ? { outputRetentionMs: input.outputRetentionMs } : {}
|
|
6831
|
+
}, context?.abortSignal);
|
|
6832
|
+
if (!receipt.data?.outputTransfer && !receipt.ok) return receipt;
|
|
6833
|
+
let transfer;
|
|
6834
|
+
try {
|
|
6835
|
+
transfer = readSystemOutputTransfer(receipt.data?.outputTransfer);
|
|
6836
|
+
const stdout = await readStream(call, transfer, "stdout", context?.abortSignal);
|
|
6837
|
+
const stderr = await readStream(call, transfer, "stderr", context?.abortSignal);
|
|
6838
|
+
const { outputTransfer: _transfer, ...data } = receipt.data ?? {};
|
|
6839
|
+
const delivered = deliverPluginTextResult({
|
|
6840
|
+
...receipt,
|
|
6841
|
+
stdout,
|
|
6842
|
+
stderr: stderr || receipt.stderr,
|
|
6843
|
+
data: { ...data, outputDelivery: "complete", summaryOmittedChars: { stdout: stdout.length, stderr: stderr.length } }
|
|
6844
|
+
}, ["stdout", "stderr"], context?.resultBudget);
|
|
6845
|
+
if (delivered.errorCode === "plugin_result_too_large") return transferFailure(receipt, context);
|
|
6846
|
+
return delivered;
|
|
6847
|
+
} catch {
|
|
6848
|
+
return transferFailure(receipt, context);
|
|
6849
|
+
} finally {
|
|
6850
|
+
if (transfer) await call("system_command_output_close", { captureId: transfer.id }, AbortSignal.timeout(3e3)).catch(() => void 0);
|
|
6851
|
+
}
|
|
6852
|
+
}
|
|
6853
|
+
async function readStream(call, transfer, stream, signal) {
|
|
6854
|
+
const size = stream === "stdout" ? transfer.stdoutBytes : transfer.stderrBytes;
|
|
6855
|
+
const digest = stream === "stdout" ? transfer.stdoutSha256 : transfer.stderrSha256;
|
|
6856
|
+
const hash = (0, import_node_crypto9.createHash)("sha256");
|
|
6857
|
+
const decoder = new import_node_string_decoder.StringDecoder("utf8");
|
|
6858
|
+
let text = "";
|
|
6859
|
+
for (let offset = 0; offset < size; offset += SYSTEM_OUTPUT_CHUNK_BYTES) {
|
|
6860
|
+
signal?.throwIfAborted();
|
|
6861
|
+
const part = await call("system_command_output", { captureId: transfer.id, stream, offset }, signal);
|
|
6862
|
+
if (!part.ok) throw new Error("system_output_transfer_failed");
|
|
6863
|
+
const data = part.data;
|
|
6864
|
+
if (data?.captureId !== transfer.id || data.stream !== stream || data.offset !== offset) throw new Error("system_output_chunk_binding_invalid");
|
|
6865
|
+
if (typeof data.bytes !== "string" || data.bytes.length > SYSTEM_OUTPUT_CHUNK_BYTES * 2) throw new Error("system_output_chunk_invalid");
|
|
6866
|
+
const bytes = Buffer.from(data.bytes, "base64");
|
|
6867
|
+
if (bytes.toString("base64") !== data.bytes) throw new Error("system_output_chunk_invalid");
|
|
6868
|
+
if (bytes.length !== Math.min(SYSTEM_OUTPUT_CHUNK_BYTES, size - offset)) throw new Error("system_output_chunk_size_invalid");
|
|
6869
|
+
hash.update(bytes);
|
|
6870
|
+
text += decoder.write(bytes);
|
|
6871
|
+
}
|
|
6872
|
+
if (hash.digest("hex") !== digest) throw new Error("system_output_digest_invalid");
|
|
6873
|
+
return text + decoder.end();
|
|
6874
|
+
}
|
|
6875
|
+
function transferFailure(receipt, context) {
|
|
6876
|
+
return failureResult({
|
|
6877
|
+
errorCode: "system_output_delivery_pending",
|
|
6878
|
+
message: "The command settled, but its retained output could not be delivered completely. Process receipt is preserved; the command was not replayed.",
|
|
6879
|
+
...receipt.exitCode !== void 0 ? { exitCode: receipt.exitCode } : {},
|
|
6880
|
+
data: { ...receipt.data, outputDelivery: "pending", commandOk: receipt.ok, commandErrorCode: receipt.errorCode ?? null }
|
|
6881
|
+
}, context?.resultBudget);
|
|
6882
|
+
}
|
|
6883
|
+
|
|
6029
6884
|
// plugins/system/source/host-dispatch.ts
|
|
6030
6885
|
var defaultSystemHostConnection = {
|
|
6031
6886
|
readHostStatus,
|
|
@@ -6060,6 +6915,18 @@ function boundOperation(input, operation) {
|
|
|
6060
6915
|
const route = requireSystemRequestRoute(input.snapshot, params.target);
|
|
6061
6916
|
if (route.kind === "native")
|
|
6062
6917
|
return await input.nativeHandlers[operation](params, context);
|
|
6918
|
+
if (!supportsProtectedCompanionResults(route.capabilities))
|
|
6919
|
+
return failureResult({
|
|
6920
|
+
errorCode: "system_companion_protection_upgrade_required",
|
|
6921
|
+
message: "Update Companion to enable protected system results. The operation was not dispatched."
|
|
6922
|
+
});
|
|
6923
|
+
if (operation === "system_command" && !supportsCompanionCommandOutput(route))
|
|
6924
|
+
return failureResult({
|
|
6925
|
+
errorCode: "system_companion_protection_upgrade_required",
|
|
6926
|
+
message: "Update Companion to enable protected complete command output. The command was not dispatched."
|
|
6927
|
+
});
|
|
6928
|
+
if (operation === "system_command")
|
|
6929
|
+
return await executeCompanionCommand({ ...input, route, params, context });
|
|
6063
6930
|
return await input.connection.executeHostOperation(input.rootDir, {
|
|
6064
6931
|
hostId: route.hostId,
|
|
6065
6932
|
connectionId: route.connectionId,
|
|
@@ -6069,7 +6936,7 @@ function boundOperation(input, operation) {
|
|
|
6069
6936
|
});
|
|
6070
6937
|
} catch (error) {
|
|
6071
6938
|
if (error instanceof SystemOperationError)
|
|
6072
|
-
return failureResult({ errorCode: error.code, message: error.message });
|
|
6939
|
+
return failureResult({ errorCode: error.code, message: redactSecretText(error.message) });
|
|
6073
6940
|
return failureResult({
|
|
6074
6941
|
errorCode: "system_execution_route_failed",
|
|
6075
6942
|
message: "The bound execution route failed. No other destination was attempted; effects may be partial if dispatch began."
|
|
@@ -6077,6 +6944,9 @@ function boundOperation(input, operation) {
|
|
|
6077
6944
|
}
|
|
6078
6945
|
};
|
|
6079
6946
|
}
|
|
6947
|
+
function supportsProtectedCompanionResults(capabilities) {
|
|
6948
|
+
return capabilities?.includes(HOST_SECRET_PROTECTION_CAPABILITY) === true;
|
|
6949
|
+
}
|
|
6080
6950
|
function hasConnectionControl(params) {
|
|
6081
6951
|
if (Object.hasOwn(params, "host_id")) return true;
|
|
6082
6952
|
if (Object.hasOwn(params, "hostId")) return true;
|
|
@@ -6112,10 +6982,18 @@ async function prepareSystemRequestModules(rootDir, modules, dependencies = {},
|
|
|
6112
6982
|
rootDir,
|
|
6113
6983
|
snapshot,
|
|
6114
6984
|
connection,
|
|
6115
|
-
nativeHandlers
|
|
6985
|
+
nativeHandlers,
|
|
6986
|
+
outputRetentionMs: dependencies.outputRetentionMs
|
|
6116
6987
|
});
|
|
6117
6988
|
return Object.freeze([
|
|
6118
|
-
...modules.filter((module2) => !isComputerTool(module2.definition.name)).map(
|
|
6989
|
+
...modules.filter((module2) => !isComputerTool(module2.definition.name)).map(
|
|
6990
|
+
(module2) => projectSystemRequestModule(
|
|
6991
|
+
module2,
|
|
6992
|
+
snapshot,
|
|
6993
|
+
handlers,
|
|
6994
|
+
preparation?.runtimePathResolver
|
|
6995
|
+
)
|
|
6996
|
+
),
|
|
6119
6997
|
...computerModules
|
|
6120
6998
|
]);
|
|
6121
6999
|
}
|
|
@@ -6132,7 +7010,7 @@ function uniqueSystemCommandRoutes(candidates) {
|
|
|
6132
7010
|
return true;
|
|
6133
7011
|
});
|
|
6134
7012
|
}
|
|
6135
|
-
function projectSystemRequestModule(module2, snapshot, handlers) {
|
|
7013
|
+
function projectSystemRequestModule(module2, snapshot, handlers, resolver) {
|
|
6136
7014
|
const targets = Object.freeze(snapshot.map(routeTargetId));
|
|
6137
7015
|
const availability = ` Available targets for this request: ${targets.join(", ")}.`;
|
|
6138
7016
|
return Object.freeze({
|
|
@@ -6153,7 +7031,7 @@ function projectSystemRequestModule(module2, snapshot, handlers) {
|
|
|
6153
7031
|
},
|
|
6154
7032
|
implementation: handlers[module2.definition.name],
|
|
6155
7033
|
adapter: {
|
|
6156
|
-
...module2.adapter,
|
|
7034
|
+
...createSystemCommandPathAdapter(module2.adapter, snapshot, resolver),
|
|
6157
7035
|
executionBinding: systemExecutionBinding(snapshot)
|
|
6158
7036
|
}
|
|
6159
7037
|
});
|
|
@@ -6173,8 +7051,251 @@ function systemExecutionBinding(snapshot) {
|
|
|
6173
7051
|
};
|
|
6174
7052
|
}
|
|
6175
7053
|
|
|
7054
|
+
// plugins/system/source/local-command-output.ts
|
|
7055
|
+
var import_node_path11 = require("node:path");
|
|
7056
|
+
|
|
7057
|
+
// plugins/system/source/security/windows-output-directory.ts
|
|
7058
|
+
var import_node_child_process5 = require("node:child_process");
|
|
7059
|
+
var import_promises9 = require("node:fs/promises");
|
|
7060
|
+
var import_node_path10 = require("node:path");
|
|
7061
|
+
var import_node_util2 = require("node:util");
|
|
7062
|
+
var execute = (0, import_node_util2.promisify)(import_node_child_process5.execFile);
|
|
7063
|
+
var privateDirectoryScript = `
|
|
7064
|
+
$env:PSModulePath = "$PSHOME\\Modules"
|
|
7065
|
+
$ErrorActionPreference = 'Stop'
|
|
7066
|
+
$target = $env:ABOT_SYSTEM_OUTPUT_DIRECTORY
|
|
7067
|
+
$current = [System.Security.Principal.WindowsIdentity]::GetCurrent().User
|
|
7068
|
+
$item = Get-Item -LiteralPath $target -Force
|
|
7069
|
+
if (-not $item.PSIsContainer) { exit 2 }
|
|
7070
|
+
if (($item.Attributes -band [IO.FileAttributes]::ReparsePoint) -ne 0) { exit 2 }
|
|
7071
|
+
$inherit = [System.Security.AccessControl.InheritanceFlags]'ContainerInherit, ObjectInherit'
|
|
7072
|
+
if ($env:ABOT_SYSTEM_OUTPUT_CREATE_PRIVATE -eq '1') {
|
|
7073
|
+
$acl = New-Object System.Security.AccessControl.DirectorySecurity
|
|
7074
|
+
$acl.SetOwner($current)
|
|
7075
|
+
$acl.SetAccessRuleProtection($true, $false)
|
|
7076
|
+
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule($current, 'FullControl', $inherit, [System.Security.AccessControl.PropagationFlags]::None, [System.Security.AccessControl.AccessControlType]::Allow)
|
|
7077
|
+
$acl.AddAccessRule($rule)
|
|
7078
|
+
Set-Acl -LiteralPath $target -AclObject $acl
|
|
7079
|
+
}
|
|
7080
|
+
$observed = Get-Acl -LiteralPath $target
|
|
7081
|
+
if ($observed.GetOwner([System.Security.Principal.SecurityIdentifier]).Value -ne $current.Value) { exit 3 }
|
|
7082
|
+
if (-not $observed.AreAccessRulesProtected) { exit 4 }
|
|
7083
|
+
$rules = @($observed.GetAccessRules($true, $true, [System.Security.Principal.SecurityIdentifier]))
|
|
7084
|
+
if ($rules.Count -ne 1) { exit 5 }
|
|
7085
|
+
$rule = $rules[0]
|
|
7086
|
+
if ($rule.IdentityReference.Value -ne $current.Value) { exit 5 }
|
|
7087
|
+
if ($rule.AccessControlType -ne [System.Security.AccessControl.AccessControlType]::Allow) { exit 5 }
|
|
7088
|
+
if ($rule.FileSystemRights -ne [System.Security.AccessControl.FileSystemRights]::FullControl) { exit 5 }
|
|
7089
|
+
if ($rule.InheritanceFlags -ne $inherit) { exit 5 }
|
|
7090
|
+
if ($rule.PropagationFlags -ne [System.Security.AccessControl.PropagationFlags]::None) { exit 5 }
|
|
7091
|
+
`;
|
|
7092
|
+
async function verifyPrivateOutputDirectory(directory, create = false) {
|
|
7093
|
+
const info = await (0, import_promises9.lstat)(directory);
|
|
7094
|
+
if (!info.isDirectory() || info.isSymbolicLink()) throw new Error("output_directory_unavailable");
|
|
7095
|
+
const powershell = (0, import_node_path10.join)(process.env.SystemRoot ?? "C:\\Windows", "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
|
|
7096
|
+
await execute(powershell, [
|
|
7097
|
+
"-NoProfile",
|
|
7098
|
+
"-NonInteractive",
|
|
7099
|
+
"-EncodedCommand",
|
|
7100
|
+
Buffer.from(privateDirectoryScript, "utf16le").toString("base64")
|
|
7101
|
+
], {
|
|
7102
|
+
windowsHide: true,
|
|
7103
|
+
timeout: 1e4,
|
|
7104
|
+
maxBuffer: 16384,
|
|
7105
|
+
env: { ...process.env, ABOT_SYSTEM_OUTPUT_DIRECTORY: directory, ABOT_SYSTEM_OUTPUT_CREATE_PRIVATE: create ? "1" : "0" }
|
|
7106
|
+
});
|
|
7107
|
+
}
|
|
7108
|
+
function isAbsentPath(error) {
|
|
7109
|
+
if (!error || typeof error !== "object" || !("code" in error)) return false;
|
|
7110
|
+
return error.code === "ENOENT";
|
|
7111
|
+
}
|
|
7112
|
+
async function hasOutputDirectoryPath(directory) {
|
|
7113
|
+
try {
|
|
7114
|
+
await (0, import_promises9.lstat)(directory);
|
|
7115
|
+
return true;
|
|
7116
|
+
} catch (error) {
|
|
7117
|
+
if (isAbsentPath(error)) return false;
|
|
7118
|
+
throw error;
|
|
7119
|
+
}
|
|
7120
|
+
}
|
|
7121
|
+
async function installPrivateOutputDirectory(directory) {
|
|
7122
|
+
if (await hasOutputDirectoryPath(directory)) return;
|
|
7123
|
+
const parent = (0, import_node_path10.dirname)(directory);
|
|
7124
|
+
await (0, import_promises9.mkdir)(parent, { recursive: true });
|
|
7125
|
+
const candidate = await (0, import_promises9.mkdtemp)((0, import_node_path10.join)(parent, `.${(0, import_node_path10.basename)(directory)}.private-`));
|
|
7126
|
+
try {
|
|
7127
|
+
await verifyPrivateOutputDirectory(candidate, true);
|
|
7128
|
+
try {
|
|
7129
|
+
await (0, import_promises9.rename)(candidate, directory);
|
|
7130
|
+
} catch (error) {
|
|
7131
|
+
if (!await hasOutputDirectoryPath(directory)) throw error;
|
|
7132
|
+
}
|
|
7133
|
+
} finally {
|
|
7134
|
+
await (0, import_promises9.rmdir)(candidate).catch((error) => {
|
|
7135
|
+
if (!isAbsentPath(error)) throw error;
|
|
7136
|
+
});
|
|
7137
|
+
}
|
|
7138
|
+
}
|
|
7139
|
+
async function ensureWindowsOutputDirectory(directory) {
|
|
7140
|
+
if (process.platform !== "win32") return;
|
|
7141
|
+
try {
|
|
7142
|
+
await installPrivateOutputDirectory(directory);
|
|
7143
|
+
await verifyPrivateOutputDirectory(directory);
|
|
7144
|
+
} catch {
|
|
7145
|
+
throw new SystemOperationError("system_output_storage_failed", "Private output storage could not be prepared. The command was not dispatched.");
|
|
7146
|
+
}
|
|
7147
|
+
}
|
|
7148
|
+
|
|
7149
|
+
// plugins/system/source/local-command-output-retention.ts
|
|
7150
|
+
function scheduleLocalSystemOutputCleanup(root, retentionMs) {
|
|
7151
|
+
if (process.platform !== "win32") {
|
|
7152
|
+
scheduleSystemOutputCleanup(root, retentionMs);
|
|
7153
|
+
return Promise.resolve();
|
|
7154
|
+
}
|
|
7155
|
+
return ensureWindowsOutputDirectory(root).then(
|
|
7156
|
+
() => scheduleSystemOutputCleanup(root, retentionMs),
|
|
7157
|
+
() => process.emitWarning("SYSTEM output cleanup skipped because private storage could not be verified.", {
|
|
7158
|
+
code: "SYSTEM_OUTPUT_PRIVATE_STORAGE_UNAVAILABLE"
|
|
7159
|
+
})
|
|
7160
|
+
);
|
|
7161
|
+
}
|
|
7162
|
+
|
|
7163
|
+
// plugins/system/source/local-command-output.ts
|
|
7164
|
+
var CONTEXT_STREAMS = Object.freeze(["stdout", "stderr"]);
|
|
7165
|
+
function createLocalSystemCommandOutput(plugin) {
|
|
7166
|
+
const root = (0, import_node_path11.join)(plugin.stateDir, "command-output");
|
|
7167
|
+
const retentionMs = systemCommandOutputRetentionMs(plugin);
|
|
7168
|
+
const initialization = scheduleLocalSystemOutputCleanup(root, retentionMs);
|
|
7169
|
+
return (context) => {
|
|
7170
|
+
let captured;
|
|
7171
|
+
return {
|
|
7172
|
+
async run(input) {
|
|
7173
|
+
if (input.abortSignal?.aborted) return runSystemProcess(input);
|
|
7174
|
+
await initialization;
|
|
7175
|
+
await ensureWindowsOutputDirectory(root);
|
|
7176
|
+
captured = await createSystemOutputCapture(root, retentionMs, redactSecretText);
|
|
7177
|
+
let result;
|
|
7178
|
+
try {
|
|
7179
|
+
result = await runSystemProcess(input, captured.capture);
|
|
7180
|
+
} catch (error) {
|
|
7181
|
+
await captured.finish();
|
|
7182
|
+
throw error;
|
|
7183
|
+
}
|
|
7184
|
+
const streams = await captured.finish(result);
|
|
7185
|
+
return {
|
|
7186
|
+
...captured.processResult,
|
|
7187
|
+
stdout: streams.stdout,
|
|
7188
|
+
stderr: streams.stderr,
|
|
7189
|
+
outputTruncated: Boolean(captured.failure)
|
|
7190
|
+
};
|
|
7191
|
+
},
|
|
7192
|
+
async present(target, result) {
|
|
7193
|
+
if (captured?.failure) return outputFailure(target, result, context, captured.receipt, captured.failure, captured.failureKind);
|
|
7194
|
+
const receipt = buildSystemProcessResult(target, result, "command_process_completion");
|
|
7195
|
+
const delivered = deliverPluginTextResult({
|
|
7196
|
+
...receipt,
|
|
7197
|
+
data: { ...receipt.data, ...captured?.receipt ? { outputCapture: captured.receipt } : {} }
|
|
7198
|
+
}, CONTEXT_STREAMS, context?.resultBudget);
|
|
7199
|
+
if (delivered.errorCode === "plugin_result_too_large")
|
|
7200
|
+
return outputFailure(target, result, context, captured?.receipt);
|
|
7201
|
+
return delivered;
|
|
7202
|
+
}
|
|
7203
|
+
};
|
|
7204
|
+
};
|
|
7205
|
+
}
|
|
7206
|
+
function outputFailure(target, result, context, capture, captureFailure, failureKind) {
|
|
7207
|
+
const failureCode = failureKind === "security" ? "system_output_protection_failed" : "system_output_storage_failed";
|
|
7208
|
+
return failureResult({
|
|
7209
|
+
errorCode: captureFailure ? failureCode : "system_output_delivery_pending",
|
|
7210
|
+
message: "The command was dispatched. Its output could not be delivered completely; do not repeat the command just to retrieve output. Inspect the process receipt and retained capture.",
|
|
7211
|
+
...result.exitCode !== null ? { exitCode: result.exitCode } : {},
|
|
7212
|
+
data: {
|
|
7213
|
+
target: target.id,
|
|
7214
|
+
transport: target.transport,
|
|
7215
|
+
processStatus: result.status,
|
|
7216
|
+
spawnedProcess: result.spawnedProcess ?? null,
|
|
7217
|
+
exitCode: result.exitCode,
|
|
7218
|
+
outputCapture: capture ?? null,
|
|
7219
|
+
...captureFailure && failureKind === "security" ? { securityFailure: captureFailure } : {},
|
|
7220
|
+
...captureFailure && failureKind !== "security" ? { storageFailure: captureFailure } : {},
|
|
7221
|
+
outputDelivery: "pending",
|
|
7222
|
+
evidenceScope: "command_process_completion",
|
|
7223
|
+
independentOutcomeCheck: "not_performed",
|
|
7224
|
+
observationMeta: { kind: "volatile_external", carryPolicy: "never" }
|
|
7225
|
+
}
|
|
7226
|
+
}, context?.resultBudget);
|
|
7227
|
+
}
|
|
7228
|
+
function systemCommandOutputRetentionMs(plugin) {
|
|
7229
|
+
return readBoundedInteger(plugin.config?.outputRetentionMs, {
|
|
7230
|
+
name: "outputRetentionMs",
|
|
7231
|
+
defaultValue: DEFAULT_SYSTEM_OUTPUT_RETENTION_MS,
|
|
7232
|
+
minimum: 1,
|
|
7233
|
+
maximum: Number.MAX_SAFE_INTEGER
|
|
7234
|
+
});
|
|
7235
|
+
}
|
|
7236
|
+
|
|
7237
|
+
// plugins/system/source/security/system-results.ts
|
|
7238
|
+
var INCOMPLETE_STREAM = "[UNAVAILABLE: incomplete output cannot be scanned for secrets]";
|
|
7239
|
+
var SENSITIVE_TARGET = "Target unavailable because its shell identity contains sensitive text.";
|
|
7240
|
+
function protectApplication(application) {
|
|
7241
|
+
if (redactSecretText(application.id) !== application.id) return void 0;
|
|
7242
|
+
return { ...application, name: redactSecretText(application.name) };
|
|
7243
|
+
}
|
|
7244
|
+
function protectCatalog(catalog) {
|
|
7245
|
+
const applications = catalog.applications.flatMap((application) => {
|
|
7246
|
+
const protectedApplication = protectApplication(application);
|
|
7247
|
+
return protectedApplication ? [protectedApplication] : [];
|
|
7248
|
+
});
|
|
7249
|
+
return {
|
|
7250
|
+
...catalog,
|
|
7251
|
+
applications,
|
|
7252
|
+
complete: catalog.complete && applications.length === catalog.applications.length,
|
|
7253
|
+
scope: { ...catalog.scope, roots: catalog.scope.roots.map(redactSecretText) }
|
|
7254
|
+
};
|
|
7255
|
+
}
|
|
7256
|
+
function protectTargets(observation) {
|
|
7257
|
+
return {
|
|
7258
|
+
...observation,
|
|
7259
|
+
host: { ...observation.host, kernelRelease: redactSecretText(observation.host.kernelRelease) },
|
|
7260
|
+
targets: observation.targets.map((target) => {
|
|
7261
|
+
if (!target.available)
|
|
7262
|
+
return { ...target, reason: redactSecretText(target.reason) };
|
|
7263
|
+
if (redactSecretText(target.shell) !== target.shell)
|
|
7264
|
+
return { id: target.id, available: false, reason: SENSITIVE_TARGET };
|
|
7265
|
+
return target;
|
|
7266
|
+
})
|
|
7267
|
+
};
|
|
7268
|
+
}
|
|
7269
|
+
function protectProcess(result) {
|
|
7270
|
+
return {
|
|
7271
|
+
...result,
|
|
7272
|
+
stdout: result.outputTruncated ? INCOMPLETE_STREAM : redactSecretText(result.stdout),
|
|
7273
|
+
stderr: result.outputTruncated ? INCOMPLETE_STREAM : redactSecretText(result.stderr),
|
|
7274
|
+
...result.spawnedProcess ? {
|
|
7275
|
+
spawnedProcess: {
|
|
7276
|
+
...result.spawnedProcess,
|
|
7277
|
+
executable: redactSecretText(result.spawnedProcess.executable)
|
|
7278
|
+
}
|
|
7279
|
+
} : {}
|
|
7280
|
+
};
|
|
7281
|
+
}
|
|
7282
|
+
var systemResultProtection = Object.freeze({
|
|
7283
|
+
protectTargets,
|
|
7284
|
+
protectCatalog,
|
|
7285
|
+
protectProcess,
|
|
7286
|
+
protectApplication,
|
|
7287
|
+
protectMessage: redactSecretText
|
|
7288
|
+
});
|
|
7289
|
+
|
|
6176
7290
|
// plugins/system/source/index.ts
|
|
6177
|
-
var index_default = defineRuntimePlugin((
|
|
6178
|
-
|
|
6179
|
-
|
|
6180
|
-
|
|
7291
|
+
var index_default = defineRuntimePlugin((context) => {
|
|
7292
|
+
const output = createLocalSystemCommandOutput(context);
|
|
7293
|
+
return {
|
|
7294
|
+
handlers: { ...createSystemHandlers(void 0, void 0, output, systemResultProtection), ...unboundComputerHandlers() },
|
|
7295
|
+
prepareRequest: (modules, preparation) => prepareSystemRequestModules(context.rootDir, modules, {
|
|
7296
|
+
outputRetentionMs: systemCommandOutputRetentionMs(context),
|
|
7297
|
+
observeTargets: async () => systemResultProtection.protectTargets(await observeSystemTargets()),
|
|
7298
|
+
createNativeHandlers: (resolve) => createSystemHandlers(void 0, resolve, output, systemResultProtection)
|
|
7299
|
+
}, preparation)
|
|
7300
|
+
};
|
|
7301
|
+
});
|