@abot-ai/runtime 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/capabilities/tool-request-resources.d.ts +3 -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/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.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/runtime-observation-connection.d.ts +5 -0
- package/dist/src/runtime/adapters/runtime-observation-connection.js +13 -0
- package/dist/src/runtime/local-host/windows-private-access.js +2 -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-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/prepared-execution.js +3 -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/format.js +2 -3
- package/dist/src/runtime/steps/execution-agent/input.js +1 -1
- package/dist/src/runtime/steps/execution-agent/prompt.js +5 -5
- package/dist/src/runtime/steps/execution-agent/response-prompt.js +1 -0
- package/dist/src/runtime/steps/execution-agent/state-context.d.ts +2 -3
- package/dist/src/runtime/steps/execution-agent/state-context.js +26 -35
- package/dist/src/runtime/steps/execution-agent/work-plan-contract.d.ts +1 -3
- package/dist/src/runtime/steps/execution-agent/work-plan-contract.js +0 -55
- package/dist/src/runtime/steps/execution-agent/work-plan-schema.d.ts +3 -0
- package/dist/src/runtime/steps/execution-agent/work-plan-schema.js +61 -0
- package/dist/src/sessions/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/app-bootstrap.js +14 -1
- package/dist/src/web-ui/app/app-state.js +0 -7
- package/dist/src/web-ui/app/app.js +53 -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/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/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/passive-learning/activity-controls.js +4 -0
- package/dist/src/web-ui/app/components/passive-learning/collection-access.js +35 -0
- package/dist/src/web-ui/app/components/passive-learning/collection-consent-dialog.js +59 -0
- package/dist/src/web-ui/app/components/passive-learning/collection-consent-gate.js +94 -0
- package/dist/src/web-ui/app/components/passive-learning/computer-update-notice.js +6 -0
- package/dist/src/web-ui/app/components/passive-learning/failure-copy.js +1 -0
- package/dist/src/web-ui/app/components/passive-learning/home.js +7 -2
- 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/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/placement.js +4 -7
- package/dist/src/web-ui/app/components/spark-chat/settings.js +7 -3
- package/dist/src/web-ui/app/components/system-host/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 +3 -0
- package/dist/src/web-ui/app/components/workspace-storage-notice.js +37 -0
- package/dist/src/web-ui/app/configuration-environment-refresh.js +27 -34
- package/dist/src/web-ui/app/configuration-feature.js +9 -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/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 +3 -2
- package/dist/src/web-ui/app/lib/reasoning-controls.js +35 -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 +16 -3
- 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.css +2 -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 +145 -4
- 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 +4 -0
- package/plugins/code-outline/README.md +20 -0
- package/plugins/code-outline/plugin.json +1 -0
- package/plugins/code-outline/source/index.ts +16 -20
- package/plugins/code-outline/source/read-failure.ts +40 -0
- package/plugins/code-outline/src/index.cjs +614 -29
- package/plugins/document-reader/README.md +33 -0
- package/plugins/document-reader/plugin.json +1 -0
- package/plugins/document-reader/source/pdf-contract.ts +57 -0
- package/plugins/document-reader/source/pdf-parser.ts +139 -0
- package/plugins/document-reader/source/pdf-process-main.ts +56 -0
- package/plugins/document-reader/source/pdf-process.ts +207 -0
- package/plugins/document-reader/source/pdf-result.ts +79 -0
- package/plugins/document-reader/source/pdf-worker.ts +39 -303
- package/plugins/document-reader/source/pdf.ts +4 -1
- package/plugins/document-reader/source/read-failure.ts +37 -0
- package/plugins/document-reader/source/reader.ts +3 -19
- package/plugins/document-reader/src/index.cjs +995 -211
- package/plugins/exec/README.md +19 -0
- package/plugins/exec/plugin.json +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 +6 -2
- package/plugins/filesystem/source/atomic-write.ts +2 -0
- package/plugins/filesystem/source/bounded-io.ts +80 -306
- package/plugins/filesystem/source/directory-sample.ts +2 -0
- package/plugins/filesystem/source/errors.ts +14 -0
- package/plugins/filesystem/source/file-observation.ts +151 -0
- package/plugins/filesystem/source/file-version.ts +41 -0
- package/plugins/filesystem/source/index.ts +6 -0
- package/plugins/filesystem/source/mutation-coordinator.ts +1 -0
- package/plugins/filesystem/source/windows/authority-script.ts +1 -0
- package/plugins/filesystem/source/windows/native-script.ts +1 -0
- package/plugins/filesystem/source/windows/operations.ts +197 -0
- package/plugins/filesystem/source/windows/process.ts +214 -0
- package/plugins/filesystem/source/windows/publication-script.ts +29 -0
- package/plugins/filesystem/source/windows/read-script.ts +63 -0
- package/plugins/filesystem/source/windows/request-availability.ts +67 -0
- package/plugins/filesystem/source/windows/source.ts +42 -0
- package/plugins/filesystem/source/windows/storage-script.ts +11 -0
- package/plugins/filesystem/source/windows/streams-script.ts +24 -0
- package/plugins/filesystem/source/windows/write-script.ts +86 -0
- package/plugins/filesystem/src/index.cjs +1208 -322
- package/plugins/json-inspector/README.md +18 -0
- package/plugins/json-inspector/plugin.json +1 -0
- package/plugins/json-inspector/source/index.ts +16 -19
- package/plugins/json-inspector/source/read-failure.ts +42 -0
- package/plugins/json-inspector/src/index.cjs +612 -27
- package/plugins/local-search/README.md +29 -0
- package/plugins/local-search/plugin.json +1 -0
- package/plugins/local-search/source/errors.ts +2 -0
- package/plugins/local-search/source/paths.ts +3 -0
- package/plugins/local-search/source/ripgrep-process.ts +31 -5
- package/plugins/local-search/source/ripgrep.ts +3 -3
- package/plugins/local-search/source/windows-authority.ts +99 -0
- package/plugins/local-search/source/windows-search-lease.ts +49 -0
- package/plugins/local-search/source/windows-search-process.ts +91 -0
- package/plugins/local-search/source/windows-search-script.ts +52 -0
- package/plugins/local-search/src/index.cjs +595 -26
- package/plugins/memory/plugin.json +4 -0
- package/plugins/memory/source/lock-directory-claim.ts +56 -0
- package/plugins/memory/source/lock-owner-file.ts +71 -0
- package/plugins/memory/source/lock-path-observation.ts +26 -0
- package/plugins/memory/source/prepared-memory-replacement.ts +40 -0
- package/plugins/memory/source/store-lock.ts +12 -7
- package/plugins/memory/source/store.ts +3 -2
- package/plugins/memory/src/index.cjs +174 -25
- package/plugins/project-orientation/README.md +23 -0
- package/plugins/project-orientation/plugin.json +1 -0
- package/plugins/project-orientation/source/index.ts +12 -9
- package/plugins/project-orientation/source/inspection-failure.ts +70 -0
- package/plugins/project-orientation/source/manifest-summary.ts +9 -2
- package/plugins/project-orientation/source/tree.ts +6 -0
- package/plugins/project-orientation/src/index.cjs +647 -31
- package/plugins/system/README.md +51 -15
- package/plugins/system/plugin.json +5 -1
- package/plugins/system/skills/system_actions/SKILL.md +1 -1
- package/plugins/system/source/command-working-directory.ts +47 -0
- package/plugins/system/source/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 +8 -2
- package/plugins/system-probe/source/disk-path.ts +8 -0
- package/plugins/system-probe/source/index.ts +10 -5
- package/plugins/system-probe/source/machine-load.ts +33 -0
- package/plugins/system-probe/source/metrics.ts +6 -8
- package/plugins/system-probe/src/index.cjs +49 -16
- package/plugins/web/plugin.json +4 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { acquireFileLock } from "../runtime/adapters/long-term-memory/file-lock/acquisition.js";
|
|
4
|
+
import { ensurePrivateRuntimeDirectory } from "../runtime/local-host/private-directory.js";
|
|
5
|
+
import { isProcessOwnerAlive, requireCurrentProcessOwnerIdentity } from "./companion/process-owner-identity.js";
|
|
6
|
+
import { hostStateDirectory, readHostPrivateJson, writeHostPrivateJson } from "./companion/private-store.js";
|
|
7
|
+
import { isHostIdentifier, isHostRecord } from "./companion/protocol.js";
|
|
8
|
+
function isNativeDeviceIdentity(value) {
|
|
9
|
+
if (!isHostRecord(value))
|
|
10
|
+
return false;
|
|
11
|
+
if (value.version !== 1)
|
|
12
|
+
return false;
|
|
13
|
+
return isHostIdentifier(value.deviceId);
|
|
14
|
+
}
|
|
15
|
+
function isNativeObservationOwnershipConflict(error) {
|
|
16
|
+
if (!(error instanceof Error))
|
|
17
|
+
return false;
|
|
18
|
+
return error.message === "long_term_memory_store_lock_timeout";
|
|
19
|
+
}
|
|
20
|
+
function readNativeDeviceId(directory) {
|
|
21
|
+
const path = join(directory, "native-device.json");
|
|
22
|
+
const value = readHostPrivateJson(path);
|
|
23
|
+
if (value === undefined) {
|
|
24
|
+
const deviceId = randomUUID();
|
|
25
|
+
writeHostPrivateJson(path, { version: 1, deviceId });
|
|
26
|
+
return deviceId;
|
|
27
|
+
}
|
|
28
|
+
if (!isNativeDeviceIdentity(value))
|
|
29
|
+
throw new Error("native_observation_identity_invalid");
|
|
30
|
+
return value.deviceId;
|
|
31
|
+
}
|
|
32
|
+
/** One installation shares a device identity and exclusive collector across environment processes. */
|
|
33
|
+
export async function acquireNativeObservationOwnership(rootDir) {
|
|
34
|
+
const directory = hostStateDirectory(rootDir);
|
|
35
|
+
await ensurePrivateRuntimeDirectory(directory);
|
|
36
|
+
const ownerIdentity = await requireCurrentProcessOwnerIdentity();
|
|
37
|
+
let release;
|
|
38
|
+
try {
|
|
39
|
+
release = await acquireFileLock(join(directory, "native-observation-owner.lock"), {
|
|
40
|
+
waitMs: 0, ownerIdentity, processIsAlive: isProcessOwnerAlive, releaseMode: "synchronous",
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
if (isNativeObservationOwnershipConflict(error))
|
|
45
|
+
throw new Error("host_observations_already_owned");
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
return { deviceId: readNativeDeviceId(directory), release };
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
await release();
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** A replacement waits only for this process's same installation and environment owner. */
|
|
2
|
+
export declare function waitForNativeObservationShutdown(rootDir: string, ownerId: string, signal: AbortSignal): Promise<void>;
|
|
3
|
+
/** The caller confirms release only after helper exit and successful physical lock cleanup. */
|
|
4
|
+
export declare function createNativeObservationShutdown(rootDir: string, ownerId: string): {
|
|
5
|
+
begin(): void;
|
|
6
|
+
confirmReleased(): void;
|
|
7
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
const stoppingLeases = new Map();
|
|
3
|
+
const NATIVE_OBSERVATION_SHUTDOWN_WAIT_MS = 2_000;
|
|
4
|
+
function shutdownKey(rootDir, ownerId) {
|
|
5
|
+
const root = resolve(rootDir);
|
|
6
|
+
return JSON.stringify([process.platform === "win32" ? root.toLowerCase() : root, ownerId]);
|
|
7
|
+
}
|
|
8
|
+
/** A replacement waits only for this process's same installation and environment owner. */
|
|
9
|
+
export async function waitForNativeObservationShutdown(rootDir, ownerId, signal) {
|
|
10
|
+
signal.throwIfAborted();
|
|
11
|
+
const previous = stoppingLeases.get(shutdownKey(rootDir, ownerId));
|
|
12
|
+
if (!previous)
|
|
13
|
+
return;
|
|
14
|
+
const waiters = previous.waiters;
|
|
15
|
+
await new Promise((resolveWait, rejectWait) => {
|
|
16
|
+
let finished = false;
|
|
17
|
+
function finish(error) {
|
|
18
|
+
if (finished)
|
|
19
|
+
return;
|
|
20
|
+
finished = true;
|
|
21
|
+
clearTimeout(timer);
|
|
22
|
+
signal.removeEventListener("abort", abort);
|
|
23
|
+
waiters.delete(released);
|
|
24
|
+
if (error !== undefined)
|
|
25
|
+
rejectWait(error);
|
|
26
|
+
else
|
|
27
|
+
resolveWait();
|
|
28
|
+
}
|
|
29
|
+
function abort() { finish(signal.reason ?? new Error("host_observation_cancelled")); }
|
|
30
|
+
function released() { finish(); }
|
|
31
|
+
const timer = setTimeout(() => finish(new Error("host_observations_already_owned")), NATIVE_OBSERVATION_SHUTDOWN_WAIT_MS);
|
|
32
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
33
|
+
waiters.add(released);
|
|
34
|
+
if (signal.aborted)
|
|
35
|
+
abort();
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/** The caller confirms release only after helper exit and successful physical lock cleanup. */
|
|
39
|
+
export function createNativeObservationShutdown(rootDir, ownerId) {
|
|
40
|
+
const key = shutdownKey(rootDir, ownerId);
|
|
41
|
+
let released = false;
|
|
42
|
+
const entry = { waiters: new Set() };
|
|
43
|
+
return {
|
|
44
|
+
begin() {
|
|
45
|
+
if (!released)
|
|
46
|
+
stoppingLeases.set(key, entry);
|
|
47
|
+
},
|
|
48
|
+
confirmReleased() {
|
|
49
|
+
if (released)
|
|
50
|
+
return;
|
|
51
|
+
released = true;
|
|
52
|
+
if (stoppingLeases.get(key) === entry)
|
|
53
|
+
stoppingLeases.delete(key);
|
|
54
|
+
for (const waiter of entry.waiters)
|
|
55
|
+
waiter();
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type RuntimeCollectionSource = Readonly<{
|
|
2
|
+
mode: "native" | "companion";
|
|
3
|
+
platform: "windows" | "macos" | "linux" | "unsupported";
|
|
4
|
+
}>;
|
|
5
|
+
/** The Runtime process selects the source; the browser and paired computer do not. */
|
|
6
|
+
export declare function readRuntimeCollectionSource(platform?: NodeJS.Platform): RuntimeCollectionSource;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** The Runtime process selects the source; the browser and paired computer do not. */
|
|
2
|
+
export function readRuntimeCollectionSource(platform = process.platform) {
|
|
3
|
+
if (platform === "win32")
|
|
4
|
+
return { mode: "native", platform: "windows" };
|
|
5
|
+
if (platform === "darwin")
|
|
6
|
+
return { mode: "companion", platform: "macos" };
|
|
7
|
+
if (platform === "linux")
|
|
8
|
+
return { mode: "companion", platform: "linux" };
|
|
9
|
+
return { mode: "companion", platform: "unsupported" };
|
|
10
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { NativeComputerResult } from "../computer/native-protocol.js";
|
|
2
|
+
type TextScanner = (input: string) => string;
|
|
3
|
+
/**
|
|
4
|
+
* Best-effort text protection before frame retention or result projection.
|
|
5
|
+
* Pixels are not inspected: a text match withholds the associated entire image.
|
|
6
|
+
*/
|
|
7
|
+
export declare function protectDesktopResult(result: NativeComputerResult, scan?: TextScanner): NativeComputerResult;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { redactSecretText } from "./secret-text.js";
|
|
2
|
+
function rectangle(value) {
|
|
3
|
+
return { x: value.x, y: value.y, width: value.width, height: value.height };
|
|
4
|
+
}
|
|
5
|
+
/** Explicit native observation fields; binding identities are never rewritten. */
|
|
6
|
+
function projectDesktopFields(result, text) {
|
|
7
|
+
const capability = (value) => ({
|
|
8
|
+
supported: value.supported,
|
|
9
|
+
available: value.available,
|
|
10
|
+
...(value.reason === undefined ? {} : { reason: text(value.reason) }),
|
|
11
|
+
});
|
|
12
|
+
const desktop = result.desktop;
|
|
13
|
+
return {
|
|
14
|
+
desktop: {
|
|
15
|
+
platform: desktop.platform,
|
|
16
|
+
binding: desktop.binding,
|
|
17
|
+
name: text(desktop.name),
|
|
18
|
+
available: desktop.available,
|
|
19
|
+
...(desktop.reason === undefined ? {} : { reason: text(desktop.reason) }),
|
|
20
|
+
bounds: rectangle(desktop.bounds),
|
|
21
|
+
...(desktop.coordinateSpace === undefined
|
|
22
|
+
? {}
|
|
23
|
+
: { coordinateSpace: desktop.coordinateSpace }),
|
|
24
|
+
capabilities: {
|
|
25
|
+
capture: capability(desktop.capabilities.capture),
|
|
26
|
+
accessibility: capability(desktop.capabilities.accessibility),
|
|
27
|
+
input: capability(desktop.capabilities.input),
|
|
28
|
+
windows: capability(desktop.capabilities.windows),
|
|
29
|
+
},
|
|
30
|
+
targetingGuarantee: desktop.targetingGuarantee,
|
|
31
|
+
},
|
|
32
|
+
windows: result.windows.map((window) => ({
|
|
33
|
+
binding: window.binding,
|
|
34
|
+
title: text(window.title),
|
|
35
|
+
...(window.application === undefined
|
|
36
|
+
? {}
|
|
37
|
+
: { application: text(window.application) }),
|
|
38
|
+
bounds: rectangle(window.bounds),
|
|
39
|
+
focused: window.focused,
|
|
40
|
+
})),
|
|
41
|
+
...(result.focusedWindow === undefined
|
|
42
|
+
? {}
|
|
43
|
+
: { focusedWindow: result.focusedWindow }),
|
|
44
|
+
...(result.observation
|
|
45
|
+
? {
|
|
46
|
+
observation: {
|
|
47
|
+
capturedAt: text(result.observation.capturedAt),
|
|
48
|
+
region: rectangle(result.observation.region),
|
|
49
|
+
imageWidth: result.observation.imageWidth,
|
|
50
|
+
imageHeight: result.observation.imageHeight,
|
|
51
|
+
accessibility: result.observation.accessibility.map((node) => ({
|
|
52
|
+
role: text(node.role),
|
|
53
|
+
...(node.name === undefined ? {} : { name: text(node.name) }),
|
|
54
|
+
...(node.value === undefined ? {} : { value: text(node.value) }),
|
|
55
|
+
...(node.bounds === undefined
|
|
56
|
+
? {}
|
|
57
|
+
: { bounds: rectangle(node.bounds) }),
|
|
58
|
+
...(node.focused === undefined ? {} : { focused: node.focused }),
|
|
59
|
+
})),
|
|
60
|
+
accessibilityTruncated: result.observation.accessibilityTruncated,
|
|
61
|
+
},
|
|
62
|
+
}
|
|
63
|
+
: {}),
|
|
64
|
+
...(result.dispatch
|
|
65
|
+
? {
|
|
66
|
+
dispatch: {
|
|
67
|
+
status: result.dispatch.status,
|
|
68
|
+
requestedInputCount: result.dispatch.requestedInputCount,
|
|
69
|
+
...(result.dispatch.acceptedInputCount === undefined
|
|
70
|
+
? {}
|
|
71
|
+
: { acceptedInputCount: result.dispatch.acceptedInputCount }),
|
|
72
|
+
...(result.dispatch.reason === undefined
|
|
73
|
+
? {}
|
|
74
|
+
: { reason: text(result.dispatch.reason) }),
|
|
75
|
+
},
|
|
76
|
+
}
|
|
77
|
+
: {}),
|
|
78
|
+
...(result.error
|
|
79
|
+
? {
|
|
80
|
+
error: {
|
|
81
|
+
code: text(result.error.code),
|
|
82
|
+
message: text(result.error.message),
|
|
83
|
+
},
|
|
84
|
+
}
|
|
85
|
+
: {}),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Best-effort text protection before frame retention or result projection.
|
|
90
|
+
* Pixels are not inspected: a text match withholds the associated entire image.
|
|
91
|
+
*/
|
|
92
|
+
export function protectDesktopResult(result, scan = redactSecretText) {
|
|
93
|
+
let suspected = false;
|
|
94
|
+
try {
|
|
95
|
+
const protectedResult = projectDesktopFields(result, (input) => {
|
|
96
|
+
const output = scan(input);
|
|
97
|
+
if (typeof output !== "string")
|
|
98
|
+
throw new Error("desktop_text_scan_failed");
|
|
99
|
+
suspected ||= output !== input;
|
|
100
|
+
return output;
|
|
101
|
+
});
|
|
102
|
+
if (!suspected)
|
|
103
|
+
return {
|
|
104
|
+
...protectedResult,
|
|
105
|
+
...(result.image
|
|
106
|
+
? {
|
|
107
|
+
image: {
|
|
108
|
+
mimeType: result.image.mimeType,
|
|
109
|
+
bytes: result.image.bytes,
|
|
110
|
+
},
|
|
111
|
+
}
|
|
112
|
+
: {}),
|
|
113
|
+
};
|
|
114
|
+
result.image?.bytes.fill(0);
|
|
115
|
+
return {
|
|
116
|
+
...protectedResult,
|
|
117
|
+
...(result.image && !protectedResult.error
|
|
118
|
+
? {
|
|
119
|
+
error: {
|
|
120
|
+
code: "computer_image_secret_blocked",
|
|
121
|
+
message: "Image withheld because desktop text contained a suspected secret. The dispatch receipt is unchanged.",
|
|
122
|
+
},
|
|
123
|
+
}
|
|
124
|
+
: {}),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
result.image?.bytes.fill(0);
|
|
129
|
+
const safe = projectDesktopFields(result, () => "[REDACTED]");
|
|
130
|
+
return {
|
|
131
|
+
desktop: {
|
|
132
|
+
...safe.desktop,
|
|
133
|
+
reason: "Desktop content withheld because its protection check failed.",
|
|
134
|
+
},
|
|
135
|
+
windows: [],
|
|
136
|
+
...(safe.focusedWindow === undefined
|
|
137
|
+
? {}
|
|
138
|
+
: { focusedWindow: safe.focusedWindow }),
|
|
139
|
+
...(safe.dispatch ? { dispatch: safe.dispatch } : {}),
|
|
140
|
+
error: {
|
|
141
|
+
code: "computer_observation_protection_failed",
|
|
142
|
+
message: "Desktop content withheld because its protection check failed. The dispatch receipt is unchanged.",
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { redactSecretText } from "./secret-text.js";
|
|
2
|
+
/** Protect the complete observed message before transport or model projection. */
|
|
3
|
+
export function protectObservedError(error, fallback) {
|
|
4
|
+
try {
|
|
5
|
+
return redactSecretText(error instanceof Error ? error.message : fallback);
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
return "Observed error details withheld because the protection check failed.";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mask the entire field when a known secret indicator is present, including
|
|
3
|
+
* surrounding useful text. No value boundaries or source-language grammar are
|
|
4
|
+
* inferred. Unlabelled arbitrary secrets and unknown encodings remain outside
|
|
5
|
+
* detection; this is not a guarantee that unchanged text contains no secrets.
|
|
6
|
+
*/
|
|
7
|
+
export declare function redactSecretText(input: string): string;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
const REDACTED = "[REDACTED]";
|
|
2
|
+
const 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)`;
|
|
3
|
+
const credentialIndicator = new RegExp(String.raw `(?<![\p{L}\p{N}_.-])(?:-{1,2})?(?:${CREDENTIAL_KEY_SOURCE}|(?:proxy-)?authorization)[\s"'\\]*[:=]`, "iu");
|
|
4
|
+
/** Detection only: normalize ASCII encodings once, without interpreting a language. */
|
|
5
|
+
function detectionText(input) {
|
|
6
|
+
const percentDecoded = input.replace(/%([0-7][0-9a-f])/giu, (_, hex) => String.fromCharCode(Number.parseInt(hex, 16)));
|
|
7
|
+
return percentDecoded.replace(/\\(?:u00|x|U000000)([0-7][0-9a-fA-F])/gu, (_, hex) => String.fromCharCode(Number.parseInt(hex, 16)));
|
|
8
|
+
}
|
|
9
|
+
function hasPrivateKeyIndicator(text) {
|
|
10
|
+
return /-----BEGIN (?:[A-Z0-9]+ )*PRIVATE KEY(?: BLOCK)?-----/u.test(text);
|
|
11
|
+
}
|
|
12
|
+
function hasUrlCredentials(text) {
|
|
13
|
+
return /\b[a-z][a-z0-9+.-]*(?::|%3a)(?:\/|%2f){2}[^\s/?#<>]*(?:@|%40)/iu.test(text);
|
|
14
|
+
}
|
|
15
|
+
function hasAuthorizationCredentials(text) {
|
|
16
|
+
for (const match of text.matchAll(/\b(Bearer|Basic)[ \t]+([A-Za-z0-9._~+/-]+={0,2})/giu)) {
|
|
17
|
+
if (match[1].toLowerCase() === "bearer")
|
|
18
|
+
return true;
|
|
19
|
+
const value = match[2];
|
|
20
|
+
if (!/^[A-Za-z0-9+/]+={0,2}$/u.test(value))
|
|
21
|
+
continue;
|
|
22
|
+
if (value.length < 8)
|
|
23
|
+
continue;
|
|
24
|
+
if (Buffer.from(value, "base64").toString("utf8").includes(":"))
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
function isAwsAccessKeyValue(value, atEnd) {
|
|
30
|
+
if (/^[A-Z0-9]{16}$/u.test(value))
|
|
31
|
+
return true;
|
|
32
|
+
if (!atEnd)
|
|
33
|
+
return false;
|
|
34
|
+
return /^[A-Z0-9]{4,15}$/u.test(value);
|
|
35
|
+
}
|
|
36
|
+
function isRecognizedProviderToken(prefix, value, atEnd) {
|
|
37
|
+
if (prefix === "AKIA" || prefix === "ASIA")
|
|
38
|
+
return isAwsAccessKeyValue(value, atEnd);
|
|
39
|
+
if (value.length >= 20)
|
|
40
|
+
return true;
|
|
41
|
+
const partialMinimum = prefix === "sk-" ? 8 : 1;
|
|
42
|
+
return atEnd && value.length >= partialMinimum;
|
|
43
|
+
}
|
|
44
|
+
function hasProviderToken(text) {
|
|
45
|
+
const provider = /\b(sk-(?:proj-|svcacct-)?|gh[pousr]_|github_pat_|xox[baprs]-|AKIA|ASIA)([A-Za-z0-9_-]+)/gu;
|
|
46
|
+
for (const match of text.matchAll(provider)) {
|
|
47
|
+
const atEnd = match.index + match[0].length === text.length;
|
|
48
|
+
if (isRecognizedProviderToken(match[1], match[2], atEnd))
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
function compactJoseSegmentCount(header) {
|
|
54
|
+
try {
|
|
55
|
+
const value = JSON.parse(Buffer.from(header, "base64url").toString("utf8"));
|
|
56
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
57
|
+
return undefined;
|
|
58
|
+
const fields = value;
|
|
59
|
+
if (typeof fields.alg !== "string")
|
|
60
|
+
return undefined;
|
|
61
|
+
return typeof fields.enc === "string" ? 5 : 3;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function hasCompactJoseToken(text) {
|
|
68
|
+
const jose = /\b([A-Za-z0-9_-]+)(?:\.[A-Za-z0-9_-]*)+/gu;
|
|
69
|
+
for (const match of text.matchAll(jose)) {
|
|
70
|
+
const parts = match[0].split(".");
|
|
71
|
+
const capturedAtEnd = match.index + match[0].length === text.length;
|
|
72
|
+
for (let index = 0; index < parts.length - 1; index += 1) {
|
|
73
|
+
const expected = compactJoseSegmentCount(parts[index]);
|
|
74
|
+
if (expected === undefined)
|
|
75
|
+
continue;
|
|
76
|
+
if (expected === 3 && parts[index + 1] === "")
|
|
77
|
+
continue;
|
|
78
|
+
if (parts.length - index >= expected)
|
|
79
|
+
return true;
|
|
80
|
+
if (capturedAtEnd)
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
function hasSecretIndicator(text) {
|
|
87
|
+
if (credentialIndicator.test(text))
|
|
88
|
+
return true;
|
|
89
|
+
if (hasPrivateKeyIndicator(text))
|
|
90
|
+
return true;
|
|
91
|
+
if (hasUrlCredentials(text))
|
|
92
|
+
return true;
|
|
93
|
+
if (hasAuthorizationCredentials(text))
|
|
94
|
+
return true;
|
|
95
|
+
if (hasProviderToken(text))
|
|
96
|
+
return true;
|
|
97
|
+
return hasCompactJoseToken(text);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Mask the entire field when a known secret indicator is present, including
|
|
101
|
+
* surrounding useful text. No value boundaries or source-language grammar are
|
|
102
|
+
* inferred. Unlabelled arbitrary secrets and unknown encodings remain outside
|
|
103
|
+
* detection; this is not a guarantee that unchanged text contains no secrets.
|
|
104
|
+
*/
|
|
105
|
+
export function redactSecretText(input) {
|
|
106
|
+
if (hasSecretIndicator(input))
|
|
107
|
+
return REDACTED;
|
|
108
|
+
if (hasSecretIndicator(detectionText(input)))
|
|
109
|
+
return REDACTED;
|
|
110
|
+
return input;
|
|
111
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { redactSecretText } from "./secret-text.js";
|
|
2
|
+
const INCOMPLETE_STREAM = "[UNAVAILABLE: incomplete output cannot be scanned for secrets]";
|
|
3
|
+
const SENSITIVE_TARGET = "Target unavailable because its shell identity contains sensitive text.";
|
|
4
|
+
function protectApplication(application) {
|
|
5
|
+
if (redactSecretText(application.id) !== application.id)
|
|
6
|
+
return undefined;
|
|
7
|
+
return { ...application, name: redactSecretText(application.name) };
|
|
8
|
+
}
|
|
9
|
+
function protectCatalog(catalog) {
|
|
10
|
+
const applications = catalog.applications.flatMap((application) => {
|
|
11
|
+
const protectedApplication = protectApplication(application);
|
|
12
|
+
return protectedApplication ? [protectedApplication] : [];
|
|
13
|
+
});
|
|
14
|
+
return {
|
|
15
|
+
...catalog,
|
|
16
|
+
applications,
|
|
17
|
+
complete: catalog.complete && applications.length === catalog.applications.length,
|
|
18
|
+
scope: { ...catalog.scope, roots: catalog.scope.roots.map(redactSecretText) },
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function protectTargets(observation) {
|
|
22
|
+
return {
|
|
23
|
+
...observation,
|
|
24
|
+
host: { ...observation.host, kernelRelease: redactSecretText(observation.host.kernelRelease) },
|
|
25
|
+
targets: observation.targets.map((target) => {
|
|
26
|
+
if (!target.available)
|
|
27
|
+
return { ...target, reason: redactSecretText(target.reason) };
|
|
28
|
+
if (redactSecretText(target.shell) !== target.shell)
|
|
29
|
+
return { id: target.id, available: false, reason: SENSITIVE_TARGET };
|
|
30
|
+
return target;
|
|
31
|
+
}),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function protectProcess(result) {
|
|
35
|
+
return {
|
|
36
|
+
...result,
|
|
37
|
+
stdout: result.outputTruncated ? INCOMPLETE_STREAM : redactSecretText(result.stdout),
|
|
38
|
+
stderr: result.outputTruncated ? INCOMPLETE_STREAM : redactSecretText(result.stderr),
|
|
39
|
+
...(result.spawnedProcess ? {
|
|
40
|
+
spawnedProcess: {
|
|
41
|
+
...result.spawnedProcess,
|
|
42
|
+
executable: redactSecretText(result.spawnedProcess.executable),
|
|
43
|
+
},
|
|
44
|
+
} : {}),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export const systemResultProtection = Object.freeze({
|
|
48
|
+
protectTargets,
|
|
49
|
+
protectCatalog,
|
|
50
|
+
protectProcess,
|
|
51
|
+
protectApplication,
|
|
52
|
+
protectMessage: redactSecretText,
|
|
53
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SystemApplicationCatalog } from "./application-catalog.js";
|
|
2
|
+
import type { SystemApplication, SystemProcessResult } from "./contracts.js";
|
|
3
|
+
import type { SystemTargetObservation } from "./target-observation.js";
|
|
4
|
+
/** Producer-owned protection, applied before formatting or delivering observations. */
|
|
5
|
+
export type SystemResultProtection = Readonly<{
|
|
6
|
+
protectTargets(observation: SystemTargetObservation): SystemTargetObservation;
|
|
7
|
+
protectCatalog(catalog: SystemApplicationCatalog): SystemApplicationCatalog;
|
|
8
|
+
protectProcess(result: SystemProcessResult): SystemProcessResult;
|
|
9
|
+
protectApplication(application: SystemApplication): SystemApplication | undefined;
|
|
10
|
+
protectMessage(message: string): string;
|
|
11
|
+
}>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/** Reads only the trace clone. Original provider bytes and errors stay untouched. */
|
|
2
|
+
export declare function captureProviderResponseBody(response: Response, startedAt: number): Promise<{
|
|
3
|
+
outcome: "completed";
|
|
4
|
+
body: string;
|
|
5
|
+
stream: {
|
|
6
|
+
sse?: {
|
|
7
|
+
eventCount: number;
|
|
8
|
+
eventTypes: {
|
|
9
|
+
[k: string]: number;
|
|
10
|
+
};
|
|
11
|
+
recentEvents: {
|
|
12
|
+
type: string;
|
|
13
|
+
afterMs: number;
|
|
14
|
+
}[];
|
|
15
|
+
oversizedLineCount: number;
|
|
16
|
+
} | undefined;
|
|
17
|
+
headersAfterMs: number;
|
|
18
|
+
elapsedMs: number;
|
|
19
|
+
bytesReceived: number;
|
|
20
|
+
chunkCount: number;
|
|
21
|
+
firstChunkAfterMs: number | null;
|
|
22
|
+
lastChunkAfterMs: number | null;
|
|
23
|
+
};
|
|
24
|
+
error?: undefined;
|
|
25
|
+
partialBodyPrefix?: undefined;
|
|
26
|
+
partialBodyPrefixBytes?: undefined;
|
|
27
|
+
partialBodyPrefixTruncated?: undefined;
|
|
28
|
+
partialBody?: undefined;
|
|
29
|
+
partialBodyBytes?: undefined;
|
|
30
|
+
bodyTruncated?: undefined;
|
|
31
|
+
} | {
|
|
32
|
+
outcome: "failed";
|
|
33
|
+
error: unknown;
|
|
34
|
+
partialBodyPrefix: string;
|
|
35
|
+
partialBodyPrefixBytes: number;
|
|
36
|
+
partialBodyPrefixTruncated: boolean;
|
|
37
|
+
partialBody: string;
|
|
38
|
+
partialBodyBytes: number;
|
|
39
|
+
bodyTruncated: boolean;
|
|
40
|
+
stream: {
|
|
41
|
+
sse?: {
|
|
42
|
+
eventCount: number;
|
|
43
|
+
eventTypes: {
|
|
44
|
+
[k: string]: number;
|
|
45
|
+
};
|
|
46
|
+
recentEvents: {
|
|
47
|
+
type: string;
|
|
48
|
+
afterMs: number;
|
|
49
|
+
}[];
|
|
50
|
+
oversizedLineCount: number;
|
|
51
|
+
} | undefined;
|
|
52
|
+
headersAfterMs: number;
|
|
53
|
+
elapsedMs: number;
|
|
54
|
+
bytesReceived: number;
|
|
55
|
+
chunkCount: number;
|
|
56
|
+
firstChunkAfterMs: number | null;
|
|
57
|
+
lastChunkAfterMs: number | null;
|
|
58
|
+
};
|
|
59
|
+
body?: undefined;
|
|
60
|
+
}>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { ProviderSseDiagnostics } from "./provider-sse-diagnostics.js";
|
|
2
|
+
import { ProviderResponsePrefix } from "./provider-response-prefix.js";
|
|
3
|
+
import { ProviderResponseTail } from "./provider-response-tail.js";
|
|
4
|
+
/** Reads only the trace clone. Original provider bytes and errors stay untouched. */
|
|
5
|
+
export async function captureProviderResponseBody(response, startedAt) {
|
|
6
|
+
const headersAfterMs = Math.max(0, Date.now() - startedAt);
|
|
7
|
+
const sse = isEventStreamResponse(response) ? new ProviderSseDiagnostics() : undefined;
|
|
8
|
+
const decoder = new TextDecoder();
|
|
9
|
+
const parts = [];
|
|
10
|
+
const prefix = new ProviderResponsePrefix();
|
|
11
|
+
const tail = new ProviderResponseTail();
|
|
12
|
+
let bytesReceived = 0;
|
|
13
|
+
let chunkCount = 0;
|
|
14
|
+
let firstChunkAfterMs = null;
|
|
15
|
+
let lastChunkAfterMs = null;
|
|
16
|
+
const reader = response.body?.getReader();
|
|
17
|
+
const streamSnapshot = () => ({
|
|
18
|
+
headersAfterMs,
|
|
19
|
+
elapsedMs: Math.max(0, Date.now() - startedAt),
|
|
20
|
+
bytesReceived,
|
|
21
|
+
chunkCount,
|
|
22
|
+
firstChunkAfterMs,
|
|
23
|
+
lastChunkAfterMs,
|
|
24
|
+
...(sse ? { sse: sse.snapshot() } : {}),
|
|
25
|
+
});
|
|
26
|
+
try {
|
|
27
|
+
while (reader) {
|
|
28
|
+
const { done, value } = await reader.read();
|
|
29
|
+
if (done)
|
|
30
|
+
break;
|
|
31
|
+
const afterMs = Math.max(0, Date.now() - startedAt);
|
|
32
|
+
bytesReceived += value.byteLength;
|
|
33
|
+
chunkCount += 1;
|
|
34
|
+
firstChunkAfterMs ??= afterMs;
|
|
35
|
+
lastChunkAfterMs = afterMs;
|
|
36
|
+
prefix.append(value);
|
|
37
|
+
tail.append(value);
|
|
38
|
+
const text = decoder.decode(value, { stream: true });
|
|
39
|
+
parts.push(text);
|
|
40
|
+
sse?.observe(text, afterMs);
|
|
41
|
+
}
|
|
42
|
+
const finalText = decoder.decode();
|
|
43
|
+
parts.push(finalText);
|
|
44
|
+
sse?.observe(finalText, Math.max(0, Date.now() - startedAt));
|
|
45
|
+
return { outcome: "completed", body: parts.join(""), stream: streamSnapshot() };
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
const partialBodyPrefix = prefix.snapshot();
|
|
49
|
+
const partialBody = tail.snapshot();
|
|
50
|
+
return {
|
|
51
|
+
outcome: "failed",
|
|
52
|
+
error,
|
|
53
|
+
partialBodyPrefix: partialBodyPrefix.toString("utf8"),
|
|
54
|
+
partialBodyPrefixBytes: partialBodyPrefix.byteLength,
|
|
55
|
+
partialBodyPrefixTruncated: bytesReceived > partialBodyPrefix.byteLength,
|
|
56
|
+
partialBody: partialBody.toString("utf8"),
|
|
57
|
+
partialBodyBytes: partialBody.byteLength,
|
|
58
|
+
bodyTruncated: bytesReceived > partialBody.byteLength,
|
|
59
|
+
stream: streamSnapshot(),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
reader?.releaseLock();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function isEventStreamResponse(response) {
|
|
67
|
+
return response.headers.get("content-type")?.split(";", 1)[0].trim().toLowerCase() === "text/event-stream";
|
|
68
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const MAX_PARTIAL_BODY_PREFIX_BYTES = 16_384;
|
|
2
|
+
/** Retains the first source bytes without allocating more storage as the stream grows. */
|
|
3
|
+
export class ProviderResponsePrefix {
|
|
4
|
+
bytes = Buffer.alloc(MAX_PARTIAL_BODY_PREFIX_BYTES);
|
|
5
|
+
usedBytes = 0;
|
|
6
|
+
append(chunk) {
|
|
7
|
+
const length = Math.min(chunk.byteLength, this.bytes.length - this.usedBytes);
|
|
8
|
+
this.bytes.set(chunk.subarray(0, length), this.usedBytes);
|
|
9
|
+
this.usedBytes += length;
|
|
10
|
+
}
|
|
11
|
+
snapshot() {
|
|
12
|
+
return Buffer.from(this.bytes.subarray(0, this.usedBytes));
|
|
13
|
+
}
|
|
14
|
+
}
|