@moretea-labs/forge 1.5.1 → 1.7.0

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 (434) hide show
  1. package/AGENTS.md +2 -0
  2. package/CHANGELOG.md +46 -0
  3. package/CLAUDE.md +2 -0
  4. package/DESIGN.md +7 -2
  5. package/README.md +4 -4
  6. package/README.zh-CN.md +2 -2
  7. package/SKILL.md +2 -2
  8. package/THIRD_PARTY_NOTICES.md +1 -1
  9. package/agents/openai.yaml +1 -1
  10. package/assets/hooks/hook-input.sh +11 -8
  11. package/assets/hooks/lib/session-state.sh +10 -7
  12. package/assets/hooks/lib/workflow-state.sh +13 -177
  13. package/assets/hooks/post-tool-observer.sh +8 -2
  14. package/assets/hooks/pre-edit-guard.sh +8 -39
  15. package/assets/hooks/prompt-guard.sh +7 -83
  16. package/assets/hooks/session-start-context.sh +56 -1
  17. package/assets/partials/05-workflow.partial.md +1 -1
  18. package/assets/partials-agents/03-orchestration.partial.md +1 -1
  19. package/assets/plugin-registry.v1.json +54 -3
  20. package/assets/reference-configs/document-generation.md +1 -1
  21. package/assets/reference-configs/harness-overview.md +1 -1
  22. package/assets/reference-configs/hook-operations.md +1 -1
  23. package/assets/reference-configs/sprint-contracts.md +3 -3
  24. package/assets/skill-version.json +2 -2
  25. package/assets/templates/contract.template.md +2 -7
  26. package/assets/templates/helpers/capture-plan.sh +2 -2
  27. package/assets/templates/helpers/check-task-workflow.sh +4 -4
  28. package/assets/templates/helpers/contract-worktree.sh +1 -21
  29. package/assets/templates/helpers/ensure-task-workflow.sh +13 -38
  30. package/assets/templates/helpers/migrate-project-template.sh +22 -45
  31. package/assets/templates/helpers/new-plan.sh +1 -1
  32. package/assets/templates/helpers/plan-to-todo.sh +12 -37
  33. package/assets/templates/helpers/ship-worktrees.sh +2 -29
  34. package/assets/templates/helpers/sprint-backlog.sh +6 -6
  35. package/assets/templates/helpers/verify-contract.sh +1 -111
  36. package/assets/templates/helpers/verify-sprint.sh +3 -180
  37. package/assets/templates/plan.template.md +1 -1
  38. package/assets/templates/review.template.md +9 -34
  39. package/assets/workflow-contract.v1.json +10 -19
  40. package/docs/README.md +10 -10
  41. package/docs/architecture/CURRENT.md +170 -0
  42. package/docs/architecture/EVOLUTION.md +42 -0
  43. package/docs/architecture/current/README.md +4 -156
  44. package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +2 -2
  45. package/docs/architecture/decisions/20260823-immediate-controller-relay.md +53 -0
  46. package/docs/architecture/decisions/20260826-browser-runtime-v2.md +73 -0
  47. package/docs/architecture/history/README.md +7 -0
  48. package/docs/architecture/{chatgpt-handoff-facade.md → history/chatgpt-handoff-facade.md} +4 -0
  49. package/docs/architecture/{global-hook-runtime.md → history/global-hook-runtime.md} +7 -3
  50. package/docs/architecture/{ios-semantic-automation-provider-v2.md → history/ios-semantic-automation-provider-v2.md} +6 -2
  51. package/docs/architecture/history.md +3 -34
  52. package/docs/architecture/index.md +15 -98
  53. package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +1 -1
  54. package/docs/architecture/reviews/2026-08-22-semantic-harness-convergence-acceptance.md +39 -0
  55. package/docs/architecture/versions/1.6.md +38 -0
  56. package/docs/architecture/versions/1.7.md +41 -0
  57. package/docs/forge-chatgpt-browser-engine.md +2 -2
  58. package/docs/forge-chatgpt-mcp-setup.md +4 -28
  59. package/docs/forge-chatgpt-supervised-automation.md +3 -3
  60. package/docs/forge-github-issue-launcher.md +1 -1
  61. package/docs/forge-runtime-self-healing-loop.md +1 -1
  62. package/docs/operations/controller-browser-plugin.md +38 -22
  63. package/docs/operations/controller-performance-and-502.md +124 -0
  64. package/docs/operations/controller-reliability-runbook.md +1 -1
  65. package/docs/operations/features.md +3 -3
  66. package/docs/operations/github-repository.md +1 -1
  67. package/docs/operations/homebrew.md +2 -2
  68. package/docs/operations/mcp-tool-exposure.md +5 -3
  69. package/docs/tutorials/01-install-and-start.md +1 -1
  70. package/docs/tutorials/01-install-and-start.zh-CN.md +1 -1
  71. package/docs/wiki/Architecture.md +6 -6
  72. package/docs/wiki/Implementation.md +2 -2
  73. package/docs/wiki/Installation.md +1 -1
  74. package/docs/wiki/Integrations.md +2 -2
  75. package/docs/wiki/Quick-Start.md +1 -1
  76. package/docs/wiki/Work-Lifecycle.md +1 -1
  77. package/package.json +29 -10
  78. package/scripts/activate-source-baseline.ts +17 -13
  79. package/scripts/benchmark-background-check-overlap.ts +228 -0
  80. package/scripts/benchmark-mcp-host.sh +117 -0
  81. package/scripts/benchmark-mcp-transport.ts +170 -0
  82. package/scripts/benchmark-quality-harness.ts +146 -0
  83. package/scripts/benchmark-route-session-concurrency.ts +207 -6
  84. package/scripts/benchmark-thin-harness-mcp-e2e.ts +7 -1
  85. package/scripts/benchmark-typescript-navigation.ts +186 -0
  86. package/scripts/benchmark-work-efficiency.ts +334 -0
  87. package/scripts/capture-plan.sh +3 -3
  88. package/scripts/check-agent-tooling.sh +8 -35
  89. package/scripts/check-architecture-sync.sh +17 -86
  90. package/scripts/check-mcp-compatibility.ts +14 -0
  91. package/scripts/check-public-docs.sh +14 -1
  92. package/scripts/check-runtime-architecture.mjs +107 -64
  93. package/scripts/check-stable-baseline.ts +92 -0
  94. package/scripts/check-task-workflow.sh +4 -4
  95. package/scripts/contract-worktree.sh +1 -21
  96. package/scripts/ensure-task-workflow.sh +22 -55
  97. package/scripts/host-temporary-cloud-mcp-e2e.sh +265 -0
  98. package/scripts/install-standalone-recovery.ts +24 -0
  99. package/scripts/lib/project-init-lib.sh +15 -44
  100. package/scripts/migrate-chatgpt-automation-schedules.ts +64 -0
  101. package/scripts/migrate-project-template.sh +23 -1179
  102. package/scripts/new-plan.sh +1 -1
  103. package/scripts/plan-to-todo.sh +11 -36
  104. package/scripts/run-governed-gate.ts +2 -1
  105. package/scripts/ship-worktrees.sh +2 -29
  106. package/scripts/smoke-ios-physical-device.ts +4 -2
  107. package/scripts/smoke-runtime-recovery.ts +1 -35
  108. package/scripts/smoke-schedule-engine.ts +1 -20
  109. package/scripts/sprint-backlog.sh +1 -1
  110. package/scripts/verify-contract.sh +1 -111
  111. package/scripts/verify-forge-runtime.sh +0 -1
  112. package/scripts/verify-sprint.sh +3 -180
  113. package/scripts/workflow-contract.ts +1 -5
  114. package/src/cli/commands/chatgpt.ts +31 -2
  115. package/src/cli/commands/init-hook.ts +3 -3
  116. package/src/cli/commands/mcp.ts +9 -5
  117. package/src/cli/commands/plugin.ts +37 -10
  118. package/src/cli/commands/recovery.ts +25 -3
  119. package/src/cli/commands/runtime.ts +55 -3
  120. package/src/cli/commands/security.ts +12 -1
  121. package/src/cli/commands/setup-profile.ts +31 -21
  122. package/src/cli/controller/check-runner.ts +106 -3
  123. package/src/cli/controller/composite-result.ts +1 -1
  124. package/src/cli/controller/context/focus.ts +51 -0
  125. package/src/cli/controller/context/instruction-context.ts +114 -0
  126. package/src/cli/controller/context/known-paths.ts +76 -0
  127. package/src/cli/controller/context/query-planning.ts +110 -0
  128. package/src/cli/controller/context/rule-resolution.ts +532 -0
  129. package/src/cli/controller/context/source-materializer.ts +278 -0
  130. package/src/cli/controller/context/structural.ts +16 -0
  131. package/src/cli/controller/context/types.ts +286 -0
  132. package/src/cli/controller/context-pack.ts +898 -430
  133. package/src/cli/controller/launch-agents.ts +77 -2
  134. package/src/cli/controller/operational-plan.ts +2 -2
  135. package/src/cli/controller/work-mode.ts +6 -4
  136. package/src/cli/editing/edit-session.ts +60 -7
  137. package/src/cli/github/github.ts +133 -0
  138. package/src/cli/hook/prompt-guard-decision.ts +17 -18
  139. package/src/cli/hook/prompt-intents.ts +1 -1
  140. package/src/cli/installer/managed-entries.ts +15 -1
  141. package/src/cli/local-bridge/console-automations.ts +225 -67
  142. package/src/cli/local-bridge/console-view-models.ts +3 -35
  143. package/src/cli/local-bridge/facade-api.ts +2 -217
  144. package/src/cli/local-bridge/frontend/src/App.tsx +3 -3
  145. package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +153 -3
  146. package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +37 -4
  147. package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +183 -3
  148. package/src/cli/local-bridge/frontend/src/features/repositories/RepositoriesView.tsx +1 -1
  149. package/src/cli/local-bridge/frontend/src/features/work/WorkView.tsx +4 -3
  150. package/src/cli/local-bridge/frontend/src/lib/api.ts +18 -11
  151. package/src/cli/local-bridge/frontend/src/lib/routes.ts +1 -1
  152. package/src/cli/local-bridge/frontend/src/shell/CommandBar.tsx +1 -1
  153. package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +4 -3
  154. package/src/cli/local-bridge/frontend/src/styles.css +27 -11
  155. package/src/cli/local-bridge/frontend/src/types.ts +8 -7
  156. package/src/cli/local-bridge/job-store.ts +1 -490
  157. package/src/cli/local-bridge/server.ts +29 -532
  158. package/src/cli/local-bridge/ui-dist/app.css +1 -1
  159. package/src/cli/local-bridge/ui-dist/app.js +5101 -4967
  160. package/src/cli/mcp/auth.ts +5 -5
  161. package/src/cli/mcp/instructions.ts +3 -2
  162. package/src/cli/mcp/legacy-tool-service.ts +0 -189
  163. package/src/cli/mcp/multi-repository.ts +16 -5
  164. package/src/cli/mcp/oauth.ts +175 -26
  165. package/src/cli/mcp/paths.ts +8 -2
  166. package/src/cli/mcp/repository-tools.ts +356 -101
  167. package/src/cli/mcp/server.ts +625 -54
  168. package/src/cli/mcp/tool-capability-cache.ts +1 -1
  169. package/src/cli/mcp/toolset-selection.ts +1 -1
  170. package/src/cli/mcp/toolset.ts +42 -5
  171. package/src/cli/mcp/transports/http.ts +125 -15
  172. package/src/cli/mcp/transports/session-registry.ts +67 -5
  173. package/src/cli/mcp/types.ts +3 -3
  174. package/src/cli/repositories/command-classifier.ts +209 -14
  175. package/src/cli/repositories/command-executor.ts +55 -521
  176. package/src/cli/repositories/command-process.ts +108 -0
  177. package/src/cli/repositories/command-scope.ts +99 -41
  178. package/src/cli/repositories/controller-home.ts +7 -8
  179. package/src/cli/repositories/git-command-executor.ts +2 -0
  180. package/src/cli/repositories/locks.ts +53 -16
  181. package/src/cli/repositories/repository-snapshot.ts +121 -0
  182. package/src/cli/repositories/safe-patch.ts +6 -4
  183. package/src/cli/repositories/selected-path-actions.ts +17 -9
  184. package/src/cli/repositories/structured-git.ts +110 -10
  185. package/src/cli/repository/inspector.ts +565 -62
  186. package/src/cli/repository/session-cache.ts +58 -17
  187. package/src/cli/v81-entry.ts +1 -4
  188. package/src/effects/fs-transaction.ts +85 -17
  189. package/src/runtime/context/codegraph-read-provider.ts +233 -2
  190. package/src/runtime/context/codegraph-sidecar.cjs +74 -40
  191. package/src/runtime/context/generic-lsp-provider.ts +355 -0
  192. package/src/runtime/context/lsp-client.ts +283 -0
  193. package/src/runtime/context/semantic-navigation.ts +275 -0
  194. package/src/runtime/context/swift-navigation.ts +565 -0
  195. package/src/runtime/context/typescript-navigation.ts +226 -0
  196. package/src/runtime/control-plane/dispatch-priority.ts +28 -0
  197. package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +196 -2
  198. package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +86 -24
  199. package/src/runtime/control-plane/execution/execution-identity.ts +65 -14
  200. package/src/runtime/control-plane/execution/session-store.ts +18 -0
  201. package/src/runtime/control-plane/execution/validation.ts +15 -2
  202. package/src/runtime/control-plane/execution/verification-evidence.ts +58 -3
  203. package/src/runtime/control-plane/execution/work-handle-store.ts +27 -2
  204. package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +258 -0
  205. package/src/runtime/control-plane/execution/work-remote-delivery.ts +215 -0
  206. package/src/runtime/control-plane/execution/work-task-receipt.ts +54 -11
  207. package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +175 -8
  208. package/src/runtime/control-plane/execution/work-validation-reconciler.ts +28 -21
  209. package/src/runtime/control-plane/execution/work-verification-snapshot.ts +87 -9
  210. package/src/runtime/control-plane/facade/capability-registry.ts +129 -25
  211. package/src/runtime/control-plane/facade/controller-round-relay.ts +991 -0
  212. package/src/runtime/control-plane/facade/controller-session-store.ts +144 -14
  213. package/src/runtime/control-plane/facade/goal-workloop-access.ts +9 -2
  214. package/src/runtime/control-plane/facade/goal-workloop.ts +885 -105
  215. package/src/runtime/control-plane/facade/index.ts +1 -0
  216. package/src/runtime/control-plane/facade/plan-contract-store.ts +211 -26
  217. package/src/runtime/control-plane/facade/requirement-board.ts +24 -8
  218. package/src/runtime/control-plane/facade/semantic-admission.ts +205 -0
  219. package/src/runtime/control-plane/facade/suggested-actions.ts +5 -1
  220. package/src/runtime/control-plane/facade/types.ts +55 -11
  221. package/src/runtime/control-plane/facade/work-contract-store.ts +204 -73
  222. package/src/runtime/control-plane/generated-cache-retention.ts +271 -0
  223. package/src/runtime/control-plane/global-scheduler/config.ts +44 -0
  224. package/src/runtime/control-plane/global-scheduler/dispatch-capacity.ts +80 -0
  225. package/src/runtime/control-plane/global-scheduler/durable-admission.ts +46 -0
  226. package/src/runtime/control-plane/global-scheduler/maintenance.ts +145 -0
  227. package/src/runtime/control-plane/global-scheduler/projection-refresh.ts +84 -0
  228. package/src/runtime/control-plane/global-scheduler/reconciliation.ts +3 -3
  229. package/src/runtime/control-plane/global-scheduler/scheduler.ts +273 -542
  230. package/src/runtime/control-plane/global-scheduler/source-scan.ts +59 -0
  231. package/src/runtime/control-plane/global-scheduler/state.ts +88 -0
  232. package/src/runtime/control-plane/global-scheduler/worker-attachment.ts +57 -0
  233. package/src/runtime/control-plane/global-scheduler/worker-exit-decision.ts +38 -0
  234. package/src/runtime/control-plane/global-scheduler/worker-exit-reconciler.ts +175 -0
  235. package/src/runtime/control-plane/global-scheduler/worker-launch.ts +111 -0
  236. package/src/runtime/control-plane/global-scheduler/worker-lifecycle-store.ts +64 -0
  237. package/src/runtime/control-plane/global-scheduler/worker-lifecycle.ts +150 -0
  238. package/src/runtime/control-plane/global-scheduler/worker-process.ts +119 -0
  239. package/src/runtime/control-plane/global-scheduler/worker-stderr.ts +60 -0
  240. package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +50 -0
  241. package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +642 -51
  242. package/src/runtime/control-plane/launcher/launch-reservation-store.ts +40 -0
  243. package/src/runtime/control-plane/launcher/thin-launcher.ts +194 -10
  244. package/src/runtime/control-plane/persistence/controller-home-migration.ts +487 -0
  245. package/src/runtime/control-plane/persistence/requirement-store.ts +15 -11
  246. package/src/runtime/control-plane/persistence/sqlite-store.ts +33 -2
  247. package/src/runtime/control-plane/release-retention.ts +62 -2
  248. package/src/runtime/control-plane/routing/route-policy.ts +7 -16
  249. package/src/runtime/control-plane/runtime-status-client.ts +0 -2
  250. package/src/runtime/diagnostics/mcp-timing.ts +19 -0
  251. package/src/runtime/diagnostics/mcp-transport-benchmark.ts +129 -0
  252. package/src/runtime/diagnostics/performance.ts +24 -1
  253. package/src/runtime/evidence/event-ledger.ts +1 -1
  254. package/src/runtime/execution/jobs/store.ts +58 -4
  255. package/src/runtime/execution/jobs/types.ts +1 -1
  256. package/src/runtime/execution/managed-workspace.ts +203 -1
  257. package/src/runtime/execution/process-runtime/check-facade.ts +52 -14
  258. package/src/runtime/execution/process-runtime/check-result.ts +63 -2
  259. package/src/runtime/execution/process-runtime/check-scheduling.ts +114 -0
  260. package/src/runtime/execution/process-runtime/command-facade.ts +346 -40
  261. package/src/runtime/execution/process-runtime/gc.ts +98 -12
  262. package/src/runtime/execution/process-runtime/lightweight-managed.ts +1184 -0
  263. package/src/runtime/execution/process-runtime/persisted-check.ts +57 -6
  264. package/src/runtime/execution/process-runtime/resource-claims.ts +97 -8
  265. package/src/runtime/execution/process-runtime/runtime.ts +59 -4
  266. package/src/runtime/execution/process-runtime/store.ts +7 -0
  267. package/src/runtime/execution/process-runtime/types.ts +2 -0
  268. package/src/runtime/execution/thin-harness/async-process.ts +12 -2
  269. package/src/runtime/execution/thin-harness/search-worker.ts +54 -5
  270. package/src/runtime/execution/workers/executor.ts +0 -48
  271. package/src/runtime/gateway/mcp/execution-tools.ts +1219 -126
  272. package/src/runtime/gateway/mcp/process-tools.ts +83 -37
  273. package/src/runtime/gateway/mcp/router.ts +185 -83
  274. package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +546 -0
  275. package/src/runtime/gateway/mcp/runtime-tools.ts +2555 -1616
  276. package/src/runtime/model-clients/deepseek-adapter.ts +0 -32
  277. package/src/runtime/plugins/app-store-connect-adapter.ts +123 -19
  278. package/src/runtime/plugins/browser-adapter.ts +2925 -318
  279. package/src/runtime/plugins/browser-automation-service.ts +10 -0
  280. package/src/runtime/plugins/browser-handoff-host.ts +6 -31
  281. package/src/runtime/plugins/browser-handoff.ts +92 -5
  282. package/src/runtime/plugins/browser-macos-bridge.ts +586 -45
  283. package/src/runtime/plugins/browser-node-bridge.ts +6 -34
  284. package/src/runtime/plugins/browser-provider-registry.ts +109 -0
  285. package/src/runtime/plugins/browser-runtime-contract.ts +152 -0
  286. package/src/runtime/plugins/browser-runtime.ts +183 -0
  287. package/src/runtime/plugins/browser-session-authority.ts +332 -0
  288. package/src/runtime/plugins/capability-authorization-grants.ts +354 -0
  289. package/src/runtime/plugins/desktop-operator-registration.ts +15 -12
  290. package/src/runtime/plugins/external-adapter.ts +324 -3
  291. package/src/runtime/plugins/external-registration.ts +84 -5
  292. package/src/runtime/plugins/external-unix-socket.ts +7 -1
  293. package/src/runtime/plugins/first-party-registry.ts +4 -2
  294. package/src/runtime/plugins/github-adapter.ts +125 -0
  295. package/src/runtime/plugins/gmail-adapter.ts +28 -2
  296. package/src/runtime/plugins/ios/agent-device-provider.ts +1 -1
  297. package/src/runtime/plugins/ios/agent-device-typed-provider.ts +52 -9
  298. package/src/runtime/plugins/ios/remote-xpc-hid.ts +1171 -0
  299. package/src/runtime/plugins/ios-adapter.ts +106 -16
  300. package/src/runtime/plugins/ios-agent-device.ts +234 -64
  301. package/src/runtime/plugins/ios-physical-device.ts +1143 -392
  302. package/src/runtime/plugins/lightweight-action.ts +153 -0
  303. package/src/runtime/plugins/local-system-adapter.ts +125 -8
  304. package/src/runtime/plugins/macos-capability-broker.ts +55 -9
  305. package/src/runtime/plugins/plugin-action-sidecar.ts +59 -0
  306. package/src/runtime/plugins/plugin-management-adapter.ts +181 -0
  307. package/src/runtime/plugins/resend-adapter.ts +1 -1
  308. package/src/runtime/plugins/store.ts +366 -24
  309. package/src/runtime/plugins/types.ts +39 -2
  310. package/src/runtime/plugins/xiaohongshu-publish.ts +515 -0
  311. package/src/runtime/projections/git-status-sampler.ts +16 -16
  312. package/src/runtime/projections/materialized-view.ts +28 -10
  313. package/src/runtime/recovery/actions.ts +0 -10
  314. package/src/runtime/recovery/classifier.ts +0 -9
  315. package/src/runtime/recovery/maintenance-executor.ts +415 -18
  316. package/src/runtime/recovery/probe.ts +0 -1
  317. package/src/runtime/recovery/types.ts +0 -1
  318. package/src/runtime/root/mcp-transport.ts +180 -10
  319. package/src/runtime/root/package-connector-service.ts +186 -8
  320. package/src/runtime/root/package-runtime-release.ts +143 -17
  321. package/src/runtime/root/package-runtime-service.ts +430 -22
  322. package/src/runtime/root/release-manifest.ts +7 -2
  323. package/src/runtime/root/release-materialize.ts +162 -19
  324. package/src/runtime/root/release-store.ts +48 -11
  325. package/src/runtime/root/runtime.ts +23 -5
  326. package/src/runtime/root/service.ts +100 -27
  327. package/src/runtime/root/types.ts +2 -0
  328. package/src/runtime/safe-tooling/index.ts +0 -1
  329. package/src/runtime/safe-tooling/ios-development.ts +321 -63
  330. package/src/runtime/safe-tooling/types.ts +0 -30
  331. package/src/runtime/shared/trusted-executable.ts +62 -0
  332. package/src/runtime/shared/trusted-node-executable.ts +48 -0
  333. package/src/runtime/standalone-recovery/core.ts +702 -94
  334. package/src/runtime/standalone-recovery/entry.ts +99 -23
  335. package/src/runtime/standalone-recovery/installer.ts +19 -3
  336. package/src/runtime/standalone-recovery/service-labels.ts +2 -0
  337. package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +160 -0
  338. package/src/runtime/workflow/schedules/browser-probe.ts +258 -0
  339. package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +40 -0
  340. package/src/runtime/workflow/schedules/engine.ts +509 -80
  341. package/src/runtime/workflow/schedules/github-issue-watch.ts +158 -0
  342. package/src/runtime/workflow/schedules/settlement.ts +48 -4
  343. package/src/runtime/workflow/schedules/store.ts +131 -10
  344. package/src/runtime/workflow/schedules/types.ts +6 -3
  345. package/src/runtime/workflow/schedules/work-continuation.ts +120 -34
  346. package/src/testing/test-governance.ts +8 -40
  347. package/assets/reference-configs/heartbeat-triage.md +0 -57
  348. package/assets/templates/helpers/harness-trace-grade.sh +0 -150
  349. package/assets/templates/helpers/heartbeat-triage.sh +0 -361
  350. package/assets/templates/helpers/maintenance-triage.sh +0 -167
  351. package/bin/forge-desktop-helper.mjs +0 -204
  352. package/docs/architecture/current/approved-target-architecture.zh-CN.md +0 -1501
  353. package/docs/architecture/current/architecture-invariants.md +0 -331
  354. package/docs/architecture/current/automation-and-schedule-engine.md +0 -453
  355. package/docs/architecture/current/codegraph-context-provider.md +0 -226
  356. package/docs/architecture/current/control-plane-authority-inventory.md +0 -94
  357. package/docs/architecture/current/controller-repository-decoupling.md +0 -148
  358. package/docs/architecture/current/dispatch-and-agent-strategy.md +0 -354
  359. package/docs/architecture/current/entity-model.md +0 -592
  360. package/docs/architecture/current/external-plugin-governance.md +0 -396
  361. package/docs/architecture/current/failure-recovery.md +0 -447
  362. package/docs/architecture/current/governance.md +0 -213
  363. package/docs/architecture/current/human-interaction-plane.md +0 -87
  364. package/docs/architecture/current/implementation-status.md +0 -128
  365. package/docs/architecture/current/job-and-run-lifecycle.md +0 -413
  366. package/docs/architecture/current/legacy-governance.md +0 -58
  367. package/docs/architecture/current/local-workspace-target-grants.md +0 -70
  368. package/docs/architecture/current/migration-roadmap.md +0 -105
  369. package/docs/architecture/current/multi-repository-execution.md +0 -371
  370. package/docs/architecture/current/operations-runbook.md +0 -45
  371. package/docs/architecture/current/peer-supercontroller-runtime.md +0 -32
  372. package/docs/architecture/current/personal-assistant-plugin-baseline.md +0 -206
  373. package/docs/architecture/current/repository-access-modes.md +0 -102
  374. package/docs/architecture/current/route-policy.md +0 -15
  375. package/docs/architecture/current/route-session-concurrency.md +0 -85
  376. package/docs/architecture/current/runtime-architecture-simplification.md +0 -214
  377. package/docs/architecture/current/runtime-directory-map.md +0 -49
  378. package/docs/architecture/current/runtime-health-and-resource-lifecycle.md +0 -85
  379. package/docs/architecture/current/scheduler-and-resource-claims.md +0 -422
  380. package/docs/architecture/current/session-aware-execution-and-authorization.md +0 -77
  381. package/docs/architecture/current/system-overview.md +0 -144
  382. package/docs/architecture/current/target-requirements-traceability.md +0 -202
  383. package/docs/architecture/current/thin-harness-governance-policy.md +0 -32
  384. package/docs/architecture/current/thin-harness-v1.md +0 -311
  385. package/docs/architecture/current/verification-and-release-gates.md +0 -391
  386. package/docs/forge-autonomous-goal-loop.md +0 -9
  387. package/docs/forge-provider-configuration.md +0 -7
  388. package/docs/operations/chatgpt-personal-assistant-runtime.md +0 -83
  389. package/docs/operations/controller-desktop-plugin.md +0 -112
  390. package/docs/operations/gmail-assistant-routines.md +0 -186
  391. package/docs/operations/personal-assistant-operator-guide.md +0 -61
  392. package/docs/operations/provider-configuration.md +0 -31
  393. package/scripts/harness-trace-grade.sh +0 -150
  394. package/scripts/heartbeat-triage.sh +0 -361
  395. package/scripts/maintenance-triage.sh +0 -167
  396. package/src/cli/local-bridge/frontend/src/features/settings/SettingsView.tsx +0 -2
  397. package/src/cli/repositories/goal-registry.ts +0 -239
  398. package/src/runtime/assistant/action-proposals.ts +0 -279
  399. package/src/runtime/assistant/intent.ts +0 -395
  400. package/src/runtime/assistant/model-provider.ts +0 -460
  401. package/src/runtime/assistant/openapi.ts +0 -223
  402. package/src/runtime/assistant/policy.ts +0 -89
  403. package/src/runtime/assistant/readiness.ts +0 -258
  404. package/src/runtime/assistant/routine-runtime.ts +0 -477
  405. package/src/runtime/assistant/schedule-binding.ts +0 -171
  406. package/src/runtime/assistant/standing-grants.ts +0 -375
  407. package/src/runtime/assistant/store.ts +0 -243
  408. package/src/runtime/assistant/types.ts +0 -135
  409. package/src/runtime/control-plane/goal-loop/config-facade.ts +0 -700
  410. package/src/runtime/control-plane/goal-loop/config-store.ts +0 -570
  411. package/src/runtime/control-plane/goal-loop/config-types.ts +0 -213
  412. package/src/runtime/control-plane/goal-loop/executor-router.ts +0 -109
  413. package/src/runtime/control-plane/goal-loop/failure-taxonomy.ts +0 -149
  414. package/src/runtime/control-plane/goal-loop/goal-contract-store.ts +0 -304
  415. package/src/runtime/control-plane/goal-loop/goal-loop-engine.ts +0 -1001
  416. package/src/runtime/control-plane/goal-loop/handoff-packet.ts +0 -160
  417. package/src/runtime/control-plane/goal-loop/index.ts +0 -13
  418. package/src/runtime/control-plane/goal-loop/local-tools.ts +0 -290
  419. package/src/runtime/control-plane/goal-loop/policy-gates.ts +0 -203
  420. package/src/runtime/control-plane/goal-loop/provider-dispatch.ts +0 -93
  421. package/src/runtime/control-plane/goal-loop/provider-registry.ts +0 -545
  422. package/src/runtime/control-plane/goal-loop/types.ts +0 -378
  423. package/src/runtime/control-plane/startup-recovery.ts +0 -198
  424. package/src/runtime/gateway/mcp/resource-policy.ts +0 -186
  425. package/src/runtime/personal-assistant/gmail-triage-manager.ts +0 -231
  426. package/src/runtime/personal-assistant/reporting-runtime.ts +0 -344
  427. package/src/runtime/personal-assistant/triage-runtime.ts +0 -748
  428. package/src/runtime/plugins/desktop-adapter.ts +0 -374
  429. package/src/runtime/safe-tooling/browser-safe.ts +0 -133
  430. package/src/runtime/workflow/findings/store.ts +0 -204
  431. package/src/runtime/workflow/findings/types.ts +0 -58
  432. package/src/runtime/workflow/portfolio/engine.ts +0 -20
  433. package/src/runtime/workflow/portfolio/store.ts +0 -185
  434. package/src/runtime/workflow/portfolio/types.ts +0 -29
@@ -1,1192 +1,36 @@
1
1
  #!/bin/bash
2
- # Migrate an existing project to the forge tasks-first harness model.
3
- # - Shared hook source of truth: .ai/hooks/
4
- # - User-level host adapters: ~/.claude/settings.json and ~/.codex/hooks.json
5
- # - Stable product truth: docs/spec.md
6
- # - Active-plan selector: .ai/harness/active-plan, with .claude/.active-plan legacy fallback
7
- # - Sprint artifacts: plans/sprints/, tasks/contracts/, tasks/reviews/, .ai/context/context-map.json
8
- # - Harness state: .ai/harness/checks/latest.json, .ai/harness/policy.json,
9
- # .ai/harness/brain-manifest.json,
10
- # .ai/harness/events.jsonl, .ai/harness/architecture/events.jsonl,
11
- # .ai/harness/session/continuation.md,
12
- # .ai/harness/session/resume.md,
13
- # .ai/harness/failures/latest.jsonl, .ai/harness/security/.gitkeep,
14
- # .ai/harness/worktrees/.gitkeep, .ai/harness/runs/.gitkeep
2
+ # Run the canonical Forge adoption path without guessing a developer checkout.
15
3
  #
16
- # Usage:
17
- # bash scripts/migrate-project-template.sh --repo /path/to/repo --dry-run
18
- # bash scripts/migrate-project-template.sh --repo /path/to/repo --apply
4
+ # The self-host repository invokes this script directly, so delegating to a
5
+ # discovered copy of this same filename used to recurse. Installed helper
6
+ # copies use an explicit source root when one is supplied, otherwise the
7
+ # installed `forge` CLI.
19
8
 
20
9
  set -euo pipefail
21
10
 
22
11
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
23
- SKILL_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
24
- PI_LIB_DIR="$SCRIPT_DIR/lib"
25
- if [[ -f "$PI_LIB_DIR/project-init-lib.sh" ]]; then
26
- # shellcheck source=/dev/null
27
- . "$PI_LIB_DIR/project-init-lib.sh"
28
- fi
29
- HOOK_ASSETS_DIR="$SKILL_ROOT/assets/hooks"
30
- TEMPLATE_ASSETS_DIR="$SKILL_ROOT/assets/templates"
31
- HELPER_ASSETS_DIR="$TEMPLATE_ASSETS_DIR/helpers"
32
- FACTOR_FACTORY_ASSETS_DIR="$TEMPLATE_ASSETS_DIR/factor-factory"
33
- WORKFLOW_CONTRACT_ASSET="$SKILL_ROOT/assets/workflow-contract.v1.json"
34
- JQ_BIN="${FORGE_JQ_BIN:-jq}"
35
-
36
- MODE="dry-run"
37
- TARGET_REPO=""
38
- INSPECT_OUTPUT=""
39
-
40
- usage() {
41
- cat <<'USAGE_EOF'
42
- Usage: migrate-project-template.sh --repo <path> [--dry-run|--apply]
43
-
44
- Options:
45
- --repo <path> Target repository path
46
- --dry-run Print planned changes only (default)
47
- --apply Apply changes
48
- --help Show help
49
- USAGE_EOF
50
- }
51
-
52
- log() {
53
- echo "[migrate] $*"
54
- }
55
-
56
- has_jq() {
57
- command -v "$JQ_BIN" >/dev/null 2>&1
58
- }
12
+ SELF_SOURCE_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
13
+ SOURCE_ROOT="${FORGE_SOURCE_ROOT:-${AGENTIC_DEV_ROOT:-${AGENTIC_DEV_SKILL_ROOT:-}}}"
59
14
 
60
- run_ts_script() {
61
- local script_path="$1"
15
+ run_source_root() {
16
+ local root="$1"
62
17
  shift
63
-
64
- if command -v bun >/dev/null 2>&1; then
65
- bun "$script_path" "$@"
66
- return $?
67
- fi
68
-
69
- if command -v node >/dev/null 2>&1; then
70
- node --loader "$SKILL_ROOT/src/runtime/shared/node-ts-loader.mjs" "$script_path" "$@"
71
- return $?
72
- fi
73
-
74
- echo "[migrate] Missing bun/node runtime for TypeScript helper: $script_path" >&2
75
- return 1
76
- }
77
-
78
- merge_hook_settings_json() {
79
- local base_file="$1"
80
- local patch_file="$2"
81
- local output_file="$3"
82
-
83
- node - "$base_file" "$patch_file" "$output_file" <<'NODE_EOF'
84
- const fs = require("fs");
85
-
86
- const [, , basePath, patchPath, outputPath] = process.argv;
87
-
88
- function readJson(path) {
89
- return JSON.parse(fs.readFileSync(path, "utf8"));
90
- }
91
-
92
- function clone(value) {
93
- return JSON.parse(JSON.stringify(value));
94
- }
95
-
96
- function matcherOf(block) {
97
- return block && Object.prototype.hasOwnProperty.call(block, "matcher")
98
- ? block.matcher ?? null
99
- : null;
100
- }
101
-
102
- function ensureHooksArray(block) {
103
- if (!Array.isArray(block.hooks)) {
104
- block.hooks = [];
105
- }
106
- return block.hooks;
107
- }
108
-
109
- function hasCommand(block, command) {
110
- return ensureHooksArray(block).some((hook) => (hook?.command ?? "") === command);
111
- }
112
-
113
- function mergeEventBlocks(baseBlocks, patchBlocks) {
114
- const result = Array.isArray(baseBlocks) ? clone(baseBlocks) : [];
115
-
116
- for (const patchBlock of Array.isArray(patchBlocks) ? patchBlocks : []) {
117
- const matcher = matcherOf(patchBlock);
118
- const patchHooks = Array.isArray(patchBlock?.hooks) ? patchBlock.hooks : [];
119
-
120
- for (const patchHook of patchHooks) {
121
- const command = patchHook?.command ?? "";
122
- if (!command) continue;
123
-
124
- const existingWithCommand = result.find(
125
- (block) => matcherOf(block) === matcher && hasCommand(block, command)
126
- );
127
- if (existingWithCommand) continue;
128
-
129
- const targetBlock = result.find((block) => matcherOf(block) === matcher);
130
- if (targetBlock) {
131
- ensureHooksArray(targetBlock).push(clone(patchHook));
132
- continue;
133
- }
134
-
135
- const newBlock = matcher === null
136
- ? { hooks: [clone(patchHook)] }
137
- : { matcher, hooks: [clone(patchHook)] };
138
- result.push(newBlock);
139
- }
140
- }
141
-
142
- return result;
143
- }
144
-
145
- const base = readJson(basePath);
146
- const patch = readJson(patchPath);
147
-
148
- const merged = {
149
- ...clone(base),
150
- ...clone(Object.fromEntries(Object.entries(patch).filter(([key]) => key !== "hooks"))),
151
- };
152
-
153
- const baseHooks = (base && typeof base.hooks === "object" && base.hooks !== null) ? clone(base.hooks) : {};
154
- const patchHooks = (patch && typeof patch.hooks === "object" && patch.hooks !== null) ? patch.hooks : {};
155
-
156
- merged.hooks = baseHooks;
157
- for (const [eventName, patchBlocks] of Object.entries(patchHooks)) {
158
- merged.hooks[eventName] = mergeEventBlocks(baseHooks[eventName], patchBlocks);
159
- }
160
-
161
- fs.writeFileSync(outputPath, JSON.stringify(merged, null, 2) + "\n");
162
- NODE_EOF
163
- }
164
-
165
- run_or_echo() {
166
- if [[ "$MODE" == "apply" ]]; then
167
- "$@"
168
- else
169
- printf '[dry-run]'
170
- printf ' %q' "$@"
171
- printf '\n'
172
- fi
173
- }
174
-
175
- backup_if_exists() {
176
- local path="$1"
177
- if [[ -f "$path" ]]; then
178
- run_or_echo cp "$path" "$path.bak.$(date +%Y%m%d%H%M%S)"
179
- fi
180
- }
181
-
182
- remove_path_if_exists() {
183
- local path="$1"
184
- if [[ "$MODE" != "apply" ]]; then
185
- echo "[dry-run] remove \"$path\" if it exists"
186
- return 0
187
- fi
188
-
189
- if [[ -e "$path" ]]; then
190
- rm -rf "$path"
191
- fi
192
- }
193
-
194
- repo_relative_path() {
195
- local repo="$1"
196
- local path="$2"
197
-
198
- if [[ "$path" == "$repo/"* ]]; then
199
- printf '%s' "${path#"$repo/"}"
200
- else
201
- printf '%s' "$path"
202
- fi
203
- }
204
-
205
- file_matches_any_source() {
206
- local file_path="$1"
207
- shift
208
- local source_path
209
-
210
- [[ -f "$file_path" ]] || return 1
211
- for source_path in "$@"; do
212
- [[ -f "$source_path" ]] || continue
213
- if cmp -s "$file_path" "$source_path"; then
214
- return 0
215
- fi
216
- done
217
-
218
- return 1
219
- }
220
-
221
- file_has_forge_marker() {
222
- local file_path="$1"
223
-
224
- [[ -f "$file_path" ]] || return 1
225
-
226
- grep -Eiq \
227
- '(forge|claude-runtime-temp|Task Contract|Sprint Review|Deferred Goal Ledger|Workflow Contract|ContractWorktree|SprintBacklog|ArchitectureSync|ArchitectureDrift|BrainSync|CurrentStatus|\.ai/harness|\.claude/templates|tasks/contracts|tasks/reviews)' \
228
- "$file_path"
229
- }
230
-
231
- is_self_host_source_repo() {
232
- local repo="$1"
233
- local repo_real
234
- local source_real
235
-
236
- repo_real="$(cd "$repo" 2>/dev/null && pwd -P || printf '%s' "$repo")"
237
- source_real="$(cd "$SKILL_ROOT" 2>/dev/null && pwd -P || printf '%s' "$SKILL_ROOT")"
238
-
239
- [[ "$repo_real" == "$source_real" ]]
240
- }
241
-
242
- is_generated_root_helper() {
243
- local repo="$1"
244
- local rel_path="$2"
245
- local path="$repo/$rel_path"
246
- local helper_name="${rel_path##*/}"
247
-
248
- [[ "$rel_path" == scripts/* && -f "$path" ]] || return 1
249
-
250
- if file_matches_any_source "$path" "$HELPER_ASSETS_DIR/$helper_name" "$SCRIPT_DIR/$helper_name"; then
251
- return 0
252
- fi
253
-
254
- case "$helper_name" in
255
- skill-factory-create.sh|skill-factory-check.sh|architecture-drift.sh)
256
- file_has_forge_marker "$path"
257
- return $?
258
- ;;
259
- esac
260
-
261
- file_has_forge_marker "$path"
262
- }
263
-
264
- remove_generated_helper_if_owned() {
265
- local repo="$1"
266
- local rel_path="$2"
267
- local path="$repo/$rel_path"
268
- local display_path
269
-
270
- display_path="$(repo_relative_path "$repo" "$path")"
271
-
272
- if is_self_host_source_repo "$repo"; then
273
- if [[ "$MODE" != "apply" ]]; then
274
- echo "[dry-run] preserve self-host source helper \"$path\""
275
- else
276
- log "Preserved self-host source helper: $display_path"
277
- fi
278
- return 0
279
- fi
280
-
281
- if [[ "$MODE" != "apply" ]]; then
282
- echo "[dry-run] remove generated helper \"$path\" if forge ownership is identifiable"
283
- return 0
284
- fi
285
-
286
- [[ -e "$path" ]] || return 0
287
-
288
- if is_generated_root_helper "$repo" "$rel_path"; then
289
- rm -f "$path"
290
- log "Removed generated legacy root helper: $display_path"
291
- else
292
- log "Preserved possible app-owned script: $display_path (not identifiable as forge generated helper)"
293
- fi
294
- }
295
-
296
- prune_removed_hook_commands() {
297
- local settings_file="$1"
298
-
299
- if [[ "$MODE" != "apply" || ! -f "$settings_file" ]]; then
300
- return 0
301
- fi
302
-
303
- if ! command -v node >/dev/null 2>&1; then
304
- log "Skipping removed-hook pruning for $settings_file because node is unavailable"
305
- return 0
306
- fi
307
-
308
- node - "$settings_file" <<'NODE_EOF'
309
- const fs = require("fs");
310
- const path = process.argv[2];
311
- const removedFragments = ["memory-intake.sh", "skill-factory-session-end.sh"];
312
-
313
- const settings = JSON.parse(fs.readFileSync(path, "utf8"));
314
- if (!settings.hooks || typeof settings.hooks !== "object") {
315
- process.exit(0);
316
- }
317
-
318
- const nextHooks = {};
319
- for (const [eventName, blocks] of Object.entries(settings.hooks)) {
320
- const keptBlocks = (Array.isArray(blocks) ? blocks : [])
321
- .map((block) => {
322
- const hooks = (Array.isArray(block.hooks) ? block.hooks : []).filter((hook) => {
323
- const command = hook?.command ?? "";
324
- return !removedFragments.some((fragment) => command.includes(fragment));
325
- });
326
- return hooks.length > 0 ? { ...block, hooks } : null;
327
- })
328
- .filter(Boolean);
329
-
330
- if (keptBlocks.length > 0) {
331
- nextHooks[eventName] = keptBlocks;
332
- }
333
- }
334
-
335
- settings.hooks = nextHooks;
336
- fs.writeFileSync(path, JSON.stringify(settings, null, 2) + "\n");
337
- NODE_EOF
338
- }
339
-
340
- cleanup_removed_workflow_assets() {
341
- local repo="$1"
342
- local cleanup_mode
343
- local rel_path
344
-
345
- while IFS=$'\t' read -r cleanup_mode rel_path; do
346
- [[ -z "$rel_path" ]] && continue
347
- case "$cleanup_mode" in
348
- generated_helper)
349
- remove_generated_helper_if_owned "$repo" "$rel_path"
350
- ;;
351
- *)
352
- remove_path_if_exists "$repo/$rel_path"
353
- ;;
354
- esac
355
- done < <(pi_workflow_contract_upgrade_action_entries "$WORKFLOW_CONTRACT_ASSET" "remove" "known_generated")
356
- }
357
-
358
- ensure_runtime_gitignore_block() {
359
- local repo="$1"
360
- local file_path="$2"
361
- local extra_entries=""
362
- local helper_entries=""
363
- if pi_should_enable_factor_factory "$(pi_plan_type)"; then
364
- extra_entries="$(pi_factor_factory_gitignore_entries)"
365
- fi
366
- if ! is_self_host_source_repo "$repo" && ! pi_repo_pins_helper_source "$repo"; then
367
- helper_entries="$(pi_helper_wrapper_gitignore_entries "$WORKFLOW_CONTRACT_ASSET")"
368
- if [[ -n "$helper_entries" ]]; then
369
- if [[ -n "$extra_entries" ]]; then
370
- extra_entries="${extra_entries}"$'\n'"${helper_entries}"
371
- else
372
- extra_entries="$helper_entries"
373
- fi
374
- fi
375
- fi
376
- pi_ensure_gitignore_block "$file_path" "" "$extra_entries" "$MODE"
377
- }
378
-
379
- generated_helper_wrapper_paths() {
380
- local helper_name
381
- while IFS= read -r helper_name; do
382
- [[ -z "$helper_name" ]] && continue
383
- printf '%s\n' "$helper_name"
384
- printf '%s\n' "scripts/forge/${helper_name#scripts/}"
385
- done < <(pi_helper_wrapper_paths "$WORKFLOW_CONTRACT_ASSET")
386
- }
387
-
388
- untrack_generated_helper_wrappers() {
389
- local repo="$1"
390
- local rel_path
391
-
392
- if is_self_host_source_repo "$repo" || pi_repo_pins_helper_source "$repo"; then
393
- return 0
394
- fi
395
-
396
- if [[ "$MODE" != "apply" ]]; then
397
- echo "[dry-run] untrack forge generated helper wrappers from git index when tracked"
398
- return 0
399
- fi
400
-
401
- if ! git -C "$repo" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
402
- return 0
403
- fi
404
-
405
- while IFS= read -r rel_path; do
406
- [[ -z "$rel_path" ]] && continue
407
- if ! git -C "$repo" ls-files --error-unmatch -- "$rel_path" >/dev/null 2>&1; then
408
- continue
409
- fi
410
- if [[ "$rel_path" == scripts/forge/* ]] || is_generated_root_helper "$repo" "$rel_path"; then
411
- git -C "$repo" rm --cached --force --quiet -- "$rel_path"
412
- log "Untracked generated helper wrapper: $rel_path"
413
- else
414
- log "Preserved tracked app-owned script: $rel_path"
415
- fi
416
- done < <(generated_helper_wrapper_paths)
417
- }
418
-
419
- migrate_active_plan_marker() {
420
- local repo="$1"
421
- local new_marker="$repo/.ai/harness/active-plan"
422
- local legacy_marker="$repo/.claude/.active-plan"
423
- local worktree_marker="$repo/.ai/harness/active-worktree"
424
- local new_value=""
425
- local legacy_value=""
426
-
427
- if [[ "$MODE" != "apply" ]]; then
428
- echo "[dry-run] migrate active-plan marker to .ai/harness/active-plan with .claude/.active-plan compatibility"
429
- return 0
430
- fi
431
-
432
- if [[ -f "$new_marker" ]]; then
433
- new_value="$(cat "$new_marker" 2>/dev/null | xargs)"
434
- fi
435
- if [[ -f "$legacy_marker" ]]; then
436
- legacy_value="$(cat "$legacy_marker" 2>/dev/null | xargs)"
437
- fi
438
-
439
- if [[ -n "$new_value" ]]; then
440
- mkdir -p "$(dirname "$legacy_marker")"
441
- printf '%s' "$new_value" > "$legacy_marker"
442
- mkdir -p "$(dirname "$worktree_marker")"
443
- (cd "$repo" && pwd -P) > "$worktree_marker"
444
- return 0
445
- fi
446
-
447
- if [[ -n "$legacy_value" ]]; then
448
- mkdir -p "$(dirname "$new_marker")"
449
- printf '%s' "$legacy_value" > "$new_marker"
450
- (cd "$repo" && pwd -P) > "$worktree_marker"
451
- fi
452
- }
453
-
454
- ensure_gitignore_entry() {
455
- local file_path="$1"
456
- local entry="$2"
457
-
458
- if [[ "$MODE" != "apply" ]]; then
459
- echo "[dry-run] ensure .gitignore entry: $entry"
460
- return
461
- fi
462
-
463
- if ! grep -Fxq "$entry" "$file_path"; then
464
- printf "%s\n" "$entry" >> "$file_path"
465
- fi
466
- }
467
-
468
- install_templates() {
469
- local repo="$1"
470
- pi_install_templates "$repo" "$TEMPLATE_ASSETS_DIR" "$MODE"
471
- }
472
-
473
- install_helpers() {
474
- local repo="$1"
475
- if [[ -d "$HELPER_ASSETS_DIR" ]]; then
476
- local helper_names
477
- helper_names="$(pi_workflow_contract_query_lines "$WORKFLOW_CONTRACT_ASSET" "helpers.scripts" | xargs)"
478
- pi_install_helpers "$repo" "$HELPER_ASSETS_DIR" "$MODE" "$helper_names"
479
- else
480
- log "Helper assets not found at $HELPER_ASSETS_DIR"
481
- fi
482
- }
483
-
484
- install_workflow_contract() {
485
- local repo="$1"
486
- pi_install_workflow_contract "$repo" "$WORKFLOW_CONTRACT_ASSET" "$MODE"
487
- }
488
-
489
- ensure_task_sync_package_script() {
490
- local repo="$1"
491
- local package_file="$repo/package.json"
492
-
493
- if [[ ! -f "$package_file" ]]; then
494
- if [[ "$MODE" == "apply" ]]; then
495
- log "package.json missing; skipped check:task-sync injection"
496
- else
497
- echo "[dry-run] package.json missing; skip task workflow script injection"
498
- fi
499
- return
500
- fi
501
-
502
- pi_ensure_task_sync "$repo" "0" "$MODE"
503
- if [[ "$MODE" == "apply" ]]; then
504
- log "Injected task workflow scripts into $package_file"
505
- fi
506
- }
507
-
508
- migrate_legacy_sprint_prds() {
509
- local repo="$1"
510
- local legacy_dir="$repo/tasks/sprints"
511
- local prd_dir="$repo/plans/prds"
512
- local sprint_dir="$repo/plans/sprints"
513
- local marker_file="$repo/.ai/harness/sprint/active-sprint"
514
- local src
515
- local stem
516
- local legacy_rel
517
- local marker_value
518
-
519
- if [[ "$MODE" != "apply" ]]; then
520
- echo "[dry-run] migrate legacy sprint files from tasks/sprints/*.sprint.md and sprint-shaped plans/prds/*.prd.md into plans/sprints/*.sprint.md"
521
- return 0
522
- fi
523
-
524
- mkdir -p "$prd_dir" "$sprint_dir"
525
- shopt -s nullglob
526
-
527
- move_sprint_file() {
528
- local src_file="$1"
529
- local old_rel="$2"
530
- local stem_name="$3"
531
- local dest_file
532
- local dest_rel_file
533
- local n
534
-
535
- dest_file="$sprint_dir/${stem_name}.sprint.md"
536
- n=2
537
- while [[ -e "$dest_file" ]]; do
538
- dest_file="$sprint_dir/${stem_name}-v${n}.sprint.md"
539
- n=$((n + 1))
540
- done
541
-
542
- mv "$src_file" "$dest_file"
543
-
544
- dest_rel_file="plans/sprints/$(basename "$dest_file")"
545
- if [[ -f "$marker_file" ]]; then
546
- marker_value="$(tr -d '\r\n' < "$marker_file")"
547
- if [[ "$marker_value" == "$old_rel" || "$marker_value" == "$src_file" ]]; then
548
- printf '%s\n' "$dest_rel_file" > "$marker_file"
549
- fi
550
- fi
551
- }
552
-
553
- for src in "$legacy_dir"/*.sprint.md; do
554
- stem="$(basename "$src" .sprint.md)"
555
- legacy_rel="tasks/sprints/${stem}.sprint.md"
556
- move_sprint_file "$src" "$legacy_rel" "$stem"
557
- done
558
-
559
- for src in "$prd_dir"/*.prd.md; do
560
- if grep -Eq '^(# Sprint:|## Backlog[[:space:]]*$)' "$src"; then
561
- stem="$(basename "$src" .prd.md)"
562
- legacy_rel="plans/prds/${stem}.prd.md"
563
- move_sprint_file "$src" "$legacy_rel" "$stem"
564
- fi
565
- done
566
- shopt -u nullglob
567
-
568
- rmdir "$legacy_dir" 2>/dev/null || true
569
- }
570
-
571
- create_task_files_if_missing() {
572
- local repo="$1"
573
- local project_name
574
- local timestamp
575
- local todo_file
576
- local legacy_todo_file
577
- local legacy_todo_archive
578
-
579
- project_name="$(basename "$repo")"
580
- timestamp="$(date '+%Y-%m-%d %H:%M')"
581
- todo_file="$repo/tasks/todos.md"
582
- legacy_todo_file="$repo/tasks/todo.md"
583
- legacy_todo_archive="$repo/tasks/archive/legacy-tasks-todo.md"
584
-
585
- if [[ "$MODE" != "apply" ]]; then
586
- echo "[dry-run] ensure docs/spec.md, tasks/*, workstreams, reviews, notes, .ai/context/{capabilities.json,context-map.json}, and .ai/harness/{checks/latest.json,policy.json,brain-manifest.json,events.jsonl,architecture/events.jsonl,handoff/current.md,handoff/resume.md,failures/latest.jsonl,security/.gitkeep,worktrees/.gitkeep,runs/.gitkeep} exist with current workflow guidance"
587
- return
588
- fi
589
-
590
- mkdir -p \
591
- "$repo/plans" \
592
- "$repo/plans/archive" \
593
- "$repo/plans/prds" \
594
- "$repo/plans/sprints" \
595
- "$repo/tasks" \
596
- "$repo/tasks/issues" \
597
- "$repo/tasks/archive" \
598
- "$repo/tasks/contracts" \
599
- "$repo/tasks/reviews" \
600
- "$repo/tasks/notes" \
601
- "$repo/tasks/workstreams" \
602
- "$repo/docs" \
603
- "$repo/docs/architecture/domains" \
604
- "$repo/docs/architecture/modules" \
605
- "$repo/docs/architecture/requests" \
606
- "$repo/docs/architecture/snapshots" \
607
- "$repo/docs/architecture/diagrams" \
608
- "$repo/.ai/context" \
609
- "$repo/.ai/harness/checks" \
610
- "$repo/.ai/harness/session" \
611
- "$repo/.ai/harness/controller/packets" \
612
- "$repo/.ai/harness/projections" \
613
- "$repo/.ai/harness/transfers" \
614
- "$repo/.ai/harness/failures" \
615
- "$repo/.ai/harness/architecture" \
616
- "$repo/.ai/harness/runs" \
617
- "$repo/.ai/harness/worktrees" \
618
- "$repo/.ai/harness/jobs" \
619
- "$repo/.ai/harness/edit-sessions"
620
-
621
- if [[ ! -f "$repo/docs/spec.md" ]]; then
622
- if [[ -f "$repo/.claude/templates/spec.template.md" ]]; then
623
- sed \
624
- -e "s/{{PROJECT_NAME}}/${project_name}/g" \
625
- -e "s/{{TIMESTAMP}}/${timestamp}/g" \
626
- "$repo/.claude/templates/spec.template.md" > "$repo/docs/spec.md"
627
- else
628
- cat > "$repo/docs/spec.md" <<EOF_SPEC
629
- # Product Spec: ${project_name}
630
-
631
- > **Status**: Draft
632
- > **Last Updated**: ${timestamp}
633
- > **Owner**: Planner
634
- EOF_SPEC
635
- fi
636
- fi
637
-
638
- if [[ -f "$legacy_todo_file" ]]; then
639
- mkdir -p "$repo/tasks/archive"
640
- if [[ ! -f "$legacy_todo_archive" ]]; then
641
- cp "$legacy_todo_file" "$legacy_todo_archive"
642
- fi
643
- if [[ ! -f "$todo_file" ]]; then
644
- if grep -Eq '^# Deferred Goal Ledger[[:space:]]*$' "$legacy_todo_file" \
645
- && grep -Eq '^> \*\*Status\*\*:[[:space:]]*Backlog[[:space:]]*$' "$legacy_todo_file"; then
646
- cp "$legacy_todo_file" "$todo_file"
647
- else
648
- cat > "$todo_file" <<'TODO_EOF'
649
- # Deferred Goal Ledger
650
-
651
- > **Status**: Backlog
652
- > **Updated**: (migration)
653
- > **Scope**: Medium/long-term goals deferred from active plan execution
654
-
655
- Current plan tasks live in the active plan's `## Task Breakdown`.
656
- Do not duplicate that execution checklist here. Record only work intentionally deferred beyond this slice, with the tradeoff and revisit trigger.
657
-
658
- ## Deferred Goals
659
-
660
- | Goal | Why Deferred | Tradeoff | Revisit Trigger |
661
- |------|--------------|----------|-----------------|
662
- | Review archived legacy checklist | Legacy tasks/todo.md contained execution checklist content before migration. | Preserve user-authored task text in tasks/archive instead of guessing which items still matter. | Open the archive and promote real follow-up work into a new plan or a deferred-goal row. |
663
- TODO_EOF
664
- fi
665
- fi
666
- mv "$legacy_todo_file" "$legacy_todo_file.migrated.bak"
667
- fi
668
-
669
- if [[ ! -f "$todo_file" ]]; then
670
- cat > "$todo_file" <<'TODO_EOF'
671
- # Deferred Goal Ledger
672
-
673
- > **Status**: Backlog
674
- > **Updated**: (migration)
675
- > **Scope**: Medium/long-term goals deferred from active plan execution
676
-
677
- Current plan tasks live in the active plan's `## Task Breakdown`.
678
- Do not duplicate that execution checklist here. Record only work intentionally deferred beyond this slice, with the tradeoff and revisit trigger.
679
-
680
- ## Deferred Goals
681
-
682
- | Goal | Why Deferred | Tradeoff | Revisit Trigger |
683
- |------|--------------|----------|-----------------|
684
- | (none) | No deferred medium/long-term goal recorded yet. | Keep migrated workflow state bounded. | Add a row when a real follow-up is postponed. |
685
- TODO_EOF
686
- elif ! grep -Eq '^> \*\*Status\*\*:[[:space:]]*Backlog[[:space:]]*$' "$todo_file"; then
687
- backup_if_exists "$todo_file"
688
- cat > "$todo_file" <<'TODO_EOF'
689
- # Deferred Goal Ledger
690
-
691
- > **Status**: Backlog
692
- > **Updated**: (migration)
693
- > **Scope**: Medium/long-term goals deferred from active plan execution
694
-
695
- Current plan tasks live in the active plan's `## Task Breakdown`.
696
- Do not duplicate that execution checklist here. Record only work intentionally deferred beyond this slice, with the tradeoff and revisit trigger.
697
-
698
- ## Deferred Goals
699
-
700
- | Goal | Why Deferred | Tradeoff | Revisit Trigger |
701
- |------|--------------|----------|-----------------|
702
- | Review archived legacy checklist | Legacy tasks/todos.md contained execution checklist content before migration. | Preserve user-authored task text in tasks/archive instead of guessing which items still matter. | Open the archive and promote real follow-up work into a new plan or a deferred-goal row. |
703
- TODO_EOF
704
- fi
705
-
706
- if [[ ! -f "$repo/tasks/current.md" ]]; then
707
- cat > "$repo/tasks/current.md" <<'CURRENT_STATUS_EOF'
708
- # Current Status Snapshot
709
-
710
- <!-- generated-by: forge refresh-current-status v1 -->
711
- <!-- updated_at: bootstrap -->
712
- <!-- stale_after: 24h -->
713
-
714
- > **Status**: Idle
715
- > **Updated At**: bootstrap
716
- > **Source Branch**: main
717
- > **Source Commit**: bootstrap
718
- > **Target Branch**: main
719
- > **Stale After**: 24h
720
- > **Reason**: bootstrap
721
- > **Derived From**: active-plan, workstreams, handoff, checks, git status
722
-
723
- This file is a tracked mainline snapshot derived from repo artifacts. It is not a live lock, not a kanban board, and not an implementation gate. If it is stale, read the source artifacts below.
724
- CURRENT_STATUS_EOF
725
- fi
726
-
727
- if [[ ! -f "$repo/tasks/lessons.md" ]]; then
728
- cat > "$repo/tasks/lessons.md" <<'LESSONS_EOF'
729
- # Lessons Learned (Self-Improvement Loop)
730
-
731
- > Capture correction-derived prevention rules here.
732
- > Promote repeated patterns into durable project rules during spa day.
733
-
734
- ## Template
735
- - Date:
736
- - Triggered by correction:
737
- - Mistake pattern:
738
- - Prevention rule:
739
- - Where to apply next time:
740
- LESSONS_EOF
741
- fi
742
-
743
- pi_ensure_harness_state_surface "$repo" "apply"
744
-
745
- }
746
-
747
- install_reference_configs() {
748
- local repo="$1"
749
- local ref_dir="$repo/docs/reference-configs"
750
- local ref_assets_dir="$SKILL_ROOT/assets/reference-configs"
751
-
752
- run_or_echo mkdir -p "$ref_dir"
753
-
754
- if [[ -d "$ref_assets_dir" ]]; then
755
- if [[ "$MODE" == "apply" ]]; then
756
- pi_install_reference_configs "$repo" "$ref_assets_dir" "apply"
757
- else
758
- pi_install_reference_configs "$repo" "$ref_assets_dir" "dry-run"
759
- fi
760
- fi
761
- }
762
-
763
- ensure_ops_scaffold() {
764
- local repo="$1"
765
- local deploy_readme="$repo/deploy/README.md"
766
-
767
- run_or_echo mkdir -p "$repo/deploy/env"
768
- run_or_echo mkdir -p "$repo/deploy/scripts"
769
- run_or_echo mkdir -p "$repo/deploy/submissions"
770
- run_or_echo mkdir -p "$repo/deploy/runbooks"
771
- run_or_echo mkdir -p "$repo/deploy/release-checklists"
772
- run_or_echo mkdir -p "$repo/deploy/sql"
773
- run_or_echo mkdir -p "$repo/_ops/env"
774
- run_or_echo mkdir -p "$repo/_ops/secrets"
775
- run_or_echo mkdir -p "$repo/_ops/artifacts"
776
- run_or_echo mkdir -p "$repo/_ops/logs"
777
- run_or_echo mkdir -p "$repo/_ops/state"
778
- run_or_echo mkdir -p "$repo/_ops/scratch"
779
-
780
- if [[ "$MODE" != "apply" ]]; then
781
- echo "[dry-run] ensure deploy workspace README, tracked placeholders, deploy/sql, and ignored _ops private state"
782
- echo "[dry-run] migrate legacy _ops runbooks/scripts/submissions/env examples into deploy/"
783
- return 0
784
- fi
785
-
786
- migrate_legacy_ops_asset() {
787
- local src="$1"
788
- local dest="$2"
789
- if [[ -e "$src" && ! -e "$dest" ]]; then
790
- mv "$src" "$dest"
791
- fi
792
- }
793
-
794
- migrate_legacy_ops_children() {
795
- local src_dir="$1"
796
- local dest_dir="$2"
797
- local src
798
- local base
799
- [[ -d "$src_dir" ]] || return 0
800
- shopt -s nullglob dotglob
801
- for src in "$src_dir"/*; do
802
- base="$(basename "$src")"
803
- [[ "$base" == ".gitkeep" ]] && continue
804
- migrate_legacy_ops_asset "$src" "$dest_dir/$base"
805
- done
806
- shopt -u nullglob dotglob
807
- }
808
-
809
- migrate_legacy_ops_asset "$repo/_ops/env/.env.example" "$repo/deploy/env/.env.example"
810
- migrate_legacy_ops_children "$repo/_ops/scripts" "$repo/deploy/scripts"
811
- migrate_legacy_ops_children "$repo/_ops/submissions" "$repo/deploy/submissions"
812
- migrate_legacy_ops_children "$repo/_ops/sql" "$repo/deploy/sql"
813
-
814
- shopt -s nullglob
815
- for legacy_doc in "$repo/_ops"/*.md; do
816
- legacy_base="$(basename "$legacy_doc")"
817
- [[ "$legacy_base" == "README.md" ]] && continue
818
- migrate_legacy_ops_asset "$legacy_doc" "$repo/deploy/$legacy_base"
819
- done
820
- shopt -u nullglob
821
-
822
- shopt -s nullglob
823
- for legacy_sql in "$repo/_ops"/*.sql; do
824
- legacy_base="$(basename "$legacy_sql")"
825
- migrate_legacy_ops_asset "$legacy_sql" "$repo/deploy/sql/$legacy_base"
826
- done
827
- shopt -u nullglob
828
-
829
- touch "$repo/deploy/env/.gitkeep"
830
- touch "$repo/deploy/scripts/.gitkeep"
831
- touch "$repo/deploy/submissions/.gitkeep"
832
- touch "$repo/deploy/runbooks/.gitkeep"
833
- touch "$repo/deploy/release-checklists/.gitkeep"
834
- touch "$repo/deploy/sql/.gitkeep"
835
-
836
- if [[ ! -f "$deploy_readme" ]]; then
837
- cat > "$deploy_readme" <<'DEPLOY_README_EOF'
838
- # Deployment Operations
839
-
840
- `deploy/` is a commit-ready surface for deployment and operations runbooks, submission materials, release checklists, helper scripts, and env examples.
841
-
842
- ## Track
843
-
844
- - `deploy/scripts/` for operational scripts.
845
- - `deploy/submissions/` for submission or review materials.
846
- - `deploy/runbooks/` and `deploy/release-checklists/` for operational documentation.
847
- - `deploy/sql/` for ordered deployment SQL files named like `0001_create_tables.sql`.
848
- - `deploy/*.md` for runbooks and operating notes.
849
- - `deploy/env/.env.example` for documented variable shapes only.
850
-
851
- ## Do Not Track
852
-
853
- - `_ops/`
854
- - private keys, real env files, provider state, production tokens, credential dumps, artifacts, logs, and local-only overrides
855
-
856
- Keep external upstream checkouts and source references in `_ref/`; `_ref/` is ignored and must stay out of commits.
857
- DEPLOY_README_EOF
858
- fi
859
- }
860
-
861
- ensure_research_surface() {
862
- local repo="$1"
863
- local research_dir="$repo/docs/researches"
864
- local research_readme="$research_dir/README.md"
865
- local legacy_research="$repo/tasks/research.md"
866
- local legacy_archive="$research_dir/legacy-research-notes.md"
867
-
868
- if [[ "$MODE" != "apply" ]]; then
869
- echo "[dry-run] ensure research reports directory at $research_dir"
870
- if [[ -f "$legacy_research" ]]; then
871
- echo "[dry-run] archive legacy $legacy_research into $legacy_archive and leave a tombstone"
872
- fi
873
- return
874
- fi
875
-
876
- mkdir -p "$research_dir"
877
-
878
- if [[ ! -f "$research_readme" ]]; then
879
- cat > "$research_readme" <<'RESEARCH_README_EOF'
880
- # Research Reports
881
-
882
- Durable research reports live in this directory as dated Markdown files.
883
-
884
- Use `YYYYMMDD-topic.md` names for new reports. Keep task-local implementation
885
- decisions in `tasks/notes/`, and keep repeated correction-derived rules in
886
- `tasks/lessons.md`.
887
- RESEARCH_README_EOF
888
- fi
889
-
890
- if [[ -f "$legacy_research" ]]; then
891
- if [[ ! -f "$legacy_archive" ]]; then
892
- cp "$legacy_research" "$legacy_archive"
893
- fi
894
-
895
- cat > "$legacy_research" <<'RESEARCH_TOMBSTONE_EOF'
896
- # Research Notes Moved
897
-
898
- > **Status**: Retired tombstone
899
- > **Canonical Surface**: `docs/researches/`
900
- > **Legacy Archive**: `docs/researches/legacy-research-notes.md`
901
-
902
- Durable research reports now live under `docs/researches/*.md`. This file is
903
- kept only as a transition pointer for older tooling and historical links; do
904
- not add new findings here.
905
- RESEARCH_TOMBSTONE_EOF
906
- fi
907
- }
908
-
909
- parse_args() {
910
- while [[ $# -gt 0 ]]; do
911
- case "$1" in
912
- --repo)
913
- TARGET_REPO="${2:-}"
914
- shift 2
915
- ;;
916
- --dry-run)
917
- MODE="dry-run"
918
- shift
919
- ;;
920
- --apply)
921
- MODE="apply"
922
- shift
923
- ;;
924
- --help)
925
- usage
926
- exit 0
927
- ;;
928
- *)
929
- echo "Unknown argument: $1" >&2
930
- usage
931
- exit 1
932
- ;;
933
- esac
934
- done
935
- }
936
-
937
- require_repo() {
938
- if [[ -z "$TARGET_REPO" ]]; then
939
- echo "--repo is required" >&2
940
- usage
18
+ [[ -f "$root/src/cli/index.ts" ]] || return 1
19
+ command -v bun >/dev/null 2>&1 || {
20
+ echo "[migrate] bun is required to run Forge from source: $root" >&2
941
21
  exit 1
942
- fi
943
-
944
- if [[ ! -d "$TARGET_REPO" ]]; then
945
- echo "Repo path does not exist: $TARGET_REPO" >&2
946
- exit 1
947
- fi
948
-
949
- local target_physical
950
- target_physical="$(cd "$TARGET_REPO" && pwd -P)"
951
- local home_physical=""
952
- if [[ -n "${HOME:-}" && -d "$HOME" ]]; then
953
- home_physical="$(cd "$HOME" && pwd -P)"
954
- fi
955
-
956
- if [[ -n "$home_physical" && "$target_physical" == "$home_physical" ]]; then
957
- echo "Refusing to migrate HOME as a repo target: $target_physical" >&2
958
- echo "Run forge adopt --repo <git-repo> from an intended project." >&2
959
- exit 2
960
- fi
961
- }
962
-
963
- inspect_project_state() {
964
- local repo="$1"
965
- local inspector="$SCRIPT_DIR/inspect-project-state.ts"
966
-
967
- if [[ ! -f "$inspector" ]]; then
968
- log "Project-state inspector missing: $inspector"
969
- return 1
970
- fi
971
-
972
- INSPECT_OUTPUT="$(run_ts_script "$inspector" --repo "$repo" --format text)"
973
- printf '%s\n' "$INSPECT_OUTPUT"
974
- }
975
-
976
- migrate_hooks() {
977
- local repo="$1"
978
- local project_claude_dir="$repo/.claude"
979
- local project_ai_hooks_dir="$repo/.ai/hooks"
980
-
981
- run_or_echo mkdir -p "$project_claude_dir" "$project_ai_hooks_dir"
982
-
983
- cleanup_removed_workflow_assets "$repo"
984
- pi_install_hook_assets "$repo" "$HOOK_ASSETS_DIR" "$MODE"
985
- pi_install_hook_adapters "$repo" "$HOOK_ASSETS_DIR" "$MODE"
986
- }
987
-
988
- migrate_docs() {
989
- local repo="$1"
990
- local migrator="$SCRIPT_DIR/migrate-workflow-docs.ts"
991
-
992
- if [[ ! -f "$migrator" ]]; then
993
- log "Legacy-doc migrator missing: $migrator"
994
- return 1
995
- fi
996
-
997
- if [[ "$MODE" == "apply" ]]; then
998
- run_ts_script "$migrator" --repo "$repo" --apply
999
- else
1000
- run_ts_script "$migrator" --repo "$repo" --dry-run
1001
- fi
1002
- }
1003
-
1004
- migrate_workflow() {
1005
- local repo="$1"
1006
-
1007
- run_or_echo mkdir -p "$repo/plans/archive"
1008
- run_or_echo mkdir -p "$repo/plans/prds"
1009
- run_or_echo mkdir -p "$repo/plans/sprints"
1010
- run_or_echo mkdir -p "$repo/tasks/archive"
1011
- run_or_echo mkdir -p "$repo/tasks/contracts"
1012
- run_or_echo mkdir -p "$repo/tasks/reviews"
1013
- run_or_echo mkdir -p "$repo/tasks/notes"
1014
- run_or_echo mkdir -p "$repo/tasks/workstreams"
1015
- run_or_echo mkdir -p "$repo/docs/reference-configs"
1016
- run_or_echo mkdir -p "$repo/.ai/harness/checks"
1017
- run_or_echo mkdir -p "$repo/.ai/harness/session" "$repo/.ai/harness/controller/packets" "$repo/.ai/harness/projections" "$repo/.ai/harness/transfers"
1018
- migrate_active_plan_marker "$repo"
1019
-
1020
- install_templates "$repo"
1021
- install_helpers "$repo"
1022
- install_workflow_contract "$repo"
1023
- if pi_should_enable_factor_factory "$(pi_plan_type)"; then
1024
- pi_install_factor_factory "$repo" "$FACTOR_FACTORY_ASSETS_DIR" "$SKILL_ROOT/scripts" "$MODE"
1025
- fi
1026
- install_reference_configs "$repo"
1027
- ensure_ops_scaffold "$repo"
1028
- ensure_research_surface "$repo"
1029
- migrate_legacy_sprint_prds "$repo"
1030
- create_task_files_if_missing "$repo"
1031
- ensure_task_sync_package_script "$repo"
1032
-
1033
- local repo_gitignore="$repo/.gitignore"
1034
- run_or_echo touch "$repo_gitignore"
1035
- ensure_gitignore_entry "$repo_gitignore" "# Project-specific"
1036
- ensure_gitignore_entry "$repo_gitignore" "artifacts/"
1037
- ensure_gitignore_entry "$repo_gitignore" "coverage/"
1038
- ensure_gitignore_entry "$repo_gitignore" "*.tar.gz"
1039
- ensure_gitignore_entry "$repo_gitignore" "*.tgz"
1040
- ensure_gitignore_entry "$repo_gitignore" "# External references"
1041
- ensure_gitignore_entry "$repo_gitignore" "_ref/"
1042
- ensure_gitignore_entry "$repo_gitignore" ".codegraph/"
1043
- ensure_gitignore_entry "$repo_gitignore" "# Local operations state"
1044
- ensure_gitignore_entry "$repo_gitignore" "_ops/"
1045
- ensure_gitignore_entry "$repo_gitignore" "# Environment"
1046
- ensure_gitignore_entry "$repo_gitignore" ".env"
1047
- ensure_gitignore_entry "$repo_gitignore" ".env.*"
1048
- ensure_gitignore_entry "$repo_gitignore" "!.env.example"
1049
- ensure_gitignore_entry "$repo_gitignore" "# OS metadata"
1050
- ensure_gitignore_entry "$repo_gitignore" ".DS_Store"
1051
- ensure_runtime_gitignore_block "$repo" "$repo_gitignore"
1052
- untrack_generated_helper_wrappers "$repo"
1053
-
1054
- }
1055
-
1056
- verify_migration_contract() {
1057
- local repo="$1"
1058
- local check_script="$repo/scripts/check-task-workflow.sh"
1059
- local handoff_script="$repo/scripts/prepare-codex-handoff.sh"
1060
-
1061
- if [[ "$MODE" != "apply" ]]; then
1062
- echo "[dry-run] refresh Codex handoff before workflow verify"
1063
- echo "[dry-run] verify migrated workflow with forge run check-task-workflow --strict"
1064
- return 0
1065
- fi
1066
-
1067
- if [[ ! -f "$check_script" ]]; then
1068
- log "Missing workflow check script after migration: $check_script"
1069
- return 1
1070
- fi
1071
-
1072
- if [[ -f "$handoff_script" ]]; then
1073
- (cd "$repo" && FORGE_SOURCE_ROOT="$SKILL_ROOT" bash "scripts/prepare-codex-handoff.sh" --reason "forge-migration-verify" >/dev/null)
1074
- log "Refreshed Codex handoff before workflow verify"
1075
- fi
1076
-
1077
- (cd "$repo" && FORGE_SOURCE_ROOT="$SKILL_ROOT" bash "scripts/check-task-workflow.sh" --strict)
1078
- }
1079
-
1080
- print_report() {
1081
- local repo="$1"
1082
- echo
1083
- echo "=== Migration Report ==="
1084
- echo "Mode: $MODE"
1085
- echo "Repo: $repo"
1086
- if [[ -n "$INSPECT_OUTPUT" ]]; then
1087
- echo "--- Inspection ---"
1088
- printf '%s\n' "$INSPECT_OUTPUT"
1089
- fi
1090
- echo "- Project hooks synced from: $HOOK_ASSETS_DIR (repo-local fallback; lib-only unless hook_source=repo)"
1091
- echo "- Host hook config target: user-level ~/.claude/settings.json and ~/.codex/hooks.json"
1092
- echo "- $(pi_print_codex_hook_trust_notice)"
1093
- echo "- Legacy docs/TODO.md / docs/plan.md / docs/PROGRESS.md: migrated by scripts/migrate-workflow-docs.ts"
1094
- echo "- Workflow migration: docs/spec.md + plans/ + tasks/contracts + tasks/reviews + .ai/context/context-map.json + .ai/harness/*"
1095
- echo "- Workflow contract manifest installed at: .ai/harness/workflow-contract.json"
1096
- echo "- Helper runtime: package-dispatched through forge run with scripts/* compatibility wrappers"
1097
- echo "- Upgrade/reconfigure/cleanup plan: generated from workflow contract migrations.upgrade"
1098
- echo "- Existing external_tooling overrides are preserved; missing defaults are merged into .ai/harness/policy.json"
1099
- echo "- Runtime temporary ignore block synced to .gitignore"
1100
- pi_print_external_tooling_report "$repo" "$MODE" "$SCRIPT_DIR/check-agent-tooling.sh"
1101
- }
1102
-
1103
- run_skill_hook() {
1104
- local event="$1"
1105
- local hook_script="$SCRIPT_DIR/run-skill-hook.ts"
1106
-
1107
- if command -v bun >/dev/null 2>&1 && [[ -f "$hook_script" ]]; then
1108
- bun "$hook_script" "$event" --context "{\"repo\":\"$TARGET_REPO\",\"mode\":\"$MODE\"}" 2>&1 || {
1109
- if [[ "$event" == pre-* ]]; then
1110
- log "Pre-hook $event failed, aborting."
1111
- return 1
1112
- else
1113
- log "Post-hook $event warning (non-fatal)."
1114
- fi
1115
- }
1116
- fi
1117
- }
1118
-
1119
- update_version_stamp() {
1120
- local repo="$1"
1121
- local stamp_file="$repo/.claude/.skill-version"
1122
- local skill_version_file="$SKILL_ROOT/assets/skill-version.json"
1123
- local sv_version="unknown"
1124
- local sv_template_version="unknown"
1125
-
1126
- if [[ -f "$skill_version_file" ]] && command -v bun >/dev/null 2>&1; then
1127
- sv_version=$(bun -e "console.log(JSON.parse(require('fs').readFileSync('$skill_version_file','utf-8')).version)")
1128
- sv_template_version=$(bun -e "console.log(JSON.parse(require('fs').readFileSync('$skill_version_file','utf-8')).templateVersion)")
1129
- elif [[ -f "$skill_version_file" ]] && command -v node >/dev/null 2>&1; then
1130
- sv_version=$(node -e "console.log(JSON.parse(require('fs').readFileSync('$skill_version_file','utf-8')).version)")
1131
- sv_template_version=$(node -e "console.log(JSON.parse(require('fs').readFileSync('$skill_version_file','utf-8')).templateVersion)")
1132
- fi
1133
-
1134
- if [[ "$MODE" == "apply" ]]; then
1135
- local existing_skill_version=""
1136
- local existing_template_version=""
1137
- local existing_migrated_at=""
1138
- local migrated_at=""
1139
-
1140
- if [[ -f "$stamp_file" ]]; then
1141
- existing_skill_version="$(awk -F= '$1 == "skill_version" { print $2 }' "$stamp_file" 2>/dev/null || true)"
1142
- existing_template_version="$(awk -F= '$1 == "template_version" { print $2 }' "$stamp_file" 2>/dev/null || true)"
1143
- existing_migrated_at="$(awk -F= '$1 == "migrated_at" { print $2 }' "$stamp_file" 2>/dev/null || true)"
1144
- fi
1145
-
1146
- if [[ "$existing_skill_version" == "$sv_version" && "$existing_template_version" == "$sv_template_version" && -n "$existing_migrated_at" ]]; then
1147
- migrated_at="$existing_migrated_at"
1148
- else
1149
- migrated_at="$(date -u '+%Y-%m-%dT%H:%M:%SZ')"
1150
- fi
1151
-
1152
- mkdir -p "$(dirname "$stamp_file")"
1153
- local stamp_tmp
1154
- stamp_tmp="$(mktemp)"
1155
- cat > "$stamp_tmp" <<STAMP_EOF
1156
- skill_version=$sv_version
1157
- template_version=$sv_template_version
1158
- migrated_at=$migrated_at
1159
- STAMP_EOF
1160
- if [[ -f "$stamp_file" ]] && cmp -s "$stamp_tmp" "$stamp_file"; then
1161
- rm -f "$stamp_tmp"
1162
- log "Version stamp already current: $stamp_file"
1163
- else
1164
- mv "$stamp_tmp" "$stamp_file"
1165
- log "Version stamp updated: $stamp_file"
1166
- fi
1167
- else
1168
- echo "[dry-run] update version stamp at $stamp_file (skill=$sv_version, template=$sv_template_version)"
1169
- fi
22
+ }
23
+ exec bun "$root/src/cli/index.ts" adopt "$@" --no-codegraph --no-verify
1170
24
  }
1171
25
 
1172
- main() {
1173
- parse_args "$@"
1174
- require_repo
1175
-
1176
- TARGET_REPO="$(cd "$TARGET_REPO" && pwd)"
1177
- log "Starting migration ($MODE) for $TARGET_REPO"
1178
-
1179
- run_skill_hook "pre-migrate" || exit 1
1180
-
1181
- inspect_project_state "$TARGET_REPO" || exit 1
1182
- migrate_hooks "$TARGET_REPO"
1183
- migrate_docs "$TARGET_REPO"
1184
- migrate_workflow "$TARGET_REPO"
1185
- update_version_stamp "$TARGET_REPO"
1186
- verify_migration_contract "$TARGET_REPO" || exit 1
1187
- print_report "$TARGET_REPO"
26
+ run_source_root "$SELF_SOURCE_ROOT" "$@"
27
+ if [[ -n "$SOURCE_ROOT" ]]; then
28
+ run_source_root "$SOURCE_ROOT" "$@"
29
+ fi
1188
30
 
1189
- run_skill_hook "post-migrate"
1190
- }
31
+ if command -v forge >/dev/null 2>&1; then
32
+ exec forge adopt "$@" --no-codegraph --no-verify
33
+ fi
1191
34
 
1192
- main "$@"
35
+ echo "[migrate] Missing Forge CLI; set FORGE_SOURCE_ROOT to a Forge source checkout." >&2
36
+ exit 1