@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
|
@@ -2809,20 +2809,20 @@ function createNativeHostState(directory, access5) {
|
|
|
2809
2809
|
let connectionPath = join(directory, "connection.json"), statusPath = join(directory, "status.json");
|
|
2810
2810
|
async function inspectPrivate(path) {
|
|
2811
2811
|
await access5.ensureDirectory(directory);
|
|
2812
|
-
let
|
|
2812
|
+
let stat3 = await lstat(path).catch((error) => {
|
|
2813
2813
|
if (!isAbsentFile(error))
|
|
2814
2814
|
throw error;
|
|
2815
2815
|
});
|
|
2816
|
-
if (
|
|
2817
|
-
if (!
|
|
2816
|
+
if (stat3) {
|
|
2817
|
+
if (!stat3.isFile() || stat3.isSymbolicLink())
|
|
2818
2818
|
throw new Error("Host companion state must be a private regular file.");
|
|
2819
|
-
return await access5.assertFile(path,
|
|
2819
|
+
return await access5.assertFile(path, stat3), stat3;
|
|
2820
2820
|
}
|
|
2821
2821
|
}
|
|
2822
2822
|
async function readPrivate(path) {
|
|
2823
|
-
let
|
|
2824
|
-
if (
|
|
2825
|
-
if (
|
|
2823
|
+
let stat3 = await inspectPrivate(path);
|
|
2824
|
+
if (stat3) {
|
|
2825
|
+
if (stat3.size > 16384)
|
|
2826
2826
|
throw new Error("Host companion state exceeds its size limit.");
|
|
2827
2827
|
return JSON.parse(await readFile(path, "utf8"));
|
|
2828
2828
|
}
|
|
@@ -4073,14 +4073,58 @@ function identityExcerpt(identity) {
|
|
|
4073
4073
|
}
|
|
4074
4074
|
|
|
4075
4075
|
// src/computer-access/handlers.ts
|
|
4076
|
-
|
|
4076
|
+
var PROTECTION_FAILURE = "The system result could not be protected for delivery.";
|
|
4077
|
+
function protectSystemResult(operation) {
|
|
4078
|
+
try {
|
|
4079
|
+
return operation();
|
|
4080
|
+
} catch {
|
|
4081
|
+
throw new SystemOperationError("system_result_protection_failed", PROTECTION_FAILURE);
|
|
4082
|
+
}
|
|
4083
|
+
}
|
|
4084
|
+
function failedSystemProtectionReceipt(target, result, evidenceScope) {
|
|
4085
|
+
let safeProcess = {
|
|
4086
|
+
status: result.status,
|
|
4087
|
+
exitCode: result.exitCode,
|
|
4088
|
+
outputTruncated: result.outputTruncated,
|
|
4089
|
+
stdout: "[UNAVAILABLE: result protection failed]",
|
|
4090
|
+
stderr: "[UNAVAILABLE: result protection failed]",
|
|
4091
|
+
...result.spawnedProcess ? {
|
|
4092
|
+
spawnedProcess: {
|
|
4093
|
+
pid: result.spawnedProcess.pid,
|
|
4094
|
+
pidNamespace: result.spawnedProcess.pidNamespace,
|
|
4095
|
+
identitySource: result.spawnedProcess.identitySource,
|
|
4096
|
+
executable: "[REDACTED]"
|
|
4097
|
+
}
|
|
4098
|
+
} : {}
|
|
4099
|
+
}, receipt = systemProcessResult(target, safeProcess, evidenceScope);
|
|
4100
|
+
return failureResult({
|
|
4101
|
+
errorCode: "system_result_protection_failed",
|
|
4102
|
+
message: PROTECTION_FAILURE,
|
|
4103
|
+
output: `The operation was dispatched. Inspect the process receipt before another action; the command was not replayed.
|
|
4104
|
+
` + receipt.output,
|
|
4105
|
+
stdout: safeProcess.stdout,
|
|
4106
|
+
stderr: safeProcess.stderr,
|
|
4107
|
+
...result.exitCode !== null ? { exitCode: result.exitCode } : {},
|
|
4108
|
+
data: receipt.data
|
|
4109
|
+
});
|
|
4110
|
+
}
|
|
4111
|
+
function withSystemOperationErrors(operation, protection) {
|
|
4077
4112
|
return async (params, context) => {
|
|
4078
4113
|
try {
|
|
4079
4114
|
return await operation(params, context);
|
|
4080
4115
|
} catch (error) {
|
|
4116
|
+
let message = error instanceof Error ? error.message : void 0;
|
|
4117
|
+
try {
|
|
4118
|
+
protection && message !== void 0 && (message = protection.protectMessage(message));
|
|
4119
|
+
} catch {
|
|
4120
|
+
return failureResult({
|
|
4121
|
+
errorCode: "system_result_protection_failed",
|
|
4122
|
+
message: PROTECTION_FAILURE
|
|
4123
|
+
});
|
|
4124
|
+
}
|
|
4081
4125
|
return error instanceof SystemOperationError ? failureResult({
|
|
4082
4126
|
errorCode: error.code,
|
|
4083
|
-
message
|
|
4127
|
+
message,
|
|
4084
4128
|
data: {
|
|
4085
4129
|
humanActionRequired: error.code === "system_authorization_required"
|
|
4086
4130
|
}
|
|
@@ -4092,9 +4136,9 @@ function withSystemOperationErrors(operation) {
|
|
|
4092
4136
|
}
|
|
4093
4137
|
};
|
|
4094
4138
|
}
|
|
4095
|
-
function createSystemHandlers(run2 = runSystemProcess, resolveTarget = (id) => resolveSystemTarget(id, run2), commandOutput) {
|
|
4139
|
+
function createSystemHandlers(run2 = runSystemProcess, resolveTarget = (id) => resolveSystemTarget(id, run2), commandOutput, protection) {
|
|
4096
4140
|
let targets = async () => {
|
|
4097
|
-
let
|
|
4141
|
+
let observed = await observeSystemTargets(run2), observation = protection ? protectSystemResult(() => protection.protectTargets(observed)) : observed;
|
|
4098
4142
|
return successResult({
|
|
4099
4143
|
output: JSON.stringify(observation),
|
|
4100
4144
|
data: {
|
|
@@ -4103,20 +4147,25 @@ function createSystemHandlers(run2 = runSystemProcess, resolveTarget = (id) => r
|
|
|
4103
4147
|
}
|
|
4104
4148
|
});
|
|
4105
4149
|
}, command = async (params, context) => {
|
|
4106
|
-
let target = await resolveTarget(readSystemTargetId(params.target)), output = commandOutput?.(context),
|
|
4150
|
+
let target = await resolveTarget(readSystemTargetId(params.target)), output = commandOutput?.(context), observed = await executeSystemCommand({
|
|
4107
4151
|
target,
|
|
4108
4152
|
params,
|
|
4109
4153
|
run: run2,
|
|
4110
4154
|
...output ? { runCommand: output.run } : {},
|
|
4111
4155
|
...context?.abortSignal ? { abortSignal: context.abortSignal } : {}
|
|
4112
|
-
});
|
|
4156
|
+
}), result = observed;
|
|
4157
|
+
try {
|
|
4158
|
+
protection && (result = protection.protectProcess(observed));
|
|
4159
|
+
} catch {
|
|
4160
|
+
return failedSystemProtectionReceipt(target, observed, "command_process_completion");
|
|
4161
|
+
}
|
|
4113
4162
|
return output ? output.present(target, result) : systemProcessResult(target, result, "command_process_completion");
|
|
4114
4163
|
}, applications = async (params) => {
|
|
4115
4164
|
let target = await resolveTarget(readSystemTargetId(params.target)), query = (readOptionalString(params.query) ?? "").toLowerCase(), limit = params.limit === void 0 ? 50 : readBoundedInteger(params.limit, {
|
|
4116
4165
|
name: "limit",
|
|
4117
4166
|
minimum: 1,
|
|
4118
4167
|
maximum: 100
|
|
4119
|
-
}),
|
|
4168
|
+
}), observed = await readSystemApplications(target, run2), catalog = protection ? protectSystemResult(() => protection.protectCatalog(observed)) : observed, { output, data } = systemApplicationObservation(
|
|
4120
4169
|
target,
|
|
4121
4170
|
catalog,
|
|
4122
4171
|
query,
|
|
@@ -4135,19 +4184,24 @@ function createSystemHandlers(run2 = runSystemProcess, resolveTarget = (id) => r
|
|
|
4135
4184
|
params,
|
|
4136
4185
|
run: run2,
|
|
4137
4186
|
...context?.abortSignal ? { abortSignal: context.abortSignal } : {}
|
|
4138
|
-
});
|
|
4187
|
+
}), process2 = result.process, application = result.application;
|
|
4188
|
+
try {
|
|
4189
|
+
protection && (process2 = protection.protectProcess(result.process), application = protection.protectApplication(result.application));
|
|
4190
|
+
} catch {
|
|
4191
|
+
return failedSystemProtectionReceipt(target, result.process, "launch_request_dispatch");
|
|
4192
|
+
}
|
|
4139
4193
|
return systemProcessResult(
|
|
4140
4194
|
target,
|
|
4141
|
-
|
|
4195
|
+
process2,
|
|
4142
4196
|
"launch_request_dispatch",
|
|
4143
|
-
|
|
4197
|
+
application
|
|
4144
4198
|
);
|
|
4145
4199
|
};
|
|
4146
4200
|
return {
|
|
4147
|
-
system_targets: withSystemOperationErrors(targets),
|
|
4148
|
-
system_command: withSystemOperationErrors(command),
|
|
4149
|
-
system_applications: withSystemOperationErrors(applications),
|
|
4150
|
-
system_launch: withSystemOperationErrors(launch)
|
|
4201
|
+
system_targets: withSystemOperationErrors(targets, protection),
|
|
4202
|
+
system_command: withSystemOperationErrors(command, protection),
|
|
4203
|
+
system_applications: withSystemOperationErrors(applications, protection),
|
|
4204
|
+
system_launch: withSystemOperationErrors(launch, protection)
|
|
4151
4205
|
};
|
|
4152
4206
|
}
|
|
4153
4207
|
|
|
@@ -4155,12 +4209,62 @@ function createSystemHandlers(run2 = runSystemProcess, resolveTarget = (id) => r
|
|
|
4155
4209
|
import { createHash, randomUUID as randomUUID2 } from "node:crypto";
|
|
4156
4210
|
import { once } from "node:events";
|
|
4157
4211
|
import { createWriteStream } from "node:fs";
|
|
4158
|
-
import { mkdir, open,
|
|
4212
|
+
import { mkdir, open, rename as rename2, writeFile as writeFile3 } from "node:fs/promises";
|
|
4159
4213
|
import { join as join5 } from "node:path";
|
|
4160
4214
|
import { finished } from "node:stream/promises";
|
|
4161
4215
|
|
|
4216
|
+
// src/computer-access/command-output-protection.ts
|
|
4217
|
+
import { readFile as readFile3, rm, writeFile as writeFile2 } from "node:fs/promises";
|
|
4218
|
+
var CapturedOutputProtectionError = class extends Error {
|
|
4219
|
+
constructor(reason) {
|
|
4220
|
+
super(reason);
|
|
4221
|
+
this.reason = reason;
|
|
4222
|
+
}
|
|
4223
|
+
reason;
|
|
4224
|
+
};
|
|
4225
|
+
async function protectCapturedOutput(paths, redact) {
|
|
4226
|
+
let stdout2, stderr;
|
|
4227
|
+
try {
|
|
4228
|
+
stdout2 = await protectStream(paths.stdout, redact), stderr = await protectStream(paths.stderr, redact);
|
|
4229
|
+
let writes = await Promise.allSettled([
|
|
4230
|
+
writeFile2(paths.stdout, stdout2, { flag: "w", mode: 384, flush: !0 }),
|
|
4231
|
+
writeFile2(paths.stderr, stderr, { flag: "w", mode: 384, flush: !0 })
|
|
4232
|
+
]);
|
|
4233
|
+
if (hasRejectedOutputWrite(writes)) throw new CapturedOutputProtectionError("output_storage_failed");
|
|
4234
|
+
return { stdout: stdout2, stderr };
|
|
4235
|
+
} catch (error) {
|
|
4236
|
+
throw stdout2?.fill(0), stderr?.fill(0), error;
|
|
4237
|
+
}
|
|
4238
|
+
}
|
|
4239
|
+
async function protectStream(path, redact) {
|
|
4240
|
+
let bytes;
|
|
4241
|
+
try {
|
|
4242
|
+
bytes = await readFile3(path);
|
|
4243
|
+
} catch {
|
|
4244
|
+
throw new CapturedOutputProtectionError("output_storage_failed");
|
|
4245
|
+
}
|
|
4246
|
+
try {
|
|
4247
|
+
let text = new TextDecoder("utf-8", { fatal: !0, ignoreBOM: !0 }).decode(bytes), protectedText = redact(text);
|
|
4248
|
+
if (!isProtectedOutputText(protectedText)) throw new Error("output_protection_failed");
|
|
4249
|
+
return Buffer.from(protectedText, "utf8");
|
|
4250
|
+
} catch {
|
|
4251
|
+
throw new CapturedOutputProtectionError("output_protection_failed");
|
|
4252
|
+
} finally {
|
|
4253
|
+
bytes.fill(0);
|
|
4254
|
+
}
|
|
4255
|
+
}
|
|
4256
|
+
async function discardCapturedOutput(paths) {
|
|
4257
|
+
return (await Promise.allSettled(Object.values(paths).map((path) => rm(path, { force: !0 })))).every((entry) => entry.status === "fulfilled");
|
|
4258
|
+
}
|
|
4259
|
+
function isProtectedOutputText(value) {
|
|
4260
|
+
return typeof value == "string";
|
|
4261
|
+
}
|
|
4262
|
+
function hasRejectedOutputWrite(writes) {
|
|
4263
|
+
return writes.some((entry) => entry.status === "rejected");
|
|
4264
|
+
}
|
|
4265
|
+
|
|
4162
4266
|
// src/computer-access/command-output-retention.ts
|
|
4163
|
-
import { readFile as
|
|
4267
|
+
import { readFile as readFile4, readdir as readdir2, rm as rm2, stat as stat2 } from "node:fs/promises";
|
|
4164
4268
|
import { join as join4 } from "node:path";
|
|
4165
4269
|
var DEFAULT_SYSTEM_OUTPUT_RETENTION_MS = 10080 * 6e4, activeSystemCaptures = /* @__PURE__ */ new Set(), jobs = /* @__PURE__ */ new Map(), CAPTURE_ID = /^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/;
|
|
4166
4270
|
async function cleanupSystemOutput(root, retentionMs) {
|
|
@@ -4173,14 +4277,14 @@ async function cleanupSystemOutput(root, retentionMs) {
|
|
|
4173
4277
|
let directory = join4(root, entry.name);
|
|
4174
4278
|
if (activeSystemCaptures.has(directory)) continue;
|
|
4175
4279
|
let files = await readdir2(directory), times = await Promise.all(files.map(async (file) => (await stat2(join4(directory, file))).mtimeMs)), completedAt = Math.max((await stat2(directory)).mtimeMs, ...times), captureRetentionMs = await readCaptureRetention(directory, entry.name, retentionMs);
|
|
4176
|
-
Date.now() - completedAt < captureRetentionMs || activeSystemCaptures.has(directory) || (await
|
|
4280
|
+
Date.now() - completedAt < captureRetentionMs || activeSystemCaptures.has(directory) || (await rm2(directory, { recursive: !0 }), removed += 1);
|
|
4177
4281
|
}
|
|
4178
4282
|
return removed;
|
|
4179
4283
|
}
|
|
4180
4284
|
async function readCaptureRetention(directory, id, fallbackMs) {
|
|
4181
4285
|
let receipt;
|
|
4182
4286
|
try {
|
|
4183
|
-
receipt = JSON.parse(await
|
|
4287
|
+
receipt = JSON.parse(await readFile4(join4(directory, "receipt.json"), "utf8"));
|
|
4184
4288
|
} catch (error) {
|
|
4185
4289
|
if (error.code === "ENOENT" || error instanceof SyntaxError) return fallbackMs;
|
|
4186
4290
|
throw error;
|
|
@@ -4218,8 +4322,10 @@ function scheduleSystemOutputCleanup(root, retentionMs) {
|
|
|
4218
4322
|
}
|
|
4219
4323
|
|
|
4220
4324
|
// src/computer-access/command-output-capture.ts
|
|
4221
|
-
var OUTPUT_IO_CHUNK_BYTES = 64 * 1024;
|
|
4222
|
-
async function createSystemOutputCapture(root, retentionMs) {
|
|
4325
|
+
var STREAMS = ["stdout", "stderr"], OUTPUT_IO_CHUNK_BYTES = 64 * 1024;
|
|
4326
|
+
async function createSystemOutputCapture(root, retentionMs, redact) {
|
|
4327
|
+
if (!hasOutputProtection(redact))
|
|
4328
|
+
throw new SystemOperationError("system_output_protection_failed", "Command output protection is unavailable. The command was not dispatched.");
|
|
4223
4329
|
let id = randomUUID2(), directory = join5(root, id);
|
|
4224
4330
|
activeSystemCaptures.add(directory);
|
|
4225
4331
|
try {
|
|
@@ -4227,11 +4333,11 @@ async function createSystemOutputCapture(root, retentionMs) {
|
|
|
4227
4333
|
} catch {
|
|
4228
4334
|
throw activeSystemCaptures.delete(directory), new SystemOperationError("system_output_storage_failed", "Output storage could not be prepared. The command was not dispatched.");
|
|
4229
4335
|
}
|
|
4230
|
-
let
|
|
4231
|
-
let
|
|
4232
|
-
|
|
4336
|
+
let storageFailure, securityFailure, stop, ended = !1, retained = !1, admitted = !1, receipt, processResult, finishing, sources = [], completeStreams = /* @__PURE__ */ new Set(), paths = { stdout: join5(directory, "stdout.bytes"), stderr: join5(directory, "stderr.bytes") }, streams = STREAMS.map((name) => {
|
|
4337
|
+
let sink = createWriteStream(paths[name], { flags: "wx", mode: 384, highWaterMark: OUTPUT_IO_CHUNK_BYTES, flush: !0 }), completion = finished(sink).catch(() => {
|
|
4338
|
+
storageFailure ??= "write_failed", stop?.();
|
|
4233
4339
|
});
|
|
4234
|
-
return {
|
|
4340
|
+
return { sink, completion };
|
|
4235
4341
|
});
|
|
4236
4342
|
try {
|
|
4237
4343
|
await Promise.all(streams.map(({ sink }) => once(sink, "open")));
|
|
@@ -4240,26 +4346,113 @@ async function createSystemOutputCapture(root, retentionMs) {
|
|
|
4240
4346
|
throw await Promise.all(streams.map(({ completion }) => completion)), activeSystemCaptures.delete(directory), scheduleSystemOutputCleanup(root, retentionMs), new SystemOperationError("system_output_storage_failed", "Output files could not be opened. The command was not dispatched.");
|
|
4241
4347
|
}
|
|
4242
4348
|
scheduleSystemOutputCleanup(root, retentionMs);
|
|
4243
|
-
let capture = {
|
|
4349
|
+
let failure = () => storageFailure ?? securityFailure, capture = {
|
|
4244
4350
|
attach(stdout2, stderr, onFailure) {
|
|
4245
|
-
|
|
4351
|
+
if (!canAttachCapture()) {
|
|
4352
|
+
securityFailure ??= "output_protection_failed", onFailure();
|
|
4353
|
+
return;
|
|
4354
|
+
}
|
|
4355
|
+
stop = onFailure, sources.push(stdout2, stderr);
|
|
4356
|
+
for (let [index, source] of sources.entries())
|
|
4357
|
+
source.once("end", () => completeStreams.add(STREAMS[index])), source.once("error", () => {
|
|
4358
|
+
securityFailure ??= "output_incomplete", stop?.();
|
|
4359
|
+
}), source.pipe(streams[index].sink);
|
|
4360
|
+
failure() && onFailure();
|
|
4246
4361
|
},
|
|
4247
4362
|
end() {
|
|
4248
4363
|
if (!ended) {
|
|
4249
|
-
ended = !0;
|
|
4364
|
+
ended = !0, hasCompleteStreams() || (securityFailure ??= "output_incomplete");
|
|
4250
4365
|
for (let source of sources)
|
|
4251
4366
|
source.unpipe(), source.destroy();
|
|
4252
4367
|
for (let { sink } of streams) !sink.destroyed && !sink.writableEnded && sink.end();
|
|
4253
4368
|
}
|
|
4254
4369
|
}
|
|
4255
|
-
}
|
|
4370
|
+
};
|
|
4371
|
+
function canAttachCapture() {
|
|
4372
|
+
return sources.length === 0 && !ended;
|
|
4373
|
+
}
|
|
4374
|
+
function hasCompleteStreams() {
|
|
4375
|
+
return completeStreams.size === 2;
|
|
4376
|
+
}
|
|
4377
|
+
function protectProcess2(result) {
|
|
4378
|
+
if (!result) return;
|
|
4379
|
+
let spawnedProcess = result.spawnedProcess;
|
|
4380
|
+
if (spawnedProcess) {
|
|
4381
|
+
let executable = "[REDACTED]";
|
|
4382
|
+
try {
|
|
4383
|
+
if (executable = redact(spawnedProcess.executable), !hasProtectedIdentity(executable)) throw new Error("output_protection_failed");
|
|
4384
|
+
} catch {
|
|
4385
|
+
securityFailure ??= "output_protection_failed", executable = "[REDACTED]";
|
|
4386
|
+
}
|
|
4387
|
+
spawnedProcess = { ...spawnedProcess, executable };
|
|
4388
|
+
}
|
|
4389
|
+
processResult = {
|
|
4390
|
+
exitCode: result.exitCode,
|
|
4391
|
+
status: result.status,
|
|
4392
|
+
outputTruncated: result.outputTruncated,
|
|
4393
|
+
stdout: "",
|
|
4394
|
+
stderr: "",
|
|
4395
|
+
...spawnedProcess ? { spawnedProcess } : {}
|
|
4396
|
+
};
|
|
4397
|
+
}
|
|
4398
|
+
async function finish(result, materialize = !0) {
|
|
4399
|
+
capture.end(), await Promise.all(streams.map(({ completion }) => completion)), protectProcess2(result);
|
|
4400
|
+
let protectedBytes;
|
|
4401
|
+
try {
|
|
4402
|
+
if (!failure())
|
|
4403
|
+
try {
|
|
4404
|
+
protectedBytes = await protectCapturedOutput(paths, redact);
|
|
4405
|
+
} catch (error) {
|
|
4406
|
+
isOutputStorageFailure(error) ? storageFailure ??= "write_failed" : securityFailure ??= "output_protection_failed";
|
|
4407
|
+
}
|
|
4408
|
+
failure() && !await discardCapturedOutput(paths) && (storageFailure = "capture_purge_failed"), receipt = {
|
|
4409
|
+
id,
|
|
4410
|
+
stdoutBytes: protectedBytes?.stdout.length ?? 0,
|
|
4411
|
+
stderrBytes: protectedBytes?.stderr.length ?? 0,
|
|
4412
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4413
|
+
retentionMs,
|
|
4414
|
+
complete: !failure(),
|
|
4415
|
+
...!materialize && protectedBytes ? {
|
|
4416
|
+
stdoutSha256: createHash("sha256").update(protectedBytes.stdout).digest("hex"),
|
|
4417
|
+
stderrSha256: createHash("sha256").update(protectedBytes.stderr).digest("hex")
|
|
4418
|
+
} : {}
|
|
4419
|
+
};
|
|
4420
|
+
try {
|
|
4421
|
+
let temporary = join5(directory, "receipt.tmp");
|
|
4422
|
+
await writeFile3(
|
|
4423
|
+
temporary,
|
|
4424
|
+
JSON.stringify({
|
|
4425
|
+
kind: "system_command_output_v1",
|
|
4426
|
+
...receipt,
|
|
4427
|
+
processStatus: processResult?.status,
|
|
4428
|
+
exitCode: processResult?.exitCode,
|
|
4429
|
+
spawnedProcess: processResult?.spawnedProcess,
|
|
4430
|
+
...securityFailure ? { securityFailure } : {},
|
|
4431
|
+
...storageFailure ? { storageFailure } : {}
|
|
4432
|
+
}),
|
|
4433
|
+
{ flag: "wx", mode: 384, flush: !0 }
|
|
4434
|
+
), await rename2(temporary, join5(directory, "receipt.json"));
|
|
4435
|
+
} catch {
|
|
4436
|
+
storageFailure ??= "receipt_write_failed", receipt = { ...receipt, complete: !1 };
|
|
4437
|
+
}
|
|
4438
|
+
return admitted = receipt.complete, !admitted || !materialize || !protectedBytes ? { stdout: "", stderr: "" } : { stdout: protectedBytes.stdout.toString("utf8"), stderr: protectedBytes.stderr.toString("utf8") };
|
|
4439
|
+
} finally {
|
|
4440
|
+
protectedBytes?.stdout.fill(0), protectedBytes?.stderr.fill(0), retained || activeSystemCaptures.delete(directory);
|
|
4441
|
+
}
|
|
4442
|
+
}
|
|
4256
4443
|
return {
|
|
4257
4444
|
capture,
|
|
4258
4445
|
get receipt() {
|
|
4259
4446
|
return receipt;
|
|
4260
4447
|
},
|
|
4261
4448
|
get failure() {
|
|
4262
|
-
return failure;
|
|
4449
|
+
return failure();
|
|
4450
|
+
},
|
|
4451
|
+
get failureKind() {
|
|
4452
|
+
return storageFailure ? "storage" : securityFailure ? "security" : void 0;
|
|
4453
|
+
},
|
|
4454
|
+
get processResult() {
|
|
4455
|
+
return processResult;
|
|
4263
4456
|
},
|
|
4264
4457
|
retain() {
|
|
4265
4458
|
retained = !0, activeSystemCaptures.add(directory);
|
|
@@ -4268,61 +4461,35 @@ async function createSystemOutputCapture(root, retentionMs) {
|
|
|
4268
4461
|
retained = !1, activeSystemCaptures.delete(directory);
|
|
4269
4462
|
},
|
|
4270
4463
|
async read(stream, offset, length) {
|
|
4271
|
-
|
|
4464
|
+
if (!admitted) throw new Error("system_output_unavailable");
|
|
4465
|
+
if (!isAdmittedOutputRead(stream, offset, length, receipt)) throw new Error("system_output_reference_invalid");
|
|
4466
|
+
let file = await open(paths[stream], "r");
|
|
4272
4467
|
try {
|
|
4273
|
-
let bytes = Buffer.alloc(length), { bytesRead } = await file.read(bytes, 0, length, offset);
|
|
4468
|
+
let size = stream === "stdout" ? receipt.stdoutBytes : receipt.stderrBytes, bytes = Buffer.alloc(Math.min(length, size - offset)), { bytesRead } = await file.read(bytes, 0, bytes.length, offset);
|
|
4274
4469
|
return bytes.subarray(0, bytesRead);
|
|
4275
4470
|
} finally {
|
|
4276
4471
|
await file.close();
|
|
4277
4472
|
}
|
|
4278
4473
|
},
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
try {
|
|
4282
|
-
await Promise.all(streams.map(({ completion }) => completion));
|
|
4283
|
-
let sizes = await Promise.all(streams.map(async ({ path }) => {
|
|
4284
|
-
try {
|
|
4285
|
-
return (await stat3(path)).size;
|
|
4286
|
-
} catch {
|
|
4287
|
-
return failure ??= "read_failed", 0;
|
|
4288
|
-
}
|
|
4289
|
-
})), stdout2 = "", stderr = "";
|
|
4290
|
-
if (!failure && materialize)
|
|
4291
|
-
try {
|
|
4292
|
-
[stdout2, stderr] = await Promise.all(streams.map(({ path }) => readFile4(path, "utf8")));
|
|
4293
|
-
} catch {
|
|
4294
|
-
failure = "read_failed";
|
|
4295
|
-
}
|
|
4296
|
-
let completedAt = Date.now();
|
|
4297
|
-
receipt = {
|
|
4298
|
-
id,
|
|
4299
|
-
stdoutBytes: sizes[0],
|
|
4300
|
-
stderrBytes: sizes[1],
|
|
4301
|
-
completedAt: new Date(completedAt).toISOString(),
|
|
4302
|
-
retentionMs,
|
|
4303
|
-
complete: !failure,
|
|
4304
|
-
...materialize ? {} : { stdoutSha256: streams[0].hash.digest("hex"), stderrSha256: streams[1].hash.digest("hex") }
|
|
4305
|
-
};
|
|
4306
|
-
try {
|
|
4307
|
-
let temporary = join5(directory, "receipt.tmp");
|
|
4308
|
-
await writeFile2(temporary, JSON.stringify({
|
|
4309
|
-
kind: "system_command_output_v1",
|
|
4310
|
-
...receipt,
|
|
4311
|
-
processStatus: result?.status,
|
|
4312
|
-
exitCode: result?.exitCode,
|
|
4313
|
-
spawnedProcess: result?.spawnedProcess,
|
|
4314
|
-
...failure ? { storageFailure: failure } : {}
|
|
4315
|
-
}), { flag: "wx", mode: 384, flush: !0 }), await rename2(temporary, join5(directory, "receipt.json"));
|
|
4316
|
-
} catch {
|
|
4317
|
-
failure ??= "receipt_write_failed", receipt = { ...receipt, complete: !1 };
|
|
4318
|
-
}
|
|
4319
|
-
return { stdout: stdout2, stderr };
|
|
4320
|
-
} finally {
|
|
4321
|
-
retained || activeSystemCaptures.delete(directory);
|
|
4322
|
-
}
|
|
4474
|
+
finish(result, materialize = !0) {
|
|
4475
|
+
return finishing ??= finish(result, materialize), finishing;
|
|
4323
4476
|
}
|
|
4324
4477
|
};
|
|
4325
4478
|
}
|
|
4479
|
+
function hasOutputProtection(value) {
|
|
4480
|
+
return typeof value == "function";
|
|
4481
|
+
}
|
|
4482
|
+
function hasProtectedIdentity(value) {
|
|
4483
|
+
return typeof value == "string";
|
|
4484
|
+
}
|
|
4485
|
+
function isOutputStorageFailure(error) {
|
|
4486
|
+
return error instanceof CapturedOutputProtectionError && error.reason === "output_storage_failed";
|
|
4487
|
+
}
|
|
4488
|
+
function isAdmittedOutputRead(stream, offset, length, receipt) {
|
|
4489
|
+
if (stream !== "stdout" && stream !== "stderr" || !Number.isSafeInteger(offset) || offset < 0 || !Number.isSafeInteger(length) || length < 0) return !1;
|
|
4490
|
+
let size = stream === "stdout" ? receipt.stdoutBytes : receipt.stderrBytes;
|
|
4491
|
+
return offset <= size;
|
|
4492
|
+
}
|
|
4326
4493
|
|
|
4327
4494
|
// src/computer-access/companion/command-output-protocol.ts
|
|
4328
4495
|
var SYSTEM_OUTPUT_CAPABILITY = "system_command_output_v1", SYSTEM_OUTPUT_CHUNK_BYTES = 64 * 1024;
|
|
@@ -4350,6 +4517,133 @@ function readSystemOutputTransfer(value) {
|
|
|
4350
4517
|
};
|
|
4351
4518
|
}
|
|
4352
4519
|
|
|
4520
|
+
// src/computer-access/security/secret-text.ts
|
|
4521
|
+
var REDACTED = "[REDACTED]", 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)`, credentialIndicator = new RegExp(
|
|
4522
|
+
String.raw`(?<![\p{L}\p{N}_.-])(?:-{1,2})?(?:${CREDENTIAL_KEY_SOURCE}|(?:proxy-)?authorization)[\s"'\\]*[:=]`,
|
|
4523
|
+
"iu"
|
|
4524
|
+
);
|
|
4525
|
+
function detectionText(input) {
|
|
4526
|
+
return input.replace(
|
|
4527
|
+
/%([0-7][0-9a-f])/giu,
|
|
4528
|
+
(_, hex) => String.fromCharCode(Number.parseInt(hex, 16))
|
|
4529
|
+
).replace(
|
|
4530
|
+
/\\(?:u00|x|U000000)([0-7][0-9a-fA-F])/gu,
|
|
4531
|
+
(_, hex) => String.fromCharCode(Number.parseInt(hex, 16))
|
|
4532
|
+
);
|
|
4533
|
+
}
|
|
4534
|
+
function hasPrivateKeyIndicator(text) {
|
|
4535
|
+
return /-----BEGIN (?:[A-Z0-9]+ )*PRIVATE KEY(?: BLOCK)?-----/u.test(text);
|
|
4536
|
+
}
|
|
4537
|
+
function hasUrlCredentials(text) {
|
|
4538
|
+
return /\b[a-z][a-z0-9+.-]*(?::|%3a)(?:\/|%2f){2}[^\s/?#<>]*(?:@|%40)/iu.test(text);
|
|
4539
|
+
}
|
|
4540
|
+
function hasAuthorizationCredentials(text) {
|
|
4541
|
+
for (let match of text.matchAll(
|
|
4542
|
+
/\b(Bearer|Basic)[ \t]+([A-Za-z0-9._~+/-]+={0,2})/giu
|
|
4543
|
+
)) {
|
|
4544
|
+
if (match[1].toLowerCase() === "bearer") return !0;
|
|
4545
|
+
let value = match[2];
|
|
4546
|
+
if (/^[A-Za-z0-9+/]+={0,2}$/u.test(value) && !(value.length < 8) && Buffer.from(value, "base64").toString("utf8").includes(":"))
|
|
4547
|
+
return !0;
|
|
4548
|
+
}
|
|
4549
|
+
return !1;
|
|
4550
|
+
}
|
|
4551
|
+
function isAwsAccessKeyValue(value, atEnd) {
|
|
4552
|
+
return /^[A-Z0-9]{16}$/u.test(value) ? !0 : atEnd ? /^[A-Z0-9]{4,15}$/u.test(value) : !1;
|
|
4553
|
+
}
|
|
4554
|
+
function isRecognizedProviderToken(prefix, value, atEnd) {
|
|
4555
|
+
if (prefix === "AKIA" || prefix === "ASIA")
|
|
4556
|
+
return isAwsAccessKeyValue(value, atEnd);
|
|
4557
|
+
if (value.length >= 20) return !0;
|
|
4558
|
+
let partialMinimum = prefix === "sk-" ? 8 : 1;
|
|
4559
|
+
return atEnd && value.length >= partialMinimum;
|
|
4560
|
+
}
|
|
4561
|
+
function hasProviderToken(text) {
|
|
4562
|
+
let provider = /\b(sk-(?:proj-|svcacct-)?|gh[pousr]_|github_pat_|xox[baprs]-|AKIA|ASIA)([A-Za-z0-9_-]+)/gu;
|
|
4563
|
+
for (let match of text.matchAll(provider)) {
|
|
4564
|
+
let atEnd = match.index + match[0].length === text.length;
|
|
4565
|
+
if (isRecognizedProviderToken(match[1], match[2], atEnd)) return !0;
|
|
4566
|
+
}
|
|
4567
|
+
return !1;
|
|
4568
|
+
}
|
|
4569
|
+
function compactJoseSegmentCount(header) {
|
|
4570
|
+
try {
|
|
4571
|
+
let value = JSON.parse(
|
|
4572
|
+
Buffer.from(header, "base64url").toString("utf8")
|
|
4573
|
+
);
|
|
4574
|
+
if (typeof value != "object" || value === null || Array.isArray(value))
|
|
4575
|
+
return;
|
|
4576
|
+
let fields = value;
|
|
4577
|
+
return typeof fields.alg != "string" ? void 0 : typeof fields.enc == "string" ? 5 : 3;
|
|
4578
|
+
} catch {
|
|
4579
|
+
return;
|
|
4580
|
+
}
|
|
4581
|
+
}
|
|
4582
|
+
function hasCompactJoseToken(text) {
|
|
4583
|
+
let jose = /\b([A-Za-z0-9_-]+)(?:\.[A-Za-z0-9_-]*)+/gu;
|
|
4584
|
+
for (let match of text.matchAll(jose)) {
|
|
4585
|
+
let parts = match[0].split("."), capturedAtEnd = match.index + match[0].length === text.length;
|
|
4586
|
+
for (let index = 0; index < parts.length - 1; index += 1) {
|
|
4587
|
+
let expected = compactJoseSegmentCount(parts[index]);
|
|
4588
|
+
if (expected !== void 0 && !(expected === 3 && parts[index + 1] === "") && (parts.length - index >= expected || capturedAtEnd))
|
|
4589
|
+
return !0;
|
|
4590
|
+
}
|
|
4591
|
+
}
|
|
4592
|
+
return !1;
|
|
4593
|
+
}
|
|
4594
|
+
function hasSecretIndicator(text) {
|
|
4595
|
+
return credentialIndicator.test(text) || hasPrivateKeyIndicator(text) || hasUrlCredentials(text) || hasAuthorizationCredentials(text) || hasProviderToken(text) ? !0 : hasCompactJoseToken(text);
|
|
4596
|
+
}
|
|
4597
|
+
function redactSecretText(input) {
|
|
4598
|
+
return hasSecretIndicator(input) || hasSecretIndicator(detectionText(input)) ? REDACTED : input;
|
|
4599
|
+
}
|
|
4600
|
+
|
|
4601
|
+
// src/computer-access/security/system-results.ts
|
|
4602
|
+
var INCOMPLETE_STREAM = "[UNAVAILABLE: incomplete output cannot be scanned for secrets]", SENSITIVE_TARGET = "Target unavailable because its shell identity contains sensitive text.";
|
|
4603
|
+
function protectApplication(application) {
|
|
4604
|
+
if (redactSecretText(application.id) === application.id)
|
|
4605
|
+
return { ...application, name: redactSecretText(application.name) };
|
|
4606
|
+
}
|
|
4607
|
+
function protectCatalog(catalog) {
|
|
4608
|
+
let applications = catalog.applications.flatMap((application) => {
|
|
4609
|
+
let protectedApplication = protectApplication(application);
|
|
4610
|
+
return protectedApplication ? [protectedApplication] : [];
|
|
4611
|
+
});
|
|
4612
|
+
return {
|
|
4613
|
+
...catalog,
|
|
4614
|
+
applications,
|
|
4615
|
+
complete: catalog.complete && applications.length === catalog.applications.length,
|
|
4616
|
+
scope: { ...catalog.scope, roots: catalog.scope.roots.map(redactSecretText) }
|
|
4617
|
+
};
|
|
4618
|
+
}
|
|
4619
|
+
function protectTargets(observation) {
|
|
4620
|
+
return {
|
|
4621
|
+
...observation,
|
|
4622
|
+
host: { ...observation.host, kernelRelease: redactSecretText(observation.host.kernelRelease) },
|
|
4623
|
+
targets: observation.targets.map((target) => target.available ? redactSecretText(target.shell) !== target.shell ? { id: target.id, available: !1, reason: SENSITIVE_TARGET } : target : { ...target, reason: redactSecretText(target.reason) })
|
|
4624
|
+
};
|
|
4625
|
+
}
|
|
4626
|
+
function protectProcess(result) {
|
|
4627
|
+
return {
|
|
4628
|
+
...result,
|
|
4629
|
+
stdout: result.outputTruncated ? INCOMPLETE_STREAM : redactSecretText(result.stdout),
|
|
4630
|
+
stderr: result.outputTruncated ? INCOMPLETE_STREAM : redactSecretText(result.stderr),
|
|
4631
|
+
...result.spawnedProcess ? {
|
|
4632
|
+
spawnedProcess: {
|
|
4633
|
+
...result.spawnedProcess,
|
|
4634
|
+
executable: redactSecretText(result.spawnedProcess.executable)
|
|
4635
|
+
}
|
|
4636
|
+
} : {}
|
|
4637
|
+
};
|
|
4638
|
+
}
|
|
4639
|
+
var systemResultProtection = Object.freeze({
|
|
4640
|
+
protectTargets,
|
|
4641
|
+
protectCatalog,
|
|
4642
|
+
protectProcess,
|
|
4643
|
+
protectApplication,
|
|
4644
|
+
protectMessage: redactSecretText
|
|
4645
|
+
});
|
|
4646
|
+
|
|
4353
4647
|
// src/computer-access/companion/command-output.ts
|
|
4354
4648
|
var CompanionCommandOutput = class {
|
|
4355
4649
|
constructor(stateDir) {
|
|
@@ -4390,10 +4684,10 @@ var CompanionCommandOutput = class {
|
|
|
4390
4684
|
}), captured, handlers = createSystemHandlers(void 0, void 0, () => ({
|
|
4391
4685
|
run: async (input) => {
|
|
4392
4686
|
if (input.abortSignal?.aborted) return runSystemProcess(input);
|
|
4393
|
-
captured = await createSystemOutputCapture(join6(this.stateDir, "command-output"), retentionMs), captured.retain();
|
|
4687
|
+
captured = await createSystemOutputCapture(join6(this.stateDir, "command-output"), retentionMs, redactSecretText), captured.retain();
|
|
4394
4688
|
try {
|
|
4395
4689
|
let result = await runSystemProcess(input, captured.capture);
|
|
4396
|
-
return await captured.finish(result, !1), { ...
|
|
4690
|
+
return await captured.finish(result, !1), { ...captured.processResult, outputTruncated: !!captured.failure };
|
|
4397
4691
|
} catch (error) {
|
|
4398
4692
|
throw await captured.finish(void 0, !1), captured.release(), error;
|
|
4399
4693
|
}
|
|
@@ -4402,13 +4696,16 @@ var CompanionCommandOutput = class {
|
|
|
4402
4696
|
let receipt = buildSystemProcessResult(target, result, "command_process_completion");
|
|
4403
4697
|
if (!captured?.receipt) return receipt;
|
|
4404
4698
|
let data = { ...receipt.data, outputCapture: captured.receipt };
|
|
4405
|
-
if (captured.failure)
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4699
|
+
if (captured.failure) {
|
|
4700
|
+
captured.release();
|
|
4701
|
+
let errorCode2 = captured.failureKind === "security" ? "system_output_protection_failed" : "system_output_storage_failed";
|
|
4702
|
+
return failureResult({
|
|
4703
|
+
errorCode: errorCode2,
|
|
4704
|
+
message: "Command output could not be admitted after dispatch; inspect the process receipt before another action. The command was not replayed.",
|
|
4705
|
+
data: { ...data, ...captured.failureKind === "security" ? { securityFailure: captured.failure } : { storageFailure: captured.failure } },
|
|
4410
4706
|
...result.exitCode !== null ? { exitCode: result.exitCode } : {}
|
|
4411
4707
|
});
|
|
4708
|
+
}
|
|
4412
4709
|
if (this.closed || context?.abortSignal?.aborted)
|
|
4413
4710
|
return captured.release(), { ...receipt, data };
|
|
4414
4711
|
let transfer = readSystemOutputTransfer({ kind: SYSTEM_OUTPUT_CAPABILITY, ...captured.receipt });
|
|
@@ -4421,8 +4718,16 @@ Streams retained for exact transfer.`,
|
|
|
4421
4718
|
data: { ...data, outputTransfer: transfer }
|
|
4422
4719
|
};
|
|
4423
4720
|
}
|
|
4424
|
-
})), { outputRetentionMs: _retention, ...command } = params;
|
|
4425
|
-
|
|
4721
|
+
}), systemResultProtection), { outputRetentionMs: _retention, ...command } = params;
|
|
4722
|
+
try {
|
|
4723
|
+
return await handlers.system_command(command, context);
|
|
4724
|
+
} finally {
|
|
4725
|
+
this.hasRegisteredTransfer(captured) || captured?.release();
|
|
4726
|
+
}
|
|
4727
|
+
}
|
|
4728
|
+
hasRegisteredTransfer(capture) {
|
|
4729
|
+
let id = capture?.receipt?.id;
|
|
4730
|
+
return id ? this.captures.get(id) === capture : !1;
|
|
4426
4731
|
}
|
|
4427
4732
|
async read(params) {
|
|
4428
4733
|
if (!isHostIdentifier(params.captureId)) throw new Error("system_output_reference_invalid");
|
|
@@ -4439,6 +4744,9 @@ Streams retained for exact transfer.`,
|
|
|
4439
4744
|
}
|
|
4440
4745
|
};
|
|
4441
4746
|
|
|
4747
|
+
// src/computer-access/companion/secret-protection-protocol.ts
|
|
4748
|
+
var HOST_SECRET_PROTECTION_CAPABILITY = "host_secret_protection_v1";
|
|
4749
|
+
|
|
4442
4750
|
// src/computer-access/companion/native-permissions.ts
|
|
4443
4751
|
import { execFile as execFile3 } from "node:child_process";
|
|
4444
4752
|
import { promisify as promisify3 } from "node:util";
|
|
@@ -4771,7 +5079,7 @@ async function sendWindowsNotification(notification, signal, run2 = runNotificat
|
|
|
4771
5079
|
|
|
4772
5080
|
// src/computer-access/companion/notification-macos.ts
|
|
4773
5081
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
4774
|
-
import { readFile as readFile5, unlink as unlink2, writeFile as
|
|
5082
|
+
import { readFile as readFile5, unlink as unlink2, writeFile as writeFile4 } from "node:fs/promises";
|
|
4775
5083
|
import { join as join8 } from "node:path";
|
|
4776
5084
|
import { setTimeout as delay } from "node:timers/promises";
|
|
4777
5085
|
function renderMacNotificationApplet(stateDir) {
|
|
@@ -4858,7 +5166,7 @@ async function sendMacNotification(notification, locations, signal, run2 = runNo
|
|
|
4858
5166
|
"pending",
|
|
4859
5167
|
randomUUID3() + ".json"
|
|
4860
5168
|
), resultFile = file + ".result";
|
|
4861
|
-
await
|
|
5169
|
+
await writeFile4(
|
|
4862
5170
|
file,
|
|
4863
5171
|
JSON.stringify({ ...notification, expiresAt: Date.now() + 15e3 }),
|
|
4864
5172
|
{ flag: "wx", mode: 384 }
|
|
@@ -5073,14 +5381,14 @@ import {
|
|
|
5073
5381
|
open as open2,
|
|
5074
5382
|
readFile as readFile7,
|
|
5075
5383
|
rename as rename3,
|
|
5076
|
-
rm as
|
|
5077
|
-
writeFile as
|
|
5384
|
+
rm as rm4,
|
|
5385
|
+
writeFile as writeFile6
|
|
5078
5386
|
} from "node:fs/promises";
|
|
5079
5387
|
import { dirname as dirname3, isAbsolute as isAbsolute2, join as join12 } from "node:path";
|
|
5080
5388
|
|
|
5081
5389
|
// src/computer-access/companion/notification-directory.ts
|
|
5082
5390
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
5083
|
-
import { mkdir as mkdir2, rm as
|
|
5391
|
+
import { mkdir as mkdir2, rm as rm3, symlink, unlink as unlink3, writeFile as writeFile5 } from "node:fs/promises";
|
|
5084
5392
|
import { basename as basename3, dirname as dirname2, join as join10 } from "node:path";
|
|
5085
5393
|
|
|
5086
5394
|
// src/computer-access/companion/notification-directory-ownership.ts
|
|
@@ -5094,9 +5402,9 @@ function renderNotificationLinkOwner(directory, backing) {
|
|
|
5094
5402
|
});
|
|
5095
5403
|
}
|
|
5096
5404
|
async function readNotificationOwnerFile(path) {
|
|
5097
|
-
let
|
|
5098
|
-
if (!
|
|
5099
|
-
if (
|
|
5405
|
+
let stat3 = await lstat2(path);
|
|
5406
|
+
if (!stat3.isFile()) throw new Error("notification_directory_not_owned");
|
|
5407
|
+
if (stat3.size > 4096) throw new Error("notification_directory_not_owned");
|
|
5100
5408
|
return readFile6(path, "utf8");
|
|
5101
5409
|
}
|
|
5102
5410
|
async function assertNotificationDirectoryMarker(directory) {
|
|
@@ -5119,21 +5427,21 @@ function hasSameNotificationFileIdentity(left, right) {
|
|
|
5119
5427
|
return left.dev !== right.dev ? !1 : left.ino === right.ino;
|
|
5120
5428
|
}
|
|
5121
5429
|
async function readOwnedNotificationPath(directory) {
|
|
5122
|
-
let
|
|
5430
|
+
let stat3 = await lstat2(directory, { bigint: !0 }).catch(
|
|
5123
5431
|
(error) => {
|
|
5124
5432
|
if (error.code !== "ENOENT")
|
|
5125
5433
|
throw error;
|
|
5126
5434
|
}
|
|
5127
5435
|
);
|
|
5128
|
-
if (!
|
|
5129
|
-
if (
|
|
5436
|
+
if (!stat3) return;
|
|
5437
|
+
if (stat3.isDirectory())
|
|
5130
5438
|
return await assertNotificationDirectoryMarker(directory), {
|
|
5131
5439
|
directory,
|
|
5132
5440
|
backing: directory,
|
|
5133
|
-
aliasIdentity:
|
|
5134
|
-
backingIdentity:
|
|
5441
|
+
aliasIdentity: stat3,
|
|
5442
|
+
backingIdentity: stat3
|
|
5135
5443
|
};
|
|
5136
|
-
if (!
|
|
5444
|
+
if (!stat3.isSymbolicLink())
|
|
5137
5445
|
throw new Error("notification_directory_not_owned");
|
|
5138
5446
|
let target = await readlink(directory);
|
|
5139
5447
|
if (!isNotificationBackingName(directory, target))
|
|
@@ -5148,12 +5456,12 @@ async function readOwnedNotificationPath(directory) {
|
|
|
5148
5456
|
if (!hasBoundNotificationLinkOwner(record, directory, target))
|
|
5149
5457
|
throw new Error("notification_directory_not_owned");
|
|
5150
5458
|
let currentAlias = await lstat2(directory, { bigint: !0 });
|
|
5151
|
-
if (!hasSameNotificationFileIdentity(
|
|
5459
|
+
if (!hasSameNotificationFileIdentity(stat3, currentAlias))
|
|
5152
5460
|
throw new Error("notification_directory_changed");
|
|
5153
5461
|
return {
|
|
5154
5462
|
directory,
|
|
5155
5463
|
backing,
|
|
5156
|
-
aliasIdentity:
|
|
5464
|
+
aliasIdentity: stat3,
|
|
5157
5465
|
backingIdentity,
|
|
5158
5466
|
linkTarget: target
|
|
5159
5467
|
};
|
|
@@ -5229,11 +5537,11 @@ async function ensureOwnedNotificationDirectory(locations, run2 = runNotificatio
|
|
|
5229
5537
|
await mkdir2(staged, { mode: 448 });
|
|
5230
5538
|
let retainBacking = !1;
|
|
5231
5539
|
try {
|
|
5232
|
-
await
|
|
5540
|
+
await writeFile5(join10(staged, ".owner"), NOTIFICATION_OWNER_MARKER, {
|
|
5233
5541
|
flag: "wx",
|
|
5234
5542
|
mode: 384,
|
|
5235
5543
|
flush: !0
|
|
5236
|
-
}), requiresNotificationDirectoryLink() && await
|
|
5544
|
+
}), requiresNotificationDirectoryLink() && await writeFile5(
|
|
5237
5545
|
join10(staged, ".owner-link"),
|
|
5238
5546
|
renderNotificationLinkOwner(directory, staged),
|
|
5239
5547
|
{
|
|
@@ -5247,17 +5555,17 @@ async function ensureOwnedNotificationDirectory(locations, run2 = runNotificatio
|
|
|
5247
5555
|
run2
|
|
5248
5556
|
);
|
|
5249
5557
|
} finally {
|
|
5250
|
-
retainBacking || await
|
|
5558
|
+
retainBacking || await rm3(staged, { recursive: !0, force: !0 });
|
|
5251
5559
|
}
|
|
5252
5560
|
}
|
|
5253
5561
|
async function removeOwnedNotificationDirectory(locations) {
|
|
5254
5562
|
let owner = await readOwnedNotificationDirectory(locations);
|
|
5255
5563
|
if (owner) {
|
|
5256
5564
|
if (await assertNotificationOwnershipUnchanged(owner), owner.linkTarget === void 0) {
|
|
5257
|
-
await
|
|
5565
|
+
await rm3(owner.directory, { recursive: !0 });
|
|
5258
5566
|
return;
|
|
5259
5567
|
}
|
|
5260
|
-
await unlink3(owner.directory), await assertNotificationBackingUnchanged(owner), await
|
|
5568
|
+
await unlink3(owner.directory), await assertNotificationBackingUnchanged(owner), await rm3(owner.backing, { recursive: !0 });
|
|
5261
5569
|
}
|
|
5262
5570
|
}
|
|
5263
5571
|
|
|
@@ -5288,13 +5596,13 @@ function isBundleExecutableName(value) {
|
|
|
5288
5596
|
return typeof value != "string" || value.length === 0 || value === "." || value === ".." ? !1 : !/[\\/\u0000-\u001f\u007f]/.test(value);
|
|
5289
5597
|
}
|
|
5290
5598
|
async function assertBundleDirectory(path) {
|
|
5291
|
-
let
|
|
5292
|
-
if (!
|
|
5599
|
+
let stat3 = await lstat3(path);
|
|
5600
|
+
if (!stat3.isDirectory() || stat3.isSymbolicLink())
|
|
5293
5601
|
throw new Error("notification_bundle_directory_invalid");
|
|
5294
5602
|
}
|
|
5295
5603
|
async function assertBundleFile(path) {
|
|
5296
|
-
let
|
|
5297
|
-
if (!
|
|
5604
|
+
let stat3 = await lstat3(path);
|
|
5605
|
+
if (!stat3.isFile() || stat3.isSymbolicLink())
|
|
5298
5606
|
throw new Error("notification_bundle_file_invalid");
|
|
5299
5607
|
}
|
|
5300
5608
|
async function readBundleMetadata(app, run2, signal) {
|
|
@@ -5374,12 +5682,12 @@ function renderLinuxNotificationDesktop(runtimeUrl) {
|
|
|
5374
5682
|
`);
|
|
5375
5683
|
}
|
|
5376
5684
|
async function assertLinuxDesktopOwnership(path) {
|
|
5377
|
-
let
|
|
5685
|
+
let stat3 = await lstat4(path).catch((error) => {
|
|
5378
5686
|
if (error.code !== "ENOENT")
|
|
5379
5687
|
throw error;
|
|
5380
5688
|
});
|
|
5381
|
-
if (!
|
|
5382
|
-
if (!
|
|
5689
|
+
if (!stat3) return !1;
|
|
5690
|
+
if (!stat3.isFile() || stat3.isSymbolicLink())
|
|
5383
5691
|
throw new Error("notification_registration_not_owned");
|
|
5384
5692
|
if (!(await readFile7(path, "utf8")).includes("# " + NOTIFICATION_OWNER_MARKER))
|
|
5385
5693
|
throw new Error("notification_registration_not_owned");
|
|
@@ -5399,9 +5707,9 @@ async function stopMacNotificationApp(locations, run2) {
|
|
|
5399
5707
|
}
|
|
5400
5708
|
async function installMacNotificationApp(locations, run2) {
|
|
5401
5709
|
let directory = notificationInstallDirectory(locations), source = join12(directory, "notification-helper.js"), temporary = join12(directory, "ABot.next.app"), app = macNotificationAppPath(locations);
|
|
5402
|
-
await
|
|
5710
|
+
await writeFile6(source, renderMacNotificationApplet(locations.stateDir), {
|
|
5403
5711
|
mode: 384
|
|
5404
|
-
}), await
|
|
5712
|
+
}), await rm4(temporary, { recursive: !0, force: !0 }), await run2({
|
|
5405
5713
|
file: "/usr/bin/osacompile",
|
|
5406
5714
|
args: ["-l", "JavaScript", "-s", "-o", temporary, source],
|
|
5407
5715
|
timeoutMs: 3e4
|
|
@@ -5416,19 +5724,19 @@ async function installMacNotificationApp(locations, run2) {
|
|
|
5416
5724
|
temporary
|
|
5417
5725
|
],
|
|
5418
5726
|
timeoutMs: 3e4
|
|
5419
|
-
}), await stopMacNotificationApp(locations, run2), await
|
|
5727
|
+
}), await stopMacNotificationApp(locations, run2), await rm4(app, { recursive: !0, force: !0 }), await rename3(temporary, app), await run2({
|
|
5420
5728
|
file: "/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister",
|
|
5421
5729
|
args: ["-f", app]
|
|
5422
5730
|
});
|
|
5423
5731
|
}
|
|
5424
5732
|
async function installDesktopNotificationIdentity(startup, runtimeUrl, run2 = runNotificationProcess) {
|
|
5425
5733
|
let locations = notificationLocationsFromStartup(startup), directory = notificationInstallDirectory(locations);
|
|
5426
|
-
await ensureOwnedNotificationDirectory(locations, run2), await
|
|
5734
|
+
await ensureOwnedNotificationDirectory(locations, run2), await rm4(join12(directory, ".ready"), { force: !0 }), await mkdir3(join12(directory, "pending"), { recursive: !0, mode: 448 }), await registerDesktopNotificationIdentity(
|
|
5427
5735
|
startup.platform,
|
|
5428
5736
|
locations,
|
|
5429
5737
|
runtimeUrl,
|
|
5430
5738
|
run2
|
|
5431
|
-
), await
|
|
5739
|
+
), await writeFile6(join12(directory, ".ready"), startup.platform, { mode: 384 });
|
|
5432
5740
|
}
|
|
5433
5741
|
async function registerDesktopNotificationIdentity(platform, locations, runtimeUrl, run2) {
|
|
5434
5742
|
if (platform === "win32") {
|
|
@@ -5450,12 +5758,12 @@ async function registerDesktopNotificationIdentity(platform, locations, runtimeU
|
|
|
5450
5758
|
throw new Error("notification_platform_unsupported");
|
|
5451
5759
|
}
|
|
5452
5760
|
async function uninstallMacNotificationApp(locations, run2) {
|
|
5453
|
-
let app = macNotificationAppPath(locations),
|
|
5761
|
+
let app = macNotificationAppPath(locations), stat3 = await lstat4(app).catch((error) => {
|
|
5454
5762
|
if (error.code !== "ENOENT")
|
|
5455
5763
|
throw error;
|
|
5456
5764
|
});
|
|
5457
|
-
if (
|
|
5458
|
-
if (!
|
|
5765
|
+
if (stat3) {
|
|
5766
|
+
if (!stat3.isDirectory() || stat3.isSymbolicLink())
|
|
5459
5767
|
throw new Error("notification_registration_not_owned");
|
|
5460
5768
|
await stopMacNotificationApp(locations, run2), await run2({
|
|
5461
5769
|
file: "/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister",
|
|
@@ -5488,7 +5796,7 @@ async function installLinuxNotificationIdentity(locations, runtimeUrl, run2) {
|
|
|
5488
5796
|
try {
|
|
5489
5797
|
await file.writeFile(content).finally(() => file.close()), await assertLinuxDesktopOwnership(path), await rename3(temporary, path);
|
|
5490
5798
|
} finally {
|
|
5491
|
-
await
|
|
5799
|
+
await rm4(temporary, { force: !0 });
|
|
5492
5800
|
}
|
|
5493
5801
|
}
|
|
5494
5802
|
async function uninstallDesktopNotificationIdentity(startup, run2 = runNotificationProcess) {
|
|
@@ -5502,7 +5810,7 @@ async function uninstallDesktopNotificationIdentity(startup, run2 = runNotificat
|
|
|
5502
5810
|
input: JSON.stringify({ action: "uninstall" })
|
|
5503
5811
|
}), startup.platform === "darwin" && await uninstallMacNotificationApp(locations, run2), startup.platform === "linux") {
|
|
5504
5812
|
let path = linuxNotificationDesktopPath(locations);
|
|
5505
|
-
await assertLinuxDesktopOwnership(path) && await
|
|
5813
|
+
await assertLinuxDesktopOwnership(path) && await rm4(path);
|
|
5506
5814
|
}
|
|
5507
5815
|
await removeOwnedNotificationDirectory(locations);
|
|
5508
5816
|
}
|
|
@@ -5587,7 +5895,7 @@ function createNotificationSession(platform, runtimeUrl, ready, renderer, probe)
|
|
|
5587
5895
|
} catch (error) {
|
|
5588
5896
|
return failureResult({
|
|
5589
5897
|
errorCode: hasUnknownNotificationOutcome(error) ? "notification_outcome_unknown" : "notification_native_failed",
|
|
5590
|
-
message: error instanceof Error ? error.message.slice(0, 1e3) : "Desktop notification submission failed."
|
|
5898
|
+
message: error instanceof Error ? redactSecretText(error.message).slice(0, 1e3) : "Desktop notification submission failed."
|
|
5591
5899
|
});
|
|
5592
5900
|
}
|
|
5593
5901
|
}
|
|
@@ -5616,7 +5924,7 @@ async function createNativeNotificationSession(platform, runtimeUrl, locations =
|
|
|
5616
5924
|
linux.close(), platform === "macos" && session.ready && await stopMacNotificationApp(locations, runNotificationProcess).catch(
|
|
5617
5925
|
(error) => {
|
|
5618
5926
|
console.warn(
|
|
5619
|
-
"Desktop notification helper could not stop: " + (error instanceof Error ? error.message : String(error))
|
|
5927
|
+
"Desktop notification helper could not stop: " + redactSecretText(error instanceof Error ? error.message : String(error))
|
|
5620
5928
|
);
|
|
5621
5929
|
}
|
|
5622
5930
|
);
|
|
@@ -6864,18 +7172,14 @@ function readUnixNativeResult(value, platform) {
|
|
|
6864
7172
|
|
|
6865
7173
|
// src/computer-access/computer/unix-native-process.ts
|
|
6866
7174
|
function createUnixNativeProcess(options) {
|
|
6867
|
-
let child, pending, closed = !1, failedReason, buffer = Buffer.alloc(0), queue = Promise.resolve(),
|
|
7175
|
+
let child, pending, closed = !1, failedReason, buffer = Buffer.alloc(0), queue = Promise.resolve(), lastDesktop;
|
|
6868
7176
|
function interruptedResult(reason) {
|
|
6869
7177
|
let dispatch = pending?.request.operation === "act" ? pending.dispatch ?? {
|
|
6870
7178
|
status: "unknown",
|
|
6871
7179
|
requestedInputCount: 1,
|
|
6872
7180
|
reason
|
|
6873
7181
|
} : void 0, result = unavailableUnixDesktop(options.platform, reason, dispatch);
|
|
6874
|
-
return
|
|
6875
|
-
...result,
|
|
6876
|
-
desktop: { ...lastResult.desktop, available: !1, reason },
|
|
6877
|
-
windows: lastResult.windows
|
|
6878
|
-
} : result;
|
|
7182
|
+
return lastDesktop ? { ...result, desktop: { ...result.desktop, ...lastDesktop } } : result;
|
|
6879
7183
|
}
|
|
6880
7184
|
function terminate(reason) {
|
|
6881
7185
|
failedReason = reason, pending?.finish(interruptedResult(reason));
|
|
@@ -6884,7 +7188,7 @@ function createUnixNativeProcess(options) {
|
|
|
6884
7188
|
let hardStop = setTimeout(() => retiring.kill("SIGKILL"), 3e3);
|
|
6885
7189
|
hardStop.unref(), retiring.once("exit", () => clearTimeout(hardStop));
|
|
6886
7190
|
}
|
|
6887
|
-
child = void 0, buffer = Buffer.alloc(0);
|
|
7191
|
+
child = void 0, buffer.fill(0), buffer = Buffer.alloc(0);
|
|
6888
7192
|
}
|
|
6889
7193
|
function receiveLine(line) {
|
|
6890
7194
|
let value = JSON.parse(line);
|
|
@@ -6899,7 +7203,17 @@ function createUnixNativeProcess(options) {
|
|
|
6899
7203
|
}
|
|
6900
7204
|
if (message.type !== "result") throw new Error("native_protocol_invalid");
|
|
6901
7205
|
let result = readUnixNativeResult(message.result, options.platform);
|
|
6902
|
-
|
|
7206
|
+
lastDesktop = {
|
|
7207
|
+
binding: result.desktop.binding,
|
|
7208
|
+
bounds: {
|
|
7209
|
+
x: result.desktop.bounds.x,
|
|
7210
|
+
y: result.desktop.bounds.y,
|
|
7211
|
+
width: result.desktop.bounds.width,
|
|
7212
|
+
height: result.desktop.bounds.height
|
|
7213
|
+
},
|
|
7214
|
+
coordinateSpace: result.desktop.coordinateSpace,
|
|
7215
|
+
targetingGuarantee: result.desktop.targetingGuarantee
|
|
7216
|
+
}, pending.finish(result);
|
|
6903
7217
|
}
|
|
6904
7218
|
function ensureHelper() {
|
|
6905
7219
|
child || (child = (options.spawnProcess ?? spawn5)(options.file, [...options.args], {
|
|
@@ -6907,14 +7221,15 @@ function createUnixNativeProcess(options) {
|
|
|
6907
7221
|
windowsHide: !0
|
|
6908
7222
|
}), child.stdin.on("error", () => terminate("computer_native_pipe_failed")), child.stderr.resume(), child.stdout.on("data", (chunk) => {
|
|
6909
7223
|
if (closed || failedReason) return;
|
|
6910
|
-
|
|
7224
|
+
let previous = buffer;
|
|
7225
|
+
if (buffer = Buffer.concat([previous, chunk]), previous.fill(0), buffer.length > NATIVE_JSON_LIMIT) {
|
|
6911
7226
|
terminate("computer_native_result_limit");
|
|
6912
7227
|
return;
|
|
6913
7228
|
}
|
|
6914
7229
|
let boundary = buffer.indexOf(10);
|
|
6915
7230
|
for (; boundary >= 0; ) {
|
|
6916
|
-
let line =
|
|
6917
|
-
buffer =
|
|
7231
|
+
let received = buffer, line = received.subarray(0, boundary).toString("utf8");
|
|
7232
|
+
buffer = Buffer.from(received.subarray(boundary + 1)), received.fill(0);
|
|
6918
7233
|
try {
|
|
6919
7234
|
receiveLine(line);
|
|
6920
7235
|
} catch {
|
|
@@ -8950,6 +9265,127 @@ function waitForDesktopTurn(previous, signal) {
|
|
|
8950
9265
|
})) : previous;
|
|
8951
9266
|
}
|
|
8952
9267
|
|
|
9268
|
+
// src/computer-access/security/desktop-result.ts
|
|
9269
|
+
function rectangle(value) {
|
|
9270
|
+
return { x: value.x, y: value.y, width: value.width, height: value.height };
|
|
9271
|
+
}
|
|
9272
|
+
function projectDesktopFields(result, text) {
|
|
9273
|
+
let capability = (value) => ({
|
|
9274
|
+
supported: value.supported,
|
|
9275
|
+
available: value.available,
|
|
9276
|
+
...value.reason === void 0 ? {} : { reason: text(value.reason) }
|
|
9277
|
+
}), desktop = result.desktop;
|
|
9278
|
+
return {
|
|
9279
|
+
desktop: {
|
|
9280
|
+
platform: desktop.platform,
|
|
9281
|
+
binding: desktop.binding,
|
|
9282
|
+
name: text(desktop.name),
|
|
9283
|
+
available: desktop.available,
|
|
9284
|
+
...desktop.reason === void 0 ? {} : { reason: text(desktop.reason) },
|
|
9285
|
+
bounds: rectangle(desktop.bounds),
|
|
9286
|
+
...desktop.coordinateSpace === void 0 ? {} : { coordinateSpace: desktop.coordinateSpace },
|
|
9287
|
+
capabilities: {
|
|
9288
|
+
capture: capability(desktop.capabilities.capture),
|
|
9289
|
+
accessibility: capability(desktop.capabilities.accessibility),
|
|
9290
|
+
input: capability(desktop.capabilities.input),
|
|
9291
|
+
windows: capability(desktop.capabilities.windows)
|
|
9292
|
+
},
|
|
9293
|
+
targetingGuarantee: desktop.targetingGuarantee
|
|
9294
|
+
},
|
|
9295
|
+
windows: result.windows.map((window) => ({
|
|
9296
|
+
binding: window.binding,
|
|
9297
|
+
title: text(window.title),
|
|
9298
|
+
...window.application === void 0 ? {} : { application: text(window.application) },
|
|
9299
|
+
bounds: rectangle(window.bounds),
|
|
9300
|
+
focused: window.focused
|
|
9301
|
+
})),
|
|
9302
|
+
...result.focusedWindow === void 0 ? {} : { focusedWindow: result.focusedWindow },
|
|
9303
|
+
...result.observation ? {
|
|
9304
|
+
observation: {
|
|
9305
|
+
capturedAt: text(result.observation.capturedAt),
|
|
9306
|
+
region: rectangle(result.observation.region),
|
|
9307
|
+
imageWidth: result.observation.imageWidth,
|
|
9308
|
+
imageHeight: result.observation.imageHeight,
|
|
9309
|
+
accessibility: result.observation.accessibility.map((node) => ({
|
|
9310
|
+
role: text(node.role),
|
|
9311
|
+
...node.name === void 0 ? {} : { name: text(node.name) },
|
|
9312
|
+
...node.value === void 0 ? {} : { value: text(node.value) },
|
|
9313
|
+
...node.bounds === void 0 ? {} : { bounds: rectangle(node.bounds) },
|
|
9314
|
+
...node.focused === void 0 ? {} : { focused: node.focused }
|
|
9315
|
+
})),
|
|
9316
|
+
accessibilityTruncated: result.observation.accessibilityTruncated
|
|
9317
|
+
}
|
|
9318
|
+
} : {},
|
|
9319
|
+
...result.dispatch ? {
|
|
9320
|
+
dispatch: {
|
|
9321
|
+
status: result.dispatch.status,
|
|
9322
|
+
requestedInputCount: result.dispatch.requestedInputCount,
|
|
9323
|
+
...result.dispatch.acceptedInputCount === void 0 ? {} : { acceptedInputCount: result.dispatch.acceptedInputCount },
|
|
9324
|
+
...result.dispatch.reason === void 0 ? {} : { reason: text(result.dispatch.reason) }
|
|
9325
|
+
}
|
|
9326
|
+
} : {},
|
|
9327
|
+
...result.error ? {
|
|
9328
|
+
error: {
|
|
9329
|
+
code: text(result.error.code),
|
|
9330
|
+
message: text(result.error.message)
|
|
9331
|
+
}
|
|
9332
|
+
} : {}
|
|
9333
|
+
};
|
|
9334
|
+
}
|
|
9335
|
+
function protectDesktopResult(result, scan = redactSecretText) {
|
|
9336
|
+
let suspected = !1;
|
|
9337
|
+
try {
|
|
9338
|
+
let protectedResult = projectDesktopFields(result, (input) => {
|
|
9339
|
+
let output = scan(input);
|
|
9340
|
+
if (typeof output != "string")
|
|
9341
|
+
throw new Error("desktop_text_scan_failed");
|
|
9342
|
+
return suspected ||= output !== input, output;
|
|
9343
|
+
});
|
|
9344
|
+
return suspected ? (result.image?.bytes.fill(0), {
|
|
9345
|
+
...protectedResult,
|
|
9346
|
+
...result.image && !protectedResult.error ? {
|
|
9347
|
+
error: {
|
|
9348
|
+
code: "computer_image_secret_blocked",
|
|
9349
|
+
message: "Image withheld because desktop text contained a suspected secret. The dispatch receipt is unchanged."
|
|
9350
|
+
}
|
|
9351
|
+
} : {}
|
|
9352
|
+
}) : {
|
|
9353
|
+
...protectedResult,
|
|
9354
|
+
...result.image ? {
|
|
9355
|
+
image: {
|
|
9356
|
+
mimeType: result.image.mimeType,
|
|
9357
|
+
bytes: result.image.bytes
|
|
9358
|
+
}
|
|
9359
|
+
} : {}
|
|
9360
|
+
};
|
|
9361
|
+
} catch {
|
|
9362
|
+
result.image?.bytes.fill(0);
|
|
9363
|
+
let safe = projectDesktopFields(result, () => "[REDACTED]");
|
|
9364
|
+
return {
|
|
9365
|
+
desktop: {
|
|
9366
|
+
...safe.desktop,
|
|
9367
|
+
reason: "Desktop content withheld because its protection check failed."
|
|
9368
|
+
},
|
|
9369
|
+
windows: [],
|
|
9370
|
+
...safe.focusedWindow === void 0 ? {} : { focusedWindow: safe.focusedWindow },
|
|
9371
|
+
...safe.dispatch ? { dispatch: safe.dispatch } : {},
|
|
9372
|
+
error: {
|
|
9373
|
+
code: "computer_observation_protection_failed",
|
|
9374
|
+
message: "Desktop content withheld because its protection check failed. The dispatch receipt is unchanged."
|
|
9375
|
+
}
|
|
9376
|
+
};
|
|
9377
|
+
}
|
|
9378
|
+
}
|
|
9379
|
+
|
|
9380
|
+
// src/computer-access/security/observed-error.ts
|
|
9381
|
+
function protectObservedError(error, fallback) {
|
|
9382
|
+
try {
|
|
9383
|
+
return redactSecretText(error instanceof Error ? error.message : fallback);
|
|
9384
|
+
} catch {
|
|
9385
|
+
return "Observed error details withheld because the protection check failed.";
|
|
9386
|
+
}
|
|
9387
|
+
}
|
|
9388
|
+
|
|
8953
9389
|
// src/computer-access/computer/companion-sessions.ts
|
|
8954
9390
|
var CompanionComputerSessions = class {
|
|
8955
9391
|
constructor(platform, createBackend = createNativeComputerBackend, resolveTarget = resolveSystemTarget) {
|
|
@@ -8973,7 +9409,10 @@ var CompanionComputerSessions = class {
|
|
|
8973
9409
|
} catch (error) {
|
|
8974
9410
|
return failureResult({
|
|
8975
9411
|
errorCode: "computer_native_operation_failed",
|
|
8976
|
-
message:
|
|
9412
|
+
message: protectObservedError(
|
|
9413
|
+
error,
|
|
9414
|
+
"The computer operation failed; observe before retrying."
|
|
9415
|
+
)
|
|
8977
9416
|
});
|
|
8978
9417
|
}
|
|
8979
9418
|
};
|
|
@@ -9033,12 +9472,13 @@ var CompanionComputerSessions = class {
|
|
|
9033
9472
|
async () => {
|
|
9034
9473
|
let session = await this.acquire(id);
|
|
9035
9474
|
this.eraseFrame(session);
|
|
9036
|
-
let result = await session.backend.execute(request, signal), { image, ...
|
|
9475
|
+
let result = await session.backend.execute(request, signal), { image: rawImage, ...rawMetadata } = result;
|
|
9037
9476
|
try {
|
|
9038
|
-
readNativeComputerResult(
|
|
9477
|
+
readNativeComputerResult(rawMetadata);
|
|
9039
9478
|
} catch (error) {
|
|
9040
|
-
throw
|
|
9479
|
+
throw rawImage?.bytes.fill(0), error;
|
|
9041
9480
|
}
|
|
9481
|
+
let { image, ...metadata } = protectDesktopResult(result);
|
|
9042
9482
|
if (!image)
|
|
9043
9483
|
return successResult({
|
|
9044
9484
|
output: "Native desktop observation.",
|
|
@@ -9117,96 +9557,45 @@ import { existsSync as existsSync2 } from "node:fs";
|
|
|
9117
9557
|
// src/computer-access/companion/observation-filter.ts
|
|
9118
9558
|
import { createHash as createHash3, createHmac, randomBytes, randomUUID as randomUUID8 } from "node:crypto";
|
|
9119
9559
|
|
|
9120
|
-
// src/
|
|
9121
|
-
var
|
|
9122
|
-
|
|
9123
|
-
"
|
|
9124
|
-
|
|
9125
|
-
|
|
9126
|
-
|
|
9127
|
-
|
|
9128
|
-
|
|
9129
|
-
|
|
9130
|
-
|
|
9131
|
-
|
|
9560
|
+
// src/shared/passive-observation-self-exclusion.ts
|
|
9561
|
+
var OWN_WEB_UI_TITLES = ["ABot Runtime — Workspace", "ABot Runtime"], BROWSER_WINDOW_NAMES = [
|
|
9562
|
+
"Mozilla Firefox",
|
|
9563
|
+
"Mozilla Firefox (Private Browsing)",
|
|
9564
|
+
"Google Chrome",
|
|
9565
|
+
"Chromium",
|
|
9566
|
+
"Microsoft Edge",
|
|
9567
|
+
"Brave",
|
|
9568
|
+
"Safari"
|
|
9569
|
+
], BROWSER_WINDOW_SUFFIXES = BROWSER_WINDOW_NAMES.flatMap((browser) => [
|
|
9570
|
+
` — ${browser}`,
|
|
9571
|
+
` - ${browser}`
|
|
9572
|
+
]);
|
|
9573
|
+
function isOwnWebUiWindowTitle(title) {
|
|
9574
|
+
if (typeof title != "string") return !1;
|
|
9575
|
+
if (OWN_WEB_UI_TITLES.includes(title)) return !0;
|
|
9576
|
+
let suffix = BROWSER_WINDOW_SUFFIXES.find(
|
|
9577
|
+
(candidate) => title.endsWith(candidate)
|
|
9132
9578
|
);
|
|
9579
|
+
return suffix ? OWN_WEB_UI_TITLES.includes(title.slice(0, -suffix.length)) : !1;
|
|
9133
9580
|
}
|
|
9134
|
-
function
|
|
9135
|
-
return
|
|
9136
|
-
}
|
|
9137
|
-
function hasUrlCredentials(text) {
|
|
9138
|
-
return /\b[a-z][a-z0-9+.-]*(?::|%3a)(?:\/|%2f){2}[^\s/?#<>]*(?:@|%40)/iu.test(text);
|
|
9139
|
-
}
|
|
9140
|
-
function hasAuthorizationCredentials(text) {
|
|
9141
|
-
for (let match of text.matchAll(
|
|
9142
|
-
/\b(Bearer|Basic)[ \t]+([A-Za-z0-9._~+/-]+={0,2})/giu
|
|
9143
|
-
)) {
|
|
9144
|
-
if (match[1].toLowerCase() === "bearer") return !0;
|
|
9145
|
-
let value = match[2];
|
|
9146
|
-
if (/^[A-Za-z0-9+/]+={0,2}$/u.test(value) && !(value.length < 8) && Buffer.from(value, "base64").toString("utf8").includes(":"))
|
|
9147
|
-
return !0;
|
|
9148
|
-
}
|
|
9149
|
-
return !1;
|
|
9150
|
-
}
|
|
9151
|
-
function isAwsAccessKeyValue(value, atEnd) {
|
|
9152
|
-
return /^[A-Z0-9]{16}$/u.test(value) ? !0 : atEnd ? /^[A-Z0-9]{4,15}$/u.test(value) : !1;
|
|
9153
|
-
}
|
|
9154
|
-
function isRecognizedProviderToken(prefix, value, atEnd) {
|
|
9155
|
-
if (prefix === "AKIA" || prefix === "ASIA")
|
|
9156
|
-
return isAwsAccessKeyValue(value, atEnd);
|
|
9157
|
-
if (value.length >= 20) return !0;
|
|
9158
|
-
let partialMinimum = prefix === "sk-" ? 8 : 1;
|
|
9159
|
-
return atEnd && value.length >= partialMinimum;
|
|
9160
|
-
}
|
|
9161
|
-
function hasProviderToken(text) {
|
|
9162
|
-
let provider = /\b(sk-(?:proj-|svcacct-)?|gh[pousr]_|github_pat_|xox[baprs]-|AKIA|ASIA)([A-Za-z0-9_-]+)/gu;
|
|
9163
|
-
for (let match of text.matchAll(provider)) {
|
|
9164
|
-
let atEnd = match.index + match[0].length === text.length;
|
|
9165
|
-
if (isRecognizedProviderToken(match[1], match[2], atEnd)) return !0;
|
|
9166
|
-
}
|
|
9167
|
-
return !1;
|
|
9168
|
-
}
|
|
9169
|
-
function compactJoseSegmentCount(header) {
|
|
9170
|
-
try {
|
|
9171
|
-
let value = JSON.parse(
|
|
9172
|
-
Buffer.from(header, "base64url").toString("utf8")
|
|
9173
|
-
);
|
|
9174
|
-
if (typeof value != "object" || value === null || Array.isArray(value))
|
|
9175
|
-
return;
|
|
9176
|
-
let fields = value;
|
|
9177
|
-
return typeof fields.alg != "string" ? void 0 : typeof fields.enc == "string" ? 5 : 3;
|
|
9178
|
-
} catch {
|
|
9179
|
-
return;
|
|
9180
|
-
}
|
|
9181
|
-
}
|
|
9182
|
-
function hasCompactJoseToken(text) {
|
|
9183
|
-
let jose = /\b([A-Za-z0-9_-]+)(?:\.[A-Za-z0-9_-]*)+/gu;
|
|
9184
|
-
for (let match of text.matchAll(jose)) {
|
|
9185
|
-
let parts = match[0].split("."), capturedAtEnd = match.index + match[0].length === text.length;
|
|
9186
|
-
for (let index = 0; index < parts.length - 1; index += 1) {
|
|
9187
|
-
let expected = compactJoseSegmentCount(parts[index]);
|
|
9188
|
-
if (expected !== void 0 && !(expected === 3 && parts[index + 1] === "") && (parts.length - index >= expected || capturedAtEnd))
|
|
9189
|
-
return !0;
|
|
9190
|
-
}
|
|
9191
|
-
}
|
|
9192
|
-
return !1;
|
|
9581
|
+
function isOwnObservationApplication(app) {
|
|
9582
|
+
return app.toLowerCase() === "abot";
|
|
9193
9583
|
}
|
|
9194
|
-
function
|
|
9195
|
-
return
|
|
9196
|
-
}
|
|
9197
|
-
function redactObservationText(input) {
|
|
9198
|
-
return hasSecretIndicator(input) || hasSecretIndicator(detectionText(input)) ? REDACTED : input;
|
|
9584
|
+
function isOwnApplicationObservation(source) {
|
|
9585
|
+
return isOwnObservationApplication(source.app) ? !0 : isOwnWebUiWindowTitle(source.title);
|
|
9199
9586
|
}
|
|
9587
|
+
|
|
9588
|
+
// src/computer-access/companion/observation-redaction.ts
|
|
9200
9589
|
function redactObservationSource(source, sourceKey) {
|
|
9201
9590
|
let redacted = {
|
|
9202
|
-
app:
|
|
9203
|
-
windowId:
|
|
9591
|
+
app: redactSecretText(source.app).slice(0, 128),
|
|
9592
|
+
windowId: redactSecretText(source.windowId).slice(0, 256),
|
|
9204
9593
|
...source.processId === void 0 ? {} : { processId: source.processId },
|
|
9205
9594
|
...source.documentId === void 0 ? {} : {
|
|
9206
|
-
documentId:
|
|
9595
|
+
documentId: redactSecretText(source.documentId).slice(0, 4096)
|
|
9207
9596
|
},
|
|
9208
|
-
...source.title === void 0 ? {} : { title:
|
|
9209
|
-
...source.url === void 0 ? {} : { url:
|
|
9597
|
+
...source.title === void 0 ? {} : { title: redactSecretText(source.title).slice(0, 4096) },
|
|
9598
|
+
...source.url === void 0 ? {} : { url: redactSecretText(source.url).slice(0, 4096) }
|
|
9210
9599
|
};
|
|
9211
9600
|
return [
|
|
9212
9601
|
"app",
|
|
@@ -9267,26 +9656,6 @@ function isPassiveCollectorEvent(value) {
|
|
|
9267
9656
|
}
|
|
9268
9657
|
|
|
9269
9658
|
// src/computer-access/companion/observation-filter.ts
|
|
9270
|
-
var OWN_WEB_UI_TITLES = ["ABot Runtime — Workspace", "ABot Runtime"], BROWSER_WINDOW_NAMES = [
|
|
9271
|
-
"Mozilla Firefox",
|
|
9272
|
-
"Mozilla Firefox (Private Browsing)",
|
|
9273
|
-
"Google Chrome",
|
|
9274
|
-
"Chromium",
|
|
9275
|
-
"Microsoft Edge",
|
|
9276
|
-
"Brave",
|
|
9277
|
-
"Safari"
|
|
9278
|
-
], BROWSER_WINDOW_SUFFIXES = BROWSER_WINDOW_NAMES.flatMap((browser) => [
|
|
9279
|
-
` — ${browser}`,
|
|
9280
|
-
` - ${browser}`
|
|
9281
|
-
]);
|
|
9282
|
-
function isOwnWebUiWindowTitle(title) {
|
|
9283
|
-
if (typeof title != "string") return !1;
|
|
9284
|
-
if (OWN_WEB_UI_TITLES.includes(title)) return !0;
|
|
9285
|
-
let suffix = BROWSER_WINDOW_SUFFIXES.find(
|
|
9286
|
-
(candidate) => title.endsWith(candidate)
|
|
9287
|
-
);
|
|
9288
|
-
return suffix ? OWN_WEB_UI_TITLES.includes(title.slice(0, -suffix.length)) : !1;
|
|
9289
|
-
}
|
|
9290
9659
|
function hasBoundedSourceMetadata(source) {
|
|
9291
9660
|
if (!isObservationOwner(source.app) || typeof source.windowId != "string" || source.windowId.length === 0 || source.windowId.length > 256) return !1;
|
|
9292
9661
|
for (let field of ["documentId", "title", "url"])
|
|
@@ -9322,7 +9691,7 @@ var ObservationFilter = class {
|
|
|
9322
9691
|
accept(value) {
|
|
9323
9692
|
if (isPassiveCollectorEvent(value) && value.type === "status") {
|
|
9324
9693
|
value.state === "paused" && (this.lastSource = void 0);
|
|
9325
|
-
let reason = value.reason === void 0 ? void 0 :
|
|
9694
|
+
let reason = value.reason === void 0 ? void 0 : redactSecretText(value.reason).slice(0, 512), identity = JSON.stringify([value.state, reason]);
|
|
9326
9695
|
return identity === this.lastStatus ? void 0 : (this.lastStatus = identity, {
|
|
9327
9696
|
type: "status",
|
|
9328
9697
|
state: value.state,
|
|
@@ -9340,7 +9709,7 @@ var ObservationFilter = class {
|
|
|
9340
9709
|
url: value.source.url
|
|
9341
9710
|
};
|
|
9342
9711
|
if (!hasBoundedSourceMetadata(rawSource)) return;
|
|
9343
|
-
if (
|
|
9712
|
+
if (isOwnApplicationObservation(rawSource)) {
|
|
9344
9713
|
this.lastSource = void 0;
|
|
9345
9714
|
return;
|
|
9346
9715
|
}
|
|
@@ -9359,11 +9728,11 @@ var ObservationFilter = class {
|
|
|
9359
9728
|
rawSource.title,
|
|
9360
9729
|
rawSource.url
|
|
9361
9730
|
])
|
|
9362
|
-
).digest("hex"), source = redactObservationSource(rawSource, sourceKey), content =
|
|
9731
|
+
).digest("hex"), source = redactObservationSource(rawSource, sourceKey), content = redactSecretText(value.content).replace(/\r\n?/gu, `
|
|
9363
9732
|
`).replace(/[ \t]+\n/gu, `
|
|
9364
9733
|
`).trim(), fingerprint = createHash3("sha256").update(content).digest("hex"), previous = this.fingerprints.get(sourceKey), duplicate = previous?.fingerprint === fingerprint;
|
|
9365
9734
|
if (duplicate && this.lastSource === sourceKey) return;
|
|
9366
|
-
let truncated = content.length > OBSERVATION_CONTENT_LIMIT, coverageReason = typeof value.coverageReason == "string" ?
|
|
9735
|
+
let truncated = content.length > OBSERVATION_CONTENT_LIMIT, coverageReason = typeof value.coverageReason == "string" ? redactSecretText(value.coverageReason).slice(0, 512) : void 0;
|
|
9367
9736
|
truncated && (coverageReason = "content_limit");
|
|
9368
9737
|
let observation = {
|
|
9369
9738
|
id: randomUUID8(),
|
|
@@ -10038,8 +10407,10 @@ function desktopCollectorCommand(platform) {
|
|
|
10038
10407
|
return { file: "python3", args: ["-u", "-c", LINUX_OBSERVATION_SCRIPT] };
|
|
10039
10408
|
}
|
|
10040
10409
|
function startDesktopCollector(options) {
|
|
10041
|
-
let command = desktopCollectorCommand(options.platform ?? process.platform), child, closed = !1,
|
|
10042
|
-
|
|
10410
|
+
let command = desktopCollectorCommand(options.platform ?? process.platform), child, closed = !1, stopped = !1, confirmStopped = () => {
|
|
10411
|
+
stopped || (stopped = !0, options.onStopped?.());
|
|
10412
|
+
}, received = Buffer.alloc(0), terminalStatus = !1, filter = new ObservationFilter(options.excludedApplications), close = () => {
|
|
10413
|
+
if (closed = !0, !(stopped || !child?.pid)) {
|
|
10043
10414
|
if (process.platform !== "win32") {
|
|
10044
10415
|
try {
|
|
10045
10416
|
process.kill(-child.pid, "SIGTERM");
|
|
@@ -10056,7 +10427,7 @@ function startDesktopCollector(options) {
|
|
|
10056
10427
|
type: "status",
|
|
10057
10428
|
state: "unavailable",
|
|
10058
10429
|
reason: "platform_unsupported"
|
|
10059
|
-
}), { close };
|
|
10430
|
+
}), confirmStopped(), { close };
|
|
10060
10431
|
if (process.platform === "darwin")
|
|
10061
10432
|
try {
|
|
10062
10433
|
let developerDirectory = execFileSync("/usr/bin/xcode-select", ["-p"], {
|
|
@@ -10070,17 +10441,23 @@ function startDesktopCollector(options) {
|
|
|
10070
10441
|
type: "status",
|
|
10071
10442
|
state: "unavailable",
|
|
10072
10443
|
reason: "macos_swift_tools_unavailable"
|
|
10073
|
-
}), { close };
|
|
10444
|
+
}), confirmStopped(), { close };
|
|
10074
10445
|
}
|
|
10075
|
-
|
|
10076
|
-
|
|
10077
|
-
|
|
10078
|
-
|
|
10079
|
-
|
|
10080
|
-
|
|
10081
|
-
|
|
10082
|
-
|
|
10083
|
-
|
|
10446
|
+
options.onEvent({ type: "status", state: "starting" });
|
|
10447
|
+
try {
|
|
10448
|
+
child = (options.spawnProcess ?? spawn6)(command.file, command.args, {
|
|
10449
|
+
windowsHide: !0,
|
|
10450
|
+
detached: process.platform !== "win32",
|
|
10451
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
10452
|
+
env: {
|
|
10453
|
+
...process.env,
|
|
10454
|
+
ABOT_OBSERVATION_EXCLUSIONS: JSON.stringify(options.excludedApplications)
|
|
10455
|
+
}
|
|
10456
|
+
});
|
|
10457
|
+
} catch {
|
|
10458
|
+
return options.onEvent({ type: "status", state: "failed", reason: "collector_start_failed" }), closed = !0, confirmStopped(), { close };
|
|
10459
|
+
}
|
|
10460
|
+
return child.stdin?.on("error", () => {
|
|
10084
10461
|
}), child.stdin?.end(command.input), child.stderr?.resume(), child.stdout?.on("data", (chunk) => {
|
|
10085
10462
|
if (closed) return;
|
|
10086
10463
|
if (received = Buffer.concat([received, chunk]), received.length > OBSERVATION_WIRE_LIMIT * 2) {
|
|
@@ -10109,17 +10486,26 @@ function startDesktopCollector(options) {
|
|
|
10109
10486
|
received = received.subarray(boundary + 1), boundary = received.indexOf(10);
|
|
10110
10487
|
}
|
|
10111
10488
|
}), child.once("error", () => {
|
|
10112
|
-
|
|
10113
|
-
|
|
10114
|
-
|
|
10115
|
-
|
|
10116
|
-
|
|
10489
|
+
try {
|
|
10490
|
+
if (closed) return;
|
|
10491
|
+
options.onEvent({
|
|
10492
|
+
type: "status",
|
|
10493
|
+
state: "unavailable",
|
|
10494
|
+
reason: "collector_dependency_unavailable"
|
|
10495
|
+
}), close();
|
|
10496
|
+
} finally {
|
|
10497
|
+
child?.pid || confirmStopped();
|
|
10498
|
+
}
|
|
10117
10499
|
}), child.once("exit", (code) => {
|
|
10118
|
-
|
|
10119
|
-
|
|
10120
|
-
|
|
10121
|
-
|
|
10122
|
-
|
|
10500
|
+
try {
|
|
10501
|
+
!closed && !terminalStatus && options.onEvent({
|
|
10502
|
+
type: "status",
|
|
10503
|
+
state: "unavailable",
|
|
10504
|
+
reason: code === 0 ? "collector_stopped" : "collector_start_failed"
|
|
10505
|
+
});
|
|
10506
|
+
} finally {
|
|
10507
|
+
closed = !0, confirmStopped();
|
|
10508
|
+
}
|
|
10123
10509
|
}), { close };
|
|
10124
10510
|
}
|
|
10125
10511
|
|
|
@@ -10298,7 +10684,7 @@ async function connectNativeHost(options) {
|
|
|
10298
10684
|
options.signal.aborted && (await ownedNotifications?.close(), options.signal.throwIfAborted());
|
|
10299
10685
|
let commandOutput = options.commandOutputStateDir && !options.handlers ? new CompanionCommandOutput(options.commandOutputStateDir) : void 0, handlers = options.handlers ?? {
|
|
10300
10686
|
...commandOutput?.handlers(),
|
|
10301
|
-
...createSystemHandlers(),
|
|
10687
|
+
...createSystemHandlers(void 0, void 0, void 0, systemResultProtection),
|
|
10302
10688
|
...computers.handlers(),
|
|
10303
10689
|
...notifications.handlers(),
|
|
10304
10690
|
...createNativePermissionHandlers(options.identity.os)
|
|
@@ -10393,7 +10779,7 @@ async function connectNativeHost(options) {
|
|
|
10393
10779
|
assertNativeOperationTarget(message, options.identity.os);
|
|
10394
10780
|
} catch (error) {
|
|
10395
10781
|
if (!(error instanceof NativeOperationInputError)) throw error;
|
|
10396
|
-
sendResult(message.id, operationFailure(error.message, error.code));
|
|
10782
|
+
sendResult(message.id, operationFailure(redactSecretText(error.message), error.code));
|
|
10397
10783
|
return;
|
|
10398
10784
|
}
|
|
10399
10785
|
let handler = handlers[message.operation];
|
|
@@ -10447,6 +10833,7 @@ async function connectNativeHost(options) {
|
|
|
10447
10833
|
version: 1,
|
|
10448
10834
|
identity: options.identity,
|
|
10449
10835
|
capabilities: [
|
|
10836
|
+
...options.handlers ? [] : [HOST_SECRET_PROTECTION_CAPABILITY],
|
|
10450
10837
|
OBSERVATION_CAPABILITY,
|
|
10451
10838
|
COMPUTER_CAPABILITY,
|
|
10452
10839
|
...commandOutput ? [SYSTEM_OUTPUT_CAPABILITY] : [],
|
|
@@ -10793,8 +11180,23 @@ async function installLockDirectory(lockPath, token, ownerIdentity) {
|
|
|
10793
11180
|
}
|
|
10794
11181
|
}
|
|
10795
11182
|
|
|
11183
|
+
// src/runtime/adapters/long-term-memory/file-lock/path-observation.ts
|
|
11184
|
+
import { lstat as lstat5 } from "node:fs/promises";
|
|
11185
|
+
async function observeLockReadFailure(path, error) {
|
|
11186
|
+
if (!isWindowsLockReadDenial(error)) return error;
|
|
11187
|
+
try {
|
|
11188
|
+
await lstat5(path);
|
|
11189
|
+
} catch (observedError) {
|
|
11190
|
+
if (fileSystemErrorCode(observedError) === "ENOENT") return observedError;
|
|
11191
|
+
}
|
|
11192
|
+
return error;
|
|
11193
|
+
}
|
|
11194
|
+
function isWindowsLockReadDenial(error) {
|
|
11195
|
+
return process.platform !== "win32" ? !1 : fileSystemErrorCode(error) === "EPERM";
|
|
11196
|
+
}
|
|
11197
|
+
|
|
10796
11198
|
// src/runtime/adapters/long-term-memory/file-lock/snapshot.ts
|
|
10797
|
-
import { lstat as
|
|
11199
|
+
import { lstat as lstat6, readdir as readdir3 } from "node:fs/promises";
|
|
10798
11200
|
import { join as join17 } from "node:path";
|
|
10799
11201
|
|
|
10800
11202
|
// src/runtime/adapters/long-term-memory/file-lock/owner-record.ts
|
|
@@ -10804,10 +11206,13 @@ import { join as join16 } from "node:path";
|
|
|
10804
11206
|
async function readOwnerRecord(lockPath, entryName, expectedToken, directoryModifiedAtMs) {
|
|
10805
11207
|
let handle;
|
|
10806
11208
|
try {
|
|
11209
|
+
let ownerPath = join16(lockPath, LEASE_DIRECTORY_NAME, entryName);
|
|
10807
11210
|
handle = await open4(
|
|
10808
|
-
|
|
11211
|
+
ownerPath,
|
|
10809
11212
|
constants3.O_RDONLY | constants3.O_NOFOLLOW
|
|
10810
|
-
)
|
|
11213
|
+
).catch(async (error) => {
|
|
11214
|
+
throw await observeLockReadFailure(ownerPath, error);
|
|
11215
|
+
});
|
|
10811
11216
|
let before = await handle.stat({ bigint: !0 }), modifiedAtMs = Math.max(
|
|
10812
11217
|
directoryModifiedAtMs,
|
|
10813
11218
|
Number(before.mtimeMs)
|
|
@@ -10904,8 +11309,8 @@ async function readLockSnapshot(lockPath) {
|
|
|
10904
11309
|
let lockEntries;
|
|
10905
11310
|
try {
|
|
10906
11311
|
lockEntries = await readdir3(lockPath, { withFileTypes: !0 });
|
|
10907
|
-
} catch (
|
|
10908
|
-
let code = fileSystemErrorCode(error);
|
|
11312
|
+
} catch (readError) {
|
|
11313
|
+
let error = await observeLockReadFailure(lockPath, readError), code = fileSystemErrorCode(error);
|
|
10909
11314
|
if (code === "ENOENT") return;
|
|
10910
11315
|
if (code === "ENOTDIR")
|
|
10911
11316
|
return Object.freeze({ kind: "legacy_file" });
|
|
@@ -10923,8 +11328,9 @@ async function readLockSnapshot(lockPath) {
|
|
|
10923
11328
|
}
|
|
10924
11329
|
async function readLockInfo(lockPath) {
|
|
10925
11330
|
try {
|
|
10926
|
-
return await
|
|
10927
|
-
} catch (
|
|
11331
|
+
return await lstat6(lockPath);
|
|
11332
|
+
} catch (readError) {
|
|
11333
|
+
let error = await observeLockReadFailure(lockPath, readError);
|
|
10928
11334
|
if (fileSystemErrorCode(error) === "ENOENT") return;
|
|
10929
11335
|
throw error;
|
|
10930
11336
|
}
|
|
@@ -10932,10 +11338,11 @@ async function readLockInfo(lockPath) {
|
|
|
10932
11338
|
async function readLeaseSnapshot(lockPath, lockModifiedAtMs) {
|
|
10933
11339
|
let leasePath = join17(lockPath, LEASE_DIRECTORY_NAME), leaseInfo, leaseEntries;
|
|
10934
11340
|
try {
|
|
10935
|
-
if (leaseInfo = await
|
|
11341
|
+
if (leaseInfo = await lstat6(leasePath), !leaseInfo.isDirectory())
|
|
10936
11342
|
return invalidLeaseSnapshot(lockModifiedAtMs);
|
|
10937
11343
|
leaseEntries = await readdir3(leasePath, { withFileTypes: !0 });
|
|
10938
|
-
} catch (
|
|
11344
|
+
} catch (readError) {
|
|
11345
|
+
let error = await observeLockReadFailure(leasePath, readError);
|
|
10939
11346
|
if (fileSystemErrorCode(error) === "ENOENT")
|
|
10940
11347
|
return invalidLeaseSnapshot(lockModifiedAtMs);
|
|
10941
11348
|
throw error;
|
|
@@ -11009,7 +11416,7 @@ async function acquireFileLock(lockPath, options) {
|
|
|
11009
11416
|
return await installLockDirectory(lockPath, token, options.ownerIdentity), createRelease(lockPath, token, options.releaseMode);
|
|
11010
11417
|
} catch (error) {
|
|
11011
11418
|
if (!isLockContention(error)) throw error;
|
|
11012
|
-
if (await removeAbandonedLock(lockPath, processIsAlive)) continue;
|
|
11419
|
+
if (await removeAbandonedLock(lockPath, processIsAlive, deadline, retryDelayMs)) continue;
|
|
11013
11420
|
if (Date.now() >= deadline)
|
|
11014
11421
|
throw new Error("long_term_memory_store_lock_timeout");
|
|
11015
11422
|
await delay3(Math.min(retryDelayMs, Math.max(deadline - Date.now(), 0)));
|
|
@@ -11031,10 +11438,19 @@ function createRelease(lockPath, token, releaseMode) {
|
|
|
11031
11438
|
function requiresSynchronousRelease(mode) {
|
|
11032
11439
|
return mode === "synchronous";
|
|
11033
11440
|
}
|
|
11034
|
-
async function removeAbandonedLock(lockPath, processIsAlive) {
|
|
11035
|
-
let snapshot = await
|
|
11441
|
+
async function removeAbandonedLock(lockPath, processIsAlive, deadline, retryDelayMs) {
|
|
11442
|
+
let snapshot = await readContendedSnapshot(lockPath, deadline, retryDelayMs);
|
|
11036
11443
|
return snapshot ? snapshot.kind === "legacy_file" || !snapshot.reclaimable || await hasLiveObservedOwner(snapshot, processIsAlive) ? !1 : snapshot.record && snapshot.ownerFileName ? removeObservedOwner(lockPath, snapshot.ownerFileName) : Date.now() - snapshot.modifiedAtMs < 3e4 ? !1 : snapshot.ownerFileName ? removeObservedOwner(lockPath, snapshot.ownerFileName) : removeEmptyLockTree(lockPath, snapshot.hasLeaseDirectory) : !0;
|
|
11037
11444
|
}
|
|
11445
|
+
async function readContendedSnapshot(lockPath, deadline, retryDelayMs) {
|
|
11446
|
+
for (; ; )
|
|
11447
|
+
try {
|
|
11448
|
+
return await readLockSnapshot(lockPath);
|
|
11449
|
+
} catch (error) {
|
|
11450
|
+
if (!isWindowsLockReadDenial(error) || Date.now() >= deadline) throw error;
|
|
11451
|
+
await delay3(Math.min(retryDelayMs, Math.max(deadline - Date.now(), 0)));
|
|
11452
|
+
}
|
|
11453
|
+
}
|
|
11038
11454
|
async function hasLiveObservedOwner(snapshot, processIsAlive) {
|
|
11039
11455
|
return snapshot.ownerPid === void 0 ? !1 : processIsAlive(snapshot.ownerPid, snapshot.record?.ownerIdentity);
|
|
11040
11456
|
}
|
|
@@ -11054,13 +11470,14 @@ function delay3(milliseconds) {
|
|
|
11054
11470
|
}
|
|
11055
11471
|
|
|
11056
11472
|
// src/runtime/local-host/private-directory.ts
|
|
11057
|
-
import { lstat as
|
|
11473
|
+
import { lstat as lstat7, mkdir as mkdir5, mkdtemp, rename as rename5, rmdir as rmdir2 } from "node:fs/promises";
|
|
11058
11474
|
import { basename as basename4, dirname as dirname4, join as join19 } from "node:path";
|
|
11059
11475
|
|
|
11060
11476
|
// src/runtime/local-host/windows-private-access.ts
|
|
11061
11477
|
import { execFile as execFile5 } from "node:child_process";
|
|
11062
11478
|
import { promisify as promisify5 } from "node:util";
|
|
11063
11479
|
var execute = promisify5(execFile5), privateAccessScript = `
|
|
11480
|
+
$env:PSModulePath = "$PSHOME\\Modules"
|
|
11064
11481
|
$ErrorActionPreference = 'Stop'
|
|
11065
11482
|
$target = $env:ABOT_LOCAL_HOST_PRIVATE_PATH
|
|
11066
11483
|
$current = [System.Security.Principal.WindowsIdentity]::GetCurrent().User
|
|
@@ -11113,7 +11530,7 @@ async function verifyWindowsPrivateAccess(path, newlyCreatedDirectory = !1) {
|
|
|
11113
11530
|
}
|
|
11114
11531
|
|
|
11115
11532
|
// src/runtime/local-host/private-access.ts
|
|
11116
|
-
async function assertPrivateRuntimeAccess(path,
|
|
11533
|
+
async function assertPrivateRuntimeAccess(path, stat3, errorCode2, newlyCreatedDirectory = !1) {
|
|
11117
11534
|
if (process.platform === "win32")
|
|
11118
11535
|
try {
|
|
11119
11536
|
await verifyWindowsPrivateAccess(path, newlyCreatedDirectory);
|
|
@@ -11121,19 +11538,19 @@ async function assertPrivateRuntimeAccess(path, stat4, errorCode2, newlyCreatedD
|
|
|
11121
11538
|
} catch {
|
|
11122
11539
|
throw new Error(errorCode2);
|
|
11123
11540
|
}
|
|
11124
|
-
if ((
|
|
11125
|
-
if (process.getuid?.() !==
|
|
11541
|
+
if ((stat3.mode & 63) !== 0) throw new Error(errorCode2);
|
|
11542
|
+
if (process.getuid?.() !== stat3.uid) throw new Error(errorCode2);
|
|
11126
11543
|
}
|
|
11127
11544
|
|
|
11128
11545
|
// src/runtime/local-host/private-directory.ts
|
|
11129
11546
|
async function ensurePrivateRuntimeDirectory(directory) {
|
|
11130
11547
|
process.platform === "win32" ? await installWindowsPrivateDirectory(directory) : await mkdir5(directory, { recursive: !0, mode: 448 });
|
|
11131
|
-
let
|
|
11132
|
-
if (!
|
|
11548
|
+
let stat3 = await lstat7(directory);
|
|
11549
|
+
if (!stat3.isDirectory() || stat3.isSymbolicLink())
|
|
11133
11550
|
throw new Error("local_runtime_directory_not_private");
|
|
11134
11551
|
await assertPrivateRuntimeAccess(
|
|
11135
11552
|
directory,
|
|
11136
|
-
|
|
11553
|
+
stat3,
|
|
11137
11554
|
"local_runtime_directory_not_private"
|
|
11138
11555
|
);
|
|
11139
11556
|
}
|
|
@@ -11161,7 +11578,7 @@ async function installWindowsPrivateDirectory(directory) {
|
|
|
11161
11578
|
}
|
|
11162
11579
|
async function hasExistingPath(path) {
|
|
11163
11580
|
try {
|
|
11164
|
-
return await
|
|
11581
|
+
return await lstat7(path), !0;
|
|
11165
11582
|
} catch (error) {
|
|
11166
11583
|
if (isMissingPath(error)) return !1;
|
|
11167
11584
|
throw error;
|
|
@@ -11177,12 +11594,12 @@ import { join as join25 } from "node:path";
|
|
|
11177
11594
|
// src/computer-access/companion/autostart.ts
|
|
11178
11595
|
import { execFile as execFile6 } from "node:child_process";
|
|
11179
11596
|
import {
|
|
11180
|
-
lstat as
|
|
11597
|
+
lstat as lstat8,
|
|
11181
11598
|
mkdir as mkdir6,
|
|
11182
11599
|
readFile as readFile10,
|
|
11183
11600
|
rename as rename6,
|
|
11184
11601
|
unlink as unlink5,
|
|
11185
|
-
writeFile as
|
|
11602
|
+
writeFile as writeFile7
|
|
11186
11603
|
} from "node:fs/promises";
|
|
11187
11604
|
import { dirname as dirname5, join as join20, posix } from "node:path";
|
|
11188
11605
|
import { promisify as promisify6 } from "node:util";
|
|
@@ -11279,12 +11696,12 @@ function errorCode(error) {
|
|
|
11279
11696
|
return error && typeof error == "object" && "code" in error ? error.code : void 0;
|
|
11280
11697
|
}
|
|
11281
11698
|
async function existingOwnedRegistration(path) {
|
|
11282
|
-
let
|
|
11699
|
+
let stat3 = await lstat8(path).catch((error) => {
|
|
11283
11700
|
if (errorCode(error) !== "ENOENT")
|
|
11284
11701
|
throw error;
|
|
11285
11702
|
});
|
|
11286
|
-
if (!
|
|
11287
|
-
if (!
|
|
11703
|
+
if (!stat3) return !1;
|
|
11704
|
+
if (!stat3.isFile() || stat3.isSymbolicLink() || stat3.size > 16384)
|
|
11288
11705
|
throw new Error(
|
|
11289
11706
|
"Refusing to change an unexpected host startup registration."
|
|
11290
11707
|
);
|
|
@@ -11321,7 +11738,7 @@ async function installNativeAutostart(options) {
|
|
|
11321
11738
|
await existingOwnedRegistration(path) && options.platform === "darwin" && await unloadMacRegistration(options), await mkdir6(dirname5(path), { recursive: !0 });
|
|
11322
11739
|
let temporary = `${path}.${randomUUID10()}.tmp`;
|
|
11323
11740
|
try {
|
|
11324
|
-
await
|
|
11741
|
+
await writeFile7(temporary, renderNativeAutostart(options), {
|
|
11325
11742
|
encoding: "utf8",
|
|
11326
11743
|
mode: 384,
|
|
11327
11744
|
flag: "wx"
|
|
@@ -11344,7 +11761,7 @@ async function uninstallNativeAutostart(options) {
|
|
|
11344
11761
|
|
|
11345
11762
|
// src/computer-access/companion/install-link-registration.ts
|
|
11346
11763
|
import { execFile as execFile8 } from "node:child_process";
|
|
11347
|
-
import { lstat as
|
|
11764
|
+
import { lstat as lstat9, mkdir as mkdir7, readFile as readFile11, rm as rm5, writeFile as writeFile8 } from "node:fs/promises";
|
|
11348
11765
|
import { dirname as dirname6, join as join22, posix as posix2 } from "node:path";
|
|
11349
11766
|
import { promisify as promisify8 } from "node:util";
|
|
11350
11767
|
|
|
@@ -11419,7 +11836,8 @@ function renderMacInstallLinkHandler(options) {
|
|
|
11419
11836
|
let literal = (value) => JSON.stringify(value);
|
|
11420
11837
|
return `ObjC.import('Foundation');
|
|
11421
11838
|
function openDocuments() {}
|
|
11422
|
-
|
|
11839
|
+
// JXA dispatches the macOS Get URL (GURL/GURL) AppleEvent to this exact name.
|
|
11840
|
+
function GURLGURL(url) {
|
|
11423
11841
|
var task = $.NSTask.alloc.init;
|
|
11424
11842
|
task.launchPath = ${literal(options.nodePath)};
|
|
11425
11843
|
task.arguments = [${literal(options.cliPath)}, 'host', 'open-link', String(url)];
|
|
@@ -11490,12 +11908,12 @@ async function run(options, file, args) {
|
|
|
11490
11908
|
});
|
|
11491
11909
|
}
|
|
11492
11910
|
async function existingOwnedDirectory(path) {
|
|
11493
|
-
let
|
|
11911
|
+
let stat3 = await lstat9(path).catch((error) => {
|
|
11494
11912
|
if (error.code !== "ENOENT")
|
|
11495
11913
|
throw error;
|
|
11496
11914
|
});
|
|
11497
|
-
if (!
|
|
11498
|
-
if (!
|
|
11915
|
+
if (!stat3) return !1;
|
|
11916
|
+
if (!stat3.isDirectory() || stat3.isSymbolicLink())
|
|
11499
11917
|
throw new Error("Installation-link directory is not owned.");
|
|
11500
11918
|
if (await readFile11(join22(path, ".owner"), "utf8") !== OWNER)
|
|
11501
11919
|
throw new Error("Installation-link directory is not owned.");
|
|
@@ -11515,11 +11933,11 @@ function linuxDesktopPath(options) {
|
|
|
11515
11933
|
);
|
|
11516
11934
|
}
|
|
11517
11935
|
async function requireOwnedLinuxRegistration(path) {
|
|
11518
|
-
let
|
|
11936
|
+
let stat3 = await lstat9(path).catch((error) => {
|
|
11519
11937
|
if (error.code !== "ENOENT")
|
|
11520
11938
|
throw error;
|
|
11521
11939
|
});
|
|
11522
|
-
if (
|
|
11940
|
+
if (stat3 && (!stat3.isFile() || stat3.isSymbolicLink() || !(await readFile11(path, "utf8")).includes("# " + OWNER)))
|
|
11523
11941
|
throw new Error("Installation-link desktop registration is not owned.");
|
|
11524
11942
|
}
|
|
11525
11943
|
function isAvailableLinuxInstallScheme(handler) {
|
|
@@ -11536,12 +11954,12 @@ async function requireAvailableLinuxInstallScheme() {
|
|
|
11536
11954
|
}
|
|
11537
11955
|
async function installCompanionInstallLinks(options) {
|
|
11538
11956
|
let directory = registrationDirectory(options);
|
|
11539
|
-
if (await existingOwnedDirectory(directory) || (await ensurePrivateRuntimeDirectory(directory), await
|
|
11957
|
+
if (await existingOwnedDirectory(directory) || (await ensurePrivateRuntimeDirectory(directory), await writeFile8(join22(directory, ".owner"), OWNER, {
|
|
11540
11958
|
flag: "wx",
|
|
11541
11959
|
mode: 384
|
|
11542
11960
|
})), options.platform === "win32") {
|
|
11543
11961
|
let launcher = windowsInstallLinkLauncherPath(options);
|
|
11544
|
-
await
|
|
11962
|
+
await writeFile8(launcher, renderWindowsInstallLinkLauncher(options), {
|
|
11545
11963
|
mode: 384
|
|
11546
11964
|
}), await run(options, "powershell.exe", [
|
|
11547
11965
|
"-NoProfile",
|
|
@@ -11556,7 +11974,7 @@ async function installCompanionInstallLinks(options) {
|
|
|
11556
11974
|
}
|
|
11557
11975
|
if (options.platform === "linux") {
|
|
11558
11976
|
let desktop = linuxDesktopPath(options);
|
|
11559
|
-
await requireOwnedLinuxRegistration(desktop), await requireAvailableLinuxInstallScheme(), await mkdir7(dirname6(desktop), { recursive: !0, mode: 448 }), await
|
|
11977
|
+
await requireOwnedLinuxRegistration(desktop), await requireAvailableLinuxInstallScheme(), await mkdir7(dirname6(desktop), { recursive: !0, mode: 448 }), await writeFile8(desktop, renderLinuxInstallLinkDesktop(options), {
|
|
11560
11978
|
mode: 384
|
|
11561
11979
|
}), await run(options, "xdg-mime", [
|
|
11562
11980
|
"default",
|
|
@@ -11568,9 +11986,9 @@ async function installCompanionInstallLinks(options) {
|
|
|
11568
11986
|
if (options.platform === "darwin") {
|
|
11569
11987
|
await requireAvailableMacInstallScheme();
|
|
11570
11988
|
let source = join22(directory, "handler.js"), app = join22(directory, "ABot Install.app");
|
|
11571
|
-
await
|
|
11989
|
+
await writeFile8(source, renderMacInstallLinkHandler(options), {
|
|
11572
11990
|
mode: 384
|
|
11573
|
-
}), await
|
|
11991
|
+
}), await rm5(app, { recursive: !0, force: !0 }), await run(options, "/usr/bin/osacompile", [
|
|
11574
11992
|
"-l",
|
|
11575
11993
|
"JavaScript",
|
|
11576
11994
|
"-o",
|
|
@@ -11614,13 +12032,13 @@ async function uninstallCompanionInstallLinks(options) {
|
|
|
11614
12032
|
).toString("base64")
|
|
11615
12033
|
]), options.platform === "linux") {
|
|
11616
12034
|
let desktop = linuxDesktopPath(options);
|
|
11617
|
-
await requireOwnedLinuxRegistration(desktop), await
|
|
12035
|
+
await requireOwnedLinuxRegistration(desktop), await rm5(desktop, { force: !0 });
|
|
11618
12036
|
}
|
|
11619
12037
|
options.platform === "darwin" && await run(
|
|
11620
12038
|
options,
|
|
11621
12039
|
"/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister",
|
|
11622
12040
|
["-u", join22(directory, "ABot Install.app")]
|
|
11623
|
-
), await
|
|
12041
|
+
), await rm5(directory, { recursive: !0 });
|
|
11624
12042
|
}
|
|
11625
12043
|
}
|
|
11626
12044
|
|
|
@@ -11738,7 +12156,7 @@ async function stopOwnedNativeCompanion(stateDir, overrides = {}) {
|
|
|
11738
12156
|
import { execFile as execFile10 } from "node:child_process";
|
|
11739
12157
|
import { createHash as createHash5, randomUUID as randomUUID11 } from "node:crypto";
|
|
11740
12158
|
import { constants as constants4 } from "node:fs";
|
|
11741
|
-
import { lstat as
|
|
12159
|
+
import { lstat as lstat10, open as open5, rename as rename7, unlink as unlink6 } from "node:fs/promises";
|
|
11742
12160
|
import { join as join24 } from "node:path";
|
|
11743
12161
|
import { promisify as promisify10 } from "node:util";
|
|
11744
12162
|
var executeFile8 = promisify10(execFile10), NATIVE_RUNTIME_INSTALLATION_FAILURE = "The Mac companion runtime could not be prepared safely. The saved pairing was not changed. Check the local Node.js installation and run setup again.";
|
|
@@ -11751,14 +12169,14 @@ function isAbsentRuntimePath(error) {
|
|
|
11751
12169
|
function hasSameRuntimeIdentity(left, right) {
|
|
11752
12170
|
return left.dev !== right.dev || left.ino !== right.ino || left.size !== right.size || left.mtimeMs !== right.mtimeMs ? !1 : left.ctimeMs === right.ctimeMs;
|
|
11753
12171
|
}
|
|
11754
|
-
function hasTrustedRuntimeSource(
|
|
11755
|
-
return !
|
|
12172
|
+
function hasTrustedRuntimeSource(stat3) {
|
|
12173
|
+
return !stat3.isFile() || stat3.isSymbolicLink() || (stat3.mode & 73) === 0 || (stat3.mode & 18) !== 0 ? !1 : stat3.uid === 0 ? !0 : stat3.uid === process.getuid?.();
|
|
11756
12174
|
}
|
|
11757
|
-
async function requireManagedRuntimeFile(path,
|
|
11758
|
-
if (!
|
|
12175
|
+
async function requireManagedRuntimeFile(path, stat3) {
|
|
12176
|
+
if (!stat3.isFile() || stat3.isSymbolicLink() || stat3.nlink !== 1 || (stat3.mode & 511) !== 320) throw runtimeInstallationFailure();
|
|
11759
12177
|
await assertPrivateRuntimeAccess(
|
|
11760
12178
|
path,
|
|
11761
|
-
|
|
12179
|
+
stat3,
|
|
11762
12180
|
NATIVE_RUNTIME_INSTALLATION_FAILURE
|
|
11763
12181
|
);
|
|
11764
12182
|
}
|
|
@@ -11772,21 +12190,21 @@ async function streamRuntimeDigest(handle) {
|
|
|
11772
12190
|
return hash.digest("hex");
|
|
11773
12191
|
}
|
|
11774
12192
|
async function readRuntimeFile(path, managed) {
|
|
11775
|
-
let
|
|
12193
|
+
let stat3 = await lstat10(path).catch((error) => {
|
|
11776
12194
|
if (!isAbsentRuntimePath(error))
|
|
11777
12195
|
throw error;
|
|
11778
12196
|
});
|
|
11779
|
-
if (!
|
|
11780
|
-
if (managed && await requireManagedRuntimeFile(path,
|
|
12197
|
+
if (!stat3) return;
|
|
12198
|
+
if (managed && await requireManagedRuntimeFile(path, stat3), !managed && !hasTrustedRuntimeSource(stat3))
|
|
11781
12199
|
throw runtimeInstallationFailure();
|
|
11782
12200
|
let handle = await open5(path, constants4.O_RDONLY | constants4.O_NOFOLLOW);
|
|
11783
12201
|
try {
|
|
11784
|
-
if (!hasSameRuntimeIdentity(
|
|
12202
|
+
if (!hasSameRuntimeIdentity(stat3, await handle.stat()))
|
|
11785
12203
|
throw runtimeInstallationFailure();
|
|
11786
12204
|
let digest = await streamRuntimeDigest(handle);
|
|
11787
|
-
if (!hasSameRuntimeIdentity(
|
|
12205
|
+
if (!hasSameRuntimeIdentity(stat3, await handle.stat()) || !hasSameRuntimeIdentity(stat3, await lstat10(path)))
|
|
11788
12206
|
throw runtimeInstallationFailure();
|
|
11789
|
-
return { stat:
|
|
12207
|
+
return { stat: stat3, digest };
|
|
11790
12208
|
} finally {
|
|
11791
12209
|
await handle.close();
|
|
11792
12210
|
}
|
|
@@ -11844,14 +12262,14 @@ async function requireUnchangedRuntimeTarget(path, expected) {
|
|
|
11844
12262
|
}
|
|
11845
12263
|
async function requireUnchangedRuntimeDirectory(path, expected) {
|
|
11846
12264
|
await ensurePrivateRuntimeDirectory(path);
|
|
11847
|
-
let current = await
|
|
12265
|
+
let current = await lstat10(path);
|
|
11848
12266
|
if (expected.dev !== current.dev || expected.ino !== current.ino) throw runtimeInstallationFailure();
|
|
11849
12267
|
}
|
|
11850
12268
|
async function installManagedRuntime(startup, dependencies) {
|
|
11851
12269
|
await ensurePrivateRuntimeDirectory(startup.stateDir);
|
|
11852
|
-
let stateIdentity = await
|
|
12270
|
+
let stateIdentity = await lstat10(startup.stateDir), directory = join24(startup.stateDir, "runtime");
|
|
11853
12271
|
await ensurePrivateRuntimeDirectory(directory);
|
|
11854
|
-
let directoryIdentity = await
|
|
12272
|
+
let directoryIdentity = await lstat10(directory), target = join24(directory, "node"), source = await readRuntimeFile(startup.nodePath, !1);
|
|
11855
12273
|
if (!source) throw runtimeInstallationFailure();
|
|
11856
12274
|
let existing = await readRuntimeFile(target, !0), expectedVersion = await runtimeVersion(startup.nodePath, dependencies);
|
|
11857
12275
|
if (existing?.digest === source.digest)
|
|
@@ -12042,9 +12460,9 @@ function printHostHelp() {
|
|
|
12042
12460
|
function createHostCompanionState() {
|
|
12043
12461
|
return createNativeHostState(join26(homedir4(), ".abot", "host-companion"), {
|
|
12044
12462
|
ensureDirectory: ensurePrivateRuntimeDirectory,
|
|
12045
|
-
assertFile: (path,
|
|
12463
|
+
assertFile: (path, stat3) => assertPrivateRuntimeAccess(
|
|
12046
12464
|
path,
|
|
12047
|
-
|
|
12465
|
+
stat3,
|
|
12048
12466
|
"host_companion_state_not_private"
|
|
12049
12467
|
)
|
|
12050
12468
|
});
|