@moretea-labs/forge 1.8.1 → 1.8.2

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 (328) hide show
  1. package/AGENTS.md +5 -2
  2. package/CHANGELOG.md +20 -0
  3. package/README.en.md +24 -3
  4. package/README.md +10 -6
  5. package/README.zh-CN.md +5 -3
  6. package/THIRD_PARTY_NOTICES.md +1 -2
  7. package/adapters/chatgpt/browser-delivery-runtime.ts +5 -3
  8. package/adapters/chatgpt/provider-delivery.ts +1 -1
  9. package/adapters/chatgpt/work-conversation-binding-store.ts +20 -1
  10. package/adapters/computer/chatgpt-extension-target.ts +295 -50
  11. package/adapters/computer/chrome-extension/background.js +227 -71
  12. package/adapters/computer/chrome-extension/content.js +181 -157
  13. package/adapters/computer/chrome-extension/manifest.json +3 -1
  14. package/adapters/computer/desktop-operator-provider.ts +18 -6
  15. package/adapters/computer/interaction-target-authority.ts +39 -9
  16. package/adapters/mcp/access-mode.ts +18 -39
  17. package/adapters/mcp/auth.ts +2 -6
  18. package/adapters/mcp/instructions.ts +2 -2
  19. package/adapters/mcp/multi-repository.ts +7 -28
  20. package/adapters/mcp/runtime-gateway/context-adapter.ts +79 -40
  21. package/adapters/mcp/runtime-gateway/context-pack-sidecar.ts +7 -15
  22. package/adapters/mcp/runtime-gateway/execution-tools.ts +7 -13
  23. package/adapters/mcp/runtime-gateway/plugin-adapter.ts +16 -3
  24. package/adapters/mcp/runtime-gateway/process-tools.ts +3 -21
  25. package/adapters/mcp/runtime-gateway/router.ts +3 -5
  26. package/adapters/mcp/runtime-gateway/routing-policy.ts +17 -10
  27. package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +1 -1
  28. package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +14 -9
  29. package/adapters/mcp/runtime-gateway/runtime-tools.ts +1 -5
  30. package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +36 -1
  31. package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +58 -4
  32. package/adapters/mcp/runtime-gateway/typescript-navigation-sidecar.ts +7 -3
  33. package/adapters/mcp/runtime-gateway/work-adapter.ts +16 -16
  34. package/adapters/mcp/runtime-gateway/work-input-wire-migration.ts +0 -17
  35. package/adapters/mcp/runtime-gateway/work-semantic-operations.ts +69 -12
  36. package/adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts +26 -2
  37. package/adapters/mcp/server.ts +24 -3
  38. package/adapters/mcp/setup.ts +4 -10
  39. package/adapters/mcp/tool-mapping/access-tools.ts +0 -6
  40. package/adapters/mcp/tool-mapping/legacy-tool-service.ts +672 -2935
  41. package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +1 -1
  42. package/adapters/mcp/tool-mapping/repository-tools.ts +52 -86
  43. package/adapters/mcp/toolset-names.ts +11 -42
  44. package/adapters/mcp/toolset.ts +16 -90
  45. package/{src/cli → adapters}/mcp/transports/AGENTS.md +5 -5
  46. package/{src/cli → adapters}/mcp/transports/CLAUDE.md +5 -5
  47. package/adapters/mcp/transports/http-observation.ts +18 -6
  48. package/adapters/mcp/transports/http-post-lifecycle.ts +19 -0
  49. package/adapters/mcp/transports/http.ts +54 -14
  50. package/adapters/mcp/types.ts +0 -6
  51. package/assets/hooks/lib/session-state.sh +0 -38
  52. package/assets/hooks/post-bash.sh +1 -1
  53. package/assets/hooks/post-tool-observer.sh +0 -5
  54. package/assets/hooks/prompt-guard.sh +0 -55
  55. package/assets/partials/04-project-structure.partial.md +1 -1
  56. package/assets/partials/07-footer.partial.md +1 -1
  57. package/assets/partials-agents/02-operating-mode.partial.md +1 -1
  58. package/assets/partials-agents/08-deep-docs.partial.md +1 -1
  59. package/assets/reference-configs/agentic-development-flow.md +1 -1
  60. package/assets/reference-configs/external-tooling.md +0 -76
  61. package/assets/reference-configs/release-deploy.md +1 -1
  62. package/assets/templates/helpers/architecture-queue.sh +1 -1
  63. package/assets/templates/helpers/check-agent-tooling.sh +1 -327
  64. package/assets/templates/helpers/check-task-workflow.sh +1 -1
  65. package/assets/templates/helpers/ensure-task-workflow.sh +0 -14
  66. package/assets/templates/helpers/migrate-project-template.sh +2 -2
  67. package/assets/workflow-contract.v1.json +0 -2
  68. package/docs/README.md +5 -2
  69. package/docs/architecture/CURRENT.md +114 -30
  70. package/docs/architecture/decisions/20260904-ios-device-migration-baseline.md +42 -0
  71. package/docs/architecture/decisions/20260918-stable-candidate-release-lifecycle.md +15 -2
  72. package/docs/architecture/decisions/20260924-thin-semantic-working-context.md +4 -2
  73. package/docs/architecture/decisions/20261001-supervisor-turn-authority.md +109 -4
  74. package/docs/architecture/decisions/20261009-exact-code-context-discovery.md +19 -0
  75. package/docs/architecture/decisions/20261009-generated-xcode-cache-retention.md +37 -0
  76. package/docs/architecture/decisions/20261011-autonomous-continuation-convergence.md +597 -0
  77. package/docs/architecture/decisions/20261017-edit-session-finalization-reconciliation.md +17 -0
  78. package/docs/architecture/decisions/20261019-retire-host-skills.md +16 -0
  79. package/docs/architecture/diagrams/agentic-dev-plugin-architecture.html +1 -1
  80. package/docs/architecture/domains/public-surface.md +3 -5
  81. package/docs/architecture/domains/verification.md +5 -5
  82. package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +2 -2
  83. package/docs/architecture/requests/2026-09-04-computer-plugin-workflow-taxonomy.md +4 -4
  84. package/docs/architecture/reviews/20261015-code-search-runtime-acceptance.md +75 -0
  85. package/docs/forge-plugin-management.md +14 -2
  86. package/docs/operations/controller-browser-plugin.md +23 -0
  87. package/docs/operations/features.md +6 -7
  88. package/docs/operations/features.zh-CN.md +1 -1
  89. package/docs/operations/github-repository.md +4 -4
  90. package/docs/operations/github-semantic-release-projection.md +20 -0
  91. package/docs/operations/homebrew.md +2 -2
  92. package/docs/operations/mcp-tool-exposure.md +13 -54
  93. package/docs/operations/runtime-performance-diagnostics.md +8 -0
  94. package/docs/operations/standalone-disaster-recovery.md +1 -1
  95. package/docs/tutorials/01-install-and-start.zh-CN.md +1 -1
  96. package/docs/tutorials/03-first-repository-task.md +2 -0
  97. package/docs/wiki/Computer-and-Plugins.md +78 -0
  98. package/docs/wiki/Computer-and-Plugins.zh-CN.md +88 -0
  99. package/docs/wiki/Home.md +16 -2
  100. package/docs/wiki/Implementation.md +24 -12
  101. package/docs/wiki/Installation.md +28 -32
  102. package/docs/wiki/Integrations.md +4 -0
  103. package/docs/wiki/Quick-Start.md +35 -22
  104. package/docs/wiki/Releases-and-Upgrades.md +15 -25
  105. package/docs/wiki/_Sidebar.md +5 -1
  106. package/package.json +1 -12
  107. package/packages/kernel/controller/infrastructure/controller-session-store.ts +63 -38
  108. package/packages/kernel/identity/infrastructure/activity-projection-store.ts +10 -0
  109. package/packages/kernel/scheduler/application/eligibility.ts +4 -1
  110. package/packages/kernel/scheduler/infrastructure/schedule-store.ts +13 -10
  111. package/packages/kernel/work/application/work-service.ts +1 -0
  112. package/packages/kernel/work/domain/repository-completion-receipt.ts +1 -1
  113. package/packages/kernel/work/domain/state-machine.ts +9 -2
  114. package/packages/kernel/work/infrastructure/work-contract-store.ts +28 -1
  115. package/packages/plugin-runtime/browser/provider-registry.ts +12 -36
  116. package/packages/plugin-runtime/computer/conversation-target.ts +17 -7
  117. package/scripts/assemble-template.ts +11 -72
  118. package/scripts/check-mcp-compatibility.ts +55 -74
  119. package/scripts/check-package-identity.mjs +0 -5
  120. package/scripts/check-runtime-architecture.mjs +305 -28
  121. package/scripts/init-project.sh +0 -46
  122. package/scripts/install-ios-hid-toolchain.sh +60 -0
  123. package/scripts/install-standalone-recovery.ts +1 -1
  124. package/scripts/lib/project-init-lib.sh +3 -3
  125. package/scripts/migrate-windows-wsl-controller-home.ts +2 -0
  126. package/scripts/open-source-audit-allowlist.txt +0 -1
  127. package/scripts/run-governed-gate.ts +2 -0
  128. package/scripts/smoke-ios-physical-device.ts +38 -10
  129. package/scripts/smoke-mcp-http-runtime.ts +7 -8
  130. package/scripts/smoke-mcp-tool-surface.ts +27 -41
  131. package/scripts/smoke-workflow-supervisor-chrome-adapter.ts +6 -3
  132. package/scripts/sync-generated-authority.mjs +0 -1
  133. package/src/cli/agent-jobs/executor-health.ts +1 -1
  134. package/src/cli/agent-jobs/integration.ts +2 -2
  135. package/src/cli/chatgpt-browser/file-policy.ts +2 -2
  136. package/src/cli/commands/doctor.ts +1 -143
  137. package/src/cli/commands/global-runtime.ts +3 -196
  138. package/src/cli/commands/init-hook.ts +6 -23
  139. package/src/cli/commands/init.ts +3 -252
  140. package/src/cli/commands/mcp.ts +0 -5
  141. package/src/cli/commands/prompt-guard-decision.ts +0 -2
  142. package/src/cli/commands/recovery.ts +2 -14
  143. package/src/cli/commands/repository.ts +17 -1
  144. package/src/cli/commands/setup-execution.ts +41 -0
  145. package/src/cli/controller/completion-orchestrator.ts +1 -1
  146. package/src/cli/controller/composite-operations.ts +1 -1
  147. package/src/cli/controller/context/instruction-context.ts +1 -1
  148. package/src/cli/controller/context/known-paths.ts +2 -2
  149. package/src/cli/controller/context/query-planning.ts +11 -4
  150. package/src/cli/controller/context/rule-resolution.ts +2 -2
  151. package/src/cli/controller/context/source-materializer.ts +2 -2
  152. package/src/cli/controller/context/structural-provider.ts +84 -0
  153. package/src/cli/controller/context/structural.ts +6 -6
  154. package/src/cli/controller/context/types.ts +8 -9
  155. package/src/cli/controller/context-pack.ts +97 -76
  156. package/src/cli/controller/operational-plan.ts +1 -1
  157. package/src/cli/controller/systemd-user.ts +4 -10
  158. package/src/cli/editing/edit-session.ts +17 -5
  159. package/src/cli/github/github.ts +4 -4
  160. package/src/cli/github/semantic-projection.ts +174 -0
  161. package/src/cli/hook/prompt-intents.ts +0 -9
  162. package/src/cli/index.ts +1 -43
  163. package/src/cli/local-bridge/connector-freshness.ts +1 -12
  164. package/src/cli/local-bridge/console-automations.ts +1 -1
  165. package/src/cli/local-bridge/console-view-models.ts +1 -1
  166. package/src/cli/local-bridge/facade-api.ts +0 -2
  167. package/src/cli/repositories/command-classifier.ts +0 -9
  168. package/src/cli/repositories/command-scope.ts +2 -2
  169. package/src/cli/repositories/locks.ts +20 -0
  170. package/src/cli/repositories/registry.ts +2 -1
  171. package/src/cli/repositories/safe-patch.ts +2 -12
  172. package/src/cli/repositories/structured-git.ts +39 -3
  173. package/src/cli/repository/inspector.ts +185 -343
  174. package/src/effects/process-runner.ts +17 -1
  175. package/src/runtime/context/generic-lsp-provider.ts +1 -1
  176. package/src/runtime/context/semantic-navigation-contract.ts +7 -0
  177. package/src/runtime/context/semantic-navigation.ts +1 -1
  178. package/src/runtime/control-plane/cleanup-artifact-retention.ts +4 -4
  179. package/src/runtime/control-plane/execution/work-delivery-service.ts +150 -31
  180. package/src/runtime/control-plane/execution/work-handle-authority.ts +12 -4
  181. package/src/runtime/control-plane/execution/work-handle-store.ts +53 -1
  182. package/src/runtime/control-plane/execution/work-operation-service.ts +20 -10
  183. package/src/runtime/control-plane/execution/work-preparation-service.ts +108 -4
  184. package/src/runtime/control-plane/execution/work-process-evidence.ts +2 -2
  185. package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +28 -13
  186. package/src/runtime/control-plane/execution/work-validation-reconciler.ts +5 -1
  187. package/src/runtime/control-plane/execution/work-verification-snapshot.ts +1 -1
  188. package/src/runtime/control-plane/facade/capability-registry.ts +2 -0
  189. package/src/runtime/control-plane/facade/work-continuation.ts +1 -1
  190. package/src/runtime/control-plane/generated-cache-retention.ts +114 -63
  191. package/src/runtime/control-plane/global-scheduler/maintenance.ts +20 -8
  192. package/src/runtime/control-plane/global-scheduler/reconciliation.ts +1 -11
  193. package/src/runtime/control-plane/governance/external-effects.ts +1 -1
  194. package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +1 -0
  195. package/src/runtime/control-plane/runtime-cleanup.ts +12 -93
  196. package/src/runtime/evidence/sensitive-output.ts +22 -2
  197. package/src/runtime/execution/jobs/child-reference.ts +11 -0
  198. package/src/runtime/execution/jobs/receipt-recovery.ts +1 -11
  199. package/src/runtime/execution/process-runtime/command-facade.ts +3 -3
  200. package/src/runtime/execution/process-runtime/runtime.ts +20 -16
  201. package/src/runtime/execution/thin-harness/execution-router.ts +16 -16
  202. package/src/runtime/execution/thin-harness/fast-executor.ts +2 -2
  203. package/src/runtime/execution/thin-harness/search-worker.ts +2 -2
  204. package/src/runtime/execution/workers/executor.ts +1 -2
  205. package/src/runtime/maintenance/cleanup.ts +41 -5
  206. package/src/runtime/plugins/action-application.ts +12 -1
  207. package/src/runtime/plugins/app-store-connect-adapter.ts +252 -4
  208. package/src/runtime/plugins/browser-adapter.ts +381 -313
  209. package/src/runtime/plugins/browser-macos-bridge.ts +114 -112
  210. package/src/runtime/plugins/browser-manifest-surface.ts +2 -1
  211. package/src/runtime/plugins/browser-registration.ts +2 -0
  212. package/src/runtime/plugins/browser-runtime.ts +26 -35
  213. package/src/runtime/plugins/computer-chatgpt-browser-adapter-installer.ts +11 -2
  214. package/src/runtime/plugins/computer-registration.ts +76 -9
  215. package/src/runtime/plugins/github-adapter.ts +30 -3
  216. package/src/runtime/plugins/gmail-adapter.ts +166 -1
  217. package/src/runtime/plugins/google-shared.ts +10 -5
  218. package/src/runtime/plugins/ios/remote-xpc-hid.ts +70 -30
  219. package/src/runtime/plugins/ios-adapter.ts +45 -40
  220. package/src/runtime/plugins/ios-agent-device.ts +54 -4
  221. package/src/runtime/plugins/ios-device-ownership.ts +103 -0
  222. package/src/runtime/plugins/ios-physical-device.ts +497 -79
  223. package/src/runtime/plugins/local-system-adapter.ts +1 -99
  224. package/src/runtime/plugins/store.ts +80 -7
  225. package/src/runtime/plugins/types.ts +4 -0
  226. package/src/runtime/projections/git-status-sampler.ts +2 -19
  227. package/src/runtime/recovery/actions.ts +1 -1
  228. package/src/runtime/recovery/lifecycle-inventory.ts +1 -11
  229. package/src/runtime/recovery/probe.ts +2 -2
  230. package/src/runtime/release/release-coordinator.ts +20 -4
  231. package/src/runtime/root/controller-progression-composition.ts +67 -5
  232. package/src/runtime/root/package-connector-service.ts +123 -11
  233. package/src/runtime/root/package-runtime-release.ts +6 -18
  234. package/src/runtime/root/package-runtime-service.ts +7 -13
  235. package/src/runtime/root/release-execution-canary.ts +18 -5
  236. package/src/runtime/root/release-manifest.ts +0 -34
  237. package/src/runtime/root/release-materialize.ts +0 -78
  238. package/src/runtime/root/runtime.ts +1 -2
  239. package/src/runtime/root/scheduled-controller-composition.ts +2 -1
  240. package/src/runtime/root/service.ts +90 -11
  241. package/src/runtime/root/types.ts +0 -6
  242. package/src/runtime/root/workflow-supervisor-composition.ts +207 -19
  243. package/src/runtime/root/workflow-supervisor-runtime.ts +365 -10
  244. package/src/runtime/safe-tooling/google-credential-store.ts +1 -11
  245. package/src/runtime/safe-tooling/ios-development.ts +22 -8
  246. package/src/runtime/safe-tooling/job-summary.ts +1 -1
  247. package/src/runtime/safe-tooling/workspace-auth.ts +4 -1
  248. package/src/runtime/shared/atomic-text-file.ts +21 -0
  249. package/src/runtime/shared/json-files.ts +8 -3
  250. package/src/runtime/standalone-recovery/core.ts +189 -174
  251. package/src/runtime/standalone-recovery/entry.ts +62 -30
  252. package/src/runtime/standalone-recovery/operation-lock.ts +11 -1
  253. package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +1 -0
  254. package/src/runtime/workflow/schedules/engine.ts +36 -14
  255. package/src/runtime/workflow/schedules/pending-activation.ts +11 -4
  256. package/src/runtime/workflow/schedules/work-continuation.ts +51 -6
  257. package/supervisor/client.ts +31 -14
  258. package/supervisor/control-plane.ts +210 -115
  259. package/supervisor/forge-validators.ts +88 -21
  260. package/supervisor/native-browser-adapter.ts +393 -28
  261. package/supervisor/native-messaging/host.ts +21 -2
  262. package/supervisor/protocol.ts +74 -26
  263. package/supervisor/server.ts +16 -8
  264. package/supervisor/store.ts +476 -57
  265. package/supervisor/types.ts +19 -13
  266. package/SKILL.md +0 -427
  267. package/adapters/computer/chatgpt-target-router.ts +0 -103
  268. package/adapters/mcp/runtime-gateway/automation-receipt-adapter.ts +0 -87
  269. package/adapters/mcp/runtime-gateway/work-validation-reconciler.ts +0 -1
  270. package/adapters/mcp/toolset-selection.ts +0 -41
  271. package/agents/openai.yaml +0 -4
  272. package/assets/skill-hooks.json +0 -41
  273. package/assets/skill-version.json +0 -189
  274. package/assets/skills/claude-review/SKILL.md +0 -231
  275. package/assets/skills/codex-review/SKILL.md +0 -103
  276. package/assets/templates/helpers/check-skill-version.ts +0 -193
  277. package/scripts/check-skill-version.ts +0 -5
  278. package/scripts/ensure-codegraph.sh +0 -16
  279. package/scripts/run-skill-hook.ts +0 -244
  280. package/scripts/sync-codex-installed-copies.sh +0 -182
  281. package/src/cli/commands/tools.ts +0 -167
  282. package/src/cli/mcp/access-mode.ts +0 -2
  283. package/src/cli/mcp/access-tools.ts +0 -2
  284. package/src/cli/mcp/audit.ts +0 -2
  285. package/src/cli/mcp/auth.ts +0 -2
  286. package/src/cli/mcp/instructions.ts +0 -2
  287. package/src/cli/mcp/legacy-context.ts +0 -2
  288. package/src/cli/mcp/legacy-tool-service.ts +0 -2
  289. package/src/cli/mcp/multi-repository.ts +0 -2
  290. package/src/cli/mcp/oauth.ts +0 -2
  291. package/src/cli/mcp/openai-secure-tunnel.ts +0 -2
  292. package/src/cli/mcp/paths.ts +0 -2
  293. package/src/cli/mcp/policy.ts +0 -2
  294. package/src/cli/mcp/post-finalize-work-attribution.ts +0 -2
  295. package/src/cli/mcp/proxy-env.ts +0 -2
  296. package/src/cli/mcp/readiness-projection.ts +0 -2
  297. package/src/cli/mcp/redaction.ts +0 -2
  298. package/src/cli/mcp/repo.ts +0 -2
  299. package/src/cli/mcp/repository-tools.ts +0 -2
  300. package/src/cli/mcp/server.ts +0 -2
  301. package/src/cli/mcp/setup.ts +0 -2
  302. package/src/cli/mcp/tool-capability-cache.ts +0 -2
  303. package/src/cli/mcp/tool-contract.ts +0 -2
  304. package/src/cli/mcp/tools.ts +0 -2
  305. package/src/cli/mcp/toolset-names.ts +0 -2
  306. package/src/cli/mcp/toolset-selection.ts +0 -2
  307. package/src/cli/mcp/toolset.ts +0 -2
  308. package/src/cli/mcp/transports/http.ts +0 -2
  309. package/src/cli/mcp/transports/session-registry.ts +0 -2
  310. package/src/cli/mcp/transports/stdio.ts +0 -2
  311. package/src/cli/mcp/types.ts +0 -2
  312. package/src/cli/mcp/umbrella-tools.ts +0 -2
  313. package/src/cli/tools/codegraph.ts +0 -695
  314. package/src/core/adoption/helper-wrapper-plan.ts +0 -159
  315. package/src/runtime/context/codegraph-cache-boundary.ts +0 -255
  316. package/src/runtime/context/codegraph-read-provider.ts +0 -611
  317. package/src/runtime/context/codegraph-sidecar.cjs +0 -248
  318. package/src/runtime/control-plane/codegraph-cache-retention.ts +0 -164
  319. package/src/runtime/gateway/mcp/execution-tools.ts +0 -2
  320. package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +0 -2
  321. package/src/runtime/gateway/mcp/persisted-check-process.ts +0 -2
  322. package/src/runtime/gateway/mcp/process-tools.ts +0 -2
  323. package/src/runtime/gateway/mcp/router.ts +0 -2
  324. package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +0 -2
  325. package/src/runtime/gateway/mcp/runtime-tools.ts +0 -2
  326. package/src/runtime/gateway/mcp/work-validation-reconciler.ts +0 -2
  327. package/src/runtime/plugins/browser-provider-registry.ts +0 -2
  328. package/src/runtime/plugins/computer-chatgpt-macos-target.ts +0 -891
@@ -1,8 +1,9 @@
1
+ import { writeAtomicTextFile } from '../shared/atomic-text-file';
1
2
  import { createHash } from 'crypto';
2
- import { chmodSync, copyFileSync, existsSync, lstatSync, mkdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from 'fs';
3
+ import { chmodSync, copyFileSync, existsSync, lstatSync, mkdirSync, readFileSync, renameSync, rmSync, statSync } from 'fs';
3
4
  import { homedir } from 'os';
4
5
  import { basename, dirname, join, resolve } from 'path';
5
- import { loadMcpServiceLocalConfig } from '../../cli/mcp/auth';
6
+ import { loadMcpServiceLocalConfig } from '../../../adapters/mcp/auth';
6
7
  import { runtimeAuthorityFreeEnvironment } from '../shared/process-environment';
7
8
  import type { PackageRuntimeRelease } from './package-runtime-release';
8
9
  import { createPlatformServiceManagerHost, platformLaunchdInstalledPath, type PlatformServiceManagerHost, type SystemdUserUnitInput } from '../platform/service-manager';
@@ -49,19 +50,22 @@ export interface PackageConnectorServiceResult {
49
50
  releaseRoot?: string;
50
51
  }
51
52
 
53
+ export interface PackageConnectorCutoverDrainMarker {
54
+ schemaVersion: 1;
55
+ sessionId: string;
56
+ stableReleaseId: string;
57
+ connectorEndpoint: string;
58
+ connectorInstalledAt: string;
59
+ ownerPid: number;
60
+ armedAt: string;
61
+ }
62
+
52
63
  export type PackageConnectorAuthMode = 'oauth' | 'none';
53
64
 
54
65
  function xml(value: string): string {
55
66
  return value.replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;');
56
67
  }
57
68
 
58
- function atomicWrite(path: string, content: string, mode = 0o600): void {
59
- mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
60
- const temporary = `${path}.${process.pid}.tmp`;
61
- writeFileSync(temporary, content, { encoding: 'utf8', mode });
62
- renameSync(temporary, path);
63
- }
64
-
65
69
  export function packageConnectorServicePaths(controllerHome: string, accountHome = process.env.HOME ?? homedir()): PackageConnectorServicePaths {
66
70
  const home = resolve(controllerHome);
67
71
  const label = forgeConnectorPersistentServiceLabel(home);
@@ -78,6 +82,114 @@ export function packageConnectorServicePaths(controllerHome: string, accountHome
78
82
  };
79
83
  }
80
84
 
85
+ const PACKAGE_CONNECTOR_CUTOVER_DRAIN_TTL_MS = 10 * 60_000;
86
+
87
+ export function packageConnectorCutoverDrainMarkerPath(controllerHome: string): string {
88
+ return join(packageConnectorServicePaths(controllerHome).serviceRoot, 'cutover-draining.json');
89
+ }
90
+
91
+ function removePackageConnectorCutoverDrainMarker(controllerHome: string): void {
92
+ rmSync(packageConnectorCutoverDrainMarkerPath(controllerHome), { force: true });
93
+ }
94
+
95
+ function livePackageConnectorCutoverDrainMarker(
96
+ controllerHome: string,
97
+ now = Date.now(),
98
+ ): PackageConnectorCutoverDrainMarker | undefined {
99
+ const path = packageConnectorCutoverDrainMarkerPath(controllerHome);
100
+ if (!existsSync(path)) return undefined;
101
+ try {
102
+ const marker = JSON.parse(readFileSync(path, 'utf8')) as Partial<PackageConnectorCutoverDrainMarker>;
103
+ const armedAt = typeof marker.armedAt === 'string' ? Date.parse(marker.armedAt) : Number.NaN;
104
+ if (
105
+ marker.schemaVersion !== 1
106
+ || typeof marker.sessionId !== 'string'
107
+ || !marker.sessionId.trim()
108
+ || typeof marker.stableReleaseId !== 'string'
109
+ || !marker.stableReleaseId.trim()
110
+ || typeof marker.connectorEndpoint !== 'string'
111
+ || !marker.connectorEndpoint.trim()
112
+ || typeof marker.connectorInstalledAt !== 'string'
113
+ || !marker.connectorInstalledAt.trim()
114
+ || !Number.isInteger(marker.ownerPid)
115
+ || Number(marker.ownerPid) <= 0
116
+ || !Number.isFinite(armedAt)
117
+ || now - armedAt > PACKAGE_CONNECTOR_CUTOVER_DRAIN_TTL_MS
118
+ ) {
119
+ removePackageConnectorCutoverDrainMarker(controllerHome);
120
+ return undefined;
121
+ }
122
+ try {
123
+ process.kill(Number(marker.ownerPid), 0);
124
+ } catch (error) {
125
+ if ((error as NodeJS.ErrnoException).code !== 'EPERM') {
126
+ removePackageConnectorCutoverDrainMarker(controllerHome);
127
+ return undefined;
128
+ }
129
+ }
130
+ return marker as PackageConnectorCutoverDrainMarker;
131
+ } catch {
132
+ removePackageConnectorCutoverDrainMarker(controllerHome);
133
+ return undefined;
134
+ }
135
+ }
136
+
137
+ export function armPackageConnectorCutoverDrain(input: {
138
+ controllerHome: string;
139
+ sessionId: string;
140
+ stableReleaseId: string;
141
+ connectorAuthority: PackageConnectorServiceAuthority;
142
+ }): PackageConnectorCutoverDrainMarker {
143
+ if (input.connectorAuthority.releaseId !== input.stableReleaseId) {
144
+ throw new Error(`PACKAGE_CONNECTOR_CUTOVER_DRAIN_STABLE_MISMATCH: expected ${input.stableReleaseId}, observed ${input.connectorAuthority.releaseId}`);
145
+ }
146
+ const currentAuthority = readPackageConnectorServiceAuthority(input.controllerHome);
147
+ if (
148
+ !currentAuthority
149
+ || currentAuthority.releaseId !== input.connectorAuthority.releaseId
150
+ || currentAuthority.endpoint !== input.connectorAuthority.endpoint
151
+ || currentAuthority.installedAt !== input.connectorAuthority.installedAt
152
+ ) {
153
+ throw new Error('PACKAGE_CONNECTOR_CUTOVER_DRAIN_AUTHORITY_CHANGED');
154
+ }
155
+ const marker: PackageConnectorCutoverDrainMarker = {
156
+ schemaVersion: 1,
157
+ sessionId: input.sessionId,
158
+ stableReleaseId: input.stableReleaseId,
159
+ connectorEndpoint: input.connectorAuthority.endpoint,
160
+ connectorInstalledAt: input.connectorAuthority.installedAt,
161
+ ownerPid: process.pid,
162
+ armedAt: new Date().toISOString(),
163
+ };
164
+ const path = packageConnectorCutoverDrainMarkerPath(input.controllerHome);
165
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
166
+ writeAtomicTextFile(path, `${JSON.stringify(marker, null, 2)}\n`, 0o600);
167
+ return marker;
168
+ }
169
+
170
+ export function clearPackageConnectorCutoverDrain(controllerHome: string): void {
171
+ removePackageConnectorCutoverDrainMarker(controllerHome);
172
+ }
173
+
174
+ export function packageConnectorCutoverDrainIsActive(
175
+ controllerHome: string,
176
+ connectorEndpoint: string,
177
+ now = Date.now(),
178
+ ): boolean {
179
+ const marker = livePackageConnectorCutoverDrainMarker(controllerHome, now);
180
+ if (!marker || marker.connectorEndpoint !== connectorEndpoint) return false;
181
+ let authority: PackageConnectorServiceAuthority | undefined;
182
+ try {
183
+ authority = readPackageConnectorServiceAuthority(controllerHome);
184
+ } catch {
185
+ return true;
186
+ }
187
+ if (!authority) return true;
188
+ return authority.releaseId === marker.stableReleaseId
189
+ && authority.endpoint === marker.connectorEndpoint
190
+ && authority.installedAt === marker.connectorInstalledAt;
191
+ }
192
+
81
193
  export function readPackageConnectorServiceAuthority(controllerHome: string): PackageConnectorServiceAuthority | undefined {
82
194
  const path = packageConnectorServicePaths(controllerHome).authorityPath;
83
195
  if (!existsSync(path)) return undefined;
@@ -111,7 +223,7 @@ function writePackageConnectorServiceAuthority(input: { release: PackageConnecto
111
223
  ...(artifact ? { connectorArtifactIdentity: artifact.identity } : {}),
112
224
  installedAt: input.installedAt ?? new Date().toISOString(),
113
225
  };
114
- atomicWrite(paths.authorityPath, `${JSON.stringify(authority, null, 2)}\n`);
226
+ writeAtomicTextFile(paths.authorityPath, `${JSON.stringify(authority, null, 2)}\n`);
115
227
  }
116
228
 
117
229
  export function packageConnectorEndpointStatusHealthy(status: number, authMode: PackageConnectorAuthMode = 'oauth'): boolean {
@@ -403,7 +515,7 @@ export async function installPackageConnectorService(input: { release: PackageCo
403
515
  port: launch.port,
404
516
  requiredArguments: ['mcp', 'serve', '--auth', launch.authMode],
405
517
  });
406
- atomicWrite(paths.sourcePlistPath, renderPackageConnectorLaunchAgent({ paths, launch }), 0o600);
518
+ writeAtomicTextFile(paths.sourcePlistPath, renderPackageConnectorLaunchAgent({ paths, launch }), 0o600);
407
519
  serviceHost.installLaunchd(paths.sourcePlistPath, paths.label);
408
520
  const result = await serviceHost.bootstrapLaunchd({ label: paths.label, plistPath: paths.installedPlistPath });
409
521
  if (!result.ok) throw new Error(`FORGE_PACKAGE_CONNECTOR_LAUNCHD_INSTALL_FAILED: ${result.diagnostics.join('; ')}`);
@@ -1,3 +1,4 @@
1
+ import { writeAtomicTextFile } from '../shared/atomic-text-file';
1
2
  import { createHash, randomUUID } from 'crypto';
2
3
  import { chmodSync, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from 'fs';
3
4
  import { dirname, join, relative, resolve } from 'path';
@@ -10,7 +11,6 @@ import { assertRuntimeReleaseExecutionSurface } from './release-manifest';
10
11
  import { assertRuntimeReleaseExecutionCanaries } from './release-execution-canary';
11
12
  import type { RuntimeReleaseManifest } from './types';
12
13
  import { assertStorageHeadroom } from '../shared/storage-capacity';
13
- import { PROCESS_RUNTIME_RELEASE_CANARY_ARG } from '../execution/process-runtime/canary';
14
14
 
15
15
  export interface PackageRuntimeFileRecord {
16
16
  path: string;
@@ -67,13 +67,6 @@ function sha256(value: Buffer | string): string {
67
67
  return createHash('sha256').update(value).digest('hex');
68
68
  }
69
69
 
70
- function atomicWrite(path: string, content: string, mode = 0o600): void {
71
- mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
72
- const temporary = `${path}.${process.pid}.${randomUUID().slice(0, 8)}.tmp`;
73
- writeFileSync(temporary, content, { encoding: 'utf8', mode });
74
- renameSync(temporary, path);
75
- }
76
-
77
70
  function walkRegularFiles(root: string, current: string, output: string[], prefix = ''): void {
78
71
  if (!existsSync(current)) return;
79
72
  const stat = lstatSync(current);
@@ -226,7 +219,6 @@ function launcherSource(input: {
226
219
  indexSha256: string;
227
220
  entryRelativePath?: string;
228
221
  managerSignalsProcessGroup?: boolean;
229
- ownsProcessRuntimeCanary?: boolean;
230
222
  }): string {
231
223
  const entryRelativePath = input.entryRelativePath ?? 'src/runtime/root/entry.ts';
232
224
  return `#!${process.execPath}\n`
@@ -249,8 +241,6 @@ function launcherSource(input: {
249
241
  + `if(digest(raw)!==expectedIndex){console.error('FORGE_PACKAGE_RUNTIME_INDEX_CHANGED');process.exit(78);}\n`
250
242
  + `let records; try { records=JSON.parse(raw.toString('utf8')).files; } catch { console.error('FORGE_PACKAGE_RUNTIME_INDEX_INVALID'); process.exit(78); }\n`
251
243
  + `for(const record of records){const path=join(packageRoot,record.path);if(!existsSync(path)||digest(readFileSync(path))!==record.sha256){console.error('FORGE_PACKAGE_RUNTIME_SOURCE_CHANGED: '+record.path);process.exit(78);}}\n`
252
- + `const ownsProcessRuntimeCanary=${input.ownsProcessRuntimeCanary === true ? 'true' : 'false'};\n`
253
- + `if(ownsProcessRuntimeCanary&&process.argv.length===3&&process.argv[2]===${JSON.stringify(PROCESS_RUNTIME_RELEASE_CANARY_ARG)})process.exit(0);\n`
254
244
  + `const entry=join(packageRoot,...${JSON.stringify(entryRelativePath.split('/'))});\n`
255
245
  + `const loader=join(packageRoot,'src','runtime','shared','node-ts-loader.mjs');\n`
256
246
  + `const args=process.versions?.bun?[entry,...process.argv.slice(2)]:['--loader',loader,entry,...process.argv.slice(2)];\n`
@@ -357,7 +347,6 @@ export function materializePackageRuntimeRelease(input: {
357
347
  const processRunnerLauncher = launcherSource({
358
348
  indexSha256,
359
349
  entryRelativePath: 'src/runtime/execution/process-runtime/process-runner-entry.ts',
360
- ownsProcessRuntimeCanary: true,
361
350
  });
362
351
  const processRunnerArtifactIdentity = `sha256:${sha256(Buffer.from(processRunnerLauncher))}`;
363
352
  const checkRunnerEntrypoint = 'forge-check-runner' as const;
@@ -365,7 +354,6 @@ export function materializePackageRuntimeRelease(input: {
365
354
  const checkRunnerLauncher = launcherSource({
366
355
  indexSha256,
367
356
  entryRelativePath: 'src/runtime/execution/process-runtime/check-runner-sidecar.ts',
368
- ownsProcessRuntimeCanary: true,
369
357
  });
370
358
  const checkRunnerArtifactIdentity = `sha256:${sha256(Buffer.from(checkRunnerLauncher))}`;
371
359
  const expectedManifest: Omit<RuntimeReleaseManifest, 'createdAt'> = {
@@ -413,16 +401,16 @@ export function materializePackageRuntimeRelease(input: {
413
401
  try {
414
402
  mkdirSync(stagingRoot, { recursive: false, mode: 0o700 });
415
403
  stagePackageRuntimeSnapshot(sourcePackageRoot, join(stagingRoot, 'package'), records);
416
- atomicWrite(join(stagingRoot, 'package-files.json'), indexJson);
417
- atomicWrite(join(stagingRoot, 'forge-runtime'), launcher, 0o700);
404
+ writeAtomicTextFile(join(stagingRoot, 'package-files.json'), indexJson);
405
+ writeAtomicTextFile(join(stagingRoot, 'forge-runtime'), launcher, 0o700);
418
406
  chmodSync(join(stagingRoot, 'forge-runtime'), 0o700);
419
- atomicWrite(join(stagingRoot, processRunnerEntrypoint), processRunnerLauncher, 0o700);
407
+ writeAtomicTextFile(join(stagingRoot, processRunnerEntrypoint), processRunnerLauncher, 0o700);
420
408
  chmodSync(join(stagingRoot, processRunnerEntrypoint), 0o700);
421
- atomicWrite(join(stagingRoot, checkRunnerEntrypoint), checkRunnerLauncher, 0o700);
409
+ writeAtomicTextFile(join(stagingRoot, checkRunnerEntrypoint), checkRunnerLauncher, 0o700);
422
410
  chmodSync(join(stagingRoot, checkRunnerEntrypoint), 0o700);
423
411
  const manifest: RuntimeReleaseManifest = { ...expectedManifest, createdAt: new Date().toISOString() };
424
412
  const stagingManifestPath = join(stagingRoot, 'manifest.json');
425
- atomicWrite(stagingManifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
413
+ writeAtomicTextFile(stagingManifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
426
414
  // A failed execution surface is still a staging failure. Do not promote an
427
415
  // immutable release directory until both manifest-owned runners execute
428
416
  // their bounded no-op canary successfully.
@@ -1,5 +1,6 @@
1
+ import { writeAtomicTextFile } from '../shared/atomic-text-file';
1
2
  import { randomUUID } from 'crypto';
2
- import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'fs';
3
+ import { existsSync, readFileSync, rmSync } from 'fs';
3
4
  import { setTimeout as sleep } from 'timers/promises';
4
5
  import { dirname, join, resolve } from 'path';
5
6
  import { resolveControllerHome } from '../../cli/repositories/controller-home';
@@ -114,13 +115,6 @@ export interface PackageRuntimeActivationDependencies {
114
115
  cleanupActivationHelper?: (request: PackageRuntimeActivationRequest) => Promise<void>;
115
116
  }
116
117
 
117
- function atomicWrite(path: string, content: string, mode = 0o600): void {
118
- mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
119
- const temporary = `${path}.${process.pid}.tmp`;
120
- writeFileSync(temporary, content, { encoding: 'utf8', mode });
121
- renameSync(temporary, path);
122
- }
123
-
124
118
  export function renderForgeRuntimeSystemdUserUnit(input: {
125
119
  description?: string;
126
120
  executable: string;
@@ -189,7 +183,7 @@ function startPortableRuntime(controllerHome: string, env: NodeJS.ProcessEnv, ho
189
183
  stderrPath: paths.stderrPath,
190
184
  errorCode: 'FORGE_PORTABLE_RUNTIME_START_FAILED',
191
185
  });
192
- atomicWrite(join(paths.serviceRoot, 'portable.json'), `${JSON.stringify({ schemaVersion: 1, pid, startedAt: new Date().toISOString() }, null, 2)}\n`);
186
+ writeAtomicTextFile(join(paths.serviceRoot, 'portable.json'), `${JSON.stringify({ schemaVersion: 1, pid, startedAt: new Date().toISOString() }, null, 2)}\n`);
193
187
  return pid;
194
188
  }
195
189
 
@@ -208,7 +202,7 @@ function activationPaths(controllerHome: string, operationId: string): { request
208
202
  }
209
203
 
210
204
  function writeActivationRequest(request: PackageRuntimeActivationRequest): void {
211
- atomicWrite(request.requestPath, `${JSON.stringify(request, null, 2)}\n`);
205
+ writeAtomicTextFile(request.requestPath, `${JSON.stringify(request, null, 2)}\n`);
212
206
  }
213
207
 
214
208
  function writeActivationReceipt(
@@ -232,7 +226,7 @@ function writeActivationReceipt(
232
226
  helperLabel: request.helperLabel,
233
227
  ...extra,
234
228
  };
235
- atomicWrite(request.receiptPath, `${JSON.stringify(receipt, null, 2)}\n`);
229
+ writeAtomicTextFile(request.receiptPath, `${JSON.stringify(receipt, null, 2)}\n`);
236
230
  return receipt;
237
231
  }
238
232
 
@@ -299,7 +293,7 @@ export function renderPackageRuntimeActivationLaunchAgent(request: PackageRuntim
299
293
  async function scheduleDarwinPackageRuntimeActivation(request: PackageRuntimeActivationRequest): Promise<{ label: string; servicePath: string }> {
300
294
  if (process.platform !== 'darwin') throw new Error('FORGE_PACKAGE_RUNTIME_ACTIVATION_HELPER_PLATFORM_UNSUPPORTED');
301
295
  const host = createPlatformServiceManagerHost({ platform: 'darwin' });
302
- atomicWrite(request.helperSourcePlistPath, renderPackageRuntimeActivationLaunchAgent(request), 0o600);
296
+ writeAtomicTextFile(request.helperSourcePlistPath, renderPackageRuntimeActivationLaunchAgent(request), 0o600);
303
297
  host.installLaunchd(request.helperSourcePlistPath, request.helperLabel);
304
298
  const result = await host.bootstrapLaunchd({ label: request.helperLabel, plistPath: request.helperInstalledPlistPath });
305
299
  if (!result.ok) throw new Error(`FORGE_PACKAGE_RUNTIME_ACTIVATION_HELPER_BOOTSTRAP_FAILED: ${result.diagnostics.join('; ')}`);
@@ -351,7 +345,7 @@ async function rollbackPackageRuntimeActivation(
351
345
  }
352
346
  try {
353
347
  if (request.priorConfigBytes === undefined) rmSync(servicePaths.configPath, { force: true });
354
- else atomicWrite(servicePaths.configPath, request.priorConfigBytes);
348
+ else writeAtomicTextFile(servicePaths.configPath, request.priorConfigBytes);
355
349
  syncForgeRuntimeActiveEntrypoint(request.controllerHome);
356
350
  } catch (error) {
357
351
  errors.push(error instanceof Error ? error.message : String(error));
@@ -1,3 +1,4 @@
1
+ import { readFileSync } from 'fs';
1
2
  import { join } from 'path';
2
3
  import { runProcess } from '../../effects/process-runner';
3
4
  import { PROCESS_RUNTIME_RELEASE_CANARY_ARG } from '../execution/process-runtime/canary';
@@ -25,9 +26,9 @@ export interface RuntimeReleaseExecutionCanaryDependencies {
25
26
  /**
26
27
  * Release execution canaries deliberately do not inherit developer-tool PATH
27
28
  * entries. Standalone-binary artifacts must execute without Homebrew, Bun, nvm,
28
- * or similar PATH dependencies. Legacy script releases predate the embedded
29
- * Runtime interpreter and are probed through the same explicitly resolved Bun
30
- * executable that their Process Runtime uses in production.
29
+ * or similar PATH dependencies. Legacy source scripts are probed through the
30
+ * same explicitly resolved Bun executable that their Process Runtime uses in
31
+ * production, while executable shebangs remain the artifact's own launch contract.
31
32
  */
32
33
  export function runtimeReleaseCanaryEnvironment(
33
34
  env: NodeJS.ProcessEnv = process.env,
@@ -43,6 +44,17 @@ export function runtimeReleaseCanaryEnvironment(
43
44
  return { ...env, PATH: '/usr/bin:/bin:/usr/sbin:/sbin' };
44
45
  }
45
46
 
47
+ /**
48
+ * Execute legacy JavaScript/TypeScript through the resolved Bun runtime only
49
+ * when the artifact does not declare a different executable shebang.
50
+ */
51
+ function releaseScriptRequiresBun(entryPath: string): boolean {
52
+ const firstLine = readFileSync(entryPath, 'utf8').split(/\r?\n/, 1)[0]?.trim() ?? '';
53
+ if (!firstLine.startsWith('#!')) return true;
54
+ const shebangTokens = firstLine.slice(2).trim().split(/\s+/).filter(Boolean);
55
+ return shebangTokens.some((token) => /(?:^|\/)bun(?:\.exe)?$/i.test(token));
56
+ }
57
+
46
58
  /**
47
59
  * Execute the minimum immutable Runtime execution surface plus the package
48
60
  * Connector CLI import graph. The latter is intentionally a help-only command:
@@ -81,10 +93,11 @@ export function assertRuntimeReleaseExecutionCanaries(
81
93
  const args = entry.canary === 'runtime_interpreter' ? ['--version'] : [PROCESS_RUNTIME_RELEASE_CANARY_ARG];
82
94
  const legacyScript = surface.manifest.executionMode !== 'standalone-binary'
83
95
  && /\.(?:[cm]?js|tsx?)$/i.test(entry.path);
96
+ const usesExplicitBun = legacyScript && releaseScriptRequiresBun(entry.path);
84
97
  assertCanary({
85
98
  name: entry.name,
86
- executable: legacyScript ? resolveBunExecutable(process.execPath, process.env) : entry.path,
87
- args: legacyScript ? [entry.path, ...args] : args,
99
+ executable: usesExplicitBun ? resolveBunExecutable(process.execPath, process.env) : entry.path,
100
+ args: usesExplicitBun ? [entry.path, ...args] : args,
88
101
  });
89
102
  }
90
103
 
@@ -65,9 +65,6 @@ export const COMPILED_RUNTIME_RELEASE_COMPONENT_FIELDS = [
65
65
  'periodicCleanupEntrypoint', 'periodicCleanupArtifactIdentity',
66
66
  'pluginActionSidecarEntrypoint', 'pluginActionSidecarArtifactIdentity',
67
67
  'externalPluginProbeEntrypoint', 'externalPluginProbeArtifactIdentity',
68
- 'codeGraphNodeEntrypoint', 'codeGraphNodeArtifactIdentity',
69
- 'codeGraphSidecarEntrypoint', 'codeGraphSidecarArtifactIdentity',
70
- 'codeGraphLibraryRoot', 'codeGraphLibraryArtifactIdentity',
71
68
  'packageRoot', 'packageArtifactIdentity',
72
69
  ] as const satisfies readonly (keyof RuntimeReleaseManifest)[];
73
70
 
@@ -278,36 +275,6 @@ export function loadRuntimeReleaseManifest(
278
275
  };
279
276
  }
280
277
 
281
- const codeGraphFields = [
282
- value.codeGraphNodeEntrypoint,
283
- value.codeGraphNodeArtifactIdentity,
284
- value.codeGraphSidecarEntrypoint,
285
- value.codeGraphSidecarArtifactIdentity,
286
- value.codeGraphLibraryRoot,
287
- value.codeGraphLibraryArtifactIdentity,
288
- ];
289
- const hasCodeGraphRuntime = codeGraphFields.some((entry) => entry !== undefined);
290
- let codeGraphRuntime: Pick<RuntimeReleaseManifest,
291
- 'codeGraphNodeEntrypoint' | 'codeGraphNodeArtifactIdentity'
292
- | 'codeGraphSidecarEntrypoint' | 'codeGraphSidecarArtifactIdentity'
293
- | 'codeGraphLibraryRoot' | 'codeGraphLibraryArtifactIdentity'> | undefined;
294
- if (hasCodeGraphRuntime) {
295
- const nodeEntrypoint = requireString(value.codeGraphNodeEntrypoint, 'codeGraphNodeEntrypoint');
296
- const sidecarEntrypoint = requireString(value.codeGraphSidecarEntrypoint, 'codeGraphSidecarEntrypoint');
297
- const libraryRoot = requireString(value.codeGraphLibraryRoot, 'codeGraphLibraryRoot');
298
- if (nodeEntrypoint !== 'codegraph-node' || sidecarEntrypoint !== 'codegraph-sidecar.cjs' || libraryRoot !== 'codegraph-lib') {
299
- throw new Error('RELEASE_MANIFEST_INVALID: CodeGraph release paths must use the canonical co-located names');
300
- }
301
- codeGraphRuntime = {
302
- codeGraphNodeEntrypoint: 'codegraph-node',
303
- codeGraphNodeArtifactIdentity: requireSha256Identity(value.codeGraphNodeArtifactIdentity, 'codeGraphNodeArtifactIdentity'),
304
- codeGraphSidecarEntrypoint: 'codegraph-sidecar.cjs',
305
- codeGraphSidecarArtifactIdentity: requireSha256Identity(value.codeGraphSidecarArtifactIdentity, 'codeGraphSidecarArtifactIdentity'),
306
- codeGraphLibraryRoot: 'codegraph-lib',
307
- codeGraphLibraryArtifactIdentity: requireSha256Identity(value.codeGraphLibraryArtifactIdentity, 'codeGraphLibraryArtifactIdentity'),
308
- };
309
- }
310
-
311
278
  const argumentsValue = value.arguments;
312
279
  if (!Array.isArray(argumentsValue) || argumentsValue.some((item) => typeof item !== 'string')) {
313
280
  throw new Error('RELEASE_MANIFEST_INVALID: arguments must be a string array');
@@ -341,7 +308,6 @@ export function loadRuntimeReleaseManifest(
341
308
  ...(pluginActionSidecar ?? {}),
342
309
  ...(externalPluginProbe ?? {}),
343
310
  ...(browserAutomationHelper ?? {}),
344
- ...(codeGraphRuntime ?? {}),
345
311
  ...(packageSnapshot ?? {}),
346
312
  ...(controllerUi ?? {}),
347
313
  arguments: argumentsValue as string[],
@@ -1,5 +1,4 @@
1
1
  import { createHash, randomUUID } from 'crypto';
2
- import { createRequire } from 'module';
3
2
  import { chmodSync, copyFileSync, cpSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, symlinkSync, writeFileSync } from 'fs';
4
3
  import { tmpdir } from 'os';
5
4
  import { dirname, join, relative, resolve } from 'path';
@@ -50,9 +49,6 @@ export interface StagedRuntimeRelease {
50
49
  periodicCleanupArtifactIdentity?: string;
51
50
  pluginActionSidecarArtifactIdentity?: string;
52
51
  externalPluginProbeArtifactIdentity?: string;
53
- codeGraphNodeArtifactIdentity?: string;
54
- codeGraphSidecarArtifactIdentity?: string;
55
- codeGraphLibraryArtifactIdentity?: string;
56
52
  packageArtifactIdentity?: string;
57
53
  controllerUiArtifactIdentity?: string;
58
54
  macosCodeSigning?: MacOSRuntimeCodeSigning;
@@ -71,12 +67,6 @@ export interface RuntimeReleaseMaterializerDependencies {
71
67
  materializeRuntimeInterpreter?: (input: { sourceRoot: string; outputPath: string }) => { ok: boolean; stderr?: string; stdout?: string; error?: string };
72
68
  bundleNodeHost?: (input: { sourceRoot: string; outputPath: string; entryPath: string }) => { ok: boolean; stderr?: string; stdout?: string; error?: string };
73
69
  bundleProcessRunner?: (input: { sourceRoot: string; outputPath: string; entryPath: string }) => { ok: boolean; stderr?: string; stdout?: string; error?: string };
74
- materializeCodeGraphRuntime?: (input: {
75
- sourceRoot: string;
76
- nodeOutputPath: string;
77
- sidecarOutputPath: string;
78
- libraryOutputPath: string;
79
- }) => { ok: boolean; stderr?: string; stdout?: string; error?: string };
80
70
  }
81
71
 
82
72
  export interface CandidateRuntimeStageReceiptV1 {
@@ -450,9 +440,6 @@ export function stageRuntimeReleaseFromCandidateSource(input: {
450
440
  periodicCleanupArtifactIdentity: manifest.periodicCleanupArtifactIdentity,
451
441
  pluginActionSidecarArtifactIdentity: manifest.pluginActionSidecarArtifactIdentity,
452
442
  externalPluginProbeArtifactIdentity: manifest.externalPluginProbeArtifactIdentity,
453
- codeGraphNodeArtifactIdentity: manifest.codeGraphNodeArtifactIdentity,
454
- codeGraphSidecarArtifactIdentity: manifest.codeGraphSidecarArtifactIdentity,
455
- codeGraphLibraryArtifactIdentity: manifest.codeGraphLibraryArtifactIdentity,
456
443
  packageArtifactIdentity: manifest.packageArtifactIdentity,
457
444
  controllerUiArtifactIdentity: manifest.controllerUiArtifactIdentity,
458
445
  ...(macosCodeSigning ? { macosCodeSigning } : {}),
@@ -526,32 +513,6 @@ function defaultBundleNodeScript(input: { sourceRoot: string; outputPath: string
526
513
  ], { cwd: input.sourceRoot, timeoutMs: 300_000, maxOutputBytes: 512 * 1024 });
527
514
  }
528
515
 
529
- function defaultMaterializeCodeGraphRuntime(input: {
530
- sourceRoot: string;
531
- nodeOutputPath: string;
532
- sidecarOutputPath: string;
533
- libraryOutputPath: string;
534
- }): { ok: boolean; stderr?: string; stdout?: string; error?: string } {
535
- try {
536
- const sourceRequire = createRequire(join(input.sourceRoot, 'package.json'));
537
- const platformPackage = `@colbymchenry/codegraph-${process.platform}-${process.arch}`;
538
- const packageJson = sourceRequire.resolve(`${platformPackage}/package.json`);
539
- const packageRoot = dirname(packageJson);
540
- const nodeSource = join(packageRoot, process.platform === 'win32' ? 'node.exe' : 'node');
541
- const librarySource = join(packageRoot, 'lib');
542
- const sidecarSource = join(input.sourceRoot, 'src', 'runtime', 'context', 'codegraph-sidecar.cjs');
543
- if (!existsSync(nodeSource) || !statSync(nodeSource).isFile()) throw new Error(`${platformPackage} Node runtime is missing`);
544
- if (!existsSync(librarySource) || !statSync(librarySource).isDirectory()) throw new Error(`${platformPackage} library is missing`);
545
- if (!existsSync(sidecarSource)) throw new Error('CodeGraph sidecar source is missing');
546
- copyFileSync(nodeSource, input.nodeOutputPath);
547
- copyFileSync(sidecarSource, input.sidecarOutputPath);
548
- cpSync(librarySource, input.libraryOutputPath, { recursive: true, force: false });
549
- return { ok: true };
550
- } catch (error) {
551
- return { ok: false, error: error instanceof Error ? error.message : String(error) };
552
- }
553
- }
554
-
555
516
  export function stageRuntimeRelease(input: {
556
517
  controllerHome: string;
557
518
  sourceRoot: string;
@@ -799,27 +760,6 @@ export function stageRuntimeRelease(input: {
799
760
  chmodSync(externalPluginProbePath, 0o700);
800
761
  const externalPluginProbeArtifactIdentity = `sha256:${sha256(externalPluginProbePath)}`;
801
762
 
802
- const codeGraphNodeEntrypoint = 'codegraph-node' as const;
803
- const codeGraphSidecarEntrypoint = 'codegraph-sidecar.cjs' as const;
804
- const codeGraphLibraryRoot = 'codegraph-lib' as const;
805
- const codeGraphNodePath = join(staging, codeGraphNodeEntrypoint);
806
- const codeGraphSidecarPath = join(staging, codeGraphSidecarEntrypoint);
807
- const codeGraphLibraryPath = join(staging, codeGraphLibraryRoot);
808
- const codeGraphRuntime = (dependencies.materializeCodeGraphRuntime ?? defaultMaterializeCodeGraphRuntime)({
809
- sourceRoot,
810
- nodeOutputPath: codeGraphNodePath,
811
- sidecarOutputPath: codeGraphSidecarPath,
812
- libraryOutputPath: codeGraphLibraryPath,
813
- });
814
- if (!codeGraphRuntime.ok) {
815
- throw new Error(`RUNTIME_RELEASE_CODEGRAPH_BUILD_FAILED: ${codeGraphRuntime.stderr || codeGraphRuntime.stdout || codeGraphRuntime.error}`.slice(0, 2_000));
816
- }
817
- chmodSync(codeGraphNodePath, 0o700);
818
- chmodSync(codeGraphSidecarPath, 0o700);
819
- const codeGraphNodeArtifactIdentity = `sha256:${sha256(codeGraphNodePath)}`;
820
- const codeGraphSidecarArtifactIdentity = `sha256:${sha256(codeGraphSidecarPath)}`;
821
- const codeGraphLibraryArtifactIdentity = `sha256:${sha256Directory(codeGraphLibraryPath)}`;
822
-
823
763
  // Keep the source-backed package projection during the Recovery migration.
824
764
  // The active standalone Recovery release can predate the compiled Connector
825
765
  // sidecar and still rebind the primary Connector through package/src/cli.
@@ -870,12 +810,6 @@ export function stageRuntimeRelease(input: {
870
810
  pluginActionSidecarArtifactIdentity,
871
811
  externalPluginProbeEntrypoint,
872
812
  externalPluginProbeArtifactIdentity,
873
- codeGraphNodeEntrypoint,
874
- codeGraphNodeArtifactIdentity,
875
- codeGraphSidecarEntrypoint,
876
- codeGraphSidecarArtifactIdentity,
877
- codeGraphLibraryRoot,
878
- codeGraphLibraryArtifactIdentity,
879
813
  packageRoot,
880
814
  packageArtifactIdentity,
881
815
  arguments: [],
@@ -917,9 +851,6 @@ export function stageRuntimeRelease(input: {
917
851
  periodicCleanupArtifactIdentity,
918
852
  pluginActionSidecarArtifactIdentity,
919
853
  externalPluginProbeArtifactIdentity,
920
- codeGraphNodeArtifactIdentity,
921
- codeGraphSidecarArtifactIdentity,
922
- codeGraphLibraryArtifactIdentity,
923
854
  packageArtifactIdentity,
924
855
  manifestSha256: createHash('sha256').update(`${JSON.stringify(manifest, null, 2)}\n`).digest('hex'),
925
856
  sourceCommit,
@@ -1165,15 +1096,6 @@ export function assertRuntimeReleaseFiles(release: StagedRuntimeRelease, depende
1165
1096
  assertComponentFile({ path: join(release.releasePath, 'forge-periodic-cleanup'), identity: release.periodicCleanupArtifactIdentity, missingCode: 'RUNTIME_RELEASE_PERIODIC_CLEANUP_MISSING', executable: true });
1166
1097
  assertComponentFile({ path: join(release.releasePath, 'forge-plugin-action-sidecar'), identity: release.pluginActionSidecarArtifactIdentity, missingCode: 'RUNTIME_RELEASE_PLUGIN_ACTION_SIDECAR_MISSING', executable: true });
1167
1098
  assertComponentFile({ path: join(release.releasePath, 'external-unix-socket-probe.cjs'), identity: release.externalPluginProbeArtifactIdentity, missingCode: 'RUNTIME_RELEASE_EXTERNAL_PLUGIN_PROBE_MISSING', executable: true });
1168
- assertComponentFile({ path: join(release.releasePath, 'codegraph-node'), identity: release.codeGraphNodeArtifactIdentity, missingCode: 'RUNTIME_RELEASE_CODEGRAPH_NODE_MISSING', executable: true });
1169
- assertComponentFile({ path: join(release.releasePath, 'codegraph-sidecar.cjs'), identity: release.codeGraphSidecarArtifactIdentity, missingCode: 'RUNTIME_RELEASE_CODEGRAPH_SIDECAR_MISSING', executable: true });
1170
- if (release.codeGraphLibraryArtifactIdentity) {
1171
- const libraryRoot = join(release.releasePath, 'codegraph-lib');
1172
- if (!existsSync(join(libraryRoot, 'dist', 'index.js'))) {
1173
- throw new Error(`RUNTIME_RELEASE_CODEGRAPH_LIBRARY_MISSING: ${join(libraryRoot, 'dist', 'index.js')}`);
1174
- }
1175
- assertDirectoryIdentity(libraryRoot, release.codeGraphLibraryArtifactIdentity);
1176
- }
1177
1099
  if (release.packageArtifactIdentity) {
1178
1100
  const packageRoot = join(release.releasePath, 'package');
1179
1101
  assertDirectoryIdentity(packageRoot, release.packageArtifactIdentity);
@@ -10,7 +10,6 @@ import {
10
10
  enableControlPlaneReadConnectionReuse,
11
11
  inspectControlPlaneDatabase,
12
12
  } from '../control-plane/persistence/sqlite-store';
13
- import { closeCodeGraphReadProviderSessions } from '../context/codegraph-read-provider';
14
13
  import { cancelAllLightweightProcesses } from '../execution/process-runtime/lightweight-managed';
15
14
  import {
16
15
  collectRuntimeSourceIdentity,
@@ -196,7 +195,7 @@ const DEFAULT_DEPENDENCIES: CanonicalRuntimeDependencies = {
196
195
  collectRuntimeSourceIdentity,
197
196
  rotateRuntimeGeneration,
198
197
  stopLightweightProcesses: cancelAllLightweightProcesses,
199
- stopContextReadHelpers: closeCodeGraphReadProviderSessions,
198
+ stopContextReadHelpers: async () => {},
200
199
  computeToolSurfaceFingerprint: runtimeGatewayToolSurfaceFingerprint,
201
200
  ensureForgeInstanceIdentity,
202
201
  captureJscSamplingProfile: captureDefaultJscSamplingProfile,
@@ -6,6 +6,7 @@ import {
6
6
  type ControllerSession,
7
7
  } from '../../../packages/kernel/controller/api/index';
8
8
  import { upsertChatgptControllerBinding } from '../../../adapters/chatgpt/controller-binding-store';
9
+ import { DEFAULT_CHATGPT_AUTOMATION_REASONING } from '../../../adapters/chatgpt/provider-delivery';
9
10
  import { getWorkContract } from '../../../packages/kernel/work/api/index';
10
11
  import { inheritWorkflowSupervisorConversationBinding } from './workflow-supervisor-composition';
11
12
  import { getChatgptWorkConversationBinding } from '../../../adapters/chatgpt/work-conversation-binding-store';
@@ -30,7 +31,7 @@ export function ensureScheduledControllerBinding(
30
31
  ].map(value => value.trim()).filter(Boolean).filter((value, index, values) => values.indexOf(value) === index),
31
32
  title: input.scheduleName,
32
33
  model: typeof input.args.model === 'string' ? input.args.model : 'gpt-5.6',
33
- reasoning: input.args.reasoning === 'medium' || input.args.reasoning === 'high' || input.args.reasoning === 'xhigh' ? input.args.reasoning : 'medium',
34
+ reasoning: input.args.reasoning === 'medium' || input.args.reasoning === 'high' || input.args.reasoning === 'xhigh' ? input.args.reasoning : DEFAULT_CHATGPT_AUTOMATION_REASONING,
34
35
  tabPolicy: input.args.tab_policy === 'reuse' || input.args.tab_policy === 'new' ? input.args.tab_policy : 'auto',
35
36
  timeoutMs: typeof input.args.timeout_ms === 'number' ? input.args.timeout_ms : undefined,
36
37
  }).binding;