@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,695 +0,0 @@
1
- import { existsSync, readFileSync, writeFileSync } from "fs";
2
- import { dirname, join, resolve } from "path";
3
- import { fileURLToPath } from "url";
4
- import { runProcess as runBoundedProcess } from "../../effects/process-runner";
5
- import { resolveControllerHome } from "../repositories/controller-home";
6
- import { createCodegraphCacheLocator, migrateLegacyCodegraphCache } from "../../runtime/context/codegraph-cache-boundary";
7
-
8
- const CLAUDE_CODEGRAPH_ALLOWED_TOOLS_PATTERN = "mcp__codegraph__*";
9
- const CLAUDE_CODEGRAPH_SERVER_NAME = "codegraph";
10
- const CODEGRAPH_SCOPED_MCP_ARGS = ["serve", "--mcp", "--path", "."] as const;
11
- const CODEGRAPH_SCOPED_MCP_TOML_ARGS = `[${CODEGRAPH_SCOPED_MCP_ARGS.map((arg) => JSON.stringify(arg)).join(", ")}]`;
12
-
13
- export type CodegraphSource = "local" | "global" | "missing";
14
- export type CodegraphStatus = "present" | "warning" | "partial" | "missing";
15
- export type CodegraphActionStatus = "changed" | "unchanged" | "failed" | "skipped";
16
- export type CodegraphHostTarget = "codex" | "claude" | "both";
17
- export type CodegraphConfigureLocation = "global" | "local";
18
-
19
- export interface CodegraphResolveOptions {
20
- repoRoot: string;
21
- env?: NodeJS.ProcessEnv;
22
- host?: CodegraphHostTarget;
23
- }
24
-
25
- export interface CodegraphEnsureOptions extends CodegraphResolveOptions {
26
- checkOnly?: boolean;
27
- init?: boolean;
28
- sync?: boolean;
29
- installDeps?: boolean;
30
- }
31
-
32
- export interface CodegraphConfigureOptions extends CodegraphResolveOptions {
33
- target: CodegraphHostTarget;
34
- location: CodegraphConfigureLocation;
35
- }
36
-
37
- export interface CodegraphResolution {
38
- source: CodegraphSource;
39
- binPath: string | null;
40
- version: string | null;
41
- localBinPath: string | null;
42
- globalBinPath: string | null;
43
- globalFallbackUsed: boolean;
44
- drift: { local: string | null; global: string | null; using: string } | null;
45
- }
46
-
47
- export interface CodegraphCheckResult {
48
- status: CodegraphStatus;
49
- reason: string;
50
- resolution: CodegraphResolution;
51
- raw: Record<string, unknown>;
52
- }
53
-
54
- export interface CodegraphEnsureResult extends CodegraphCheckResult {
55
- changed: boolean;
56
- readOnly: boolean;
57
- actions: CodegraphAction[];
58
- }
59
-
60
- export interface CodegraphConfigureResult extends CodegraphCheckResult {
61
- target: CodegraphHostTarget;
62
- location: CodegraphConfigureLocation;
63
- changed: boolean;
64
- readOnly: false;
65
- actions: CodegraphAction[];
66
- }
67
-
68
- export interface CodegraphAction {
69
- action: string;
70
- status: CodegraphActionStatus;
71
- command: string[];
72
- stdout?: string;
73
- stderr?: string;
74
- }
75
-
76
- const SCRIPT_DIR = dirname(fileURLToPath(import.meta.url));
77
- const REPO_ROOT = join(SCRIPT_DIR, "..", "..", "..");
78
-
79
- function runJson(command: string, args: string[], repoRoot: string, env?: NodeJS.ProcessEnv) {
80
- const result = runBoundedProcess(command, args, { cwd: repoRoot, env });
81
-
82
- if (!result.ok) {
83
- throw new Error(result.stderr || result.stdout || String(result.error));
84
- }
85
-
86
- return JSON.parse(result.stdout);
87
- }
88
-
89
- function run(command: string, args: string[], cwd: string, env?: NodeJS.ProcessEnv) {
90
- const result = runBoundedProcess(command, args, { cwd, env });
91
-
92
- return {
93
- ok: result.ok,
94
- status: result.status,
95
- stdout: result.stdout,
96
- stderr: result.stderr,
97
- error: result.error,
98
- };
99
- }
100
-
101
- function trimOutput(value: string) {
102
- if (value.length <= 4096) return value;
103
- return `${value.slice(0, 4096)}\n[output truncated]`;
104
- }
105
-
106
- function readJson(path: string) {
107
- try {
108
- return JSON.parse(readFileSync(path, "utf8"));
109
- } catch (_error) {
110
- return null;
111
- }
112
- }
113
-
114
- function readToolingReport(repoRoot: string, env?: NodeJS.ProcessEnv, host: CodegraphHostTarget = "codex") {
115
- const checker = join(REPO_ROOT, "scripts", "check-agent-tooling.sh");
116
- const report = runJson("bash", [checker, "--json", "--host", host], repoRoot, env);
117
- return report.tools.codegraph;
118
- }
119
-
120
- function hasCodegraphDependency(repoRoot: string) {
121
- const pkg = readJson(join(repoRoot, "package.json"));
122
- return Boolean(
123
- pkg?.devDependencies?.["@colbymchenry/codegraph"] ||
124
- pkg?.dependencies?.["@colbymchenry/codegraph"] ||
125
- pkg?.optionalDependencies?.["@colbymchenry/codegraph"]
126
- );
127
- }
128
-
129
- function appendAction(
130
- actions: CodegraphAction[],
131
- action: string,
132
- command: string[],
133
- result: ReturnType<typeof run>
134
- ): boolean {
135
- actions.push({
136
- action,
137
- status: result.ok ? "changed" : "failed",
138
- command,
139
- stdout: trimOutput(result.stdout),
140
- stderr: trimOutput(result.stderr || result.error),
141
- });
142
- return result.ok;
143
- }
144
-
145
- function normalize(raw: Record<string, any>): CodegraphCheckResult {
146
- return {
147
- status: raw.status,
148
- reason: raw.reason,
149
- resolution: {
150
- source: raw.source,
151
- binPath: raw.bin_path,
152
- version: raw.version,
153
- localBinPath: raw.local_bin_path,
154
- globalBinPath: raw.global_bin_path,
155
- globalFallbackUsed: Boolean(raw.global_fallback_used),
156
- drift: raw.drift,
157
- },
158
- raw,
159
- };
160
- }
161
-
162
- export function checkCodegraph(opts: CodegraphResolveOptions): CodegraphCheckResult {
163
- const locator = createCodegraphCacheLocator(opts.repoRoot, resolveControllerHome(), { createTarget: false });
164
- if (!locator) return normalize(readToolingReport(opts.repoRoot, opts.env, opts.host));
165
- try {
166
- return normalize(readToolingReport(opts.repoRoot, { ...opts.env, CODEGRAPH_DIR: locator.name }, opts.host));
167
- } finally {
168
- locator.release();
169
- }
170
- }
171
-
172
- export function resolveCodegraph(opts: CodegraphResolveOptions): CodegraphResolution {
173
- return checkCodegraph(opts).resolution;
174
- }
175
-
176
- /** @deprecated Compatibility name retained for callers; no persistent repo symlink is created. */
177
- export function ensureCodegraphCacheCompatibilityLink(repoRoot: string, controllerHome = resolveControllerHome()): string {
178
- return migrateLegacyCodegraphCache(repoRoot, controllerHome);
179
- }
180
-
181
- export function ensureCodegraph(opts: CodegraphEnsureOptions): CodegraphEnsureResult {
182
- const actions: CodegraphAction[] = [];
183
-
184
- if (opts.checkOnly) {
185
- return {
186
- ...checkCodegraph(opts),
187
- changed: false,
188
- readOnly: true,
189
- actions,
190
- };
191
- }
192
-
193
- const locator = createCodegraphCacheLocator(opts.repoRoot, resolveControllerHome(), { migrateLegacy: true, createTarget: true });
194
- if (!locator) throw new Error('CODEGRAPH_LOCATOR_UNAVAILABLE');
195
- const env = { ...opts.env, CODEGRAPH_DIR: locator.name };
196
- try {
197
- let codegraph = readToolingReport(opts.repoRoot, env, opts.host);
198
- if (opts.installDeps !== false && hasCodegraphDependency(opts.repoRoot) && !codegraph.local_bin_path) {
199
- appendAction(actions, "install-deps", ["bun", "install"], run("bun", ["install"], opts.repoRoot, env));
200
- codegraph = readToolingReport(opts.repoRoot, env, opts.host);
201
- }
202
-
203
- const binPath = codegraph.bin_path;
204
- if (binPath && opts.init && codegraph.project_index?.status === "not-initialized") {
205
- appendAction(actions, "init-index", [binPath, "init", "-i", "."], run(binPath, ["init", "-i", "."], opts.repoRoot, env));
206
- codegraph = readToolingReport(opts.repoRoot, env, opts.host);
207
- }
208
-
209
- if (binPath && opts.sync) {
210
- appendAction(actions, "sync-index", [binPath, "sync", "."], run(binPath, ["sync", "."], opts.repoRoot, env));
211
- codegraph = readToolingReport(opts.repoRoot, env, opts.host);
212
- }
213
-
214
- const normalized = normalize(codegraph);
215
- return {
216
- ...normalized,
217
- changed: actions.some((entry) => entry.status === "changed"),
218
- readOnly: false,
219
- actions,
220
- };
221
- } finally {
222
- locator.release();
223
- }
224
- }
225
-
226
- function configureTargets(target: CodegraphHostTarget): Array<"codex" | "claude"> {
227
- return target === "both" ? ["codex", "claude"] : [target];
228
- }
229
-
230
- function isMcpHostConfigured(raw: Record<string, unknown>, target: "codex" | "claude"): boolean {
231
- const hosts = (raw as { mcp_hosts?: Record<string, { status?: string }> }).mcp_hosts ?? {};
232
- return hosts[target]?.status === "configured";
233
- }
234
-
235
- function appendSkippedAction(actions: CodegraphAction[], action: string, command: string[], reason: string): void {
236
- actions.push({
237
- action,
238
- status: "skipped",
239
- command,
240
- stderr: reason,
241
- });
242
- }
243
-
244
- function claudeSettingsPath(env?: NodeJS.ProcessEnv): string | null {
245
- const home = env?.HOME ?? process.env.HOME ?? process.env.USERPROFILE;
246
- return home ? join(home, ".claude", "settings.json") : null;
247
- }
248
-
249
- function claudeRootConfigPath(env?: NodeJS.ProcessEnv): string | null {
250
- const home = env?.HOME ?? process.env.HOME ?? process.env.USERPROFILE;
251
- return home ? join(home, ".claude.json") : null;
252
- }
253
-
254
- function codexConfigPath(env?: NodeJS.ProcessEnv): string | null {
255
- const home = env?.HOME ?? process.env.HOME ?? process.env.USERPROFILE;
256
- return home ? join(home, ".codex", "config.toml") : null;
257
- }
258
-
259
- function codegraphArgsAreScoped(args: unknown): boolean {
260
- return Array.isArray(args) &&
261
- args.length === CODEGRAPH_SCOPED_MCP_ARGS.length &&
262
- args.every((arg, index) => arg === CODEGRAPH_SCOPED_MCP_ARGS[index]);
263
- }
264
-
265
- function configureCodexProjectPath(actions: CodegraphAction[], env?: NodeJS.ProcessEnv): void {
266
- const path = codexConfigPath(env);
267
- const command = ["codex-config", "scope-codegraph-mcp", path ?? "<HOME>/.codex/config.toml"];
268
-
269
- if (!path) {
270
- actions.push({
271
- action: "codex-project-path",
272
- status: "skipped",
273
- command,
274
- stderr: "HOME environment variable not set; cannot locate ~/.codex/config.toml.",
275
- });
276
- return;
277
- }
278
-
279
- let raw: string;
280
- try {
281
- raw = readFileSync(path, "utf8");
282
- } catch (_error) {
283
- actions.push({
284
- action: "codex-project-path",
285
- status: "skipped",
286
- command,
287
- stderr: `${path} not found; CodeGraph did not create a Codex MCP config.`,
288
- });
289
- return;
290
- }
291
-
292
- const sectionMatch = raw.match(/(^\[mcp_servers\.codegraph\]\n)([\s\S]*?)(?=^\[|(?![\s\S]))/m);
293
- if (!sectionMatch) {
294
- actions.push({
295
- action: "codex-project-path",
296
- status: "skipped",
297
- command,
298
- stderr: "Codex CodeGraph MCP server entry was not found; run codegraph install first.",
299
- });
300
- return;
301
- }
302
-
303
- const [section, header, body] = sectionMatch;
304
- const desiredArgsLine = `args = ${CODEGRAPH_SCOPED_MCP_TOML_ARGS}`;
305
- const argsLine = body.match(/^args\s*=\s*(.+)$/m)?.[1]?.trim();
306
- if (argsLine === CODEGRAPH_SCOPED_MCP_TOML_ARGS) {
307
- actions.push({
308
- action: "codex-project-path",
309
- status: "unchanged",
310
- command,
311
- });
312
- return;
313
- }
314
-
315
- let nextBody: string;
316
- if (/^args\s*=/m.test(body)) {
317
- nextBody = body.replace(/^args\s*=.*$/m, desiredArgsLine);
318
- } else if (/^command\s*=/m.test(body)) {
319
- nextBody = body.replace(/^(command\s*=.*)$/m, `$1\n${desiredArgsLine}`);
320
- } else {
321
- nextBody = `${desiredArgsLine}\n${body}`;
322
- }
323
-
324
- const next = raw.replace(section, `${header}${nextBody}`);
325
- try {
326
- writeFileSync(path, next);
327
- } catch (error) {
328
- actions.push({
329
- action: "codex-project-path",
330
- status: "failed",
331
- command,
332
- stderr: `Failed to write ${path}: ${String((error as Error).message ?? error)}`,
333
- });
334
- return;
335
- }
336
-
337
- actions.push({
338
- action: "codex-project-path",
339
- status: "changed",
340
- command,
341
- });
342
- }
343
-
344
- function configureClaudeProjectPath(
345
- actions: CodegraphAction[],
346
- repoRoot: string,
347
- location: CodegraphConfigureLocation,
348
- env?: NodeJS.ProcessEnv,
349
- ): void {
350
- const path = claudeRootConfigPath(env);
351
- const command = ["claude-root-config", "scope-codegraph-mcp", path ?? "<HOME>/.claude.json"];
352
-
353
- if (!path) {
354
- actions.push({
355
- action: "claude-project-path",
356
- status: "skipped",
357
- command,
358
- stderr: "HOME environment variable not set; cannot locate ~/.claude.json.",
359
- });
360
- return;
361
- }
362
-
363
- let raw: string;
364
- try {
365
- raw = readFileSync(path, "utf8");
366
- } catch (_error) {
367
- actions.push({
368
- action: "claude-project-path",
369
- status: "skipped",
370
- command,
371
- stderr: `${path} not found; CodeGraph did not create a Claude root MCP config.`,
372
- });
373
- return;
374
- }
375
-
376
- let parsed: any;
377
- try {
378
- parsed = JSON.parse(raw);
379
- } catch (error) {
380
- actions.push({
381
- action: "claude-project-path",
382
- status: "failed",
383
- command,
384
- stderr: `Failed to parse ${path} as JSON: ${String((error as Error).message ?? error)}`,
385
- });
386
- return;
387
- }
388
-
389
- const mcpServers =
390
- location === "global"
391
- ? parsed?.mcpServers
392
- : parsed?.projects?.[repoRoot]?.mcpServers;
393
- const server = mcpServers?.[CLAUDE_CODEGRAPH_SERVER_NAME];
394
- if (!server || typeof server !== "object" || Array.isArray(server)) {
395
- actions.push({
396
- action: "claude-project-path",
397
- status: "skipped",
398
- command,
399
- stderr: `Claude ${location} CodeGraph MCP server entry was not found; run codegraph install first.`,
400
- });
401
- return;
402
- }
403
-
404
- if (codegraphArgsAreScoped(server.args)) {
405
- actions.push({
406
- action: "claude-project-path",
407
- status: "unchanged",
408
- command,
409
- });
410
- return;
411
- }
412
-
413
- server.args = [...CODEGRAPH_SCOPED_MCP_ARGS];
414
- const trailingNewline = raw.endsWith("\n") ? "\n" : "";
415
- const serialized = `${JSON.stringify(parsed, null, 2)}${trailingNewline}`;
416
- try {
417
- writeFileSync(path, serialized);
418
- } catch (error) {
419
- actions.push({
420
- action: "claude-project-path",
421
- status: "failed",
422
- command,
423
- stderr: `Failed to write ${path}: ${String((error as Error).message ?? error)}`,
424
- });
425
- return;
426
- }
427
-
428
- actions.push({
429
- action: "claude-project-path",
430
- status: "changed",
431
- command,
432
- });
433
- }
434
-
435
- function configureClaudeAlwaysLoad(
436
- actions: CodegraphAction[],
437
- repoRoot: string,
438
- location: CodegraphConfigureLocation,
439
- env?: NodeJS.ProcessEnv,
440
- ): void {
441
- const path = claudeRootConfigPath(env);
442
- const command = ["claude-root-config", "set-codegraph-always-load", path ?? "<HOME>/.claude.json"];
443
-
444
- if (!path) {
445
- actions.push({
446
- action: "claude-always-load",
447
- status: "skipped",
448
- command,
449
- stderr: "HOME environment variable not set; cannot locate ~/.claude.json.",
450
- });
451
- return;
452
- }
453
-
454
- let raw: string;
455
- try {
456
- raw = readFileSync(path, "utf8");
457
- } catch (_error) {
458
- actions.push({
459
- action: "claude-always-load",
460
- status: "skipped",
461
- command,
462
- stderr: `${path} not found; CodeGraph did not create a Claude root MCP config.`,
463
- });
464
- return;
465
- }
466
-
467
- let parsed: any;
468
- try {
469
- parsed = JSON.parse(raw);
470
- } catch (error) {
471
- actions.push({
472
- action: "claude-always-load",
473
- status: "failed",
474
- command,
475
- stderr: `Failed to parse ${path} as JSON: ${String((error as Error).message ?? error)}`,
476
- });
477
- return;
478
- }
479
-
480
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
481
- actions.push({
482
- action: "claude-always-load",
483
- status: "failed",
484
- command,
485
- stderr: `${path} is not a JSON object; refusing to mutate.`,
486
- });
487
- return;
488
- }
489
-
490
- const mcpServers =
491
- location === "global"
492
- ? parsed.mcpServers
493
- : parsed.projects?.[repoRoot]?.mcpServers;
494
- const server = mcpServers?.[CLAUDE_CODEGRAPH_SERVER_NAME];
495
- if (!server || typeof server !== "object" || Array.isArray(server)) {
496
- actions.push({
497
- action: "claude-always-load",
498
- status: "skipped",
499
- command,
500
- stderr: `Claude ${location} CodeGraph MCP server entry was not found; run codegraph install first.`,
501
- });
502
- return;
503
- }
504
-
505
- if (server.alwaysLoad === true) {
506
- actions.push({
507
- action: "claude-always-load",
508
- status: "unchanged",
509
- command,
510
- });
511
- return;
512
- }
513
-
514
- server.alwaysLoad = true;
515
- const trailingNewline = raw.endsWith("\n") ? "\n" : "";
516
- const serialized = `${JSON.stringify(parsed, null, 2)}${trailingNewline}`;
517
-
518
- try {
519
- writeFileSync(path, serialized);
520
- } catch (error) {
521
- actions.push({
522
- action: "claude-always-load",
523
- status: "failed",
524
- command,
525
- stderr: `Failed to write ${path}: ${String((error as Error).message ?? error)}`,
526
- });
527
- return;
528
- }
529
-
530
- actions.push({
531
- action: "claude-always-load",
532
- status: "changed",
533
- command,
534
- });
535
- }
536
-
537
- function configureClaudeAllowedTools(actions: CodegraphAction[], env?: NodeJS.ProcessEnv): void {
538
- // Hosts claude_settings_path is shown only as a path token; the pattern itself
539
- // travels via writeFile, not via the command echo. This keeps host-agnostic
540
- // invariants intact for consumers that grep CLI stdout for concrete tool
541
- // call syntax such as codegraph_context(...).
542
- const path = claudeSettingsPath(env);
543
- const command = ["claude-settings", "register-allowed-tools", path ?? "<HOME>/.claude/settings.json"];
544
-
545
- if (!path) {
546
- actions.push({
547
- action: "claude-allowed-tools",
548
- status: "skipped",
549
- command,
550
- stderr: "HOME environment variable not set; cannot locate ~/.claude/settings.json.",
551
- });
552
- return;
553
- }
554
-
555
- let raw: string;
556
- try {
557
- raw = readFileSync(path, "utf8");
558
- } catch (_error) {
559
- actions.push({
560
- action: "claude-allowed-tools",
561
- status: "skipped",
562
- command,
563
- stderr: `${path} not found; Claude Code is not installed for this user. Skipping eager-load registration.`,
564
- });
565
- return;
566
- }
567
-
568
- let parsed: any;
569
- try {
570
- parsed = JSON.parse(raw);
571
- } catch (error) {
572
- actions.push({
573
- action: "claude-allowed-tools",
574
- status: "failed",
575
- command,
576
- stderr: `Failed to parse ${path} as JSON: ${String((error as Error).message ?? error)}`,
577
- });
578
- return;
579
- }
580
-
581
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
582
- actions.push({
583
- action: "claude-allowed-tools",
584
- status: "failed",
585
- command,
586
- stderr: `${path} is not a JSON object; refusing to mutate.`,
587
- });
588
- return;
589
- }
590
-
591
- const existing = Array.isArray(parsed.allowedTools) ? (parsed.allowedTools as unknown[]) : [];
592
- if (existing.includes(CLAUDE_CODEGRAPH_ALLOWED_TOOLS_PATTERN)) {
593
- actions.push({
594
- action: "claude-allowed-tools",
595
- status: "unchanged",
596
- command,
597
- });
598
- return;
599
- }
600
-
601
- parsed.allowedTools = [...existing, CLAUDE_CODEGRAPH_ALLOWED_TOOLS_PATTERN];
602
- const trailingNewline = raw.endsWith("\n") ? "\n" : "";
603
- const serialized = `${JSON.stringify(parsed, null, 2)}${trailingNewline}`;
604
-
605
- try {
606
- writeFileSync(path, serialized);
607
- } catch (error) {
608
- actions.push({
609
- action: "claude-allowed-tools",
610
- status: "failed",
611
- command,
612
- stderr: `Failed to write ${path}: ${String((error as Error).message ?? error)}`,
613
- });
614
- return;
615
- }
616
-
617
- actions.push({
618
- action: "claude-allowed-tools",
619
- status: "changed",
620
- command,
621
- });
622
- }
623
-
624
- export function configureCodegraph(opts: CodegraphConfigureOptions): CodegraphConfigureResult {
625
- const actions: CodegraphAction[] = [];
626
- const initial = checkCodegraph({ repoRoot: opts.repoRoot, env: opts.env, host: opts.target });
627
- const binPath = initial.resolution.binPath;
628
-
629
- for (const target of configureTargets(opts.target)) {
630
- const command = [binPath ?? "codegraph", "install", "--target", target, "--location", opts.location, "--yes"];
631
- const actionName = `configure-${target}`;
632
-
633
- if (target === "codex" && opts.location === "local") {
634
- const reason = "Codex has no project-local MCP configuration; use --location global.";
635
- if (opts.target === "codex") {
636
- actions.push({
637
- action: actionName,
638
- status: "failed",
639
- command,
640
- stderr: reason,
641
- });
642
- } else {
643
- appendSkippedAction(actions, actionName, command, reason);
644
- }
645
- continue;
646
- }
647
-
648
- if (!binPath) {
649
- actions.push({
650
- action: actionName,
651
- status: "failed",
652
- command,
653
- stderr: "CodeGraph CLI is missing; run forge tools ensure codegraph first.",
654
- });
655
- if (target === "claude") {
656
- configureClaudeAllowedTools(actions, opts.env);
657
- }
658
- continue;
659
- }
660
-
661
- if (target === "claude" && opts.location === "global" && isMcpHostConfigured(initial.raw, target)) {
662
- appendSkippedAction(actions, actionName, command, "Claude CodeGraph MCP is already configured.");
663
- } else {
664
- appendAction(actions, actionName, command, run(binPath, command.slice(1), opts.repoRoot, opts.env));
665
- }
666
-
667
- if (target === "codex") {
668
- configureCodexProjectPath(actions, opts.env);
669
- }
670
-
671
- if (target === "claude") {
672
- configureClaudeProjectPath(actions, opts.repoRoot, opts.location, opts.env);
673
- configureClaudeAlwaysLoad(actions, opts.repoRoot, opts.location, opts.env);
674
- configureClaudeAllowedTools(actions, opts.env);
675
- }
676
- }
677
-
678
- let refreshed = initial;
679
- if (actions.some((entry) => entry.status === "changed")) {
680
- try {
681
- refreshed = checkCodegraph({ repoRoot: opts.repoRoot, env: opts.env, host: opts.target });
682
- } catch (_error) {
683
- refreshed = initial;
684
- }
685
- }
686
-
687
- return {
688
- ...refreshed,
689
- target: opts.target,
690
- location: opts.location,
691
- changed: actions.some((entry) => entry.status === "changed"),
692
- readOnly: false,
693
- actions,
694
- };
695
- }