@abot-ai/runtime 1.7.0 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +216 -222
- package/dist/src/capabilities/tool-definition-validator/definition-parser.js +8 -0
- package/dist/src/capabilities/tool-request-resources.d.ts +3 -0
- package/dist/src/capabilities/tool-types.d.ts +4 -0
- package/dist/src/cli/abot.js +2 -0
- package/dist/src/cli/host-companion-bundle.mjs +751 -333
- 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 +17 -6
- package/dist/src/computer-access/command-output-capture.js +134 -68
- 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/companion/command-output.d.ts +1 -0
- package/dist/src/computer-access/companion/command-output.js +23 -6
- package/dist/src/computer-access/companion/install-link-macos.js +2 -1
- package/dist/src/computer-access/companion/native-notifications.js +3 -2
- package/dist/src/computer-access/companion/native-session.js +6 -2
- 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/secret-protection-protocol.d.ts +6 -0
- package/dist/src/computer-access/companion/secret-protection-protocol.js +6 -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/handlers.d.ts +2 -1
- package/dist/src/computer-access/handlers.js +79 -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/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/protocol/message-contract.d.ts +1 -0
- package/dist/src/model-gateway/protocol/message-contract.js +1 -1
- 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/chat-handler.js +5 -7
- package/dist/src/model-gateway/server/chat-stream-response.d.ts +7 -0
- package/dist/src/model-gateway/server/chat-stream-response.js +25 -0
- 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/manifest.d.ts +2 -0
- 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 +4 -0
- package/dist/src/plugin-sdk/computer-access.js +1 -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/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/registered-tool-worker-capabilities/payload-rejection.d.ts +2 -2
- package/dist/src/runtime/adapters/registered-tool-worker-capabilities/payload-rejection.js +2 -2
- package/dist/src/runtime/adapters/registered-tool-worker-capabilities/prepared-execution.js +17 -11
- 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/capabilities/tool-availability.js +6 -0
- package/dist/src/runtime/context/capability-brief.d.ts +2 -2
- package/dist/src/runtime/context/capability-brief.js +3 -3
- package/dist/src/runtime/context/capability-descriptions.d.ts +3 -2
- package/dist/src/runtime/context/capability-descriptions.js +57 -20
- package/dist/src/runtime/local-host/windows-private-access.js +2 -0
- package/dist/src/runtime/long-term-memory/conversation-authoring/context.d.ts +6 -1
- package/dist/src/runtime/long-term-memory/conversation-authoring/context.js +51 -25
- package/dist/src/runtime/long-term-memory/initial-context.d.ts +17 -0
- package/dist/src/runtime/long-term-memory/initial-context.js +57 -0
- package/dist/src/runtime/long-term-memory/projection.js +1 -1
- package/dist/src/runtime/orchestration/role-calls/candidate-validation.js +2 -1
- package/dist/src/runtime/orchestration/role-calls/checkpoint-state.d.ts +1 -1
- package/dist/src/runtime/orchestration/role-calls/checkpoint-state.js +5 -2
- package/dist/src/runtime/orchestration/role-calls/contracts.d.ts +2 -1
- package/dist/src/runtime/orchestration/role-calls/ledger.d.ts +2 -1
- package/dist/src/runtime/orchestration/role-calls/ledger.js +2 -2
- package/dist/src/runtime/orchestration/role-calls/memory-recall-contract.d.ts +7 -0
- package/dist/src/runtime/orchestration/role-calls/memory-recall-state-validation.d.ts +2 -0
- package/dist/src/runtime/orchestration/role-calls/memory-recall-state-validation.js +88 -0
- package/dist/src/runtime/orchestration/role-calls/reducer.d.ts +1 -1
- package/dist/src/runtime/orchestration/role-calls/reducer.js +2 -1
- package/dist/src/runtime/orchestration/worker-capabilities/contracts.d.ts +3 -1
- package/dist/src/runtime/orchestration/worker-capabilities/contracts.js +1 -1
- package/dist/src/runtime/orchestration/worker-capabilities/execution/approval-group.js +5 -1
- package/dist/src/runtime/orchestration/worker-capabilities/execution/execution-freshness.d.ts +5 -0
- package/dist/src/runtime/orchestration/worker-capabilities/execution/execution-freshness.js +31 -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/installation/package.d.ts +8 -0
- package/dist/src/runtime/plugins/installation/package.js +2 -0
- package/dist/src/runtime/plugins/installation/service.d.ts +7 -0
- package/dist/src/runtime/plugins/loader.js +24 -14
- 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 +3 -0
- package/dist/src/runtime/plugins/manifest-validator.js +9 -1
- 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/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/capability-execution-freshness.js +6 -1
- package/dist/src/runtime/request/execution-agent-root-execution.js +11 -1
- package/dist/src/runtime/request/prepared-execution.js +3 -0
- package/dist/src/runtime/request/root-contract.d.ts +2 -0
- package/dist/src/runtime/request/root-execution-kernel.js +1 -0
- package/dist/src/runtime/request/runner.js +9 -3
- package/dist/src/runtime/request/supervisor-root-execution.js +6 -0
- 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/contracts.d.ts +10 -0
- package/dist/src/runtime/steps/execution-agent/decision-parsing.js +13 -1
- package/dist/src/runtime/steps/execution-agent/direct-response-configuration.d.ts +3 -0
- package/dist/src/runtime/steps/execution-agent/direct-response-configuration.js +64 -0
- package/dist/src/runtime/steps/execution-agent/direct-response-contract.d.ts +7 -0
- package/dist/src/runtime/steps/execution-agent/direct-response-contract.js +56 -0
- package/dist/src/runtime/steps/execution-agent/direct-response-policy.d.ts +9 -0
- package/dist/src/runtime/steps/execution-agent/direct-response-policy.js +30 -0
- package/dist/src/runtime/steps/execution-agent/direct-response-prompt.d.ts +7 -0
- package/dist/src/runtime/steps/execution-agent/direct-response-prompt.js +43 -0
- package/dist/src/runtime/steps/execution-agent/format.js +4 -3
- package/dist/src/runtime/steps/execution-agent/input.d.ts +2 -0
- package/dist/src/runtime/steps/execution-agent/input.js +22 -1
- package/dist/src/runtime/steps/execution-agent/plugin-catalog.d.ts +4 -0
- package/dist/src/runtime/steps/execution-agent/plugin-catalog.js +8 -0
- package/dist/src/runtime/steps/execution-agent/prompt.d.ts +1 -0
- package/dist/src/runtime/steps/execution-agent/prompt.js +7 -8
- package/dist/src/runtime/steps/execution-agent/response-prompt.js +1 -0
- package/dist/src/runtime/steps/execution-agent/response-run.js +5 -11
- package/dist/src/runtime/steps/execution-agent/run.js +4 -1
- package/dist/src/runtime/steps/execution-agent/state-context.d.ts +3 -5
- package/dist/src/runtime/steps/execution-agent/state-context.js +5 -51
- 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/runtime/steps/planner-decision/capability-brief.d.ts +2 -0
- package/dist/src/runtime/steps/planner-decision/prompt.js +26 -49
- package/dist/src/runtime/steps/supervisor-decision/input.d.ts +1 -0
- package/dist/src/runtime/steps/supervisor-decision/input.js +5 -0
- package/dist/src/runtime/steps/supervisor-decision/prompt.d.ts +1 -0
- package/dist/src/runtime/steps/supervisor-decision/prompt.js +6 -2
- package/dist/src/runtime/steps/supervisor-decision/run.d.ts +1 -0
- package/dist/src/runtime/steps/supervisor-decision/run.js +4 -0
- package/dist/src/runtime/steps/supervisor-response/run.d.ts +2 -0
- package/dist/src/runtime/steps/supervisor-response/run.js +3 -6
- package/dist/src/sessions/durable-session-commit.js +3 -3
- 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/session-store.js +3 -3
- 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/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 +1 -1
- 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 +54 -156
- 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/automations/timeline.js +3 -2
- package/dist/src/web-ui/app/components/composer-submission-notice.js +50 -0
- package/dist/src/web-ui/app/components/config-workspace/model-plugin-permissions.js +7 -1
- package/dist/src/web-ui/app/components/config-workspace/workspace-mutations.js +22 -2
- package/dist/src/web-ui/app/components/dashboard/compact-layout.js +137 -0
- package/dist/src/web-ui/app/components/dashboard/icons.js +5 -0
- package/dist/src/web-ui/app/components/dashboard/widget-card.js +85 -0
- package/dist/src/web-ui/app/components/dashboard/widget-dialog.js +83 -0
- package/dist/src/web-ui/app/components/dashboard/widget-summaries.js +155 -0
- package/dist/src/web-ui/app/components/dashboard/workspace.js +28 -4
- 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 +2 -1
- 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-widget-preview.js +32 -0
- package/dist/src/web-ui/app/components/passive-learning/home.js +11 -3
- 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/discovery-rendering.js +9 -1
- package/dist/src/web-ui/app/components/plugins/installation-compatibility.js +7 -0
- package/dist/src/web-ui/app/components/plugins/installation.js +2 -1
- package/dist/src/web-ui/app/components/plugins/rendering.js +3 -0
- 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/optional-steps.js +7 -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/schedules/details.js +3 -2
- 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/handoff-actions.js +9 -3
- package/dist/src/web-ui/app/components/spark-chat/panel.js +1 -1
- package/dist/src/web-ui/app/components/spark-chat/placement.js +4 -7
- package/dist/src/web-ui/app/components/spark-chat/settings.js +8 -4
- package/dist/src/web-ui/app/components/system-host/home-widget-permission-preview.js +75 -0
- package/dist/src/web-ui/app/components/system-host/home-widget-summary.js +93 -0
- package/dist/src/web-ui/app/components/system-host/macos-permission-rendering.js +2 -2
- package/dist/src/web-ui/app/components/system-host/macos-permissions.js +2 -0
- 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 +6 -3
- package/dist/src/web-ui/app/components/system-host/windows-store-setup.js +2 -2
- package/dist/src/web-ui/app/components/workspace-storage-notice.js +37 -0
- package/dist/src/web-ui/app/computer-access-feature.js +13 -1
- package/dist/src/web-ui/app/configuration-environment-refresh.js +27 -34
- package/dist/src/web-ui/app/configuration-feature.js +11 -1
- package/dist/src/web-ui/app/controllers/app-event-bindings.js +38 -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-request-hydration.js +20 -17
- package/dist/src/web-ui/app/controllers/conversation-session-controller.d.ts +1 -2
- package/dist/src/web-ui/app/controllers/conversation-session-controller.js +49 -22
- 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/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.js +2 -1
- 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-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 +33 -17
- package/dist/src/web-ui/app/controllers/session-pin-updates.js +14 -0
- package/dist/src/web-ui/app/controllers/session-sidebar-controller.js +12 -14
- package/dist/src/web-ui/app/controllers/spark-chat-sync.js +2 -2
- 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/dashboard-feature.js +12 -2
- package/dist/src/web-ui/app/lib/reasoning-controls.js +40 -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/passive-learning-feature.js +18 -5
- 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/memory.js +7 -2
- package/dist/src/web-ui/app/services/runtime-web-client/system-host.js +2 -0
- package/dist/src/web-ui/app/services/runtime-web-client.d.ts +2 -0
- package/dist/src/web-ui/app/services/runtime-web-client.js +2 -0
- 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 +10 -4
- package/dist/src/web-ui/app/styles/21-composer-controls.css +16 -0
- package/dist/src/web-ui/app/styles/41-plugin-management.css +8 -0
- package/dist/src/web-ui/app/styles/42-model-plugin-permissions.css +1 -0
- package/dist/src/web-ui/app/styles/49-collection-consent.css +30 -0
- package/dist/src/web-ui/app/styles/64-workspace-storage.css +23 -0
- package/dist/src/web-ui/app/styles/95-home-widgets.css +109 -0
- package/dist/src/web-ui/app/styles.css +3 -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/configuration-activation-source.js +2 -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/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-control-observation.js +2 -2
- package/dist/src/web-ui/local-runtime/request-execution.js +18 -18
- 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 +2 -9
- package/dist/src/web-ui/local-runtime/runtime-setup-context-window.js +4 -27
- 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-service.js +4 -0
- package/dist/src/web-ui/local-runtime-backend.js +14 -0
- package/dist/src/web-ui/plugin-management-catalog.d.ts +3 -1
- package/dist/src/web-ui/plugin-management-catalog.js +3 -1
- package/dist/src/web-ui/plugin-management-service.d.ts +1 -0
- package/dist/src/web-ui/plugin-removal-service.d.ts +1 -0
- 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 +23 -1
- 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/docs/installation.md +44 -5
- package/docs/plugins.md +174 -28
- package/docs/tool-execution-result-evidence-contract.md +57 -0
- package/docs/windows-companion-store.md +5 -0
- package/package.json +4 -2
- package/plugins/capability-brief/plugin.json +5 -1
- package/plugins/code-outline/README.md +20 -0
- package/plugins/code-outline/plugin.json +2 -1
- 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 -1
- 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 +4 -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 +7 -3
- 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 +2 -1
- 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 -1
- 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 +5 -1
- 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 +2 -1
- 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 +51 -15
- package/plugins/system/plugin.json +6 -2
- package/plugins/system/skills/system_actions/SKILL.md +1 -1
- package/plugins/system/source/command-working-directory.ts +47 -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 +18 -2
- package/plugins/system/source/index.ts +5 -3
- package/plugins/system/source/local-command-output-retention.ts +16 -0
- package/plugins/system/source/local-command-output.ts +16 -8
- package/plugins/system/source/request-system-modules.ts +12 -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 +837 -151
- package/plugins/system-probe/plugin.json +9 -3
- 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/plugin.json +5 -1
|
@@ -252,6 +252,9 @@ function canHandOffContextText(original, assessed, budget) {
|
|
|
252
252
|
// src/capabilities/tool-media.ts
|
|
253
253
|
var TOOL_IMAGE_MAX_BYTES = 10 * 1024 * 1024;
|
|
254
254
|
|
|
255
|
+
// src/computer-access/companion/secret-protection-protocol.ts
|
|
256
|
+
var HOST_SECRET_PROTECTION_CAPABILITY = "host_secret_protection_v1";
|
|
257
|
+
|
|
255
258
|
// src/computer-access/companion/broker-client.ts
|
|
256
259
|
var import_node_net = require("node:net");
|
|
257
260
|
|
|
@@ -270,25 +273,25 @@ function hostStateDirectory(rootDir) {
|
|
|
270
273
|
}
|
|
271
274
|
function ensureHostStateDirectory(directory) {
|
|
272
275
|
(0, import_node_fs.mkdirSync)(directory, { recursive: true, mode: 448 });
|
|
273
|
-
const
|
|
274
|
-
if (!
|
|
276
|
+
const stat3 = (0, import_node_fs.lstatSync)(directory);
|
|
277
|
+
if (!stat3.isDirectory()) throw new Error("host_state_directory_invalid");
|
|
275
278
|
if (process.platform === "win32") return;
|
|
276
|
-
if (
|
|
279
|
+
if (stat3.uid !== process.getuid?.())
|
|
277
280
|
throw new Error("host_state_owner_invalid");
|
|
278
|
-
if ((
|
|
281
|
+
if ((stat3.mode & 63) !== 0)
|
|
279
282
|
throw new Error("host_state_directory_not_private");
|
|
280
283
|
}
|
|
281
284
|
function readHostPrivateJson(path) {
|
|
282
285
|
try {
|
|
283
|
-
const
|
|
284
|
-
if (!
|
|
286
|
+
const stat3 = (0, import_node_fs.lstatSync)(path);
|
|
287
|
+
if (!stat3.isFile()) throw new Error("host_state_file_invalid");
|
|
285
288
|
if (process.platform !== "win32") {
|
|
286
|
-
if (
|
|
289
|
+
if (stat3.uid !== process.getuid?.())
|
|
287
290
|
throw new Error("host_state_owner_invalid");
|
|
288
|
-
if ((
|
|
291
|
+
if ((stat3.mode & 63) !== 0)
|
|
289
292
|
throw new Error("host_state_file_not_private");
|
|
290
293
|
}
|
|
291
|
-
if (
|
|
294
|
+
if (stat3.size > 16384) throw new Error("host_state_file_too_large");
|
|
292
295
|
return JSON.parse((0, import_node_fs.readFileSync)(path, "utf8"));
|
|
293
296
|
} catch (error) {
|
|
294
297
|
if (error.code === "ENOENT") return void 0;
|
|
@@ -2139,7 +2142,7 @@ function createUnixNativeProcess(options) {
|
|
|
2139
2142
|
let failedReason;
|
|
2140
2143
|
let buffer = Buffer.alloc(0);
|
|
2141
2144
|
let queue = Promise.resolve();
|
|
2142
|
-
let
|
|
2145
|
+
let lastDesktop;
|
|
2143
2146
|
function interruptedResult(reason) {
|
|
2144
2147
|
const dispatch = pending?.request.operation === "act" ? pending.dispatch ?? {
|
|
2145
2148
|
status: "unknown",
|
|
@@ -2147,12 +2150,8 @@ function createUnixNativeProcess(options) {
|
|
|
2147
2150
|
reason
|
|
2148
2151
|
} : void 0;
|
|
2149
2152
|
const result = unavailableUnixDesktop(options.platform, reason, dispatch);
|
|
2150
|
-
if (!
|
|
2151
|
-
return {
|
|
2152
|
-
...result,
|
|
2153
|
-
desktop: { ...lastResult.desktop, available: false, reason },
|
|
2154
|
-
windows: lastResult.windows
|
|
2155
|
-
};
|
|
2153
|
+
if (!lastDesktop) return result;
|
|
2154
|
+
return { ...result, desktop: { ...result.desktop, ...lastDesktop } };
|
|
2156
2155
|
}
|
|
2157
2156
|
function terminate(reason) {
|
|
2158
2157
|
failedReason = reason;
|
|
@@ -2165,6 +2164,7 @@ function createUnixNativeProcess(options) {
|
|
|
2165
2164
|
retiring.once("exit", () => clearTimeout(hardStop));
|
|
2166
2165
|
}
|
|
2167
2166
|
child = void 0;
|
|
2167
|
+
buffer.fill(0);
|
|
2168
2168
|
buffer = Buffer.alloc(0);
|
|
2169
2169
|
}
|
|
2170
2170
|
function receiveLine(line) {
|
|
@@ -2180,7 +2180,17 @@ function createUnixNativeProcess(options) {
|
|
|
2180
2180
|
}
|
|
2181
2181
|
if (message.type !== "result") throw new Error("native_protocol_invalid");
|
|
2182
2182
|
const result = readUnixNativeResult(message.result, options.platform);
|
|
2183
|
-
|
|
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
|
+
};
|
|
2184
2194
|
pending.finish(result);
|
|
2185
2195
|
}
|
|
2186
2196
|
function ensureHelper() {
|
|
@@ -2193,15 +2203,19 @@ function createUnixNativeProcess(options) {
|
|
|
2193
2203
|
child.stderr.resume();
|
|
2194
2204
|
child.stdout.on("data", (chunk) => {
|
|
2195
2205
|
if (closed || failedReason) return;
|
|
2196
|
-
|
|
2206
|
+
const previous = buffer;
|
|
2207
|
+
buffer = Buffer.concat([previous, chunk]);
|
|
2208
|
+
previous.fill(0);
|
|
2197
2209
|
if (buffer.length > NATIVE_JSON_LIMIT) {
|
|
2198
2210
|
terminate("computer_native_result_limit");
|
|
2199
2211
|
return;
|
|
2200
2212
|
}
|
|
2201
2213
|
let boundary = buffer.indexOf(10);
|
|
2202
2214
|
while (boundary >= 0) {
|
|
2203
|
-
const
|
|
2204
|
-
|
|
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);
|
|
2205
2219
|
try {
|
|
2206
2220
|
receiveLine(line);
|
|
2207
2221
|
} catch {
|
|
@@ -5114,15 +5128,60 @@ function identityExcerpt(identity) {
|
|
|
5114
5128
|
}
|
|
5115
5129
|
|
|
5116
5130
|
// src/computer-access/handlers.ts
|
|
5117
|
-
|
|
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) {
|
|
5118
5167
|
return async (params, context) => {
|
|
5119
5168
|
try {
|
|
5120
5169
|
return await operation(params, context);
|
|
5121
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
|
+
}
|
|
5122
5181
|
if (error instanceof SystemOperationError)
|
|
5123
5182
|
return failureResult({
|
|
5124
5183
|
errorCode: error.code,
|
|
5125
|
-
message
|
|
5184
|
+
message,
|
|
5126
5185
|
data: {
|
|
5127
5186
|
humanActionRequired: error.code === "system_authorization_required"
|
|
5128
5187
|
}
|
|
@@ -5135,9 +5194,10 @@ function withSystemOperationErrors(operation) {
|
|
|
5135
5194
|
}
|
|
5136
5195
|
};
|
|
5137
5196
|
}
|
|
5138
|
-
function createSystemHandlers(run = runSystemProcess, resolveTarget = (id) => resolveSystemTarget(id, run), commandOutput) {
|
|
5197
|
+
function createSystemHandlers(run = runSystemProcess, resolveTarget = (id) => resolveSystemTarget(id, run), commandOutput, protection) {
|
|
5139
5198
|
const targets = async () => {
|
|
5140
|
-
const
|
|
5199
|
+
const observed = await observeSystemTargets(run);
|
|
5200
|
+
const observation = protection ? protectSystemResult(() => protection.protectTargets(observed)) : observed;
|
|
5141
5201
|
return successResult({
|
|
5142
5202
|
output: JSON.stringify(observation),
|
|
5143
5203
|
data: {
|
|
@@ -5149,13 +5209,19 @@ function createSystemHandlers(run = runSystemProcess, resolveTarget = (id) => re
|
|
|
5149
5209
|
const command = async (params, context) => {
|
|
5150
5210
|
const target = await resolveTarget(readSystemTargetId(params.target));
|
|
5151
5211
|
const output = commandOutput?.(context);
|
|
5152
|
-
const
|
|
5212
|
+
const observed = await executeSystemCommand({
|
|
5153
5213
|
target,
|
|
5154
5214
|
params,
|
|
5155
5215
|
run,
|
|
5156
5216
|
...output ? { runCommand: output.run } : {},
|
|
5157
5217
|
...context?.abortSignal ? { abortSignal: context.abortSignal } : {}
|
|
5158
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
|
+
}
|
|
5159
5225
|
if (output) return output.present(target, result);
|
|
5160
5226
|
return systemProcessResult(target, result, "command_process_completion");
|
|
5161
5227
|
};
|
|
@@ -5167,7 +5233,8 @@ function createSystemHandlers(run = runSystemProcess, resolveTarget = (id) => re
|
|
|
5167
5233
|
minimum: 1,
|
|
5168
5234
|
maximum: 100
|
|
5169
5235
|
});
|
|
5170
|
-
const
|
|
5236
|
+
const observed = await readSystemApplications(target, run);
|
|
5237
|
+
const catalog = protection ? protectSystemResult(() => protection.protectCatalog(observed)) : observed;
|
|
5171
5238
|
const { output, data } = systemApplicationObservation(
|
|
5172
5239
|
target,
|
|
5173
5240
|
catalog,
|
|
@@ -5190,18 +5257,28 @@ function createSystemHandlers(run = runSystemProcess, resolveTarget = (id) => re
|
|
|
5190
5257
|
run,
|
|
5191
5258
|
...context?.abortSignal ? { abortSignal: context.abortSignal } : {}
|
|
5192
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
|
+
}
|
|
5193
5270
|
return systemProcessResult(
|
|
5194
5271
|
target,
|
|
5195
|
-
|
|
5272
|
+
process2,
|
|
5196
5273
|
"launch_request_dispatch",
|
|
5197
|
-
|
|
5274
|
+
application
|
|
5198
5275
|
);
|
|
5199
5276
|
};
|
|
5200
5277
|
return {
|
|
5201
|
-
system_targets: withSystemOperationErrors(targets),
|
|
5202
|
-
system_command: withSystemOperationErrors(command),
|
|
5203
|
-
system_applications: withSystemOperationErrors(applications),
|
|
5204
|
-
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)
|
|
5205
5282
|
};
|
|
5206
5283
|
}
|
|
5207
5284
|
|
|
@@ -5209,19 +5286,74 @@ function createSystemHandlers(run = runSystemProcess, resolveTarget = (id) => re
|
|
|
5209
5286
|
var import_node_crypto6 = require("node:crypto");
|
|
5210
5287
|
var import_node_events = require("node:events");
|
|
5211
5288
|
var import_node_fs5 = require("node:fs");
|
|
5212
|
-
var
|
|
5289
|
+
var import_promises7 = require("node:fs/promises");
|
|
5213
5290
|
var import_node_path8 = require("node:path");
|
|
5214
|
-
var
|
|
5291
|
+
var import_promises8 = require("node:stream/promises");
|
|
5215
5292
|
|
|
5216
|
-
// src/computer-access/command-output-
|
|
5293
|
+
// src/computer-access/command-output-protection.ts
|
|
5217
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");
|
|
5218
5350
|
var import_node_path7 = require("node:path");
|
|
5219
5351
|
var DEFAULT_SYSTEM_OUTPUT_RETENTION_MS = 7 * 24 * 60 * 6e4;
|
|
5220
5352
|
var activeSystemCaptures = /* @__PURE__ */ new Set();
|
|
5221
5353
|
var jobs = /* @__PURE__ */ new Map();
|
|
5222
5354
|
var CAPTURE_ID = /^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/;
|
|
5223
5355
|
async function cleanupSystemOutput(root, retentionMs) {
|
|
5224
|
-
const entries = await (0,
|
|
5356
|
+
const entries = await (0, import_promises6.readdir)(root, { withFileTypes: true }).catch((error) => {
|
|
5225
5357
|
if (error.code === "ENOENT") return [];
|
|
5226
5358
|
throw error;
|
|
5227
5359
|
});
|
|
@@ -5230,13 +5362,13 @@ async function cleanupSystemOutput(root, retentionMs) {
|
|
|
5230
5362
|
if (!entry.isDirectory() || !CAPTURE_ID.test(entry.name)) continue;
|
|
5231
5363
|
const directory = (0, import_node_path7.join)(root, entry.name);
|
|
5232
5364
|
if (activeSystemCaptures.has(directory)) continue;
|
|
5233
|
-
const files = await (0,
|
|
5234
|
-
const times = await Promise.all(files.map(async (file) => (await (0,
|
|
5235
|
-
const completedAt = Math.max((await (0,
|
|
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);
|
|
5236
5368
|
const captureRetentionMs = await readCaptureRetention(directory, entry.name, retentionMs);
|
|
5237
5369
|
if (Date.now() - completedAt < captureRetentionMs) continue;
|
|
5238
5370
|
if (activeSystemCaptures.has(directory)) continue;
|
|
5239
|
-
await (0,
|
|
5371
|
+
await (0, import_promises6.rm)(directory, { recursive: true });
|
|
5240
5372
|
removed += 1;
|
|
5241
5373
|
}
|
|
5242
5374
|
return removed;
|
|
@@ -5244,7 +5376,7 @@ async function cleanupSystemOutput(root, retentionMs) {
|
|
|
5244
5376
|
async function readCaptureRetention(directory, id, fallbackMs) {
|
|
5245
5377
|
let receipt;
|
|
5246
5378
|
try {
|
|
5247
|
-
receipt = JSON.parse(await (0,
|
|
5379
|
+
receipt = JSON.parse(await (0, import_promises6.readFile)((0, import_node_path7.join)(directory, "receipt.json"), "utf8"));
|
|
5248
5380
|
} catch (error) {
|
|
5249
5381
|
if (error.code === "ENOENT") return fallbackMs;
|
|
5250
5382
|
if (error instanceof SyntaxError) return fallbackMs;
|
|
@@ -5271,7 +5403,7 @@ function scheduleSystemOutputCleanup(root, retentionMs) {
|
|
|
5271
5403
|
let empty = false;
|
|
5272
5404
|
try {
|
|
5273
5405
|
await cleanupSystemOutput(root, job.retentionMs);
|
|
5274
|
-
empty = (await (0,
|
|
5406
|
+
empty = (await (0, import_promises6.readdir)(root).catch((error) => {
|
|
5275
5407
|
if (error.code === "ENOENT") return [];
|
|
5276
5408
|
throw error;
|
|
5277
5409
|
})).length === 0;
|
|
@@ -5291,30 +5423,36 @@ function scheduleSystemOutputCleanup(root, retentionMs) {
|
|
|
5291
5423
|
}
|
|
5292
5424
|
|
|
5293
5425
|
// src/computer-access/command-output-capture.ts
|
|
5426
|
+
var STREAMS = ["stdout", "stderr"];
|
|
5294
5427
|
var OUTPUT_IO_CHUNK_BYTES = 64 * 1024;
|
|
5295
|
-
async function createSystemOutputCapture(root, retentionMs) {
|
|
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.");
|
|
5296
5431
|
const id = (0, import_node_crypto6.randomUUID)();
|
|
5297
5432
|
const directory = (0, import_node_path8.join)(root, id);
|
|
5298
5433
|
activeSystemCaptures.add(directory);
|
|
5299
5434
|
try {
|
|
5300
|
-
await (0,
|
|
5435
|
+
await (0, import_promises7.mkdir)(directory, { recursive: true, mode: 448 });
|
|
5301
5436
|
} catch {
|
|
5302
5437
|
activeSystemCaptures.delete(directory);
|
|
5303
5438
|
throw new SystemOperationError("system_output_storage_failed", "Output storage could not be prepared. The command was not dispatched.");
|
|
5304
5439
|
}
|
|
5305
|
-
let
|
|
5440
|
+
let storageFailure, securityFailure;
|
|
5306
5441
|
let stop;
|
|
5307
|
-
let ended = false;
|
|
5308
|
-
let
|
|
5442
|
+
let ended = false, retained = false, admitted = false;
|
|
5443
|
+
let receipt;
|
|
5444
|
+
let processResult;
|
|
5445
|
+
let finishing;
|
|
5309
5446
|
const sources = [];
|
|
5310
|
-
const
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
const
|
|
5314
|
-
|
|
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";
|
|
5315
5453
|
stop?.();
|
|
5316
5454
|
});
|
|
5317
|
-
return {
|
|
5455
|
+
return { sink, completion };
|
|
5318
5456
|
});
|
|
5319
5457
|
try {
|
|
5320
5458
|
await Promise.all(streams.map(({ sink }) => (0, import_node_events.once)(sink, "open")));
|
|
@@ -5326,19 +5464,30 @@ async function createSystemOutputCapture(root, retentionMs) {
|
|
|
5326
5464
|
throw new SystemOperationError("system_output_storage_failed", "Output files could not be opened. The command was not dispatched.");
|
|
5327
5465
|
}
|
|
5328
5466
|
scheduleSystemOutputCleanup(root, retentionMs);
|
|
5467
|
+
const failure = () => storageFailure ?? securityFailure;
|
|
5329
5468
|
const capture = {
|
|
5330
5469
|
attach(stdout, stderr, onFailure) {
|
|
5470
|
+
if (!canAttachCapture()) {
|
|
5471
|
+
securityFailure ??= "output_protection_failed";
|
|
5472
|
+
onFailure();
|
|
5473
|
+
return;
|
|
5474
|
+
}
|
|
5331
5475
|
stop = onFailure;
|
|
5332
5476
|
sources.push(stdout, stderr);
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
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();
|
|
5338
5486
|
},
|
|
5339
5487
|
end() {
|
|
5340
5488
|
if (ended) return;
|
|
5341
5489
|
ended = true;
|
|
5490
|
+
if (!hasCompleteStreams()) securityFailure ??= "output_incomplete";
|
|
5342
5491
|
for (const source of sources) {
|
|
5343
5492
|
source.unpipe();
|
|
5344
5493
|
source.destroy();
|
|
@@ -5346,14 +5495,105 @@ async function createSystemOutputCapture(root, retentionMs) {
|
|
|
5346
5495
|
for (const { sink } of streams) if (!sink.destroyed && !sink.writableEnded) sink.end();
|
|
5347
5496
|
}
|
|
5348
5497
|
};
|
|
5349
|
-
|
|
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
|
+
}
|
|
5350
5583
|
return {
|
|
5351
5584
|
capture,
|
|
5352
5585
|
get receipt() {
|
|
5353
5586
|
return receipt;
|
|
5354
5587
|
},
|
|
5355
5588
|
get failure() {
|
|
5356
|
-
return 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;
|
|
5357
5597
|
},
|
|
5358
5598
|
retain() {
|
|
5359
5599
|
retained = true;
|
|
@@ -5364,68 +5604,40 @@ async function createSystemOutputCapture(root, retentionMs) {
|
|
|
5364
5604
|
activeSystemCaptures.delete(directory);
|
|
5365
5605
|
},
|
|
5366
5606
|
async read(stream, offset, length) {
|
|
5367
|
-
|
|
5368
|
-
|
|
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");
|
|
5369
5610
|
try {
|
|
5370
|
-
const
|
|
5371
|
-
const
|
|
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);
|
|
5372
5614
|
return bytes.subarray(0, bytesRead);
|
|
5373
5615
|
} finally {
|
|
5374
5616
|
await file.close();
|
|
5375
5617
|
}
|
|
5376
5618
|
},
|
|
5377
|
-
|
|
5378
|
-
|
|
5379
|
-
|
|
5380
|
-
await Promise.all(streams.map(({ completion }) => completion));
|
|
5381
|
-
const sizes = await Promise.all(streams.map(async ({ path }) => {
|
|
5382
|
-
try {
|
|
5383
|
-
return (await (0, import_promises6.stat)(path)).size;
|
|
5384
|
-
} catch {
|
|
5385
|
-
failure ??= "read_failed";
|
|
5386
|
-
return 0;
|
|
5387
|
-
}
|
|
5388
|
-
}));
|
|
5389
|
-
let stdout = "", stderr = "";
|
|
5390
|
-
if (!failure && materialize) {
|
|
5391
|
-
try {
|
|
5392
|
-
[stdout, stderr] = await Promise.all(streams.map(({ path }) => (0, import_promises6.readFile)(path, "utf8")));
|
|
5393
|
-
} catch {
|
|
5394
|
-
failure = "read_failed";
|
|
5395
|
-
}
|
|
5396
|
-
}
|
|
5397
|
-
const completedAt = Date.now();
|
|
5398
|
-
receipt = {
|
|
5399
|
-
id,
|
|
5400
|
-
stdoutBytes: sizes[0],
|
|
5401
|
-
stderrBytes: sizes[1],
|
|
5402
|
-
completedAt: new Date(completedAt).toISOString(),
|
|
5403
|
-
retentionMs,
|
|
5404
|
-
complete: !failure,
|
|
5405
|
-
...!materialize ? { stdoutSha256: streams[0].hash.digest("hex"), stderrSha256: streams[1].hash.digest("hex") } : {}
|
|
5406
|
-
};
|
|
5407
|
-
try {
|
|
5408
|
-
const temporary = (0, import_node_path8.join)(directory, "receipt.tmp");
|
|
5409
|
-
await (0, import_promises6.writeFile)(temporary, JSON.stringify({
|
|
5410
|
-
kind: "system_command_output_v1",
|
|
5411
|
-
...receipt,
|
|
5412
|
-
processStatus: result?.status,
|
|
5413
|
-
exitCode: result?.exitCode,
|
|
5414
|
-
spawnedProcess: result?.spawnedProcess,
|
|
5415
|
-
...failure ? { storageFailure: failure } : {}
|
|
5416
|
-
}), { flag: "wx", mode: 384, flush: true });
|
|
5417
|
-
await (0, import_promises6.rename)(temporary, (0, import_node_path8.join)(directory, "receipt.json"));
|
|
5418
|
-
} catch {
|
|
5419
|
-
failure ??= "receipt_write_failed";
|
|
5420
|
-
receipt = { ...receipt, complete: false };
|
|
5421
|
-
}
|
|
5422
|
-
return { stdout, stderr };
|
|
5423
|
-
} finally {
|
|
5424
|
-
if (!retained) activeSystemCaptures.delete(directory);
|
|
5425
|
-
}
|
|
5619
|
+
finish(result, materialize = true) {
|
|
5620
|
+
finishing ??= finish(result, materialize);
|
|
5621
|
+
return finishing;
|
|
5426
5622
|
}
|
|
5427
5623
|
};
|
|
5428
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
|
+
}
|
|
5429
5641
|
|
|
5430
5642
|
// src/computer-access/companion/command-output-protocol.ts
|
|
5431
5643
|
var SYSTEM_OUTPUT_CAPABILITY = "system_command_output_v1";
|
|
@@ -5454,6 +5666,39 @@ function readSystemOutputTransfer(value) {
|
|
|
5454
5666
|
};
|
|
5455
5667
|
}
|
|
5456
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
|
+
}
|
|
5687
|
+
};
|
|
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
|
+
}
|
|
5701
|
+
|
|
5457
5702
|
// plugins/system/source/computer/public-action.ts
|
|
5458
5703
|
function readPublicComputerAction(params) {
|
|
5459
5704
|
const fields = ["desktop_ref", "observation_ref", "action_kind"];
|
|
@@ -5615,6 +5860,113 @@ function fits(value) {
|
|
|
5615
5860
|
return Buffer.byteLength(value, "utf8") <= COMPUTER_OBSERVATION_OUTPUT_MAX_BYTES;
|
|
5616
5861
|
}
|
|
5617
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
|
+
|
|
5618
5970
|
// plugins/system/source/computer/request-computers.ts
|
|
5619
5971
|
var import_node_crypto8 = require("node:crypto");
|
|
5620
5972
|
|
|
@@ -5704,7 +6056,7 @@ function systemRouteMetadata(route) {
|
|
|
5704
6056
|
return {
|
|
5705
6057
|
displayTarget: route.target,
|
|
5706
6058
|
transport: "host_companion",
|
|
5707
|
-
computerName: route.identity.name
|
|
6059
|
+
computerName: redactSecretText(route.identity.name)
|
|
5708
6060
|
};
|
|
5709
6061
|
}
|
|
5710
6062
|
function observeCapturedSystemTargets(snapshot) {
|
|
@@ -5851,7 +6203,7 @@ var DesktopBindings = class {
|
|
|
5851
6203
|
this.current = void 0;
|
|
5852
6204
|
this.windows.clear();
|
|
5853
6205
|
}
|
|
5854
|
-
regionalObservation(observationRef,
|
|
6206
|
+
regionalObservation(observationRef, rectangle2) {
|
|
5855
6207
|
const current = this.current;
|
|
5856
6208
|
if (!current || current.id !== observationRef)
|
|
5857
6209
|
throw new SystemOperationError(
|
|
@@ -5859,7 +6211,7 @@ var DesktopBindings = class {
|
|
|
5859
6211
|
"Use a current observation to select a smaller region."
|
|
5860
6212
|
);
|
|
5861
6213
|
const observation = current.observation;
|
|
5862
|
-
if (!isRegionInsideImage(
|
|
6214
|
+
if (!isRegionInsideImage(rectangle2, observation))
|
|
5863
6215
|
throw new SystemOperationError(
|
|
5864
6216
|
"computer_region_outside_image",
|
|
5865
6217
|
"Select a region inside the returned image."
|
|
@@ -5871,10 +6223,10 @@ var DesktopBindings = class {
|
|
|
5871
6223
|
desktopBinding: current.result.desktop.binding,
|
|
5872
6224
|
expectedGeometry: current.result.desktop.bounds,
|
|
5873
6225
|
region: {
|
|
5874
|
-
x: Math.round(observation.region.x +
|
|
5875
|
-
y: Math.round(observation.region.y +
|
|
5876
|
-
width: Math.max(1, Math.floor(
|
|
5877
|
-
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))
|
|
5878
6230
|
}
|
|
5879
6231
|
};
|
|
5880
6232
|
}
|
|
@@ -5906,10 +6258,10 @@ function imageRectangle(bounds, observation) {
|
|
|
5906
6258
|
height: bounds.height * scaleY
|
|
5907
6259
|
};
|
|
5908
6260
|
}
|
|
5909
|
-
function isRegionInsideImage(
|
|
5910
|
-
if (
|
|
5911
|
-
if (
|
|
5912
|
-
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;
|
|
5913
6265
|
}
|
|
5914
6266
|
function translateAction(action, observation) {
|
|
5915
6267
|
const point = (value) => {
|
|
@@ -5934,6 +6286,131 @@ function translateAction(action, observation) {
|
|
|
5934
6286
|
return action;
|
|
5935
6287
|
}
|
|
5936
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
|
+
|
|
5937
6414
|
// plugins/system/source/computer/request-computers.ts
|
|
5938
6415
|
var RequestComputers = class {
|
|
5939
6416
|
constructor(rootDir, routes, connection, nativeFactory = createNativeComputerBackend, snapshot) {
|
|
@@ -5988,7 +6465,7 @@ var RequestComputers = class {
|
|
|
5988
6465
|
"Install the companion from this Runtime build to enable desktop observation and input."
|
|
5989
6466
|
);
|
|
5990
6467
|
if (entry.backend) return entry.backend;
|
|
5991
|
-
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(
|
|
5992
6469
|
this.rootDir,
|
|
5993
6470
|
entry.route,
|
|
5994
6471
|
this.connection
|
|
@@ -6015,7 +6492,7 @@ function computerQueueIdentity(entry) {
|
|
|
6015
6492
|
}
|
|
6016
6493
|
function supportsComputerRoute(route) {
|
|
6017
6494
|
if (route.kind === "native") return true;
|
|
6018
|
-
return route.capabilities?.includes(COMPUTER_CAPABILITY) === true;
|
|
6495
|
+
return route.capabilities?.includes(COMPUTER_CAPABILITY) === true && route.capabilities.includes(HOST_SECRET_PROTECTION_CAPABILITY);
|
|
6019
6496
|
}
|
|
6020
6497
|
function restoreComputers(routes, value) {
|
|
6021
6498
|
if (!value || typeof value !== "object" || !("kind" in value) || value.kind !== "request_computers_v1" || !("entries" in value) || !Array.isArray(value.entries))
|
|
@@ -6064,7 +6541,7 @@ async function projectComputerResult(entry, result, context) {
|
|
|
6064
6541
|
);
|
|
6065
6542
|
media.push(image);
|
|
6066
6543
|
} catch (error) {
|
|
6067
|
-
imageFailure = error
|
|
6544
|
+
imageFailure = protectObservedError(error, "Image admission failed.");
|
|
6068
6545
|
} finally {
|
|
6069
6546
|
result.image.bytes.fill(0);
|
|
6070
6547
|
}
|
|
@@ -6075,7 +6552,10 @@ async function projectComputerResult(entry, result, context) {
|
|
|
6075
6552
|
description.observation_ref = void 0;
|
|
6076
6553
|
}
|
|
6077
6554
|
const hasPartialInputDispatch = result.dispatch?.status === "partial";
|
|
6078
|
-
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);
|
|
6079
6559
|
const data = {
|
|
6080
6560
|
desktop_ref: entry.ref,
|
|
6081
6561
|
...description.observation_ref ? { observation_ref: description.observation_ref } : {},
|
|
@@ -6154,7 +6634,10 @@ function createComputerHandlers(computers) {
|
|
|
6154
6634
|
} catch (error) {
|
|
6155
6635
|
return failureResult({
|
|
6156
6636
|
errorCode: error instanceof SystemOperationError ? error.code : "computer_operation_interrupted",
|
|
6157
|
-
message:
|
|
6637
|
+
message: protectObservedError(
|
|
6638
|
+
error,
|
|
6639
|
+
"Computer operation interrupted; effects may be partial. Observe before another action."
|
|
6640
|
+
)
|
|
6158
6641
|
});
|
|
6159
6642
|
}
|
|
6160
6643
|
};
|
|
@@ -6175,7 +6658,10 @@ function createComputerHandlers(computers) {
|
|
|
6175
6658
|
return {
|
|
6176
6659
|
...computerRouteLabel(entry),
|
|
6177
6660
|
available: false,
|
|
6178
|
-
reason:
|
|
6661
|
+
reason: protectObservedError(
|
|
6662
|
+
error,
|
|
6663
|
+
"Desktop inspection failed."
|
|
6664
|
+
)
|
|
6179
6665
|
};
|
|
6180
6666
|
}
|
|
6181
6667
|
}
|
|
@@ -6244,20 +6730,34 @@ function requireMedia(context) {
|
|
|
6244
6730
|
);
|
|
6245
6731
|
}
|
|
6246
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
|
+
|
|
6247
6749
|
// plugins/system/source/computer/request-modules.ts
|
|
6248
6750
|
function unboundComputerHandlers() {
|
|
6249
6751
|
return Object.fromEntries(
|
|
6250
6752
|
COMPUTER_TOOLS.map((name) => [
|
|
6251
6753
|
name,
|
|
6252
|
-
async () =>
|
|
6253
|
-
errorCode: "computer_request_binding_required",
|
|
6254
|
-
message: "Computer control requires a prepared request."
|
|
6255
|
-
})
|
|
6754
|
+
async () => unboundComputerFailure()
|
|
6256
6755
|
])
|
|
6257
6756
|
);
|
|
6258
6757
|
}
|
|
6259
6758
|
function prepareComputerModules(rootDir, modules, routes, connection, preparation) {
|
|
6260
6759
|
if (modules.length === 0) return [];
|
|
6760
|
+
if (!supportsRuntimeDesktopTools()) return [];
|
|
6261
6761
|
const computers = new RequestComputers(
|
|
6262
6762
|
rootDir,
|
|
6263
6763
|
routes,
|
|
@@ -6415,7 +6915,17 @@ function boundOperation(input, operation) {
|
|
|
6415
6915
|
const route = requireSystemRequestRoute(input.snapshot, params.target);
|
|
6416
6916
|
if (route.kind === "native")
|
|
6417
6917
|
return await input.nativeHandlers[operation](params, context);
|
|
6418
|
-
if (
|
|
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")
|
|
6419
6929
|
return await executeCompanionCommand({ ...input, route, params, context });
|
|
6420
6930
|
return await input.connection.executeHostOperation(input.rootDir, {
|
|
6421
6931
|
hostId: route.hostId,
|
|
@@ -6426,7 +6936,7 @@ function boundOperation(input, operation) {
|
|
|
6426
6936
|
});
|
|
6427
6937
|
} catch (error) {
|
|
6428
6938
|
if (error instanceof SystemOperationError)
|
|
6429
|
-
return failureResult({ errorCode: error.code, message: error.message });
|
|
6939
|
+
return failureResult({ errorCode: error.code, message: redactSecretText(error.message) });
|
|
6430
6940
|
return failureResult({
|
|
6431
6941
|
errorCode: "system_execution_route_failed",
|
|
6432
6942
|
message: "The bound execution route failed. No other destination was attempted; effects may be partial if dispatch began."
|
|
@@ -6434,6 +6944,9 @@ function boundOperation(input, operation) {
|
|
|
6434
6944
|
}
|
|
6435
6945
|
};
|
|
6436
6946
|
}
|
|
6947
|
+
function supportsProtectedCompanionResults(capabilities) {
|
|
6948
|
+
return capabilities?.includes(HOST_SECRET_PROTECTION_CAPABILITY) === true;
|
|
6949
|
+
}
|
|
6437
6950
|
function hasConnectionControl(params) {
|
|
6438
6951
|
if (Object.hasOwn(params, "host_id")) return true;
|
|
6439
6952
|
if (Object.hasOwn(params, "hostId")) return true;
|
|
@@ -6473,7 +6986,14 @@ async function prepareSystemRequestModules(rootDir, modules, dependencies = {},
|
|
|
6473
6986
|
outputRetentionMs: dependencies.outputRetentionMs
|
|
6474
6987
|
});
|
|
6475
6988
|
return Object.freeze([
|
|
6476
|
-
...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
|
+
),
|
|
6477
6997
|
...computerModules
|
|
6478
6998
|
]);
|
|
6479
6999
|
}
|
|
@@ -6490,7 +7010,7 @@ function uniqueSystemCommandRoutes(candidates) {
|
|
|
6490
7010
|
return true;
|
|
6491
7011
|
});
|
|
6492
7012
|
}
|
|
6493
|
-
function projectSystemRequestModule(module2, snapshot, handlers) {
|
|
7013
|
+
function projectSystemRequestModule(module2, snapshot, handlers, resolver) {
|
|
6494
7014
|
const targets = Object.freeze(snapshot.map(routeTargetId));
|
|
6495
7015
|
const availability = ` Available targets for this request: ${targets.join(", ")}.`;
|
|
6496
7016
|
return Object.freeze({
|
|
@@ -6511,7 +7031,7 @@ function projectSystemRequestModule(module2, snapshot, handlers) {
|
|
|
6511
7031
|
},
|
|
6512
7032
|
implementation: handlers[module2.definition.name],
|
|
6513
7033
|
adapter: {
|
|
6514
|
-
...module2.adapter,
|
|
7034
|
+
...createSystemCommandPathAdapter(module2.adapter, snapshot, resolver),
|
|
6515
7035
|
executionBinding: systemExecutionBinding(snapshot)
|
|
6516
7036
|
}
|
|
6517
7037
|
});
|
|
@@ -6532,18 +7052,128 @@ function systemExecutionBinding(snapshot) {
|
|
|
6532
7052
|
}
|
|
6533
7053
|
|
|
6534
7054
|
// plugins/system/source/local-command-output.ts
|
|
6535
|
-
var
|
|
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
|
|
6536
7164
|
var CONTEXT_STREAMS = Object.freeze(["stdout", "stderr"]);
|
|
6537
7165
|
function createLocalSystemCommandOutput(plugin) {
|
|
6538
|
-
const root = (0,
|
|
7166
|
+
const root = (0, import_node_path11.join)(plugin.stateDir, "command-output");
|
|
6539
7167
|
const retentionMs = systemCommandOutputRetentionMs(plugin);
|
|
6540
|
-
|
|
7168
|
+
const initialization = scheduleLocalSystemOutputCleanup(root, retentionMs);
|
|
6541
7169
|
return (context) => {
|
|
6542
7170
|
let captured;
|
|
6543
7171
|
return {
|
|
6544
7172
|
async run(input) {
|
|
6545
7173
|
if (input.abortSignal?.aborted) return runSystemProcess(input);
|
|
6546
|
-
|
|
7174
|
+
await initialization;
|
|
7175
|
+
await ensureWindowsOutputDirectory(root);
|
|
7176
|
+
captured = await createSystemOutputCapture(root, retentionMs, redactSecretText);
|
|
6547
7177
|
let result;
|
|
6548
7178
|
try {
|
|
6549
7179
|
result = await runSystemProcess(input, captured.capture);
|
|
@@ -6553,14 +7183,14 @@ function createLocalSystemCommandOutput(plugin) {
|
|
|
6553
7183
|
}
|
|
6554
7184
|
const streams = await captured.finish(result);
|
|
6555
7185
|
return {
|
|
6556
|
-
...
|
|
7186
|
+
...captured.processResult,
|
|
6557
7187
|
stdout: streams.stdout,
|
|
6558
|
-
stderr: streams.stderr
|
|
7188
|
+
stderr: streams.stderr,
|
|
6559
7189
|
outputTruncated: Boolean(captured.failure)
|
|
6560
7190
|
};
|
|
6561
7191
|
},
|
|
6562
7192
|
async present(target, result) {
|
|
6563
|
-
if (captured?.failure) return outputFailure(target, result, context, captured.receipt, captured.failure);
|
|
7193
|
+
if (captured?.failure) return outputFailure(target, result, context, captured.receipt, captured.failure, captured.failureKind);
|
|
6564
7194
|
const receipt = buildSystemProcessResult(target, result, "command_process_completion");
|
|
6565
7195
|
const delivered = deliverPluginTextResult({
|
|
6566
7196
|
...receipt,
|
|
@@ -6573,9 +7203,10 @@ function createLocalSystemCommandOutput(plugin) {
|
|
|
6573
7203
|
};
|
|
6574
7204
|
};
|
|
6575
7205
|
}
|
|
6576
|
-
function outputFailure(target, result, context, capture,
|
|
7206
|
+
function outputFailure(target, result, context, capture, captureFailure, failureKind) {
|
|
7207
|
+
const failureCode = failureKind === "security" ? "system_output_protection_failed" : "system_output_storage_failed";
|
|
6577
7208
|
return failureResult({
|
|
6578
|
-
errorCode:
|
|
7209
|
+
errorCode: captureFailure ? failureCode : "system_output_delivery_pending",
|
|
6579
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.",
|
|
6580
7211
|
...result.exitCode !== null ? { exitCode: result.exitCode } : {},
|
|
6581
7212
|
data: {
|
|
@@ -6585,7 +7216,8 @@ function outputFailure(target, result, context, capture, storageFailure) {
|
|
|
6585
7216
|
spawnedProcess: result.spawnedProcess ?? null,
|
|
6586
7217
|
exitCode: result.exitCode,
|
|
6587
7218
|
outputCapture: capture ?? null,
|
|
6588
|
-
...
|
|
7219
|
+
...captureFailure && failureKind === "security" ? { securityFailure: captureFailure } : {},
|
|
7220
|
+
...captureFailure && failureKind !== "security" ? { storageFailure: captureFailure } : {},
|
|
6589
7221
|
outputDelivery: "pending",
|
|
6590
7222
|
evidenceScope: "command_process_completion",
|
|
6591
7223
|
independentOutcomeCheck: "not_performed",
|
|
@@ -6602,14 +7234,68 @@ function systemCommandOutputRetentionMs(plugin) {
|
|
|
6602
7234
|
});
|
|
6603
7235
|
}
|
|
6604
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
|
+
|
|
6605
7290
|
// plugins/system/source/index.ts
|
|
6606
7291
|
var index_default = defineRuntimePlugin((context) => {
|
|
6607
7292
|
const output = createLocalSystemCommandOutput(context);
|
|
6608
7293
|
return {
|
|
6609
|
-
handlers: { ...createSystemHandlers(void 0, void 0, output), ...unboundComputerHandlers() },
|
|
7294
|
+
handlers: { ...createSystemHandlers(void 0, void 0, output, systemResultProtection), ...unboundComputerHandlers() },
|
|
6610
7295
|
prepareRequest: (modules, preparation) => prepareSystemRequestModules(context.rootDir, modules, {
|
|
6611
7296
|
outputRetentionMs: systemCommandOutputRetentionMs(context),
|
|
6612
|
-
|
|
7297
|
+
observeTargets: async () => systemResultProtection.protectTargets(await observeSystemTargets()),
|
|
7298
|
+
createNativeHandlers: (resolve) => createSystemHandlers(void 0, resolve, output, systemResultProtection)
|
|
6613
7299
|
}, preparation)
|
|
6614
7300
|
};
|
|
6615
7301
|
});
|