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.
Files changed (473) hide show
  1. package/CHANGELOG.md +1142 -0
  2. package/CONTRIBUTING.md +23 -25
  3. package/GOVERNANCE.md +2 -2
  4. package/README.md +58 -20
  5. package/SECURITY.md +161 -120
  6. package/SUPPORT.md +1 -1
  7. package/browser-extension/broker-auth.js +83 -0
  8. package/browser-extension/broker-liveness.js +35 -0
  9. package/browser-extension/browser-error-boundary.js +96 -0
  10. package/browser-extension/browser-operations.js +1456 -101
  11. package/browser-extension/devtools-input.js +195 -34
  12. package/browser-extension/devtools-observation.js +429 -0
  13. package/browser-extension/devtools-session.js +48 -0
  14. package/browser-extension/manifest.json +4 -3
  15. package/browser-extension/page-automation.js +578 -118
  16. package/browser-extension/pairing-bootstrap.js +42 -0
  17. package/browser-extension/pairing.js +28 -12
  18. package/browser-extension/service-worker.js +126 -106
  19. package/docs/AGENT_CONTEXT.md +13 -10
  20. package/docs/ARCHITECTURE.md +159 -67
  21. package/docs/AUDIT.md +1302 -4
  22. package/docs/CLIENTS.md +19 -6
  23. package/docs/COMPUTER_USE.md +297 -0
  24. package/docs/ENGINEERING.md +72 -13
  25. package/docs/GETTING_STARTED.md +18 -20
  26. package/docs/LOCAL_AUTHORIZATION.md +115 -72
  27. package/docs/LOCAL_AUTOMATION.md +27 -21
  28. package/docs/LOGGING.md +40 -19
  29. package/docs/MANAGED_JOBS.md +37 -34
  30. package/docs/MULTI_ACCOUNT.md +98 -37
  31. package/docs/OPERATIONS.md +145 -51
  32. package/docs/OVERVIEW.md +14 -11
  33. package/docs/POLICY_REFERENCE.md +71 -3
  34. package/docs/PRIVACY.md +41 -2
  35. package/docs/PROJECT_STANDARDS.md +29 -6
  36. package/docs/RELEASING.md +238 -64
  37. package/docs/TESTING.md +150 -39
  38. package/docs/THREAT_MODEL.md +164 -67
  39. package/docs/TOOL_REFERENCE.md +653 -60
  40. package/docs/UPGRADING.md +78 -18
  41. package/native/macos/MachineBridgeBackgroundInput.swift +1051 -0
  42. package/native/macos/MachineBridgeBackgroundInputSmokeFixture.swift +295 -0
  43. package/native/macos/MachineBridgeTrustBroker.swift +233 -0
  44. package/package.json +94 -16
  45. package/scripts/accepted-candidate-tarball.mjs +77 -0
  46. package/scripts/candidate-runtime-store.mjs +93 -0
  47. package/scripts/check-plan.mjs +73 -3
  48. package/scripts/check-runner.mjs +129 -17
  49. package/scripts/commit-message-check.mjs +5 -2
  50. package/scripts/consumer-package-security.mjs +293 -0
  51. package/scripts/coverage-check.mjs +251 -15
  52. package/scripts/coverage-generation.mjs +41 -0
  53. package/scripts/coverage-range-merge.mjs +41 -0
  54. package/scripts/foreground-daemon-recovery.mjs +88 -0
  55. package/scripts/generate-policy-reference.mjs +28 -5
  56. package/scripts/generate-tool-reference.mjs +1 -1
  57. package/scripts/generate-worker-types.mjs +21 -11
  58. package/scripts/github-backlog.mjs +11 -10
  59. package/scripts/github-push.mjs +62 -16
  60. package/scripts/github-release-asset.mjs +58 -0
  61. package/scripts/github-release.mjs +241 -132
  62. package/scripts/global-package-installation.mjs +68 -0
  63. package/scripts/hardened-npm-session.mjs +42 -0
  64. package/scripts/install-published-prerelease.mjs +198 -0
  65. package/scripts/local-release-acceptance.mjs +103 -45
  66. package/scripts/macos-background-input-smoke.mjs +515 -0
  67. package/scripts/network-retry.mjs +8 -1
  68. package/scripts/npm-global-prefix.mjs +27 -0
  69. package/scripts/npm-publication-policy.mjs +17 -0
  70. package/scripts/official-mcp-conformance.mjs +267 -0
  71. package/scripts/persistent-activation-process.mjs +101 -0
  72. package/scripts/prepare-pinned-npm.mjs +12 -69
  73. package/scripts/prerelease-activation.mjs +160 -0
  74. package/scripts/privacy-check.mjs +14 -6
  75. package/scripts/promotion-digest.mjs +128 -0
  76. package/scripts/publish-npm.mjs +260 -0
  77. package/scripts/published-release.mjs +132 -0
  78. package/scripts/release-acceptance.mjs +62 -54
  79. package/scripts/release-browser-extension-store.mjs +172 -0
  80. package/scripts/release-candidate-manifest.mjs +52 -0
  81. package/scripts/release-channel.mjs +106 -0
  82. package/scripts/release-diagnostic.mjs +41 -0
  83. package/scripts/release-impact-check.mjs +12 -22
  84. package/scripts/release-oauth-canary-core.mjs +325 -0
  85. package/scripts/release-oauth-canary-evidence.mjs +100 -0
  86. package/scripts/release-oauth-canary.mjs +127 -0
  87. package/scripts/release-publication-guard.mjs +67 -0
  88. package/scripts/release-soak.mjs +284 -0
  89. package/scripts/release-state.mjs +1 -1
  90. package/scripts/run-checks.mjs +44 -7
  91. package/scripts/run-worker-dry-run.mjs +21 -0
  92. package/scripts/sarif-security-gate.mjs +2 -1
  93. package/scripts/sbom-check.mjs +106 -0
  94. package/scripts/start-release-candidate.mjs +267 -44
  95. package/scripts/syntax-check.mjs +36 -14
  96. package/scripts/verification-generation-guard.mjs +15 -0
  97. package/scripts/verification-idle-sleep-guard.mjs +37 -0
  98. package/scripts/verification-state.mjs +108 -0
  99. package/scripts/wrangler-command-lifecycle.mjs +115 -0
  100. package/src/local/account-access.mjs +13 -1
  101. package/src/local/account-admin-response.mjs +92 -0
  102. package/src/local/account-admin.mjs +52 -19
  103. package/src/local/agent-context-projection.mjs +26 -7
  104. package/src/local/agent-context.mjs +88 -49
  105. package/src/local/agent-skill-discovery.mjs +16 -5
  106. package/src/local/app-automation-macos-jxa.mjs +350 -0
  107. package/src/local/app-automation.mjs +873 -163
  108. package/src/local/application-capability-projection.mjs +24 -0
  109. package/src/local/authority-context.mjs +106 -0
  110. package/src/local/autostart-log-maintenance.mjs +36 -0
  111. package/src/local/browser-bridge-http.mjs +5 -3
  112. package/src/local/browser-bridge.mjs +109 -31
  113. package/src/local/browser-broker-auth-http.mjs +67 -0
  114. package/src/local/browser-broker-auth.mjs +98 -0
  115. package/src/local/browser-broker-routes.mjs +63 -20
  116. package/src/local/browser-broker-server.mjs +17 -7
  117. package/src/local/browser-command.mjs +79 -30
  118. package/src/local/browser-computer-observation-service.mjs +266 -0
  119. package/src/local/browser-extension-identity.mjs +50 -0
  120. package/src/local/browser-extension-path.mjs +22 -0
  121. package/src/local/browser-extension-protocol.mjs +50 -11
  122. package/src/local/browser-operation-service.mjs +147 -117
  123. package/src/local/browser-pairing-grant.mjs +109 -0
  124. package/src/local/browser-pairing-http.mjs +36 -0
  125. package/src/local/browser-pairing-launch.mjs +58 -0
  126. package/src/local/browser-pairing-store.mjs +85 -48
  127. package/src/local/browser-request-registry.mjs +40 -14
  128. package/src/local/browser-request-settlement.mjs +78 -0
  129. package/src/local/browser-resource-input.mjs +74 -0
  130. package/src/local/browser-trusted-input-health.mjs +63 -0
  131. package/src/local/call-authority.mjs +21 -0
  132. package/src/local/call-capacity.mjs +45 -0
  133. package/src/local/call-registry-drain.mjs +54 -0
  134. package/src/local/call-registry.mjs +30 -15
  135. package/src/local/capability-observer.mjs +5 -0
  136. package/src/local/capability-ranking.mjs +3 -2
  137. package/src/local/child-process-settlement.mjs +132 -0
  138. package/src/local/cli-account-admin.mjs +40 -6
  139. package/src/local/cli-activate.mjs +162 -0
  140. package/src/local/cli-local-admin.mjs +20 -45
  141. package/src/local/cli-options.mjs +12 -13
  142. package/src/local/cli-ready-output.mjs +52 -0
  143. package/src/local/cli-service.mjs +91 -11
  144. package/src/local/cli.mjs +232 -150
  145. package/src/local/computer-use-application-observation.mjs +224 -0
  146. package/src/local/computer-use-arguments.mjs +270 -0
  147. package/src/local/computer-use-deadline.mjs +50 -0
  148. package/src/local/computer-use-dispatch-settlement.mjs +40 -0
  149. package/src/local/computer-use-expectation.mjs +171 -0
  150. package/src/local/computer-use-observation.mjs +769 -0
  151. package/src/local/computer-use-recovery.mjs +82 -0
  152. package/src/local/computer-use-result-budget.mjs +145 -0
  153. package/src/local/computer-use-snapshot-store.mjs +67 -0
  154. package/src/local/computer-use.mjs +2255 -0
  155. package/src/local/daemon-http-relay-auth.mjs +26 -0
  156. package/src/local/daemon-http-relay-connection.mjs +298 -0
  157. package/src/local/daemon-http-relay-request.mjs +64 -0
  158. package/src/local/daemon-http-relay-sequence.mjs +49 -0
  159. package/src/local/daemon-process.mjs +40 -7
  160. package/src/local/delegated-process-sandbox.mjs +148 -0
  161. package/src/local/device-identity.mjs +156 -49
  162. package/src/local/device-root-provider.mjs +81 -0
  163. package/src/local/directory-metadata.mjs +47 -0
  164. package/src/local/doctor-reporting.mjs +23 -0
  165. package/src/local/durable-process-spec.mjs +80 -0
  166. package/src/local/errors.mjs +25 -15
  167. package/src/local/exclusive-file.mjs +74 -26
  168. package/src/local/execution-limits.mjs +9 -0
  169. package/src/local/execution-routing.mjs +276 -0
  170. package/src/local/execution-surface.mjs +23 -0
  171. package/src/local/file-mutation-coordinator.mjs +47 -0
  172. package/src/local/file-snapshot-preservation.mjs +24 -0
  173. package/src/local/filesystem-identity.mjs +54 -0
  174. package/src/local/fixed-process-environment.mjs +21 -0
  175. package/src/local/full-access-test.mjs +31 -13
  176. package/src/local/git-commit.mjs +69 -0
  177. package/src/local/git-config-safety.mjs +55 -0
  178. package/src/local/git-log-parser.mjs +41 -0
  179. package/src/local/git-metadata-boundary.mjs +77 -0
  180. package/src/local/git-metadata-tree-safety.mjs +59 -0
  181. package/src/local/git-operation-state.mjs +19 -0
  182. package/src/local/git-service.mjs +165 -30
  183. package/src/local/hardened-npm-download-timeout.mjs +46 -0
  184. package/src/local/hardened-npm-download.mjs +109 -0
  185. package/src/local/hardened-npm-extract.mjs +20 -0
  186. package/src/local/hardened-npm-verification.mjs +104 -0
  187. package/src/local/hardened-npm.mjs +199 -0
  188. package/src/local/job-runner.mjs +244 -89
  189. package/src/local/lifecycle.mjs +6 -0
  190. package/src/local/log.mjs +19 -45
  191. package/src/local/macos-background-input.mjs +398 -0
  192. package/src/local/macos-idle-sleep-assertion.mjs +65 -0
  193. package/src/local/macos-trust-broker.mjs +404 -0
  194. package/src/local/managed-job-cancellation.mjs +42 -0
  195. package/src/local/managed-job-capacity.mjs +16 -0
  196. package/src/local/managed-job-directory-generation.mjs +60 -0
  197. package/src/local/managed-job-directory.mjs +75 -0
  198. package/src/local/managed-job-durable-process.mjs +49 -0
  199. package/src/local/managed-job-lock.mjs +46 -14
  200. package/src/local/managed-job-plan.mjs +38 -14
  201. package/src/local/managed-job-projection.mjs +23 -15
  202. package/src/local/managed-job-retention.mjs +128 -0
  203. package/src/local/managed-job-runner-claim.mjs +70 -0
  204. package/src/local/managed-job-runner.mjs +35 -10
  205. package/src/local/managed-job-storage.mjs +22 -6
  206. package/src/local/managed-job-terminal-maintenance.mjs +40 -0
  207. package/src/local/managed-job-terminal.mjs +150 -0
  208. package/src/local/managed-jobs.mjs +424 -287
  209. package/src/local/npm-cli.mjs +42 -0
  210. package/src/local/npm-environment.mjs +37 -0
  211. package/src/local/operation-authorization.mjs +68 -324
  212. package/src/local/operation-risk.mjs +51 -4
  213. package/src/local/owner-state-lock.mjs +118 -0
  214. package/src/local/package-identity.mjs +9 -0
  215. package/src/local/patch.mjs +20 -18
  216. package/src/local/path-inspection.mjs +23 -0
  217. package/src/local/policy.mjs +19 -0
  218. package/src/local/private-toolchain-integrity.mjs +54 -0
  219. package/src/local/process-execution.mjs +87 -75
  220. package/src/local/process-foreground-timeout.mjs +50 -0
  221. package/src/local/process-identity.mjs +41 -7
  222. package/src/local/process-nonreplayable-settlement.mjs +50 -0
  223. package/src/local/process-result-projection.mjs +22 -0
  224. package/src/local/process-session-events.mjs +47 -0
  225. package/src/local/process-session-remote-activity.mjs +10 -0
  226. package/src/local/process-session-termination.mjs +73 -0
  227. package/src/local/process-sessions.mjs +144 -112
  228. package/src/local/process-tracker.mjs +140 -13
  229. package/src/local/process-tree-ownership-types.d.ts +37 -0
  230. package/src/local/process-tree-ownership.mjs +57 -0
  231. package/src/local/process-tree-signal.mjs +34 -0
  232. package/src/local/process-tree-snapshot.mjs +77 -0
  233. package/src/local/process-tree-supervisor.mjs +69 -0
  234. package/src/local/process-tree.mjs +11 -53
  235. package/src/local/project-metadata.mjs +19 -6
  236. package/src/local/relay-call-recovery.mjs +58 -38
  237. package/src/local/relay-connection-classification.mjs +131 -0
  238. package/src/local/relay-connection-support.mjs +91 -0
  239. package/src/local/relay-connection.mjs +179 -272
  240. package/src/local/relay-diagnostics.mjs +91 -0
  241. package/src/local/relay-heartbeat.mjs +119 -0
  242. package/src/local/relay-liveness.mjs +109 -0
  243. package/src/local/relay-peer-diagnostics.mjs +29 -0
  244. package/src/local/release-runtime-lock.mjs +18 -0
  245. package/src/local/remote-activity-idle-sleep-guard.mjs +77 -0
  246. package/src/local/remote-configuration.mjs +48 -0
  247. package/src/local/resilient-relay-connection.mjs +178 -0
  248. package/src/local/resource-admission-diagnostics.mjs +52 -0
  249. package/src/local/resource-admission-policy.mjs +115 -0
  250. package/src/local/resource-admission.mjs +339 -0
  251. package/src/local/resource-build-root.mjs +83 -0
  252. package/src/local/resource-cargo-concurrency.mjs +38 -0
  253. package/src/local/resource-cmake-concurrency.mjs +42 -0
  254. package/src/local/resource-command-concurrency.mjs +37 -0
  255. package/src/local/resource-command-profile.mjs +176 -0
  256. package/src/local/resource-coordinator-accounting.mjs +21 -0
  257. package/src/local/resource-cpu-window.mjs +20 -0
  258. package/src/local/resource-disk-headroom.mjs +13 -0
  259. package/src/local/resource-elastic-memory.mjs +19 -0
  260. package/src/local/resource-elastic-request.mjs +36 -0
  261. package/src/local/resource-foreground-wait.mjs +29 -0
  262. package/src/local/resource-go-concurrency.mjs +43 -0
  263. package/src/local/resource-gradle-concurrency.mjs +57 -0
  264. package/src/local/resource-host-cache.mjs +39 -0
  265. package/src/local/resource-host-darwin.mjs +54 -0
  266. package/src/local/resource-host-linux.mjs +35 -0
  267. package/src/local/resource-host-sample-file.mjs +23 -0
  268. package/src/local/resource-host-snapshot.mjs +99 -0
  269. package/src/local/resource-lease-accounting.mjs +119 -0
  270. package/src/local/resource-light-command.mjs +6 -0
  271. package/src/local/resource-make-concurrency.mjs +42 -0
  272. package/src/local/resource-maven-concurrency.mjs +38 -0
  273. package/src/local/resource-ninja-command-concurrency.mjs +20 -0
  274. package/src/local/resource-ninja-concurrency.mjs +28 -0
  275. package/src/local/resource-operations.mjs +26 -10
  276. package/src/local/resource-pressure.mjs +67 -0
  277. package/src/local/resource-probe-command.mjs +35 -0
  278. package/src/local/resource-process-admission.mjs +59 -0
  279. package/src/local/resource-process-ancestry-cache.mjs +43 -0
  280. package/src/local/resource-process-ancestry.mjs +32 -0
  281. package/src/local/resource-process-priority.mjs +15 -0
  282. package/src/local/resource-project-key.mjs +53 -0
  283. package/src/local/resource-pytest-concurrency.mjs +33 -0
  284. package/src/local/resource-release-control-classification.mjs +14 -0
  285. package/src/local/resource-release-control-executable.mjs +70 -0
  286. package/src/local/resource-release-control-workspace.mjs +41 -0
  287. package/src/local/resource-request-contract.mjs +30 -0
  288. package/src/local/resource-script-classification.mjs +44 -0
  289. package/src/local/resource-shell-analysis.mjs +58 -0
  290. package/src/local/resource-staging-recovery.mjs +97 -0
  291. package/src/local/resource-swift-concurrency.mjs +31 -0
  292. package/src/local/resource-transaction-lock.mjs +189 -0
  293. package/src/local/resource-wait.mjs +48 -0
  294. package/src/local/resource-waiters.mjs +139 -0
  295. package/src/local/resource-xcode-command.mjs +7 -0
  296. package/src/local/resource-xcode-concurrency.mjs +34 -0
  297. package/src/local/resource-xcode-non-build.mjs +19 -0
  298. package/src/local/runtime-activation.mjs +700 -0
  299. package/src/local/runtime-activity-projection.mjs +48 -0
  300. package/src/local/runtime-capabilities.mjs +48 -15
  301. package/src/local/runtime-diagnostic-state.mjs +14 -0
  302. package/src/local/runtime-diagnostics.mjs +40 -13
  303. package/src/local/runtime-info-projection.mjs +60 -0
  304. package/src/local/runtime-info-relay-projection.mjs +21 -0
  305. package/src/local/runtime-paths.mjs +2 -1
  306. package/src/local/runtime-process-routing.mjs +33 -0
  307. package/src/local/runtime-relay-connection-options.mjs +44 -0
  308. package/src/local/runtime-relay-control.mjs +98 -0
  309. package/src/local/runtime-relay.mjs +26 -50
  310. package/src/local/runtime-reporting.mjs +37 -21
  311. package/src/local/runtime-resource-service.mjs +77 -0
  312. package/src/local/runtime-tool-handlers.mjs +13 -10
  313. package/src/local/runtime.mjs +244 -208
  314. package/src/local/secure-file.mjs +73 -20
  315. package/src/local/security-audit-dispatch.mjs +35 -0
  316. package/src/local/security-audit-log.mjs +215 -0
  317. package/src/local/security-audit-state.mjs +139 -0
  318. package/src/local/security-audit-storage.mjs +135 -0
  319. package/src/local/security-audit-warning.mjs +31 -0
  320. package/src/local/security-audit-worker.mjs +87 -0
  321. package/src/local/service-convergence.mjs +42 -1
  322. package/src/local/service-definition.mjs +24 -0
  323. package/src/local/service-environment.mjs +18 -10
  324. package/src/local/service-owner.mjs +146 -0
  325. package/src/local/service-ownership.mjs +17 -0
  326. package/src/local/service-restart-handoff.mjs +64 -0
  327. package/src/local/service-restart-scheduler.mjs +49 -0
  328. package/src/local/service-runtime-convergence.mjs +52 -0
  329. package/src/local/service-runtime.mjs +105 -0
  330. package/src/local/service-status.mjs +60 -0
  331. package/src/local/service.mjs +385 -92
  332. package/src/local/shell.mjs +39 -19
  333. package/src/local/ssh-key.mjs +158 -42
  334. package/src/local/state-inventory.mjs +50 -24
  335. package/src/local/state-owner-lock-inventory.mjs +23 -0
  336. package/src/local/state-root-owned-namespaces.mjs +83 -0
  337. package/src/local/state-root-retirement.mjs +89 -0
  338. package/src/local/state.mjs +386 -96
  339. package/src/local/stdio.mjs +96 -66
  340. package/src/local/support-state-projection.mjs +30 -0
  341. package/src/local/system-network-route.mjs +76 -0
  342. package/src/local/systemd-removal.mjs +20 -0
  343. package/src/local/tool-executor.mjs +85 -20
  344. package/src/local/tool-result-boundary.mjs +51 -0
  345. package/src/local/toolchain-operation-lock.mjs +41 -0
  346. package/src/local/tools.mjs +7 -5
  347. package/src/local/trusted-executable.mjs +53 -0
  348. package/src/local/trusted-git-executable.mjs +34 -0
  349. package/src/local/trusted-github-cli.mjs +24 -0
  350. package/src/local/windows-service-convergence.mjs +49 -0
  351. package/src/local/windows-service.mjs +52 -45
  352. package/src/local/worker-deployment-fingerprint.mjs +102 -0
  353. package/src/local/worker-deployment.mjs +48 -60
  354. package/src/local/worker-health.mjs +12 -4
  355. package/src/local/worker-secret-file.mjs +37 -17
  356. package/src/local/workspace-file-service.mjs +156 -239
  357. package/src/local/workspace-file-transaction.mjs +189 -0
  358. package/src/local/workspace-search.mjs +55 -0
  359. package/src/local/wrangler-toolchain/package-lock.json +1505 -0
  360. package/src/local/wrangler-toolchain/package.json +23 -0
  361. package/src/local/wrangler-toolchain-verification.mjs +135 -0
  362. package/src/local/wrangler-toolchain.mjs +188 -0
  363. package/src/shared/access-contract.json +7 -1
  364. package/src/shared/activation-recovery.mjs +49 -0
  365. package/src/shared/admin-auth.d.mts +2 -1
  366. package/src/shared/admin-auth.mjs +3 -3
  367. package/src/shared/authority-revocation.d.mts +9 -0
  368. package/src/shared/authority-revocation.mjs +28 -0
  369. package/src/shared/daemon-auth.d.mts +11 -0
  370. package/src/shared/daemon-auth.mjs +17 -0
  371. package/src/shared/device-session-auth.d.mts +20 -0
  372. package/src/shared/device-session-auth.mjs +51 -0
  373. package/src/shared/foreground-timeout.d.mts +15 -0
  374. package/src/shared/foreground-timeout.mjs +70 -0
  375. package/src/shared/log-redaction.d.mts +9 -0
  376. package/src/shared/log-redaction.mjs +51 -0
  377. package/src/shared/mcp-protocol.d.mts +27 -0
  378. package/src/shared/mcp-protocol.mjs +275 -0
  379. package/src/shared/project-overview-projection.d.mts +4 -0
  380. package/src/shared/project-overview-projection.mjs +96 -0
  381. package/src/shared/relay-contract.json +28 -0
  382. package/src/shared/result-projection.d.mts +2 -1
  383. package/src/shared/result-projection.mjs +13 -2
  384. package/src/shared/server-metadata.json +15 -9
  385. package/src/shared/tool-argument-validation.d.mts +17 -0
  386. package/src/shared/tool-argument-validation.mjs +325 -0
  387. package/src/shared/tool-call-capacity.d.mts +41 -0
  388. package/src/shared/tool-call-capacity.mjs +59 -0
  389. package/src/shared/tool-catalog.json +626 -57
  390. package/src/worker/access.ts +12 -0
  391. package/src/worker/account-admin.ts +55 -33
  392. package/src/worker/authority-revocations.ts +174 -0
  393. package/src/worker/authority.ts +52 -6
  394. package/src/worker/daemon-auth.ts +49 -68
  395. package/src/worker/daemon-channel.ts +36 -0
  396. package/src/worker/daemon-http-auth.ts +63 -0
  397. package/src/worker/daemon-http-channel.ts +120 -0
  398. package/src/worker/daemon-http-controller.ts +163 -0
  399. package/src/worker/daemon-http-protocol.ts +62 -0
  400. package/src/worker/daemon-http-registry.ts +82 -0
  401. package/src/worker/daemon-last-observation.ts +30 -0
  402. package/src/worker/daemon-liveness.ts +8 -6
  403. package/src/worker/daemon-ready-dispatch.ts +17 -0
  404. package/src/worker/daemon-ready-messages.ts +73 -0
  405. package/src/worker/daemon-ready-waiters.ts +79 -0
  406. package/src/worker/daemon-recovery-budget.ts +13 -0
  407. package/src/worker/daemon-registry.ts +58 -0
  408. package/src/worker/daemon-relay-diagnostics.ts +127 -0
  409. package/src/worker/daemon-socket-attachment.ts +55 -0
  410. package/src/worker/daemon-sockets.ts +72 -62
  411. package/src/worker/daemon-status.ts +38 -0
  412. package/src/worker/device-session-verifier.ts +129 -0
  413. package/src/worker/dpop.ts +157 -0
  414. package/src/worker/durable-process-timeout.ts +29 -0
  415. package/src/worker/errors.ts +57 -0
  416. package/src/worker/http.ts +112 -26
  417. package/src/worker/index.ts +446 -440
  418. package/src/worker/mcp-access.ts +57 -0
  419. package/src/worker/mcp-controller.ts +188 -0
  420. package/src/worker/mcp-http-accept.ts +11 -0
  421. package/src/worker/mcp-http-contract.ts +322 -0
  422. package/src/worker/mcp-initialization-compat.ts +141 -0
  423. package/src/worker/mcp-jsonrpc.ts +11 -29
  424. package/src/worker/mcp-removed-protocol.ts +17 -0
  425. package/src/worker/mcp-response-proxy.ts +135 -0
  426. package/src/worker/mcp-response-stream.ts +65 -0
  427. package/src/worker/mcp-stale-schema-compat.ts +57 -0
  428. package/src/worker/mcp-stream-proxy-contract.ts +48 -0
  429. package/src/worker/mcp-tool-call-input.ts +23 -0
  430. package/src/worker/nonce-store.ts +33 -35
  431. package/src/worker/oauth-authorization-page.ts +21 -1
  432. package/src/worker/oauth-client-admin.ts +52 -0
  433. package/src/worker/oauth-client-contract.ts +38 -0
  434. package/src/worker/oauth-controller.ts +107 -47
  435. package/src/worker/oauth-field-contract.ts +31 -0
  436. package/src/worker/oauth-record-contract.ts +7 -0
  437. package/src/worker/oauth-refresh-authority.ts +27 -0
  438. package/src/worker/oauth-refresh-exchange.ts +162 -0
  439. package/src/worker/oauth-refresh-families.ts +130 -27
  440. package/src/worker/oauth-refresh-persistence.ts +116 -0
  441. package/src/worker/oauth-state.ts +33 -18
  442. package/src/worker/oauth-store-validation.ts +131 -0
  443. package/src/worker/oauth-token-derivation.ts +33 -0
  444. package/src/worker/oauth-token-issuance.ts +119 -0
  445. package/src/worker/oauth-tokens.ts +56 -190
  446. package/src/worker/observability.ts +38 -5
  447. package/src/worker/pending-admission.ts +15 -0
  448. package/src/worker/pending-call-capacity.ts +108 -0
  449. package/src/worker/pending-call-contract.ts +42 -5
  450. package/src/worker/pending-call-deadlines.ts +75 -0
  451. package/src/worker/pending-calls.ts +131 -125
  452. package/src/worker/runtime-alarm-storage.ts +37 -0
  453. package/src/worker/runtime-alarm.ts +136 -0
  454. package/src/worker/server-info-activity.ts +36 -0
  455. package/src/worker/server-info-tool-delivery.ts +15 -0
  456. package/src/worker/server-info.ts +168 -0
  457. package/src/worker/tool-catalog.ts +47 -1
  458. package/src/worker/tool-timeout.ts +75 -14
  459. package/src/worker/websocket-protocol.ts +26 -2
  460. package/src/worker/worker-edge-guard.ts +90 -0
  461. package/src/worker/worker-edge-log.ts +65 -0
  462. package/src/worker/worker-entry.ts +52 -0
  463. package/src/worker/worker-mcp-config.ts +23 -0
  464. package/src/worker/worker-metadata.ts +48 -0
  465. package/src/worker/worker-rate-limit-key.ts +30 -0
  466. package/src/worker/worker-runtime-config.ts +20 -0
  467. package/src/worker/worker-static-routes.ts +54 -0
  468. package/src/worker/worker-task-lifetime.ts +18 -0
  469. package/tsconfig.local.json +17 -1
  470. package/wrangler.jsonc +13 -0
  471. package/src/local/cli-approval.mjs +0 -117
  472. package/src/local/operation-state-lock.mjs +0 -92
  473. package/src/worker/mcp-session.ts +0 -72
@@ -27,11 +27,17 @@ const MAX_CONTEXT_SKILL_SUMMARY_CHARS = 8_000;
27
27
  const MAX_CONFIG_BYTES = 256 * 1024;
28
28
  const MAX_INSTRUCTION_FILE_BYTES = 512 * 1024;
29
29
  const MAX_INSTRUCTION_FILES = 64;
30
+ const METADATA_AUTHORITY = Object.freeze({
31
+ capability_metadata: "project-or-user-provided-planning-context",
32
+ execution_authority: "machine-bridge-policy-account-and-operation-gates",
33
+ authority_expansion: false,
34
+ });
30
35
 
31
36
  export class AgentContextManager {
32
- constructor({ workspace, policy, displayPath, resolveExistingPath, throwIfCancelled = () => {}, home = process.env.HOME || process.env.USERPROFILE || "", codexHome = process.env.CODEX_HOME || "" }) {
37
+ constructor({ workspace, policy, policyForContext = null, displayPath, resolveExistingPath, throwIfCancelled = () => {}, home = process.env.HOME || process.env.USERPROFILE || "", codexHome = process.env.CODEX_HOME || "" }) {
33
38
  this.workspace = resolve(workspace);
34
39
  this.policy = policy || {};
40
+ this.policyForContext = typeof policyForContext === "function" ? policyForContext : () => this.policy;
35
41
  this.displayPath = displayPath;
36
42
  this.resolveExistingPath = resolveExistingPath;
37
43
  this.throwIfCancelled = throwIfCancelled;
@@ -44,23 +50,23 @@ export class AgentContextManager {
44
50
  const includeContent = args.include_instruction_content !== false;
45
51
  const skillLimit = clampInteger(args.max_skills, 100, 1, MAX_SKILL_RESULTS);
46
52
  const discoveredSkills = await this.discoverSkills(state, { maxResults: MAX_SKILL_RESULTS }, context);
47
- const contextSkills = contextSkillSummaries(discoveredSkills.skills, this.displayPath, skillLimit, MAX_CONTEXT_SKILL_SUMMARY_CHARS);
53
+ const contextSkills = contextSkillSummaries(discoveredSkills.skills, (value) => this.displayPath(value, context), skillLimit, MAX_CONTEXT_SKILL_SUMMARY_CHARS);
48
54
  const result = {
49
- target: this.displayPath(state.target),
50
- scope_root: this.displayPath(state.scopeRoot),
55
+ target: this.displayPath(state.target, context),
56
+ scope_root: this.displayPath(state.scopeRoot, context),
51
57
  precedence: "built-in defaults, automatic project facts, user-global guidance, then scope root to target directory; explicit files loaded later have higher precedence",
52
- config_files: state.configFiles.map((file) => this.displayPath(file)),
58
+ config_files: state.configFiles.map((file) => this.displayPath(file, context)),
53
59
  builtin_instructions: publicVirtualInstruction(state.builtinInstructions, includeContent),
54
60
  automatic_project_context: publicVirtualInstruction(state.automaticProjectContext, includeContent),
55
61
  model_instructions_file: state.modelInstructions ? {
56
- path: this.displayPath(state.modelInstructions.path),
62
+ path: this.displayPath(state.modelInstructions.path, context),
57
63
  bytes: state.modelInstructions.bytes,
58
64
  sha256: state.modelInstructions.sha256,
59
65
  ...(includeContent ? { content: state.modelInstructions.content } : {}),
60
66
  } : null,
61
67
  instruction_files: state.instructions.map((item) => ({
62
68
  scope: item.scope,
63
- path: this.displayPath(item.path),
69
+ path: this.displayPath(item.path, context),
64
70
  bytes: item.bytes,
65
71
  sha256: item.sha256,
66
72
  precedence: item.precedence,
@@ -68,9 +74,10 @@ export class AgentContextManager {
68
74
  })),
69
75
  skills: contextSkills.skills,
70
76
  skills_truncated: discoveredSkills.truncated || contextSkills.truncated,
71
- skill_warnings: publicSkillWarnings(discoveredSkills.warnings, this.displayPath),
77
+ skill_warnings: publicSkillWarnings(discoveredSkills.warnings, (value) => this.displayPath(value, context)),
72
78
  instructions_truncated: state.instructionsTruncated,
73
- commands: publicCommands(state.commands, this.displayPath),
79
+ commands: publicCommands(state.commands, (value) => this.displayPath(value, context)),
80
+ metadata_authority: METADATA_AUTHORITY,
74
81
  guidance: [
75
82
  "Apply built-in instructions and automatic project context as lower-precedence defaults; explicit global/project instruction files loaded later take precedence.",
76
83
  "Treat instruction_files as authoritative workspace guidance in the returned precedence order.",
@@ -78,7 +85,7 @@ export class AgentContextManager {
78
85
  "Prefer run_local_command for registered repeatable commands. Use run_process or exec_command only when no registered command fits and policy permits it.",
79
86
  ],
80
87
  };
81
- if (includeContent) result.effective_instructions = renderEffectiveInstructions(effectiveInstructionItems(state), this.displayPath);
88
+ if (includeContent) result.effective_instructions = renderEffectiveInstructions(effectiveInstructionItems(state), (value) => this.displayPath(value, context));
82
89
  return result;
83
90
  }
84
91
 
@@ -86,11 +93,11 @@ export class AgentContextManager {
86
93
  const state = await this.discoverState(args.path || ".", context);
87
94
  const fingerprint = capabilityFingerprint(state, []);
88
95
  return {
89
- target: this.displayPath(state.target),
90
- instructions: renderEffectiveInstructions(effectiveInstructionItems(state), this.displayPath),
96
+ target: this.displayPath(state.target, context),
97
+ instructions: renderEffectiveInstructions(effectiveInstructionItems(state), (value) => this.displayPath(value, context)),
91
98
  builtin_instructions: publicVirtualInstruction(state.builtinInstructions, false),
92
99
  automatic_project_context: publicVirtualInstruction(state.automaticProjectContext, false),
93
- model_instructions_file: state.modelInstructions ? this.displayPath(state.modelInstructions.path) : null,
100
+ model_instructions_file: state.modelInstructions ? this.displayPath(state.modelInstructions.path, context) : null,
94
101
  capability_refresh: {
95
102
  strategy: "resolve_task_capabilities-rescans-on-every-call",
96
103
  instruction_and_command_fingerprint: fingerprint,
@@ -99,7 +106,7 @@ export class AgentContextManager {
99
106
  },
100
107
  guidance: [
101
108
  "Built-in working agreements and bounded automatic project facts are present by default unless disabled in the user-global agent config.",
102
- "Call resolve_task_capabilities with the current user task before substantive local work or at the start of a reused-host conversation.",
109
+ "Call resolve_task_capabilities only when skill, command, application/browser routing, or refreshed project instructions are needed; use direct file, Git, and execution tools for straightforward work.",
103
110
  "The resolver returns the effective instructions again and rescans skill and command metadata on every call; the runtime supplements application and browser capability metadata.",
104
111
  ],
105
112
  };
@@ -125,7 +132,7 @@ export class AgentContextManager {
125
132
  let selectedSkill = null;
126
133
  if (selected && args.include_selected_skill !== false) {
127
134
  const content = await readRegularUtf8(selected.entrypoint, MAX_SKILL_ENTRY_BYTES, "skill entrypoint");
128
- selectedSkill = { ...publicSkill(selected, this.displayPath), instructions: content.text };
135
+ selectedSkill = { ...publicSkill(selected, (value) => this.displayPath(value, context)), instructions: content.text };
129
136
  }
130
137
  const recommendedTools = recommendTools(task, {
131
138
  commandsAvailable: state.commands.size > 0,
@@ -133,22 +140,44 @@ export class AgentContextManager {
133
140
  skillRelevant: Boolean(selected),
134
141
  });
135
142
  const refresh = capabilityFingerprint(state, discovered.skills);
136
- return {
137
- task,
138
- target: this.displayPath(state.target),
139
- effective_instructions: renderEffectiveInstructions(effectiveInstructionItems(state), this.displayPath),
143
+ const knownRefreshFingerprint = args.known_refresh_fingerprint === undefined
144
+ ? ""
145
+ : String(args.known_refresh_fingerprint || "");
146
+ if (knownRefreshFingerprint && !/^[a-f0-9]{64}$/.test(knownRefreshFingerprint)) {
147
+ throw new Error("known_refresh_fingerprint must be a lowercase SHA-256 hex digest");
148
+ }
149
+ const contextUnchanged = Boolean(knownRefreshFingerprint && knownRefreshFingerprint === refresh);
150
+ const staticContext = contextUnchanged ? {} : {
151
+ effective_instructions: renderEffectiveInstructions(effectiveInstructionItems(state), (value) => this.displayPath(value, context)),
140
152
  builtin_instructions: publicVirtualInstruction(state.builtinInstructions, false),
141
153
  automatic_project_context: publicVirtualInstruction(state.automaticProjectContext, false),
142
- model_instructions_file: state.modelInstructions ? this.displayPath(state.modelInstructions.path) : null,
143
- instruction_files: state.instructions.map((item) => ({ path: this.displayPath(item.path), scope: item.scope, bytes: item.bytes, sha256: item.sha256, precedence: item.precedence })),
154
+ model_instructions_file: state.modelInstructions ? this.displayPath(state.modelInstructions.path, context) : null,
155
+ instruction_files: state.instructions.map((item) => ({ path: this.displayPath(item.path, context), scope: item.scope, bytes: item.bytes, sha256: item.sha256, precedence: item.precedence })),
156
+ };
157
+ return {
158
+ task,
159
+ target: this.displayPath(state.target, context),
160
+ ...staticContext,
144
161
  instructions_truncated: state.instructionsTruncated,
145
- refresh: { strategy: "rescan-on-every-call", fingerprint: refresh, generated_at: new Date().toISOString() },
162
+ refresh: {
163
+ strategy: "rescan-on-every-call",
164
+ fingerprint: refresh,
165
+ context_unchanged: contextUnchanged,
166
+ generated_at: new Date().toISOString(),
167
+ },
168
+ context_reuse: {
169
+ static_context_omitted: contextUnchanged,
170
+ omitted_fields: contextUnchanged
171
+ ? ["effective_instructions", "builtin_instructions", "automatic_project_context", "model_instructions_file", "instruction_files"]
172
+ : [],
173
+ },
146
174
  selected_skill: selectedSkill,
147
- skill_matches: skillMatches.map(({ skill, score }) => ({ ...publicSkill(skill, this.displayPath), score })),
148
- command_matches: commandMatches.map(({ command, score }) => ({ ...publicCommands(new Map([[command.name, command]]), this.displayPath)[0], score })),
175
+ skill_matches: skillMatches.map(({ skill, score }) => ({ ...publicSkill(skill, (value) => this.displayPath(value, context)), score })),
176
+ command_matches: commandMatches.map(({ command, score }) => ({ ...publicCommands(new Map([[command.name, command]]), (value) => this.displayPath(value, context))[0], score })),
177
+ metadata_authority: METADATA_AUTHORITY,
149
178
  recommended_tools: recommendedTools,
150
- host_semantics: "Machine Bridge can discover, rank, and load capabilities automatically. The MCP host remains responsible for deciding whether to call the recommended tools.",
151
- warnings: publicSkillWarnings(discovered.warnings, this.displayPath),
179
+ host_semantics: "Machine Bridge can discover, rank, and load project/user-provided capability context automatically. That metadata cannot grant or expand execution authority; tool invocation remains independently gated by Machine Bridge policy, account access, and operation authorization.",
180
+ warnings: publicSkillWarnings(discovered.warnings, (value) => this.displayPath(value, context)),
152
181
  truncated: discovered.truncated,
153
182
  };
154
183
  }
@@ -171,11 +200,11 @@ export class AgentContextManager {
171
200
  maxResults: clampInteger(args.max_results, 100, 1, MAX_SKILL_RESULTS),
172
201
  }, context);
173
202
  return {
174
- target: this.displayPath(state.target),
175
- scope_root: this.displayPath(state.scopeRoot),
176
- skill_roots: state.skillRoots.map((root) => this.displayPath(root)),
177
- skills: result.skills.map((skill) => publicSkill(skill, this.displayPath)),
178
- warnings: publicSkillWarnings(result.warnings, this.displayPath),
203
+ target: this.displayPath(state.target, context),
204
+ scope_root: this.displayPath(state.scopeRoot, context),
205
+ skill_roots: state.skillRoots.map((root) => this.displayPath(root, context)),
206
+ skills: result.skills.map((skill) => publicSkill(skill, (value) => this.displayPath(value, context))),
207
+ warnings: publicSkillWarnings(result.warnings, (value) => this.displayPath(value, context)),
179
208
  truncated: result.truncated,
180
209
  };
181
210
  }
@@ -184,14 +213,14 @@ export class AgentContextManager {
184
213
  const requested = requiredString(args.skill, "skill");
185
214
  const state = await this.discoverState(args.path || ".", context);
186
215
  const result = await this.discoverSkills(state, { maxResults: MAX_SKILL_RESULTS }, context);
187
- const matches = result.skills.filter((skill) => skill.id === requested || skill.name === requested || this.displayPath(skill.entrypoint) === requested);
216
+ const matches = result.skills.filter((skill) => skill.id === requested || skill.name === requested || this.displayPath(skill.entrypoint, context) === requested);
188
217
  if (!matches.length) throw new Error(`local skill not found: ${requested}`);
189
218
  if (matches.length > 1) throw new Error(`local skill name is ambiguous; use its id: ${requested}`);
190
219
  const skill = matches[0];
191
220
  const content = await readRegularUtf8(skill.entrypoint, MAX_SKILL_ENTRY_BYTES, "skill entrypoint");
192
221
  const inventory = await listSkillFiles(skill.directory, clampInteger(args.max_files, 200, 1, MAX_SKILL_FILES), context, this.throwIfCancelled);
193
222
  return {
194
- skill: publicSkill(skill, this.displayPath),
223
+ skill: publicSkill(skill, (value) => this.displayPath(value, context)),
195
224
  instructions: content.text,
196
225
  files: inventory.files,
197
226
  files_truncated: inventory.truncated,
@@ -202,9 +231,9 @@ export class AgentContextManager {
202
231
  async listLocalCommands(args = {}, context = {}) {
203
232
  const state = await this.discoverState(args.path || ".", context);
204
233
  return {
205
- target: this.displayPath(state.target),
206
- scope_root: this.displayPath(state.scopeRoot),
207
- commands: publicCommands(state.commands, this.displayPath),
234
+ target: this.displayPath(state.target, context),
235
+ scope_root: this.displayPath(state.scopeRoot, context),
236
+ commands: publicCommands(state.commands, (value) => this.displayPath(value, context)),
208
237
  };
209
238
  }
210
239
 
@@ -227,23 +256,25 @@ export class AgentContextManager {
227
256
 
228
257
  async discoverState(inputPath, context = {}) {
229
258
  this.throwIfCancelled(context);
259
+ const effectivePolicy = this.policyForContext(context);
230
260
  this.workspace = await realpath(this.workspace);
231
- const target = await realpath(await this.resolveExistingPath(inputPath));
261
+ const target = await realpath(await this.resolveExistingPath(inputPath, context));
232
262
  const targetInfo = await stat(target);
233
263
  const targetDir = targetInfo.isDirectory() ? target : dirname(target);
234
264
  const scopeRoot = await findScopeRoot({
235
265
  targetDir,
236
266
  workspace: this.workspace,
237
- unrestricted: this.policy.unrestrictedPaths === true,
267
+ unrestricted: effectivePolicy.unrestrictedPaths === true,
238
268
  });
239
269
  const directories = directoriesBetween(scopeRoot, targetDir);
270
+ const userGlobalContextAllowed = allowsUserGlobalContext(context, effectivePolicy);
240
271
  const state = {
241
272
  target,
242
273
  targetDir,
243
274
  scopeRoot,
244
275
  instructionFiles: [...DEFAULT_INSTRUCTION_FILES],
245
276
  instructionMaxBytes: DEFAULT_INSTRUCTION_MAX_BYTES,
246
- skillRoots: defaultSkillRoots(directories, this.home, this.codexHome, this.policy.unrestrictedPaths === true),
277
+ skillRoots: defaultSkillRoots(directories, this.home, this.codexHome, effectivePolicy.unrestrictedPaths === true),
247
278
  commands: new Map(),
248
279
  builtinInstructionsEnabled: true,
249
280
  automaticProjectContextEnabled: true,
@@ -260,11 +291,11 @@ export class AgentContextManager {
260
291
  const packageMetadata = await readProjectPackageMetadata(scopeRoot, () => this.throwIfCancelled(context));
261
292
  state.commands = automaticPackageCommands(packageMetadata, scopeRoot);
262
293
 
263
- if (this.home) {
294
+ if (this.home && userGlobalContextAllowed) {
264
295
  const globalConfig = join(this.home, GLOBAL_CONFIG_RELATIVE_PATH);
265
296
  const config = await readOptionalConfig(globalConfig, this.home, false);
266
297
  if (config) {
267
- if (this.policy.unrestrictedPaths === true) this.applyConfig(state, config, globalConfig, this.home, { global: true });
298
+ if (effectivePolicy.unrestrictedPaths === true) this.applyConfig(state, config, globalConfig, this.home, { global: true, unrestricted: true });
268
299
  else {
269
300
  state.configFiles.push(globalConfig);
270
301
  if (config.builtinInstructions !== null) state.builtinInstructionsEnabled = config.builtinInstructions;
@@ -282,22 +313,22 @@ export class AgentContextManager {
282
313
  throwIfCancelled: () => this.throwIfCancelled(context),
283
314
  });
284
315
 
285
- if (this.home) {
316
+ if (this.home && userGlobalContextAllowed) {
286
317
  if (state.modelInstructionsFile) await this.collectModelInstructions(state, context);
287
- if (this.policy.unrestrictedPaths === true && this.codexHome) await this.collectDirectoryInstruction(state, this.codexHome, context, "global");
318
+ if (effectivePolicy.unrestrictedPaths === true && this.codexHome) await this.collectDirectoryInstruction(state, this.codexHome, context, "global");
288
319
  }
289
320
 
290
321
  for (const directory of directories) {
291
322
  this.throwIfCancelled(context);
292
323
  const configPath = join(directory, CONFIG_RELATIVE_PATH);
293
324
  const config = await readOptionalConfig(configPath, directory, true);
294
- if (config) this.applyConfig(state, config, configPath, directory, { global: false });
325
+ if (config) this.applyConfig(state, config, configPath, directory, { global: false, unrestricted: effectivePolicy.unrestrictedPaths === true });
295
326
  await this.collectDirectoryInstruction(state, directory, context, "project");
296
327
  }
297
328
  return state;
298
329
  }
299
330
 
300
- applyConfig(state, config, configPath, baseDir, { global = false } = {}) {
331
+ applyConfig(state, config, configPath, baseDir, { global = false, unrestricted = false } = {}) {
301
332
  state.configFiles.push(configPath);
302
333
  if (config.builtinInstructions !== null) {
303
334
  if (!global) throw new Error(`builtin_instructions is only allowed in the global agent config: ${configPath}`);
@@ -317,14 +348,14 @@ export class AgentContextManager {
317
348
  if (state.instructionBytes >= state.instructionMaxBytes) state.instructionsTruncated = true;
318
349
  }
319
350
  if (config.skillRoots) {
320
- state.skillRoots = config.skillRoots.map((value) => resolveConfiguredPath(value, baseDir, this.home, this.workspace, this.policy.unrestrictedPaths === true));
351
+ state.skillRoots = config.skillRoots.map((value) => resolveConfiguredPath(value, baseDir, this.home, this.workspace, unrestricted));
321
352
  }
322
353
  for (const [name, definition] of config.commands) {
323
354
  if (definition === null) {
324
355
  state.commands.delete(name);
325
356
  continue;
326
357
  }
327
- const cwd = resolveConfiguredPath(definition.cwd, baseDir, this.home, this.workspace, this.policy.unrestrictedPaths === true);
358
+ const cwd = resolveConfiguredPath(definition.cwd, baseDir, this.home, this.workspace, unrestricted);
328
359
  state.commands.set(name, {
329
360
  name,
330
361
  description: definition.description,
@@ -379,13 +410,14 @@ export class AgentContextManager {
379
410
  }
380
411
 
381
412
  async discoverSkills(state, options = {}, context = {}) {
413
+ const effectivePolicy = this.policyForContext(context);
382
414
  return discoverLocalSkills({
383
415
  skillRoots: state.skillRoots,
384
416
  query: String(options.query || ""),
385
417
  maxResults: clampInteger(options.maxResults, 100, 1, MAX_SKILL_RESULTS),
386
418
  workspace: this.workspace,
387
- unrestricted: this.policy.unrestrictedPaths === true,
388
- displayPath: this.displayPath,
419
+ unrestricted: effectivePolicy.unrestrictedPaths === true,
420
+ displayPath: (value) => this.displayPath(value, context),
389
421
  context,
390
422
  throwIfCancelled: this.throwIfCancelled,
391
423
  });
@@ -424,6 +456,13 @@ function directoriesBetween(root, leaf) {
424
456
  return result.reverse();
425
457
  }
426
458
 
459
+ function allowsUserGlobalContext(context, effectivePolicy) {
460
+ if (effectivePolicy?.unrestrictedPaths === true) return true;
461
+ const principal = context?.authority?.principal;
462
+ if (context?.origin === "relay" || principal?.kind === "account") return false;
463
+ return true;
464
+ }
465
+
427
466
  function defaultSkillRoots(directories, home, codexHome, unrestricted) {
428
467
  const roots = [];
429
468
  for (const directory of [...directories].reverse()) {
@@ -4,6 +4,7 @@ import { dirname, join, relative, sep } from "node:path";
4
4
  import { assertAllowedPath, MAX_SKILL_ROOTS } from "./agent-contract.mjs";
5
5
  import { sha256 } from "./agent-context-projection.mjs";
6
6
  import { readRegularUtf8 } from "./agent-text-file.mjs";
7
+ import { classifyOperationalError } from "./log.mjs";
7
8
 
8
9
  export const MAX_SKILL_ENTRY_BYTES = 512 * 1024;
9
10
  export const MAX_SKILL_RESULTS = 500;
@@ -99,10 +100,17 @@ export async function discoverLocalSkills(options) {
99
100
  if (entry.isDirectory()) {
100
101
  stack.push({ directory: child, depth: current.depth + 1 });
101
102
  } else if (entry.isSymbolicLink()) {
102
- const target = await realpath(child).catch(() => "");
103
- if (!target) continue;
104
- const targetInfo = await stat(target).catch(() => null);
105
- if (!targetInfo?.isDirectory()) continue;
103
+ let target;
104
+ try { target = await realpath(child); } catch (error) {
105
+ if (warnings.length < 100) warnings.push({ entrypoint: child, message: boundedMessage(error) });
106
+ continue;
107
+ }
108
+ let targetInfo;
109
+ try { targetInfo = await stat(target); } catch (error) {
110
+ if (warnings.length < 100) warnings.push({ entrypoint: child, message: boundedMessage(error) });
111
+ continue;
112
+ }
113
+ if (!targetInfo.isDirectory()) continue;
106
114
  assertAllowedPath(target, options.workspace, options.unrestricted, "skill symlink target");
107
115
  stack.push({ directory: target, depth: current.depth + 1 });
108
116
  }
@@ -214,8 +222,11 @@ async function summarizeSkill(entrypoint, sourceRoot) {
214
222
 
215
223
  /** @param {unknown} error */
216
224
  function boundedMessage(error) {
225
+ if (error !== null && typeof error === "object" && "code" in error && error.code) {
226
+ return `local skill access failed (${classifyOperationalError(error)})`;
227
+ }
217
228
  const message = error instanceof Error ? error.message : String(error || "invalid local skill");
218
- return message.replace(/[\r\n]+/g, " ").slice(0, 1000);
229
+ return message.replace(/[\r\n\u0000-\u001f\u007f]+/g, " ").slice(0, 1000);
219
230
  }
220
231
 
221
232
  /** @param {string} value */