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,115 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
|
|
4
|
+
const DEFAULT_TIMEOUT_MS = 120_000;
|
|
5
|
+
const DEFAULT_COMPLETION_EXIT_GRACE_MS = 500;
|
|
6
|
+
const DEFAULT_TERMINATION_GRACE_MS = 2_000;
|
|
7
|
+
|
|
8
|
+
export async function runCompletedWranglerCommand(options = {}) {
|
|
9
|
+
const cwd = requiredString(options.cwd, "cwd");
|
|
10
|
+
const wranglerPath = requiredString(options.wranglerPath, "wranglerPath");
|
|
11
|
+
const args = Array.isArray(options.args) ? options.args.map(String) : [];
|
|
12
|
+
const label = requiredString(options.label, "label");
|
|
13
|
+
const completionMarker = requiredString(options.completionMarker, "completionMarker");
|
|
14
|
+
const completionCheck = typeof options.completionCheck === "function" ? options.completionCheck : () => true;
|
|
15
|
+
const timeoutMs = positiveInteger(options.timeoutMs, DEFAULT_TIMEOUT_MS, "timeoutMs");
|
|
16
|
+
const completionExitGraceMs = positiveInteger(options.completionExitGraceMs, DEFAULT_COMPLETION_EXIT_GRACE_MS, "completionExitGraceMs");
|
|
17
|
+
const terminationGraceMs = positiveInteger(options.terminationGraceMs, DEFAULT_TERMINATION_GRACE_MS, "terminationGraceMs");
|
|
18
|
+
const stdout = options.stdout || process.stdout;
|
|
19
|
+
const stderr = options.stderr || process.stderr;
|
|
20
|
+
const env = options.env || process.env;
|
|
21
|
+
const killChild = typeof options.killChild === "function" ? options.killChild : null;
|
|
22
|
+
const child = spawn(process.execPath, [wranglerPath, ...args], {
|
|
23
|
+
cwd,
|
|
24
|
+
env,
|
|
25
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
26
|
+
windowsHide: true,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
await new Promise((resolvePromise, rejectPromise) => {
|
|
30
|
+
let completionObserved = false;
|
|
31
|
+
let cleanupRequested = false;
|
|
32
|
+
let forceKillUsed = false;
|
|
33
|
+
let hardTimedOut = false;
|
|
34
|
+
let outputTail = "";
|
|
35
|
+
let completionTimer;
|
|
36
|
+
let forceTimer;
|
|
37
|
+
let settled = false;
|
|
38
|
+
|
|
39
|
+
const hardTimer = setTimeout(() => {
|
|
40
|
+
hardTimedOut = true;
|
|
41
|
+
requestTermination();
|
|
42
|
+
}, timeoutMs);
|
|
43
|
+
const clearTimers = () => {
|
|
44
|
+
clearTimeout(hardTimer);
|
|
45
|
+
clearTimeout(completionTimer);
|
|
46
|
+
clearTimeout(forceTimer);
|
|
47
|
+
};
|
|
48
|
+
const finish = (error) => {
|
|
49
|
+
if (settled) return;
|
|
50
|
+
settled = true;
|
|
51
|
+
clearTimers();
|
|
52
|
+
if (error) rejectPromise(error);
|
|
53
|
+
else resolvePromise();
|
|
54
|
+
};
|
|
55
|
+
const requestTermination = () => {
|
|
56
|
+
if (cleanupRequested) return;
|
|
57
|
+
cleanupRequested = true;
|
|
58
|
+
try {
|
|
59
|
+
if (killChild) killChild(child, "SIGTERM");
|
|
60
|
+
else child.kill("SIGTERM");
|
|
61
|
+
}
|
|
62
|
+
catch (error) { finish(new Error(`${label} could not request graceful cleanup`, { cause: error })); return; }
|
|
63
|
+
forceTimer = setTimeout(() => {
|
|
64
|
+
if (child.exitCode !== null || child.signalCode !== null) return;
|
|
65
|
+
forceKillUsed = true;
|
|
66
|
+
try {
|
|
67
|
+
const killed = killChild ? killChild(child, "SIGKILL") : child.kill("SIGKILL");
|
|
68
|
+
if (killed !== true) finish(new Error(`${label} could not force cleanup`));
|
|
69
|
+
} catch (error) { finish(new Error(`${label} could not force cleanup`, { cause: error })); }
|
|
70
|
+
}, terminationGraceMs);
|
|
71
|
+
};
|
|
72
|
+
const observeOutput = (destination, chunk) => {
|
|
73
|
+
destination.write(chunk);
|
|
74
|
+
outputTail = `${outputTail}${String(chunk)}`.slice(-4096);
|
|
75
|
+
if (completionObserved || !outputTail.includes(completionMarker)) return;
|
|
76
|
+
completionObserved = true;
|
|
77
|
+
completionTimer = setTimeout(() => {
|
|
78
|
+
if (child.exitCode === null && child.signalCode === null) requestTermination();
|
|
79
|
+
}, completionExitGraceMs);
|
|
80
|
+
};
|
|
81
|
+
const completionIsValid = () => {
|
|
82
|
+
try { return completionCheck() === true; }
|
|
83
|
+
catch (error) { finish(error); return false; }
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
child.stdout.on("data", (chunk) => observeOutput(stdout, chunk));
|
|
87
|
+
child.stderr.on("data", (chunk) => observeOutput(stderr, chunk));
|
|
88
|
+
child.once("error", finish);
|
|
89
|
+
child.once("close", (code, signal) => {
|
|
90
|
+
if (hardTimedOut) { finish(new Error(`${label} timed out after ${timeoutMs}ms`)); return; }
|
|
91
|
+
if (forceKillUsed) { finish(new Error(`${label} completed but did not terminate after graceful cleanup`)); return; }
|
|
92
|
+
if (code === 0 && completionIsValid()) { finish(); return; }
|
|
93
|
+
if (cleanupRequested && completionObserved && signal === "SIGTERM" && completionIsValid()) {
|
|
94
|
+
stderr.write(`${label} completed but did not exit; terminated the completed CLI after a bounded grace period\n`);
|
|
95
|
+
finish();
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (settled) return;
|
|
99
|
+
const status = signal ? `signal ${signal}` : `exit code ${code ?? "unknown"}`;
|
|
100
|
+
finish(new Error(`${label} failed with ${status}`));
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function requiredString(value, name) {
|
|
106
|
+
const text = String(value || "");
|
|
107
|
+
if (!text) throw new TypeError(`${name} must be a non-empty string`);
|
|
108
|
+
return text;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function positiveInteger(value, fallback, name) {
|
|
112
|
+
if (value === undefined) return fallback;
|
|
113
|
+
if (!Number.isSafeInteger(value) || value <= 0) throw new TypeError(`${name} must be a positive integer`);
|
|
114
|
+
return value;
|
|
115
|
+
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import accessContract from "../shared/access-contract.json" with { type: "json" };
|
|
2
2
|
import { BridgeError } from "./errors.mjs";
|
|
3
|
+
import { buildAuthorityContext } from "./authority-context.mjs";
|
|
3
4
|
import { policyProfile, toolNamesForPolicy, assertToolAllowed } from "./policy.mjs";
|
|
4
5
|
|
|
5
6
|
export const ACCOUNT_ACCESS_REVISION = Number(accessContract.revision);
|
|
7
|
+
const OWNER_ONLY_TOOLS = new Set((accessContract.ownerOnlyTools || []).map(String));
|
|
6
8
|
const ACCOUNT_ROLE_ENTRIES = Object.entries(accessContract.roles)
|
|
7
9
|
.map(([name, value]) => [name, Object.freeze({ ...value })]);
|
|
8
10
|
const ACCOUNT_ROLE_BY_NAME = new Map(ACCOUNT_ROLE_ENTRIES);
|
|
@@ -22,16 +24,26 @@ export function accountRolePolicy(role) {
|
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
export function accountRoleToolNames(role) {
|
|
25
|
-
|
|
27
|
+
const normalized = normalizeAccountRole(role);
|
|
28
|
+
const names = toolNamesForPolicy(accountRolePolicy(normalized));
|
|
29
|
+
return normalized === OWNER_ACCOUNT_ROLE ? names : names.filter((name) => !OWNER_ONLY_TOOLS.has(name));
|
|
26
30
|
}
|
|
27
31
|
|
|
28
32
|
export class AccountAccessGate {
|
|
29
33
|
assert(role, tool) {
|
|
30
34
|
const normalized = normalizeAccountRole(role);
|
|
35
|
+
if (normalized !== OWNER_ACCOUNT_ROLE && OWNER_ONLY_TOOLS.has(String(tool || ""))) {
|
|
36
|
+
throw new BridgeError("authorization_denied", `tool is reserved for the owner account: ${String(tool || "")}`);
|
|
37
|
+
}
|
|
31
38
|
assertToolAllowed(accountRolePolicy(normalized), tool);
|
|
32
39
|
return normalized;
|
|
33
40
|
}
|
|
34
41
|
|
|
42
|
+
authority(authorization, daemonPolicy, origin = "relay") {
|
|
43
|
+
const role = origin === "relay" ? normalizeAccountRole(authorization?.role) : "owner";
|
|
44
|
+
return buildAuthorityContext({ authorization: { ...authorization, role }, daemonPolicy, origin });
|
|
45
|
+
}
|
|
46
|
+
|
|
35
47
|
names(role) {
|
|
36
48
|
return accountRoleToolNames(role);
|
|
37
49
|
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { BridgeError } from "./errors.mjs";
|
|
2
|
+
|
|
3
|
+
const MAX_ADMIN_RESPONSE_BYTES = 1024 * 1024;
|
|
4
|
+
const MAX_ADMIN_ERROR_CHARS = 2_000;
|
|
5
|
+
|
|
6
|
+
export function isReadOnlyAdminMethod(method) { return method === "GET" || method === "HEAD"; }
|
|
7
|
+
|
|
8
|
+
export async function validateAdminResponseStatus(response, method, pathname) {
|
|
9
|
+
const expectedStatus = method === "DELETE" && pathname === "/admin/accounts" ? 204
|
|
10
|
+
: method === "POST" && pathname === "/admin/accounts" ? 201 : 200;
|
|
11
|
+
if (!response.ok || response.status === expectedStatus) return;
|
|
12
|
+
await cancelResponseBody(response.body);
|
|
13
|
+
throw adminResponseProtocolError(response, method, "account administration response used an unexpected success status");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function boundedRemoteAdminMessage(payload, status) {
|
|
17
|
+
const fallback = `account administration failed (${status})`;
|
|
18
|
+
const candidate = typeof payload?.message === "string" ? payload.message : typeof payload?.error === "string" ? payload.error : fallback;
|
|
19
|
+
const normalized = candidate.replace(/[\u0000-\u001f\u007f\u200B-\u200F\u202A-\u202E\u2066-\u2069\uFEFF]/g, " ").replace(/\s+/g, " ").trim();
|
|
20
|
+
return (normalized || fallback).slice(0, MAX_ADMIN_ERROR_CHARS);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function readAdminJsonResponse(response, method) {
|
|
24
|
+
const declared = Number(response.headers.get("content-length") || "0");
|
|
25
|
+
if (Number.isFinite(declared) && declared > MAX_ADMIN_RESPONSE_BYTES) {
|
|
26
|
+
await cancelResponseBody(response.body);
|
|
27
|
+
throw adminResponseProtocolError(response, method, "account administration response exceeded the size limit");
|
|
28
|
+
}
|
|
29
|
+
if (!response.body) {
|
|
30
|
+
if (response.ok) throw adminResponseProtocolError(response, method, "account administration response was empty");
|
|
31
|
+
return {};
|
|
32
|
+
}
|
|
33
|
+
const reader = response.body.getReader();
|
|
34
|
+
const chunks = [];
|
|
35
|
+
let bytes = 0;
|
|
36
|
+
try {
|
|
37
|
+
for (;;) {
|
|
38
|
+
const { done, value } = await reader.read();
|
|
39
|
+
if (done) break;
|
|
40
|
+
if (!value) continue;
|
|
41
|
+
bytes += value.byteLength;
|
|
42
|
+
if (bytes > MAX_ADMIN_RESPONSE_BYTES) {
|
|
43
|
+
await cancelReader(reader);
|
|
44
|
+
throw adminResponseProtocolError(response, method, "account administration response exceeded the size limit");
|
|
45
|
+
}
|
|
46
|
+
chunks.push(value);
|
|
47
|
+
}
|
|
48
|
+
} finally {
|
|
49
|
+
reader.releaseLock();
|
|
50
|
+
}
|
|
51
|
+
let payload;
|
|
52
|
+
try {
|
|
53
|
+
const text = new TextDecoder("utf-8", { fatal: true }).decode(concatBytes(chunks, bytes));
|
|
54
|
+
payload = JSON.parse(text);
|
|
55
|
+
} catch (cause) {
|
|
56
|
+
if (response.ok) throw adminResponseProtocolError(response, method, "account administration response was not valid JSON", cause);
|
|
57
|
+
return {};
|
|
58
|
+
}
|
|
59
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
|
|
60
|
+
if (response.ok) throw adminResponseProtocolError(response, method, "account administration response was not a JSON object");
|
|
61
|
+
return {};
|
|
62
|
+
}
|
|
63
|
+
return payload;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function adminResponseProtocolError(response, method, message, cause) {
|
|
67
|
+
const mutation = response.ok && !isReadOnlyAdminMethod(method);
|
|
68
|
+
return new BridgeError("protocol_error", message, {
|
|
69
|
+
...(cause ? { cause } : {}),
|
|
70
|
+
...(mutation ? { retryable: false, details: { request_delivery: "sent", effect_settlement: "unknown" } } : {}),
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function cancelResponseBody(body) {
|
|
75
|
+
if (!body) return;
|
|
76
|
+
const reader = body.getReader();
|
|
77
|
+
try { await cancelReader(reader); } finally { reader.releaseLock(); }
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async function cancelReader(reader) {
|
|
81
|
+
try { await reader.cancel("response size limit reached"); } catch { /* cleanup only */ }
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function concatBytes(chunks, bytes) {
|
|
85
|
+
const output = new Uint8Array(bytes);
|
|
86
|
+
let offset = 0;
|
|
87
|
+
for (const chunk of chunks) {
|
|
88
|
+
output.set(chunk, offset);
|
|
89
|
+
offset += chunk.byteLength;
|
|
90
|
+
}
|
|
91
|
+
return output;
|
|
92
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { createHash,
|
|
1
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
2
2
|
import { ADMIN_AUTH_SCHEME, adminAuthTranscript } from "../shared/admin-auth.mjs";
|
|
3
3
|
import { ACCOUNT_ROLES, normalizeAccountRole } from "./account-access.mjs";
|
|
4
|
+
import { boundedRemoteAdminMessage, isReadOnlyAdminMethod, readAdminJsonResponse, validateAdminResponseStatus } from "./account-admin-response.mjs";
|
|
5
|
+
import { encodeDeviceSessionCertificate, signWithDeviceSessionIdentity, validateDeviceSessionIdentity } from "./device-identity.mjs";
|
|
4
6
|
import { BridgeError } from "./errors.mjs";
|
|
5
7
|
|
|
6
8
|
const REQUEST_TIMEOUT_MS = 15_000;
|
|
@@ -10,15 +12,18 @@ export function generateAccountPassword() {
|
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
export class AccountAdminClient {
|
|
13
|
-
constructor({ workerUrl,
|
|
15
|
+
constructor({ workerUrl, sessionIdentity, fetchImpl = fetch }) {
|
|
14
16
|
this.workerUrl = normalizeWorkerUrl(workerUrl);
|
|
15
|
-
|
|
16
|
-
this.adminSecret = adminSecret;
|
|
17
|
+
this.sessionIdentity = validateDeviceSessionIdentity(sessionIdentity);
|
|
17
18
|
this.fetchImpl = fetchImpl;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
list() {
|
|
21
|
-
|
|
21
|
+
list() { return this.request("GET", "/admin/accounts"); }
|
|
22
|
+
listClients() { return this.request("GET", "/admin/clients"); }
|
|
23
|
+
|
|
24
|
+
removeClient({ clientId }) {
|
|
25
|
+
if (!/^mcp_client_[A-Za-z0-9_-]{43}$/.test(String(clientId || ""))) throw new BridgeError("invalid_request", "OAuth client id is invalid");
|
|
26
|
+
return this.request("DELETE", "/admin/clients", { client_id: clientId });
|
|
22
27
|
}
|
|
23
28
|
|
|
24
29
|
create({ name, role, password, displayName = "" }) {
|
|
@@ -61,7 +66,7 @@ export class AccountAdminClient {
|
|
|
61
66
|
async request(method, pathname, body) {
|
|
62
67
|
const serializedBody = body === undefined ? "" : JSON.stringify(body);
|
|
63
68
|
const headers = accountAdminRequestHeaders({
|
|
64
|
-
|
|
69
|
+
sessionIdentity: this.sessionIdentity,
|
|
65
70
|
origin: this.workerUrl,
|
|
66
71
|
method,
|
|
67
72
|
pathname,
|
|
@@ -74,40 +79,68 @@ export class AccountAdminClient {
|
|
|
74
79
|
...(body === undefined ? {} : { "content-type": "application/json" }),
|
|
75
80
|
},
|
|
76
81
|
body: body === undefined ? undefined : serializedBody,
|
|
82
|
+
redirect: "error",
|
|
77
83
|
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
78
84
|
cache: "no-store",
|
|
79
85
|
}).catch((error) => {
|
|
80
|
-
|
|
86
|
+
const retryable = isReadOnlyAdminMethod(method);
|
|
87
|
+
throw new BridgeError("network_error", "account administration request failed", {
|
|
88
|
+
cause: error,
|
|
89
|
+
retryable,
|
|
90
|
+
...(retryable ? {} : { details: { request_delivery: "unknown", effect_settlement: "unknown" } }),
|
|
91
|
+
});
|
|
81
92
|
});
|
|
93
|
+
await validateAdminResponseStatus(response, method, pathname);
|
|
82
94
|
if (response.status === 204) return { removed: true };
|
|
83
|
-
const payload = await response
|
|
95
|
+
const payload = await readAdminJsonResponse(response, method);
|
|
84
96
|
if (!response.ok) {
|
|
85
|
-
const message =
|
|
97
|
+
const message = boundedRemoteAdminMessage(payload, response.status);
|
|
98
|
+
if (response.status >= 500) {
|
|
99
|
+
const retryable = isReadOnlyAdminMethod(method);
|
|
100
|
+
throw new BridgeError("unavailable", message, {
|
|
101
|
+
retryable,
|
|
102
|
+
...(retryable ? {} : { details: { request_delivery: "sent", effect_settlement: "unknown" } }),
|
|
103
|
+
});
|
|
104
|
+
}
|
|
86
105
|
throw new BridgeError(response.status === 404 ? "not_found" : response.status === 409 ? "conflict" : response.status === 401 ? "authentication_failed" : "invalid_request", message);
|
|
87
106
|
}
|
|
88
107
|
return payload;
|
|
89
108
|
}
|
|
90
109
|
}
|
|
91
110
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
111
|
+
export function accountAdminRequestHeaders({
|
|
112
|
+
sessionIdentity,
|
|
113
|
+
origin,
|
|
114
|
+
method,
|
|
115
|
+
pathname,
|
|
116
|
+
body = "",
|
|
117
|
+
now = Date.now(),
|
|
118
|
+
nonce = randomBytes(24).toString("base64url"),
|
|
119
|
+
}) {
|
|
120
|
+
validateDeviceSessionIdentity(sessionIdentity, now);
|
|
95
121
|
const issuedAt = Math.floor(Number(now) / 1000);
|
|
96
122
|
const bodyHash = createHash("sha256").update(String(body)).digest("hex");
|
|
97
|
-
const transcript = adminAuthTranscript({
|
|
98
|
-
|
|
123
|
+
const transcript = adminAuthTranscript({
|
|
124
|
+
origin,
|
|
125
|
+
method: String(method).toUpperCase(),
|
|
126
|
+
pathname,
|
|
127
|
+
bodyHash,
|
|
128
|
+
keyId: sessionIdentity.keyId,
|
|
129
|
+
issuedAt,
|
|
130
|
+
nonce,
|
|
131
|
+
});
|
|
99
132
|
return {
|
|
100
133
|
"X-Bridge-Admin-Scheme": ADMIN_AUTH_SCHEME,
|
|
101
134
|
"X-Bridge-Admin-Time": String(issuedAt),
|
|
102
135
|
"X-Bridge-Admin-Nonce": nonce,
|
|
103
136
|
"X-Bridge-Admin-Body-SHA256": bodyHash,
|
|
104
|
-
"X-Bridge-Admin-
|
|
137
|
+
"X-Bridge-Admin-Key": sessionIdentity.keyId,
|
|
138
|
+
"X-Bridge-Admin-Signature": signWithDeviceSessionIdentity(sessionIdentity, transcript),
|
|
139
|
+
"X-Bridge-Device-Certificate": encodeDeviceSessionCertificate(sessionIdentity),
|
|
105
140
|
};
|
|
106
141
|
}
|
|
107
142
|
|
|
108
|
-
export function accountRoleNames() {
|
|
109
|
-
return Object.keys(ACCOUNT_ROLES);
|
|
110
|
-
}
|
|
143
|
+
export function accountRoleNames() { return Object.keys(ACCOUNT_ROLES); }
|
|
111
144
|
|
|
112
145
|
function normalizeWorkerUrl(value) {
|
|
113
146
|
const url = new URL(String(value || ""));
|
|
@@ -36,6 +36,9 @@ import { createHash } from "node:crypto";
|
|
|
36
36
|
*/
|
|
37
37
|
/**
|
|
38
38
|
* @typedef {object} ProjectionState
|
|
39
|
+
* @property {string} target
|
|
40
|
+
* @property {string} targetDir
|
|
41
|
+
* @property {string} scopeRoot
|
|
39
42
|
* @property {string[]} configFiles
|
|
40
43
|
* @property {InstructionItem | null} builtinInstructions
|
|
41
44
|
* @property {InstructionItem | null} automaticProjectContext
|
|
@@ -47,18 +50,34 @@ import { createHash } from "node:crypto";
|
|
|
47
50
|
/** @param {ProjectionState} state @param {SkillSummary[]} skills */
|
|
48
51
|
export function capabilityFingerprint(state, skills) {
|
|
49
52
|
return sha256(JSON.stringify({
|
|
50
|
-
|
|
53
|
+
target: state.target,
|
|
54
|
+
target_dir: state.targetDir,
|
|
55
|
+
scope_root: state.scopeRoot,
|
|
56
|
+
configs: [...state.configFiles],
|
|
51
57
|
instructions: [
|
|
52
|
-
state.builtinInstructions
|
|
53
|
-
state.automaticProjectContext
|
|
54
|
-
state.modelInstructions
|
|
55
|
-
...state.instructions.map(
|
|
58
|
+
instructionFingerprintItem(state.builtinInstructions),
|
|
59
|
+
instructionFingerprintItem(state.automaticProjectContext),
|
|
60
|
+
instructionFingerprintItem(state.modelInstructions),
|
|
61
|
+
...state.instructions.map(instructionFingerprintItem),
|
|
56
62
|
],
|
|
57
|
-
skills: skills
|
|
58
|
-
|
|
63
|
+
skills: skills
|
|
64
|
+
.map((skill) => [skill.id, skill.name, skill.entrypoint, skill.sourceRoot, skill.sha256])
|
|
65
|
+
.sort((left, right) => String(left[0]).localeCompare(String(right[0]))),
|
|
66
|
+
commands: [...state.commands.values()]
|
|
67
|
+
.map((command) => [
|
|
68
|
+
command.name, command.description, command.argv, command.cwd, command.timeoutSeconds,
|
|
69
|
+
command.allowExtraArgs, command.source, command.sourceType || "", command.script || "",
|
|
70
|
+
])
|
|
71
|
+
.sort((left, right) => String(left[0]).localeCompare(String(right[0]))),
|
|
59
72
|
}));
|
|
60
73
|
}
|
|
61
74
|
|
|
75
|
+
/** @param {InstructionItem | null | undefined} item */
|
|
76
|
+
function instructionFingerprintItem(item) {
|
|
77
|
+
if (!item) return null;
|
|
78
|
+
return [item.source || "", item.path || "", item.scope, item.sha256, item.precedence, item.bytes];
|
|
79
|
+
}
|
|
80
|
+
|
|
62
81
|
/** @param {SkillSummary} skill @param {DisplayPath} displayPath */
|
|
63
82
|
export function publicSkill(skill, displayPath) {
|
|
64
83
|
return {
|