machine-bridge-mcp 2.0.0 → 3.0.0-beta.102
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/CHANGELOG.md +1142 -0
- package/CONTRIBUTING.md +23 -25
- package/GOVERNANCE.md +2 -2
- package/README.md +58 -20
- package/SECURITY.md +161 -120
- package/SUPPORT.md +1 -1
- package/browser-extension/broker-auth.js +83 -0
- package/browser-extension/broker-liveness.js +35 -0
- package/browser-extension/browser-error-boundary.js +96 -0
- package/browser-extension/browser-operations.js +1456 -101
- package/browser-extension/devtools-input.js +195 -34
- package/browser-extension/devtools-observation.js +429 -0
- package/browser-extension/devtools-session.js +48 -0
- package/browser-extension/manifest.json +4 -3
- package/browser-extension/page-automation.js +578 -118
- package/browser-extension/pairing-bootstrap.js +42 -0
- package/browser-extension/pairing.js +28 -12
- package/browser-extension/service-worker.js +126 -106
- package/docs/AGENT_CONTEXT.md +13 -10
- package/docs/ARCHITECTURE.md +159 -67
- package/docs/AUDIT.md +1302 -4
- package/docs/CLIENTS.md +19 -6
- package/docs/COMPUTER_USE.md +297 -0
- package/docs/ENGINEERING.md +72 -13
- package/docs/GETTING_STARTED.md +18 -20
- package/docs/LOCAL_AUTHORIZATION.md +115 -72
- package/docs/LOCAL_AUTOMATION.md +27 -21
- package/docs/LOGGING.md +40 -19
- package/docs/MANAGED_JOBS.md +37 -34
- package/docs/MULTI_ACCOUNT.md +98 -37
- package/docs/OPERATIONS.md +145 -51
- package/docs/OVERVIEW.md +14 -11
- package/docs/POLICY_REFERENCE.md +71 -3
- package/docs/PRIVACY.md +41 -2
- package/docs/PROJECT_STANDARDS.md +29 -6
- package/docs/RELEASING.md +238 -64
- package/docs/TESTING.md +150 -39
- package/docs/THREAT_MODEL.md +164 -67
- package/docs/TOOL_REFERENCE.md +653 -60
- package/docs/UPGRADING.md +78 -18
- package/native/macos/MachineBridgeBackgroundInput.swift +1051 -0
- package/native/macos/MachineBridgeBackgroundInputSmokeFixture.swift +295 -0
- package/native/macos/MachineBridgeTrustBroker.swift +233 -0
- package/package.json +94 -16
- package/scripts/accepted-candidate-tarball.mjs +77 -0
- package/scripts/candidate-runtime-store.mjs +93 -0
- package/scripts/check-plan.mjs +73 -3
- package/scripts/check-runner.mjs +129 -17
- package/scripts/commit-message-check.mjs +5 -2
- package/scripts/consumer-package-security.mjs +293 -0
- package/scripts/coverage-check.mjs +251 -15
- package/scripts/coverage-generation.mjs +41 -0
- package/scripts/coverage-range-merge.mjs +41 -0
- package/scripts/foreground-daemon-recovery.mjs +88 -0
- package/scripts/generate-policy-reference.mjs +28 -5
- package/scripts/generate-tool-reference.mjs +1 -1
- package/scripts/generate-worker-types.mjs +21 -11
- package/scripts/github-backlog.mjs +11 -10
- package/scripts/github-push.mjs +62 -16
- package/scripts/github-release-asset.mjs +58 -0
- package/scripts/github-release.mjs +241 -132
- package/scripts/global-package-installation.mjs +68 -0
- package/scripts/hardened-npm-session.mjs +42 -0
- package/scripts/install-published-prerelease.mjs +198 -0
- package/scripts/local-release-acceptance.mjs +103 -45
- package/scripts/macos-background-input-smoke.mjs +515 -0
- package/scripts/network-retry.mjs +8 -1
- package/scripts/npm-global-prefix.mjs +27 -0
- package/scripts/npm-publication-policy.mjs +17 -0
- package/scripts/official-mcp-conformance.mjs +267 -0
- package/scripts/persistent-activation-process.mjs +101 -0
- package/scripts/prepare-pinned-npm.mjs +12 -69
- package/scripts/prerelease-activation.mjs +160 -0
- package/scripts/privacy-check.mjs +14 -6
- package/scripts/promotion-digest.mjs +128 -0
- package/scripts/publish-npm.mjs +260 -0
- package/scripts/published-release.mjs +132 -0
- package/scripts/release-acceptance.mjs +62 -54
- package/scripts/release-browser-extension-store.mjs +172 -0
- package/scripts/release-candidate-manifest.mjs +52 -0
- package/scripts/release-channel.mjs +106 -0
- package/scripts/release-diagnostic.mjs +41 -0
- package/scripts/release-impact-check.mjs +12 -22
- package/scripts/release-oauth-canary-core.mjs +325 -0
- package/scripts/release-oauth-canary-evidence.mjs +100 -0
- package/scripts/release-oauth-canary.mjs +127 -0
- package/scripts/release-publication-guard.mjs +67 -0
- package/scripts/release-soak.mjs +284 -0
- package/scripts/release-state.mjs +1 -1
- package/scripts/run-checks.mjs +44 -7
- package/scripts/run-worker-dry-run.mjs +21 -0
- package/scripts/sarif-security-gate.mjs +2 -1
- package/scripts/sbom-check.mjs +106 -0
- package/scripts/start-release-candidate.mjs +267 -44
- package/scripts/syntax-check.mjs +36 -14
- package/scripts/verification-generation-guard.mjs +15 -0
- package/scripts/verification-idle-sleep-guard.mjs +37 -0
- package/scripts/verification-state.mjs +108 -0
- package/scripts/wrangler-command-lifecycle.mjs +115 -0
- package/src/local/account-access.mjs +13 -1
- package/src/local/account-admin-response.mjs +92 -0
- package/src/local/account-admin.mjs +52 -19
- package/src/local/agent-context-projection.mjs +26 -7
- package/src/local/agent-context.mjs +88 -49
- package/src/local/agent-skill-discovery.mjs +16 -5
- package/src/local/app-automation-macos-jxa.mjs +350 -0
- package/src/local/app-automation.mjs +873 -163
- package/src/local/application-capability-projection.mjs +24 -0
- package/src/local/authority-context.mjs +106 -0
- package/src/local/autostart-log-maintenance.mjs +36 -0
- package/src/local/browser-bridge-http.mjs +5 -3
- package/src/local/browser-bridge.mjs +109 -31
- package/src/local/browser-broker-auth-http.mjs +67 -0
- package/src/local/browser-broker-auth.mjs +98 -0
- package/src/local/browser-broker-routes.mjs +63 -20
- package/src/local/browser-broker-server.mjs +17 -7
- package/src/local/browser-command.mjs +79 -30
- package/src/local/browser-computer-observation-service.mjs +266 -0
- package/src/local/browser-extension-identity.mjs +50 -0
- package/src/local/browser-extension-path.mjs +22 -0
- package/src/local/browser-extension-protocol.mjs +50 -11
- package/src/local/browser-operation-service.mjs +147 -117
- package/src/local/browser-pairing-grant.mjs +109 -0
- package/src/local/browser-pairing-http.mjs +36 -0
- package/src/local/browser-pairing-launch.mjs +58 -0
- package/src/local/browser-pairing-store.mjs +85 -48
- package/src/local/browser-request-registry.mjs +40 -14
- package/src/local/browser-request-settlement.mjs +78 -0
- package/src/local/browser-resource-input.mjs +74 -0
- package/src/local/browser-trusted-input-health.mjs +63 -0
- package/src/local/call-authority.mjs +21 -0
- package/src/local/call-capacity.mjs +45 -0
- package/src/local/call-registry-drain.mjs +54 -0
- package/src/local/call-registry.mjs +30 -15
- package/src/local/capability-observer.mjs +5 -0
- package/src/local/capability-ranking.mjs +3 -2
- package/src/local/child-process-settlement.mjs +132 -0
- package/src/local/cli-account-admin.mjs +40 -6
- package/src/local/cli-activate.mjs +162 -0
- package/src/local/cli-local-admin.mjs +20 -45
- package/src/local/cli-options.mjs +12 -13
- package/src/local/cli-ready-output.mjs +52 -0
- package/src/local/cli-service.mjs +91 -11
- package/src/local/cli.mjs +232 -150
- package/src/local/computer-use-application-observation.mjs +224 -0
- package/src/local/computer-use-arguments.mjs +270 -0
- package/src/local/computer-use-deadline.mjs +50 -0
- package/src/local/computer-use-dispatch-settlement.mjs +40 -0
- package/src/local/computer-use-expectation.mjs +171 -0
- package/src/local/computer-use-observation.mjs +769 -0
- package/src/local/computer-use-recovery.mjs +82 -0
- package/src/local/computer-use-result-budget.mjs +145 -0
- package/src/local/computer-use-snapshot-store.mjs +67 -0
- package/src/local/computer-use.mjs +2255 -0
- package/src/local/daemon-http-relay-auth.mjs +26 -0
- package/src/local/daemon-http-relay-connection.mjs +298 -0
- package/src/local/daemon-http-relay-request.mjs +64 -0
- package/src/local/daemon-http-relay-sequence.mjs +49 -0
- package/src/local/daemon-process.mjs +40 -7
- package/src/local/delegated-process-sandbox.mjs +148 -0
- package/src/local/device-identity.mjs +156 -49
- package/src/local/device-root-provider.mjs +81 -0
- package/src/local/directory-metadata.mjs +47 -0
- package/src/local/doctor-reporting.mjs +23 -0
- package/src/local/durable-process-spec.mjs +80 -0
- package/src/local/errors.mjs +25 -15
- package/src/local/exclusive-file.mjs +74 -26
- package/src/local/execution-limits.mjs +9 -0
- package/src/local/execution-routing.mjs +276 -0
- package/src/local/execution-surface.mjs +23 -0
- package/src/local/file-mutation-coordinator.mjs +47 -0
- package/src/local/file-snapshot-preservation.mjs +24 -0
- package/src/local/filesystem-identity.mjs +54 -0
- package/src/local/fixed-process-environment.mjs +21 -0
- package/src/local/full-access-test.mjs +31 -13
- package/src/local/git-commit.mjs +69 -0
- package/src/local/git-config-safety.mjs +55 -0
- package/src/local/git-log-parser.mjs +41 -0
- package/src/local/git-metadata-boundary.mjs +77 -0
- package/src/local/git-metadata-tree-safety.mjs +59 -0
- package/src/local/git-operation-state.mjs +19 -0
- package/src/local/git-service.mjs +165 -30
- package/src/local/hardened-npm-download-timeout.mjs +46 -0
- package/src/local/hardened-npm-download.mjs +109 -0
- package/src/local/hardened-npm-extract.mjs +20 -0
- package/src/local/hardened-npm-verification.mjs +104 -0
- package/src/local/hardened-npm.mjs +199 -0
- package/src/local/job-runner.mjs +244 -89
- package/src/local/lifecycle.mjs +6 -0
- package/src/local/log.mjs +19 -45
- package/src/local/macos-background-input.mjs +398 -0
- package/src/local/macos-idle-sleep-assertion.mjs +65 -0
- package/src/local/macos-trust-broker.mjs +404 -0
- package/src/local/managed-job-cancellation.mjs +42 -0
- package/src/local/managed-job-capacity.mjs +16 -0
- package/src/local/managed-job-directory-generation.mjs +60 -0
- package/src/local/managed-job-directory.mjs +75 -0
- package/src/local/managed-job-durable-process.mjs +49 -0
- package/src/local/managed-job-lock.mjs +46 -14
- package/src/local/managed-job-plan.mjs +38 -14
- package/src/local/managed-job-projection.mjs +23 -15
- package/src/local/managed-job-retention.mjs +128 -0
- package/src/local/managed-job-runner-claim.mjs +70 -0
- package/src/local/managed-job-runner.mjs +35 -10
- package/src/local/managed-job-storage.mjs +22 -6
- package/src/local/managed-job-terminal-maintenance.mjs +40 -0
- package/src/local/managed-job-terminal.mjs +150 -0
- package/src/local/managed-jobs.mjs +424 -287
- package/src/local/npm-cli.mjs +42 -0
- package/src/local/npm-environment.mjs +37 -0
- package/src/local/operation-authorization.mjs +68 -324
- package/src/local/operation-risk.mjs +51 -4
- package/src/local/owner-state-lock.mjs +118 -0
- package/src/local/package-identity.mjs +9 -0
- package/src/local/patch.mjs +20 -18
- package/src/local/path-inspection.mjs +23 -0
- package/src/local/policy.mjs +19 -0
- package/src/local/private-toolchain-integrity.mjs +54 -0
- package/src/local/process-execution.mjs +87 -75
- package/src/local/process-foreground-timeout.mjs +50 -0
- package/src/local/process-identity.mjs +41 -7
- package/src/local/process-nonreplayable-settlement.mjs +50 -0
- package/src/local/process-result-projection.mjs +22 -0
- package/src/local/process-session-events.mjs +47 -0
- package/src/local/process-session-remote-activity.mjs +10 -0
- package/src/local/process-session-termination.mjs +73 -0
- package/src/local/process-sessions.mjs +144 -112
- package/src/local/process-tracker.mjs +140 -13
- package/src/local/process-tree-ownership-types.d.ts +37 -0
- package/src/local/process-tree-ownership.mjs +57 -0
- package/src/local/process-tree-signal.mjs +34 -0
- package/src/local/process-tree-snapshot.mjs +77 -0
- package/src/local/process-tree-supervisor.mjs +69 -0
- package/src/local/process-tree.mjs +11 -53
- package/src/local/project-metadata.mjs +19 -6
- package/src/local/relay-call-recovery.mjs +58 -38
- package/src/local/relay-connection-classification.mjs +131 -0
- package/src/local/relay-connection-support.mjs +91 -0
- package/src/local/relay-connection.mjs +179 -272
- package/src/local/relay-diagnostics.mjs +91 -0
- package/src/local/relay-heartbeat.mjs +119 -0
- package/src/local/relay-liveness.mjs +109 -0
- package/src/local/relay-peer-diagnostics.mjs +29 -0
- package/src/local/release-runtime-lock.mjs +18 -0
- package/src/local/remote-activity-idle-sleep-guard.mjs +77 -0
- package/src/local/remote-configuration.mjs +48 -0
- package/src/local/resilient-relay-connection.mjs +178 -0
- package/src/local/resource-admission-diagnostics.mjs +52 -0
- package/src/local/resource-admission-policy.mjs +115 -0
- package/src/local/resource-admission.mjs +339 -0
- package/src/local/resource-build-root.mjs +83 -0
- package/src/local/resource-cargo-concurrency.mjs +38 -0
- package/src/local/resource-cmake-concurrency.mjs +42 -0
- package/src/local/resource-command-concurrency.mjs +37 -0
- package/src/local/resource-command-profile.mjs +176 -0
- package/src/local/resource-coordinator-accounting.mjs +21 -0
- package/src/local/resource-cpu-window.mjs +20 -0
- package/src/local/resource-disk-headroom.mjs +13 -0
- package/src/local/resource-elastic-memory.mjs +19 -0
- package/src/local/resource-elastic-request.mjs +36 -0
- package/src/local/resource-foreground-wait.mjs +29 -0
- package/src/local/resource-go-concurrency.mjs +43 -0
- package/src/local/resource-gradle-concurrency.mjs +57 -0
- package/src/local/resource-host-cache.mjs +39 -0
- package/src/local/resource-host-darwin.mjs +54 -0
- package/src/local/resource-host-linux.mjs +35 -0
- package/src/local/resource-host-sample-file.mjs +23 -0
- package/src/local/resource-host-snapshot.mjs +99 -0
- package/src/local/resource-lease-accounting.mjs +119 -0
- package/src/local/resource-light-command.mjs +6 -0
- package/src/local/resource-make-concurrency.mjs +42 -0
- package/src/local/resource-maven-concurrency.mjs +38 -0
- package/src/local/resource-ninja-command-concurrency.mjs +20 -0
- package/src/local/resource-ninja-concurrency.mjs +28 -0
- package/src/local/resource-operations.mjs +26 -10
- package/src/local/resource-pressure.mjs +67 -0
- package/src/local/resource-probe-command.mjs +35 -0
- package/src/local/resource-process-admission.mjs +59 -0
- package/src/local/resource-process-ancestry-cache.mjs +43 -0
- package/src/local/resource-process-ancestry.mjs +32 -0
- package/src/local/resource-process-priority.mjs +15 -0
- package/src/local/resource-project-key.mjs +53 -0
- package/src/local/resource-pytest-concurrency.mjs +33 -0
- package/src/local/resource-release-control-classification.mjs +14 -0
- package/src/local/resource-release-control-executable.mjs +70 -0
- package/src/local/resource-release-control-workspace.mjs +41 -0
- package/src/local/resource-request-contract.mjs +30 -0
- package/src/local/resource-script-classification.mjs +44 -0
- package/src/local/resource-shell-analysis.mjs +58 -0
- package/src/local/resource-staging-recovery.mjs +97 -0
- package/src/local/resource-swift-concurrency.mjs +31 -0
- package/src/local/resource-transaction-lock.mjs +189 -0
- package/src/local/resource-wait.mjs +48 -0
- package/src/local/resource-waiters.mjs +139 -0
- package/src/local/resource-xcode-command.mjs +7 -0
- package/src/local/resource-xcode-concurrency.mjs +34 -0
- package/src/local/resource-xcode-non-build.mjs +19 -0
- package/src/local/runtime-activation.mjs +700 -0
- package/src/local/runtime-activity-projection.mjs +48 -0
- package/src/local/runtime-capabilities.mjs +48 -15
- package/src/local/runtime-diagnostic-state.mjs +14 -0
- package/src/local/runtime-diagnostics.mjs +40 -13
- package/src/local/runtime-info-projection.mjs +60 -0
- package/src/local/runtime-info-relay-projection.mjs +21 -0
- package/src/local/runtime-paths.mjs +2 -1
- package/src/local/runtime-process-routing.mjs +33 -0
- package/src/local/runtime-relay-connection-options.mjs +44 -0
- package/src/local/runtime-relay-control.mjs +98 -0
- package/src/local/runtime-relay.mjs +26 -50
- package/src/local/runtime-reporting.mjs +37 -21
- package/src/local/runtime-resource-service.mjs +77 -0
- package/src/local/runtime-tool-handlers.mjs +13 -10
- package/src/local/runtime.mjs +244 -208
- package/src/local/secure-file.mjs +73 -20
- package/src/local/security-audit-dispatch.mjs +35 -0
- package/src/local/security-audit-log.mjs +215 -0
- package/src/local/security-audit-state.mjs +139 -0
- package/src/local/security-audit-storage.mjs +135 -0
- package/src/local/security-audit-warning.mjs +31 -0
- package/src/local/security-audit-worker.mjs +87 -0
- package/src/local/service-convergence.mjs +42 -1
- package/src/local/service-definition.mjs +24 -0
- package/src/local/service-environment.mjs +18 -10
- package/src/local/service-owner.mjs +146 -0
- package/src/local/service-ownership.mjs +17 -0
- package/src/local/service-restart-handoff.mjs +64 -0
- package/src/local/service-restart-scheduler.mjs +49 -0
- package/src/local/service-runtime-convergence.mjs +52 -0
- package/src/local/service-runtime.mjs +105 -0
- package/src/local/service-status.mjs +60 -0
- package/src/local/service.mjs +385 -92
- package/src/local/shell.mjs +39 -19
- package/src/local/ssh-key.mjs +158 -42
- package/src/local/state-inventory.mjs +50 -24
- package/src/local/state-owner-lock-inventory.mjs +23 -0
- package/src/local/state-root-owned-namespaces.mjs +83 -0
- package/src/local/state-root-retirement.mjs +89 -0
- package/src/local/state.mjs +386 -96
- package/src/local/stdio.mjs +96 -66
- package/src/local/support-state-projection.mjs +30 -0
- package/src/local/system-network-route.mjs +76 -0
- package/src/local/systemd-removal.mjs +20 -0
- package/src/local/tool-executor.mjs +85 -20
- package/src/local/tool-result-boundary.mjs +51 -0
- package/src/local/toolchain-operation-lock.mjs +41 -0
- package/src/local/tools.mjs +7 -5
- package/src/local/trusted-executable.mjs +53 -0
- package/src/local/trusted-git-executable.mjs +34 -0
- package/src/local/trusted-github-cli.mjs +24 -0
- package/src/local/windows-service-convergence.mjs +49 -0
- package/src/local/windows-service.mjs +52 -45
- package/src/local/worker-deployment-fingerprint.mjs +102 -0
- package/src/local/worker-deployment.mjs +48 -60
- package/src/local/worker-health.mjs +12 -4
- package/src/local/worker-secret-file.mjs +37 -17
- package/src/local/workspace-file-service.mjs +156 -239
- package/src/local/workspace-file-transaction.mjs +189 -0
- package/src/local/workspace-search.mjs +55 -0
- package/src/local/wrangler-toolchain/package-lock.json +1505 -0
- package/src/local/wrangler-toolchain/package.json +23 -0
- package/src/local/wrangler-toolchain-verification.mjs +135 -0
- package/src/local/wrangler-toolchain.mjs +188 -0
- package/src/shared/access-contract.json +7 -1
- package/src/shared/activation-recovery.mjs +49 -0
- package/src/shared/admin-auth.d.mts +2 -1
- package/src/shared/admin-auth.mjs +3 -3
- package/src/shared/authority-revocation.d.mts +9 -0
- package/src/shared/authority-revocation.mjs +28 -0
- package/src/shared/daemon-auth.d.mts +11 -0
- package/src/shared/daemon-auth.mjs +17 -0
- package/src/shared/device-session-auth.d.mts +20 -0
- package/src/shared/device-session-auth.mjs +51 -0
- package/src/shared/foreground-timeout.d.mts +15 -0
- package/src/shared/foreground-timeout.mjs +70 -0
- package/src/shared/log-redaction.d.mts +9 -0
- package/src/shared/log-redaction.mjs +51 -0
- package/src/shared/mcp-protocol.d.mts +27 -0
- package/src/shared/mcp-protocol.mjs +275 -0
- package/src/shared/project-overview-projection.d.mts +4 -0
- package/src/shared/project-overview-projection.mjs +96 -0
- package/src/shared/relay-contract.json +28 -0
- package/src/shared/result-projection.d.mts +2 -1
- package/src/shared/result-projection.mjs +13 -2
- package/src/shared/server-metadata.json +15 -9
- package/src/shared/tool-argument-validation.d.mts +17 -0
- package/src/shared/tool-argument-validation.mjs +325 -0
- package/src/shared/tool-call-capacity.d.mts +41 -0
- package/src/shared/tool-call-capacity.mjs +59 -0
- package/src/shared/tool-catalog.json +626 -57
- package/src/worker/access.ts +12 -0
- package/src/worker/account-admin.ts +55 -33
- package/src/worker/authority-revocations.ts +174 -0
- package/src/worker/authority.ts +52 -6
- package/src/worker/daemon-auth.ts +49 -68
- package/src/worker/daemon-channel.ts +36 -0
- package/src/worker/daemon-http-auth.ts +63 -0
- package/src/worker/daemon-http-channel.ts +120 -0
- package/src/worker/daemon-http-controller.ts +163 -0
- package/src/worker/daemon-http-protocol.ts +62 -0
- package/src/worker/daemon-http-registry.ts +82 -0
- package/src/worker/daemon-last-observation.ts +30 -0
- package/src/worker/daemon-liveness.ts +8 -6
- package/src/worker/daemon-ready-dispatch.ts +17 -0
- package/src/worker/daemon-ready-messages.ts +73 -0
- package/src/worker/daemon-ready-waiters.ts +79 -0
- package/src/worker/daemon-recovery-budget.ts +13 -0
- package/src/worker/daemon-registry.ts +58 -0
- package/src/worker/daemon-relay-diagnostics.ts +127 -0
- package/src/worker/daemon-socket-attachment.ts +55 -0
- package/src/worker/daemon-sockets.ts +72 -62
- package/src/worker/daemon-status.ts +38 -0
- package/src/worker/device-session-verifier.ts +129 -0
- package/src/worker/dpop.ts +157 -0
- package/src/worker/durable-process-timeout.ts +29 -0
- package/src/worker/errors.ts +57 -0
- package/src/worker/http.ts +112 -26
- package/src/worker/index.ts +446 -440
- package/src/worker/mcp-access.ts +57 -0
- package/src/worker/mcp-controller.ts +188 -0
- package/src/worker/mcp-http-accept.ts +11 -0
- package/src/worker/mcp-http-contract.ts +322 -0
- package/src/worker/mcp-initialization-compat.ts +141 -0
- package/src/worker/mcp-jsonrpc.ts +11 -29
- package/src/worker/mcp-removed-protocol.ts +17 -0
- package/src/worker/mcp-response-proxy.ts +135 -0
- package/src/worker/mcp-response-stream.ts +65 -0
- package/src/worker/mcp-stale-schema-compat.ts +57 -0
- package/src/worker/mcp-stream-proxy-contract.ts +48 -0
- package/src/worker/mcp-tool-call-input.ts +23 -0
- package/src/worker/nonce-store.ts +33 -35
- package/src/worker/oauth-authorization-page.ts +21 -1
- package/src/worker/oauth-client-admin.ts +52 -0
- package/src/worker/oauth-client-contract.ts +38 -0
- package/src/worker/oauth-controller.ts +107 -47
- package/src/worker/oauth-field-contract.ts +31 -0
- package/src/worker/oauth-record-contract.ts +7 -0
- package/src/worker/oauth-refresh-authority.ts +27 -0
- package/src/worker/oauth-refresh-exchange.ts +162 -0
- package/src/worker/oauth-refresh-families.ts +130 -27
- package/src/worker/oauth-refresh-persistence.ts +116 -0
- package/src/worker/oauth-state.ts +33 -18
- package/src/worker/oauth-store-validation.ts +131 -0
- package/src/worker/oauth-token-derivation.ts +33 -0
- package/src/worker/oauth-token-issuance.ts +119 -0
- package/src/worker/oauth-tokens.ts +56 -190
- package/src/worker/observability.ts +38 -5
- package/src/worker/pending-admission.ts +15 -0
- package/src/worker/pending-call-capacity.ts +108 -0
- package/src/worker/pending-call-contract.ts +42 -5
- package/src/worker/pending-call-deadlines.ts +75 -0
- package/src/worker/pending-calls.ts +131 -125
- package/src/worker/runtime-alarm-storage.ts +37 -0
- package/src/worker/runtime-alarm.ts +136 -0
- package/src/worker/server-info-activity.ts +36 -0
- package/src/worker/server-info-tool-delivery.ts +15 -0
- package/src/worker/server-info.ts +168 -0
- package/src/worker/tool-catalog.ts +47 -1
- package/src/worker/tool-timeout.ts +75 -14
- package/src/worker/websocket-protocol.ts +26 -2
- package/src/worker/worker-edge-guard.ts +90 -0
- package/src/worker/worker-edge-log.ts +65 -0
- package/src/worker/worker-entry.ts +52 -0
- package/src/worker/worker-mcp-config.ts +23 -0
- package/src/worker/worker-metadata.ts +48 -0
- package/src/worker/worker-rate-limit-key.ts +30 -0
- package/src/worker/worker-runtime-config.ts +20 -0
- package/src/worker/worker-static-routes.ts +54 -0
- package/src/worker/worker-task-lifetime.ts +18 -0
- package/tsconfig.local.json +17 -1
- package/wrangler.jsonc +13 -0
- package/src/local/cli-approval.mjs +0 -117
- package/src/local/operation-state-lock.mjs +0 -92
- package/src/worker/mcp-session.ts +0 -72
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { createExclusiveFileSync, removeOwnedJsonFileSync } from "./exclusive-file.mjs";
|
|
4
|
+
import { createMonotonicDeadline } from "./monotonic-deadline.mjs";
|
|
5
|
+
import { currentProcessStartTimeMs, inspectProcessInstance } from "./process-identity.mjs";
|
|
6
|
+
import { ensureOwnerOnlyDirectorySync, readBoundedRegularFileSync, retryTransientMultipleLinksSync } from "./secure-file.mjs";
|
|
7
|
+
|
|
8
|
+
const MAX_LOCK_BYTES = 8 * 1024;
|
|
9
|
+
const DEFAULT_WAIT_MS = 5_000;
|
|
10
|
+
const DEFAULT_POLL_MS = 25;
|
|
11
|
+
|
|
12
|
+
export async function withOwnerStateLock(root, callback, options = {}) {
|
|
13
|
+
if (typeof callback !== "function") throw new TypeError("owner-state lock requires a callback");
|
|
14
|
+
const requestedRoot = String(root || "").trim();
|
|
15
|
+
if (!requestedRoot) throw new Error("owner-state lock root is missing");
|
|
16
|
+
const purpose = boundedIdentifier(options.purpose, "state");
|
|
17
|
+
const fileName = boundedFileName(options.fileName, `${purpose}.lock`);
|
|
18
|
+
const label = String(options.label || purpose).replace(/[\r\n\t\u0000-\u001f\u007f]/g, " ").trim().slice(0, 80) || purpose;
|
|
19
|
+
const directory = path.resolve(requestedRoot);
|
|
20
|
+
ensureOwnerOnlyDirectorySync(directory);
|
|
21
|
+
const lockPath = path.join(directory, fileName);
|
|
22
|
+
const timeoutMs = positiveInteger(options.timeoutMs, DEFAULT_WAIT_MS);
|
|
23
|
+
const pollMs = positiveInteger(options.pollMs, DEFAULT_POLL_MS);
|
|
24
|
+
const maxAgeMs = Number.isFinite(Number(options.maxAgeMs)) ? Math.max(1, Number(options.maxAgeMs)) : Number.POSITIVE_INFINITY;
|
|
25
|
+
const deadline = createMonotonicDeadline(timeoutMs);
|
|
26
|
+
const owner = lockOwner(purpose);
|
|
27
|
+
|
|
28
|
+
while (true) {
|
|
29
|
+
try {
|
|
30
|
+
createExclusiveFileSync(lockPath, `${JSON.stringify(owner, null, 2)}\n`, { mode: 0o600 });
|
|
31
|
+
break;
|
|
32
|
+
} catch (error) {
|
|
33
|
+
if (error?.code !== "EEXIST") throw error;
|
|
34
|
+
const inspected = retryTransientMultipleLinksSync(() => readOwnerStateLock(lockPath, purpose));
|
|
35
|
+
if (inspected.kind === "missing") continue;
|
|
36
|
+
if (inspected.kind === "invalid") {
|
|
37
|
+
throw new Error(`${label} lock is malformed; inspect the owner-only state directory`);
|
|
38
|
+
}
|
|
39
|
+
const existing = inspected.owner;
|
|
40
|
+
const identity = inspectProcessInstance(existing, { maxAgeMs });
|
|
41
|
+
if (identity.reclaimable) {
|
|
42
|
+
if (removeOwnedJsonFileSync(lockPath, { token: existing.token, purpose }, { maxBytes: MAX_LOCK_BYTES })) continue;
|
|
43
|
+
}
|
|
44
|
+
if (deadline.expired()) {
|
|
45
|
+
const pid = Number.isInteger(existing.pid) ? `pid ${existing.pid}` : "unknown process";
|
|
46
|
+
throw new Error(`${label} state is busy (${pid}); retry after the current operation finishes`);
|
|
47
|
+
}
|
|
48
|
+
await delay(Math.min(pollMs, Math.max(1, deadline.remainingMs())));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
let result;
|
|
53
|
+
let callbackError;
|
|
54
|
+
try {
|
|
55
|
+
result = await callback();
|
|
56
|
+
} catch (error) {
|
|
57
|
+
callbackError = error;
|
|
58
|
+
}
|
|
59
|
+
let releaseError;
|
|
60
|
+
try {
|
|
61
|
+
const released = removeOwnedJsonFileSync(lockPath, { token: owner.token, purpose }, { maxBytes: MAX_LOCK_BYTES });
|
|
62
|
+
if (!released) releaseError = new Error(`${label} lock changed before release; state may require inspection`);
|
|
63
|
+
} catch (error) {
|
|
64
|
+
releaseError = new Error(`${label} lock release failed; state may require inspection`, { cause: error });
|
|
65
|
+
}
|
|
66
|
+
if (callbackError && releaseError) {
|
|
67
|
+
throw new AggregateError([callbackError, releaseError], `${label} operation failed and lock release was incomplete`);
|
|
68
|
+
}
|
|
69
|
+
if (releaseError) throw releaseError;
|
|
70
|
+
if (callbackError) throw callbackError;
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function lockOwner(purpose) {
|
|
75
|
+
return {
|
|
76
|
+
pid: process.pid,
|
|
77
|
+
token: randomBytes(16).toString("hex"),
|
|
78
|
+
purpose,
|
|
79
|
+
startedAt: new Date().toISOString(),
|
|
80
|
+
processStartedAt: new Date(currentProcessStartTimeMs()).toISOString(),
|
|
81
|
+
entryScript: String(process.argv[1] || "").slice(0, 4096),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function readOwnerStateLock(file, purpose) {
|
|
86
|
+
let text;
|
|
87
|
+
try { text = readBoundedRegularFileSync(file, MAX_LOCK_BYTES, "owner-state lock", { verifyPathIdentity: true, rejectMultipleLinks: true }).toString("utf8"); }
|
|
88
|
+
catch (error) { if (error?.code === "ENOENT") return { kind: "missing" }; throw error; }
|
|
89
|
+
let parsed;
|
|
90
|
+
try { parsed = JSON.parse(text); } catch { return { kind: "invalid" }; }
|
|
91
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return { kind: "invalid" };
|
|
92
|
+
if (!Number.isInteger(parsed.pid) || parsed.pid <= 0) return { kind: "invalid" };
|
|
93
|
+
if (!/^[a-f0-9]{32}$/.test(String(parsed.token || ""))) return { kind: "invalid" };
|
|
94
|
+
if (parsed.purpose !== purpose) return { kind: "invalid" };
|
|
95
|
+
if (!Number.isFinite(Date.parse(String(parsed.startedAt || "")))) return { kind: "invalid" };
|
|
96
|
+
if (!Number.isFinite(Date.parse(String(parsed.processStartedAt || "")))) return { kind: "invalid" };
|
|
97
|
+
return { kind: "owner", owner: parsed };
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function boundedIdentifier(value, fallback) {
|
|
101
|
+
const text = String(value || fallback).toLowerCase().replace(/[^a-z0-9._-]/g, "-").slice(0, 64);
|
|
102
|
+
return text || fallback;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function boundedFileName(value, fallback) {
|
|
106
|
+
const name = path.basename(String(value || fallback));
|
|
107
|
+
if (!/^[a-z0-9][a-z0-9._-]{0,95}\.lock$/.test(name)) throw new Error("owner-state lock filename is invalid");
|
|
108
|
+
return name;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function positiveInteger(value, fallback) {
|
|
112
|
+
const number = Number(value);
|
|
113
|
+
return Number.isFinite(number) && number > 0 ? Math.floor(number) : fallback;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function delay(milliseconds) {
|
|
117
|
+
return new Promise((resolvePromise) => { setTimeout(resolvePromise, milliseconds); });
|
|
118
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import serverMetadata from "../shared/server-metadata.json" with { type: "json" };
|
|
4
|
+
import packageManifest from "../../package.json" with { type: "json" };
|
|
5
|
+
|
|
6
|
+
export const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
|
|
7
|
+
export const packageName = String(packageManifest.name);
|
|
8
|
+
export const packageVersion = String(packageManifest.version);
|
|
9
|
+
export const appName = String(serverMetadata.name);
|
package/src/local/patch.mjs
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { BridgeError } from "./errors.mjs";
|
|
2
|
+
|
|
1
3
|
const BEGIN = "*** Begin Patch";
|
|
2
4
|
const END = "*** End Patch";
|
|
3
5
|
const SECTION_PREFIXES = ["*** Add File: ", "*** Update File: ", "*** Delete File: "];
|
|
@@ -5,10 +7,10 @@ const SECTION_PREFIXES = ["*** Add File: ", "*** Update File: ", "*** Delete Fil
|
|
|
5
7
|
export function parsePatchEnvelope(input) {
|
|
6
8
|
const text = String(input ?? "").replaceAll("\r\n", "\n");
|
|
7
9
|
const lines = text.split("\n");
|
|
8
|
-
if (lines[0] !== BEGIN) throw new
|
|
10
|
+
if (lines[0] !== BEGIN) throw new BridgeError("invalid_request", `patch must start with ${BEGIN}`, { details: { reason: "missing_begin_marker" } });
|
|
9
11
|
const endIndex = lines.lastIndexOf(END);
|
|
10
|
-
if (endIndex < 1) throw new
|
|
11
|
-
if (lines.slice(endIndex + 1).some((line) => line !== "")) throw new
|
|
12
|
+
if (endIndex < 1) throw new BridgeError("invalid_request", `patch must end with ${END}`, { details: { reason: "missing_end_marker" } });
|
|
13
|
+
if (lines.slice(endIndex + 1).some((line) => line !== "")) throw new BridgeError("invalid_request", "unexpected content after patch envelope", { details: { reason: "trailing_content" } });
|
|
12
14
|
|
|
13
15
|
const operations = [];
|
|
14
16
|
let index = 1;
|
|
@@ -25,17 +27,17 @@ export function parsePatchEnvelope(input) {
|
|
|
25
27
|
: header.startsWith(SECTION_PREFIXES[2])
|
|
26
28
|
? "delete"
|
|
27
29
|
: "";
|
|
28
|
-
if (!kind) throw new
|
|
30
|
+
if (!kind) throw new BridgeError("invalid_request", `invalid patch section header at line ${index + 1}`, { details: { reason: "invalid_section_header", line: index + 1 } });
|
|
29
31
|
const prefix = SECTION_PREFIXES[kind === "add" ? 0 : kind === "update" ? 1 : 2];
|
|
30
32
|
const path = header.slice(prefix.length).trim();
|
|
31
|
-
if (!path) throw new
|
|
33
|
+
if (!path) throw new BridgeError("invalid_request", `patch ${kind} path is empty`, { details: { reason: "empty_path", operation: kind } });
|
|
32
34
|
index += 1;
|
|
33
35
|
|
|
34
36
|
if (kind === "add") {
|
|
35
37
|
const contentLines = [];
|
|
36
38
|
while (index < endIndex && !isSectionHeader(lines[index])) {
|
|
37
39
|
const line = lines[index];
|
|
38
|
-
if (!line.startsWith("+")) throw new
|
|
40
|
+
if (!line.startsWith("+")) throw new BridgeError("invalid_request", `added file content must start with + at line ${index + 1}`, { details: { reason: "invalid_add_line", line: index + 1 } });
|
|
39
41
|
contentLines.push(line.slice(1));
|
|
40
42
|
index += 1;
|
|
41
43
|
}
|
|
@@ -45,7 +47,7 @@ export function parsePatchEnvelope(input) {
|
|
|
45
47
|
|
|
46
48
|
if (kind === "delete") {
|
|
47
49
|
if (index < endIndex && !isSectionHeader(lines[index]) && lines[index] !== "") {
|
|
48
|
-
throw new
|
|
50
|
+
throw new BridgeError("invalid_request", `delete section must not contain patch body at line ${index + 1}`, { details: { reason: "unexpected_delete_body", line: index + 1 } });
|
|
49
51
|
}
|
|
50
52
|
operations.push({ kind, path });
|
|
51
53
|
continue;
|
|
@@ -54,7 +56,7 @@ export function parsePatchEnvelope(input) {
|
|
|
54
56
|
let moveTo = "";
|
|
55
57
|
if (lines[index]?.startsWith("*** Move to: ")) {
|
|
56
58
|
moveTo = lines[index].slice("*** Move to: ".length).trim();
|
|
57
|
-
if (!moveTo) throw new
|
|
59
|
+
if (!moveTo) throw new BridgeError("invalid_request", "move destination is empty", { details: { reason: "empty_move_destination" } });
|
|
58
60
|
index += 1;
|
|
59
61
|
}
|
|
60
62
|
const hunks = [];
|
|
@@ -63,38 +65,38 @@ export function parsePatchEnvelope(input) {
|
|
|
63
65
|
index += 1;
|
|
64
66
|
continue;
|
|
65
67
|
}
|
|
66
|
-
if (!lines[index].startsWith("@@")) throw new
|
|
68
|
+
if (!lines[index].startsWith("@@")) throw new BridgeError("invalid_request", `update hunk must start with @@ at line ${index + 1}`, { details: { reason: "missing_hunk_header", line: index + 1 } });
|
|
67
69
|
const headerText = lines[index].slice(2).trim();
|
|
68
70
|
index += 1;
|
|
69
71
|
const hunkLines = [];
|
|
70
72
|
while (index < endIndex && !isSectionHeader(lines[index]) && !lines[index].startsWith("@@")) {
|
|
71
73
|
const line = lines[index];
|
|
72
74
|
if (!line || ![" ", "+", "-"].includes(line[0])) {
|
|
73
|
-
throw new
|
|
75
|
+
throw new BridgeError("invalid_request", `invalid update line prefix at line ${index + 1}`, { details: { reason: "invalid_update_line", line: index + 1 } });
|
|
74
76
|
}
|
|
75
77
|
hunkLines.push({ type: line[0], text: line.slice(1) });
|
|
76
78
|
index += 1;
|
|
77
79
|
}
|
|
78
|
-
if (!hunkLines.length) throw new
|
|
79
|
-
if (!hunkLines.some((line) => line.type !== "+")) throw new
|
|
80
|
+
if (!hunkLines.length) throw new BridgeError("invalid_request", "empty update hunk", { details: { reason: "empty_hunk" } });
|
|
81
|
+
if (!hunkLines.some((line) => line.type !== "+")) throw new BridgeError("invalid_request", "update hunk needs context or removed lines", { details: { reason: "context_free_hunk" } });
|
|
80
82
|
hunks.push({ header: headerText, lines: hunkLines });
|
|
81
83
|
}
|
|
82
|
-
if (!hunks.length) throw new
|
|
84
|
+
if (!hunks.length) throw new BridgeError("invalid_request", "update section contains no hunks", { details: { reason: "missing_hunks" } });
|
|
83
85
|
operations.push({ kind, path, moveTo: moveTo || undefined, hunks });
|
|
84
86
|
}
|
|
85
87
|
|
|
86
|
-
if (!operations.length) throw new
|
|
88
|
+
if (!operations.length) throw new BridgeError("invalid_request", "patch contains no file operations", { details: { reason: "empty_patch" } });
|
|
87
89
|
const touched = new Set();
|
|
88
90
|
for (const operation of operations) {
|
|
89
91
|
for (const path of [operation.path, operation.moveTo].filter(Boolean)) {
|
|
90
|
-
if (touched.has(path)) throw new
|
|
92
|
+
if (touched.has(path)) throw new BridgeError("conflict", "patch touches the same path more than once", { details: { reason: "duplicate_path" } });
|
|
91
93
|
touched.add(path);
|
|
92
94
|
}
|
|
93
95
|
}
|
|
94
96
|
return operations;
|
|
95
97
|
}
|
|
96
98
|
|
|
97
|
-
export function applyUpdateHunks(content, hunks
|
|
99
|
+
export function applyUpdateHunks(content, hunks) {
|
|
98
100
|
const normalized = String(content).replaceAll("\r\n", "\n");
|
|
99
101
|
const trailingNewline = normalized.endsWith("\n");
|
|
100
102
|
let lines = normalized.split("\n");
|
|
@@ -106,10 +108,10 @@ export function applyUpdateHunks(content, hunks, path = "file") {
|
|
|
106
108
|
const newLines = hunk.lines.filter((line) => line.type !== "-").map((line) => line.text);
|
|
107
109
|
const matches = findSequenceMatches(lines, oldLines, searchFrom);
|
|
108
110
|
if (matches.length === 0) {
|
|
109
|
-
throw new
|
|
111
|
+
throw new BridgeError("conflict", "patch context did not match current file state", { details: { reason: "context_not_found", hunk: hunkIndex + 1 } });
|
|
110
112
|
}
|
|
111
113
|
if (matches.length > 1) {
|
|
112
|
-
throw new
|
|
114
|
+
throw new BridgeError("conflict", "patch context matched more than once", { details: { reason: "context_ambiguous", hunk: hunkIndex + 1 } });
|
|
113
115
|
}
|
|
114
116
|
const at = matches[0];
|
|
115
117
|
lines.splice(at, oldLines.length, ...newLines);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { lstat, opendir } from "node:fs/promises";
|
|
2
|
+
|
|
3
|
+
export function isMissingPathError(error) {
|
|
4
|
+
return error?.code === "ENOENT";
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export async function pathEntryIfExists(path, inspect = lstat) {
|
|
8
|
+
try {
|
|
9
|
+
return await inspect(path);
|
|
10
|
+
} catch (error) {
|
|
11
|
+
if (isMissingPathError(error)) return null;
|
|
12
|
+
throw error;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export async function openDirectoryIfExists(path, openDirectory = opendir) {
|
|
17
|
+
try {
|
|
18
|
+
return await openDirectory(path);
|
|
19
|
+
} catch (error) {
|
|
20
|
+
if (isMissingPathError(error)) return null;
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
}
|
package/src/local/policy.mjs
CHANGED
|
@@ -111,6 +111,25 @@ export function normalizePolicy(policy = {}) {
|
|
|
111
111
|
return Object.freeze(normalized);
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
/** @param {PolicyInput} left @param {PolicyInput} right @param {{profile?: string, origin?: string}} [options] */
|
|
115
|
+
export function intersectPolicies(left, right, options = {}) {
|
|
116
|
+
const a = normalizePolicy(left);
|
|
117
|
+
const b = normalizePolicy(right);
|
|
118
|
+
const rank = { off: 0, direct: 1, shell: 2 };
|
|
119
|
+
const execMode = rank[a.execMode] <= rank[b.execMode] ? a.execMode : b.execMode;
|
|
120
|
+
return Object.freeze({
|
|
121
|
+
profile: typeof options.profile === "string" && options.profile ? options.profile : "custom",
|
|
122
|
+
origin: typeof options.origin === "string" && options.origin ? options.origin : "custom",
|
|
123
|
+
revision: Math.max(a.revision, b.revision),
|
|
124
|
+
allowWrite: a.allowWrite && b.allowWrite,
|
|
125
|
+
allowExec: execMode !== "off",
|
|
126
|
+
execMode,
|
|
127
|
+
unrestrictedPaths: a.unrestrictedPaths && b.unrestrictedPaths,
|
|
128
|
+
minimalEnv: a.minimalEnv || b.minimalEnv,
|
|
129
|
+
exposeAbsolutePaths: a.exposeAbsolutePaths && b.exposeAbsolutePaths,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
114
133
|
/** @param {PolicyCapabilities} left @param {PolicyCapabilities} right */
|
|
115
134
|
export function policyCapabilitiesEqual(left, right) {
|
|
116
135
|
return left.allowWrite === right.allowWrite
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const OPERATIONAL_ERROR_CODES = new Set([
|
|
2
|
+
"EACCES",
|
|
3
|
+
"EPERM",
|
|
4
|
+
"EIO",
|
|
5
|
+
"ENOSPC",
|
|
6
|
+
"EDQUOT",
|
|
7
|
+
"ENOMEM",
|
|
8
|
+
"EROFS",
|
|
9
|
+
"EMFILE",
|
|
10
|
+
"ENFILE",
|
|
11
|
+
"EAGAIN",
|
|
12
|
+
"ENOBUFS",
|
|
13
|
+
"EINTR",
|
|
14
|
+
"ESTALE",
|
|
15
|
+
"EBUSY",
|
|
16
|
+
"ETIMEDOUT",
|
|
17
|
+
]);
|
|
18
|
+
|
|
19
|
+
export class PrivateToolchainIntegrityError extends Error {
|
|
20
|
+
constructor(message, options = {}) {
|
|
21
|
+
super(message, options);
|
|
22
|
+
this.name = "PrivateToolchainIntegrityError";
|
|
23
|
+
this.code = "private_toolchain_integrity_invalid";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function privateToolchainIntegrityError(message, cause = undefined) {
|
|
28
|
+
return new PrivateToolchainIntegrityError(message, cause === undefined ? {} : { cause });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function isPrivateToolchainIntegrityError(error) {
|
|
32
|
+
return error instanceof PrivateToolchainIntegrityError
|
|
33
|
+
|| error?.code === "private_toolchain_integrity_invalid";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function throwOperationalOrIntegrity(error, message) {
|
|
37
|
+
if (error instanceof TypeError || error instanceof RangeError || operationalErrorCode(error)) throw error;
|
|
38
|
+
throw privateToolchainIntegrityError(message, error);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function operationalErrorCode(error) {
|
|
42
|
+
const pending = [error];
|
|
43
|
+
const seen = new Set();
|
|
44
|
+
while (pending.length) {
|
|
45
|
+
const current = pending.shift();
|
|
46
|
+
if (!current || typeof current !== "object" || seen.has(current)) continue;
|
|
47
|
+
seen.add(current);
|
|
48
|
+
const code = String(current.code || "");
|
|
49
|
+
if (OPERATIONAL_ERROR_CODES.has(code)) return code;
|
|
50
|
+
if (current.cause) pending.push(current.cause);
|
|
51
|
+
if (Array.isArray(current.errors)) pending.push(...current.errors);
|
|
52
|
+
}
|
|
53
|
+
return "";
|
|
54
|
+
}
|