@moretea-labs/forge 1.6.0 → 1.7.1

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 (469) hide show
  1. package/AGENTS.md +4 -0
  2. package/CHANGELOG.md +39 -0
  3. package/CLAUDE.md +4 -0
  4. package/README.md +2 -2
  5. package/README.zh-CN.md +1 -1
  6. package/SKILL.md +2 -2
  7. package/THIRD_PARTY_NOTICES.md +1 -1
  8. package/agents/openai.yaml +1 -1
  9. package/assets/hooks/hook-input.sh +11 -8
  10. package/assets/hooks/lib/session-state.sh +10 -7
  11. package/assets/hooks/lib/workflow-state.sh +13 -177
  12. package/assets/hooks/post-tool-observer.sh +8 -2
  13. package/assets/hooks/prompt-guard.sh +5 -81
  14. package/assets/hooks/session-start-context.sh +56 -1
  15. package/assets/partials/05-workflow.partial.md +1 -1
  16. package/assets/partials-agents/02-operating-mode.partial.md +2 -0
  17. package/assets/partials-agents/03-orchestration.partial.md +1 -1
  18. package/assets/plugin-registry.v1.json +3 -3
  19. package/assets/reference-configs/document-generation.md +1 -1
  20. package/assets/reference-configs/harness-overview.md +1 -1
  21. package/assets/reference-configs/sprint-contracts.md +3 -3
  22. package/assets/skill-version.json +2 -2
  23. package/assets/templates/contract.template.md +2 -7
  24. package/assets/templates/helpers/capture-plan.sh +2 -2
  25. package/assets/templates/helpers/check-architecture-sync.sh +17 -0
  26. package/assets/templates/helpers/check-task-workflow.sh +4 -4
  27. package/assets/templates/helpers/contract-worktree.sh +1 -21
  28. package/assets/templates/helpers/ensure-task-workflow.sh +11 -36
  29. package/assets/templates/helpers/inspect-project-state.ts +8 -6
  30. package/assets/templates/helpers/migrate-project-template.sh +22 -45
  31. package/assets/templates/helpers/migrate-workflow-docs.ts +9 -7
  32. package/assets/templates/helpers/new-plan.sh +1 -1
  33. package/assets/templates/helpers/plan-to-todo.sh +12 -37
  34. package/assets/templates/helpers/ship-worktrees.sh +2 -29
  35. package/assets/templates/helpers/verify-contract.sh +1 -111
  36. package/assets/templates/helpers/verify-sprint.sh +3 -180
  37. package/assets/templates/helpers/workflow-contract.ts +5 -1
  38. package/assets/templates/plan.template.md +1 -1
  39. package/assets/templates/review.template.md +9 -34
  40. package/assets/workflow-contract.v1.json +10 -19
  41. package/docs/README.md +10 -10
  42. package/docs/architecture/CURRENT.md +178 -0
  43. package/docs/architecture/EVOLUTION.md +42 -0
  44. package/docs/architecture/current/README.md +4 -156
  45. package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +2 -2
  46. package/docs/architecture/decisions/20260823-immediate-controller-relay.md +53 -0
  47. package/docs/architecture/decisions/20260826-browser-runtime-v2.md +73 -0
  48. package/docs/architecture/history/README.md +7 -0
  49. package/docs/architecture/{chatgpt-handoff-facade.md → history/chatgpt-handoff-facade.md} +4 -0
  50. package/docs/architecture/{global-hook-runtime.md → history/global-hook-runtime.md} +7 -3
  51. package/docs/architecture/{ios-semantic-automation-provider-v2.md → history/ios-semantic-automation-provider-v2.md} +6 -2
  52. package/docs/architecture/history.md +3 -34
  53. package/docs/architecture/index.md +15 -98
  54. package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +1 -1
  55. package/docs/architecture/reviews/2026-08-22-semantic-harness-convergence-acceptance.md +39 -0
  56. package/docs/architecture/versions/1.6.md +38 -0
  57. package/docs/architecture/versions/1.7.md +41 -0
  58. package/docs/forge-chatgpt-browser-engine.md +2 -2
  59. package/docs/forge-chatgpt-mcp-setup.md +4 -28
  60. package/docs/forge-chatgpt-supervised-automation.md +3 -3
  61. package/docs/forge-github-issue-launcher.md +1 -1
  62. package/docs/forge-plugin-management.md +1 -1
  63. package/docs/forge-runtime-self-healing-loop.md +1 -1
  64. package/docs/operations/controller-browser-plugin.md +26 -6
  65. package/docs/operations/controller-performance-and-502.md +143 -0
  66. package/docs/operations/controller-reliability-runbook.md +1 -1
  67. package/docs/operations/features.md +2 -2
  68. package/docs/operations/github-repository.md +1 -1
  69. package/docs/operations/homebrew.md +2 -2
  70. package/docs/operations/mcp-tool-exposure.md +5 -3
  71. package/docs/wiki/Architecture.md +6 -6
  72. package/docs/wiki/Implementation.md +2 -2
  73. package/docs/wiki/Integrations.md +2 -2
  74. package/docs/wiki/Work-Lifecycle.md +1 -1
  75. package/package.json +33 -11
  76. package/scripts/activate-source-baseline.ts +17 -13
  77. package/scripts/architecture-event.ts +2 -820
  78. package/scripts/architecture-queue.sh +2 -645
  79. package/scripts/archive-architecture-request.sh +2 -242
  80. package/scripts/archive-workflow.sh +1 -291
  81. package/scripts/benchmark-background-check-overlap.ts +228 -0
  82. package/scripts/benchmark-mcp-host.sh +117 -0
  83. package/scripts/benchmark-mcp-transport.ts +170 -0
  84. package/scripts/benchmark-quality-harness.ts +146 -0
  85. package/scripts/benchmark-route-session-concurrency.ts +207 -6
  86. package/scripts/benchmark-thin-harness-mcp-e2e.ts +7 -1
  87. package/scripts/benchmark-typescript-navigation.ts +186 -0
  88. package/scripts/benchmark-work-efficiency.ts +334 -0
  89. package/scripts/capability-config.ts +2 -392
  90. package/scripts/capability-resolver.ts +2 -503
  91. package/scripts/capture-plan.sh +1 -332
  92. package/scripts/check-agent-tooling.sh +2 -1558
  93. package/scripts/check-architecture-sync.sh +2 -371
  94. package/scripts/check-brain-manifest.sh +2 -253
  95. package/scripts/check-context-files.sh +2 -47
  96. package/scripts/check-deploy-sql-order.sh +2 -115
  97. package/scripts/check-mcp-compatibility.ts +14 -0
  98. package/scripts/check-runtime-architecture.mjs +349 -79
  99. package/scripts/check-skill-version.ts +3 -191
  100. package/scripts/check-source-duplication.mjs +61 -0
  101. package/scripts/check-stable-baseline.ts +92 -0
  102. package/scripts/check-task-sync.sh +2 -63
  103. package/scripts/check-task-workflow.sh +2 -1000
  104. package/scripts/codex-handoff-resume.sh +2 -267
  105. package/scripts/context-contract-sync.sh +2 -514
  106. package/scripts/contract-run.ts +2 -463
  107. package/scripts/contract-worktree.sh +1 -722
  108. package/scripts/ensure-task-workflow.sh +1 -1225
  109. package/scripts/host-temporary-cloud-mcp-e2e.sh +265 -0
  110. package/scripts/inspect-project-state.ts +4 -279
  111. package/scripts/install-standalone-recovery.ts +24 -0
  112. package/scripts/lib/project-init-lib.sh +22 -46
  113. package/scripts/lib/run-forge-helper.sh +19 -0
  114. package/scripts/lib/run-forge-helper.ts +26 -0
  115. package/scripts/migrate-project-template.sh +1 -1189
  116. package/scripts/migrate-workflow-docs.ts +4 -412
  117. package/scripts/new-plan.sh +1 -180
  118. package/scripts/new-spec.sh +1 -47
  119. package/scripts/new-sprint.sh +1 -46
  120. package/scripts/plan-to-todo.sh +1 -796
  121. package/scripts/prepare-codex-handoff.sh +2 -201
  122. package/scripts/prepare-handoff.sh +1 -78
  123. package/scripts/refresh-current-status.sh +2 -467
  124. package/scripts/run-governed-gate.ts +5 -1
  125. package/scripts/select-agent-context-blocks.sh +2 -64
  126. package/scripts/ship-worktrees.sh +1 -558
  127. package/scripts/smoke-ios-physical-device.ts +4 -2
  128. package/scripts/smoke-runtime-recovery.ts +1 -35
  129. package/scripts/smoke-schedule-engine.ts +1 -20
  130. package/scripts/sprint-backlog.sh +1 -834
  131. package/scripts/stage-runtime-release.ts +2 -1
  132. package/scripts/summarize-failures.sh +2 -123
  133. package/scripts/switch-plan.sh +1 -150
  134. package/scripts/sync-brain-docs.sh +2 -379
  135. package/scripts/sync-generated-authority.mjs +175 -0
  136. package/scripts/verify-contract.sh +2 -703
  137. package/scripts/verify-forge-runtime.sh +0 -1
  138. package/scripts/verify-sprint.sh +1 -677
  139. package/scripts/workflow-contract.ts +4 -205
  140. package/scripts/workstream-sync.sh +2 -261
  141. package/src/cli/agent-jobs/executor-health.ts +1 -1
  142. package/src/cli/commands/init-hook.ts +3 -3
  143. package/src/cli/commands/mcp.ts +9 -5
  144. package/src/cli/commands/plugin.ts +12 -3
  145. package/src/cli/commands/recovery.ts +25 -3
  146. package/src/cli/commands/runtime.ts +55 -3
  147. package/src/cli/commands/security.ts +12 -1
  148. package/src/cli/commands/setup-profile.ts +31 -21
  149. package/src/cli/controller/check-runner.ts +113 -5
  150. package/src/cli/controller/composite-result.ts +1 -1
  151. package/src/cli/controller/context/focus.ts +51 -0
  152. package/src/cli/controller/context/instruction-context.ts +114 -0
  153. package/src/cli/controller/context/known-paths.ts +76 -0
  154. package/src/cli/controller/context/query-planning.ts +110 -0
  155. package/src/cli/controller/context/rule-resolution.ts +532 -0
  156. package/src/cli/controller/context/source-materializer.ts +278 -0
  157. package/src/cli/controller/context/structural.ts +16 -0
  158. package/src/cli/controller/context/types.ts +286 -0
  159. package/src/cli/controller/context-pack.ts +828 -487
  160. package/src/cli/controller/launch-agents.ts +77 -2
  161. package/src/cli/controller/operational-plan.ts +2 -2
  162. package/src/cli/controller/work-mode.ts +6 -4
  163. package/src/cli/editing/edit-session.ts +60 -7
  164. package/src/cli/github/contracts.ts +16 -0
  165. package/src/cli/github/github.ts +135 -16
  166. package/src/cli/github/session.ts +2 -1
  167. package/src/cli/installer/managed-entries.ts +15 -1
  168. package/src/cli/local-bridge/console-automations.ts +54 -78
  169. package/src/cli/local-bridge/console-view-models.ts +1 -35
  170. package/src/cli/local-bridge/facade-api.ts +37 -264
  171. package/src/cli/local-bridge/frontend/src/App.tsx +3 -3
  172. package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +23 -13
  173. package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +37 -4
  174. package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +6 -4
  175. package/src/cli/local-bridge/frontend/src/lib/api.ts +1 -6
  176. package/src/cli/local-bridge/frontend/src/lib/routes.ts +1 -1
  177. package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +2 -2
  178. package/src/cli/local-bridge/frontend/src/styles.css +1 -1
  179. package/src/cli/local-bridge/frontend/src/types.ts +5 -8
  180. package/src/cli/local-bridge/job-store.ts +1 -490
  181. package/src/cli/local-bridge/server.ts +2 -515
  182. package/src/cli/local-bridge/ui-dist/app.css +1 -1
  183. package/src/cli/local-bridge/ui-dist/app.js +3703 -3757
  184. package/src/cli/mcp/auth.ts +5 -5
  185. package/src/cli/mcp/instructions.ts +3 -2
  186. package/src/cli/mcp/legacy-tool-service.ts +10 -222
  187. package/src/cli/mcp/multi-repository.ts +16 -5
  188. package/src/cli/mcp/oauth.ts +175 -26
  189. package/src/cli/mcp/post-finalize-work-attribution.ts +150 -0
  190. package/src/cli/mcp/repository-tools.ts +282 -146
  191. package/src/cli/mcp/server.ts +586 -116
  192. package/src/cli/mcp/tool-capability-cache.ts +1 -1
  193. package/src/cli/mcp/tool-contract.ts +14 -0
  194. package/src/cli/mcp/toolset-selection.ts +1 -1
  195. package/src/cli/mcp/toolset.ts +44 -7
  196. package/src/cli/mcp/transports/http.ts +124 -14
  197. package/src/cli/mcp/transports/session-registry.ts +43 -5
  198. package/src/cli/mcp/types.ts +3 -3
  199. package/src/cli/repositories/command-classifier.ts +103 -21
  200. package/src/cli/repositories/command-executor.ts +78 -526
  201. package/src/cli/repositories/command-process.ts +108 -0
  202. package/src/cli/repositories/command-scope.ts +99 -41
  203. package/src/cli/repositories/controller-home.ts +7 -8
  204. package/src/cli/repositories/git-command-executor.ts +2 -0
  205. package/src/cli/repositories/locks.ts +53 -16
  206. package/src/cli/repositories/repository-snapshot.ts +124 -0
  207. package/src/cli/repositories/selected-path-actions.ts +17 -9
  208. package/src/cli/repositories/structured-git.ts +118 -6
  209. package/src/cli/repository/inspector.ts +563 -65
  210. package/src/cli/repository/session-cache.ts +58 -17
  211. package/src/cli/v81-entry.ts +1 -4
  212. package/src/effects/fs-transaction.ts +85 -17
  213. package/src/runtime/context/codegraph-read-provider.ts +233 -2
  214. package/src/runtime/context/codegraph-sidecar.cjs +74 -40
  215. package/src/runtime/context/generic-lsp-provider.ts +355 -0
  216. package/src/runtime/context/lsp-client.ts +283 -0
  217. package/src/runtime/context/semantic-navigation-contract.ts +61 -0
  218. package/src/runtime/context/semantic-navigation.ts +223 -0
  219. package/src/runtime/context/swift-navigation.ts +565 -0
  220. package/src/runtime/context/typescript-navigation.ts +226 -0
  221. package/src/runtime/control-plane/dispatch-priority.ts +28 -0
  222. package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +48 -16
  223. package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +86 -24
  224. package/src/runtime/control-plane/execution/repository-work-attribution.ts +106 -0
  225. package/src/runtime/control-plane/execution/retained-work-resume.ts +203 -0
  226. package/src/runtime/control-plane/execution/session-store.ts +18 -0
  227. package/src/runtime/control-plane/execution/verification-evidence.ts +58 -3
  228. package/src/runtime/control-plane/execution/work-completion-authority.ts +58 -0
  229. package/src/runtime/control-plane/execution/work-evidence-policy.ts +200 -0
  230. package/src/runtime/control-plane/execution/work-execution-support.ts +386 -0
  231. package/src/runtime/control-plane/execution/work-finalization-service.ts +1913 -0
  232. package/src/runtime/control-plane/execution/work-handle-authority.ts +96 -0
  233. package/src/runtime/control-plane/execution/work-handle-store.ts +27 -2
  234. package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +258 -0
  235. package/src/runtime/control-plane/execution/work-operation-service.ts +468 -0
  236. package/src/runtime/control-plane/execution/work-path-scope.ts +37 -0
  237. package/src/runtime/control-plane/execution/work-preparation-service.ts +479 -0
  238. package/src/runtime/control-plane/execution/work-process-evidence.ts +129 -0
  239. package/src/runtime/control-plane/execution/work-remote-delivery.ts +215 -0
  240. package/src/runtime/control-plane/execution/work-task-receipt.ts +22 -18
  241. package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +156 -11
  242. package/src/runtime/control-plane/execution/work-validation-reconciler.ts +22 -14
  243. package/src/runtime/control-plane/execution/work-verification-context.ts +56 -0
  244. package/src/runtime/control-plane/execution/work-verification-service.ts +388 -0
  245. package/src/runtime/control-plane/execution/work-verification-snapshot.ts +90 -9
  246. package/src/runtime/control-plane/facade/capability-registry.ts +129 -25
  247. package/src/runtime/control-plane/facade/controller-round-relay.ts +1118 -0
  248. package/src/runtime/control-plane/facade/controller-session-store.ts +302 -12
  249. package/src/runtime/control-plane/facade/goal-workloop-access.ts +17 -1
  250. package/src/runtime/control-plane/facade/goal-workloop.ts +928 -190
  251. package/src/runtime/control-plane/facade/index.ts +3 -0
  252. package/src/runtime/control-plane/facade/plan-contract-store.ts +275 -42
  253. package/src/runtime/control-plane/facade/repository-work-admission.ts +147 -0
  254. package/src/runtime/control-plane/facade/requirement-authority.ts +83 -0
  255. package/src/runtime/control-plane/facade/semantic-admission.ts +205 -0
  256. package/src/runtime/control-plane/facade/suggested-actions.ts +5 -1
  257. package/src/runtime/control-plane/facade/types.ts +90 -10
  258. package/src/runtime/control-plane/facade/work-contract-store.ts +157 -261
  259. package/src/runtime/control-plane/facade/work-state-machine.ts +250 -0
  260. package/src/runtime/control-plane/generated-cache-retention.ts +271 -0
  261. package/src/runtime/control-plane/global-scheduler/config.ts +44 -0
  262. package/src/runtime/control-plane/global-scheduler/dispatch-capacity.ts +80 -0
  263. package/src/runtime/control-plane/global-scheduler/durable-admission.ts +46 -0
  264. package/src/runtime/control-plane/global-scheduler/maintenance.ts +152 -0
  265. package/src/runtime/control-plane/global-scheduler/projection-refresh.ts +84 -0
  266. package/src/runtime/control-plane/global-scheduler/reconciliation.ts +3 -3
  267. package/src/runtime/control-plane/global-scheduler/scheduler.ts +278 -543
  268. package/src/runtime/control-plane/global-scheduler/source-scan.ts +59 -0
  269. package/src/runtime/control-plane/global-scheduler/state.ts +88 -0
  270. package/src/runtime/control-plane/global-scheduler/worker-attachment.ts +57 -0
  271. package/src/runtime/control-plane/global-scheduler/worker-exit-decision.ts +38 -0
  272. package/src/runtime/control-plane/global-scheduler/worker-exit-reconciler.ts +175 -0
  273. package/src/runtime/control-plane/global-scheduler/worker-launch.ts +111 -0
  274. package/src/runtime/control-plane/global-scheduler/worker-lifecycle-store.ts +64 -0
  275. package/src/runtime/control-plane/global-scheduler/worker-lifecycle.ts +150 -0
  276. package/src/runtime/control-plane/global-scheduler/worker-process.ts +119 -0
  277. package/src/runtime/control-plane/global-scheduler/worker-stderr.ts +60 -0
  278. package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +63 -0
  279. package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +365 -117
  280. package/src/runtime/control-plane/launcher/launch-reservation-store.ts +89 -0
  281. package/src/runtime/control-plane/launcher/thin-launcher.ts +244 -11
  282. package/src/runtime/control-plane/persistence/controller-home-migration.ts +487 -0
  283. package/src/runtime/control-plane/persistence/requirement-store.ts +0 -12
  284. package/src/runtime/control-plane/persistence/sqlite-store.ts +33 -2
  285. package/src/runtime/control-plane/release-retention.ts +62 -2
  286. package/src/runtime/control-plane/repo-actor/registry.ts +4 -2
  287. package/src/runtime/control-plane/routing/route-policy.ts +24 -21
  288. package/src/runtime/control-plane/routing/workspace-admission.ts +70 -0
  289. package/src/runtime/control-plane/runtime-status-client.ts +0 -2
  290. package/src/runtime/diagnostics/mcp-timing.ts +13 -0
  291. package/src/runtime/diagnostics/mcp-transport-benchmark.ts +129 -0
  292. package/src/runtime/diagnostics/performance.ts +24 -1
  293. package/src/runtime/evidence/event-ledger.ts +1 -1
  294. package/src/runtime/evidence/process-check-execution.ts +18 -0
  295. package/src/runtime/execution/jobs/child-reference.ts +6 -2
  296. package/src/runtime/execution/jobs/store.ts +58 -4
  297. package/src/runtime/execution/jobs/types.ts +1 -1
  298. package/src/runtime/execution/managed-workspace.ts +203 -1
  299. package/src/runtime/execution/process-runtime/check-facade.ts +51 -4
  300. package/src/runtime/execution/process-runtime/check-result.ts +88 -0
  301. package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +7 -1
  302. package/src/runtime/execution/process-runtime/check-scheduling.ts +114 -0
  303. package/src/runtime/execution/process-runtime/command-facade.ts +367 -40
  304. package/src/runtime/execution/process-runtime/gc.ts +38 -6
  305. package/src/runtime/execution/process-runtime/lightweight-managed.ts +1201 -0
  306. package/src/runtime/execution/process-runtime/persisted-check.ts +51 -5
  307. package/src/runtime/execution/process-runtime/resource-claims.ts +10 -6
  308. package/src/runtime/execution/process-runtime/runtime.ts +53 -3
  309. package/src/runtime/execution/process-runtime/store.ts +1 -0
  310. package/src/runtime/execution/process-runtime/types.ts +4 -12
  311. package/src/runtime/execution/thin-harness/async-process.ts +12 -2
  312. package/src/runtime/execution/thin-harness/search-worker.ts +54 -5
  313. package/src/runtime/execution/work-activity.ts +21 -0
  314. package/src/runtime/execution/workers/executor.ts +18 -61
  315. package/src/runtime/gateway/mcp/execution-tools.ts +35 -1852
  316. package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +61 -0
  317. package/src/runtime/gateway/mcp/process-tools.ts +83 -37
  318. package/src/runtime/gateway/mcp/router.ts +186 -84
  319. package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +565 -0
  320. package/src/runtime/gateway/mcp/runtime-tools.ts +2378 -1947
  321. package/src/runtime/plugins/app-store-connect-adapter.ts +216 -47
  322. package/src/runtime/plugins/browser-adapter.ts +2662 -829
  323. package/src/runtime/plugins/browser-automation-service.ts +10 -0
  324. package/src/runtime/plugins/browser-handoff-host.ts +2 -25
  325. package/src/runtime/plugins/browser-handoff.ts +110 -5
  326. package/src/runtime/plugins/browser-macos-bridge.ts +701 -63
  327. package/src/runtime/plugins/browser-manifest-surface.ts +603 -0
  328. package/src/runtime/plugins/browser-native-session-service.ts +222 -0
  329. package/src/runtime/plugins/browser-node-bridge.ts +6 -34
  330. package/src/runtime/plugins/browser-provider-registry.ts +109 -0
  331. package/src/runtime/plugins/browser-runtime-contract.ts +154 -0
  332. package/src/runtime/plugins/browser-runtime.ts +193 -0
  333. package/src/runtime/plugins/browser-session-authority.ts +332 -0
  334. package/src/runtime/plugins/browser-session-store.ts +121 -0
  335. package/src/runtime/plugins/browser-session-types.ts +98 -0
  336. package/src/runtime/plugins/capability-authorization-grants.ts +354 -0
  337. package/src/runtime/plugins/desktop-operator-registration.ts +10 -4
  338. package/src/runtime/plugins/external-adapter.ts +358 -3
  339. package/src/runtime/plugins/external-unix-socket.ts +7 -1
  340. package/src/runtime/plugins/first-party-registry.ts +2 -0
  341. package/src/runtime/plugins/github-adapter.ts +125 -0
  342. package/src/runtime/plugins/ios/agent-device-provider.ts +1 -1
  343. package/src/runtime/plugins/ios/agent-device-typed-provider.ts +52 -9
  344. package/src/runtime/plugins/ios/remote-xpc-hid.ts +1171 -0
  345. package/src/runtime/plugins/ios-adapter.ts +106 -16
  346. package/src/runtime/plugins/ios-agent-device.ts +234 -64
  347. package/src/runtime/plugins/ios-physical-device.ts +1143 -392
  348. package/src/runtime/plugins/lightweight-action.ts +153 -0
  349. package/src/runtime/plugins/local-system-adapter.ts +123 -6
  350. package/src/runtime/plugins/macos-capability-broker.ts +47 -9
  351. package/src/runtime/plugins/plugin-action-sidecar.ts +59 -0
  352. package/src/runtime/plugins/plugin-management-adapter.ts +49 -8
  353. package/src/runtime/plugins/resend-adapter.ts +1 -1
  354. package/src/runtime/plugins/store.ts +330 -33
  355. package/src/runtime/plugins/types.ts +38 -3
  356. package/src/runtime/plugins/xiaohongshu-publish.ts +515 -0
  357. package/src/runtime/projections/git-status-sampler.ts +16 -16
  358. package/src/runtime/projections/materialized-view.ts +28 -10
  359. package/src/runtime/recovery/maintenance-executor.ts +426 -25
  360. package/src/runtime/root/mcp-transport.ts +180 -10
  361. package/src/runtime/root/package-connector-service.ts +230 -10
  362. package/src/runtime/root/package-runtime-release.ts +143 -17
  363. package/src/runtime/root/package-runtime-service.ts +461 -22
  364. package/src/runtime/root/release-manifest.ts +144 -18
  365. package/src/runtime/root/release-materialize.ts +125 -32
  366. package/src/runtime/root/release-store.ts +48 -11
  367. package/src/runtime/root/runtime.ts +23 -5
  368. package/src/runtime/root/service.ts +100 -29
  369. package/src/runtime/root/types.ts +12 -0
  370. package/src/runtime/safe-tooling/ios-development.ts +321 -63
  371. package/src/runtime/shared/trusted-executable.ts +62 -0
  372. package/src/runtime/shared/trusted-node-executable.ts +48 -0
  373. package/src/runtime/standalone-recovery/core.ts +1079 -240
  374. package/src/runtime/standalone-recovery/entry.ts +100 -24
  375. package/src/runtime/standalone-recovery/installer.ts +20 -4
  376. package/src/runtime/standalone-recovery/service-labels.ts +2 -0
  377. package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +160 -0
  378. package/src/runtime/workflow/schedules/browser-probe.ts +81 -3
  379. package/src/runtime/workflow/schedules/engine.ts +364 -202
  380. package/src/runtime/workflow/schedules/github-issue-watch.ts +158 -0
  381. package/src/runtime/workflow/schedules/settlement.ts +64 -17
  382. package/src/runtime/workflow/schedules/store.ts +209 -19
  383. package/src/runtime/workflow/schedules/types.ts +2 -4
  384. package/src/runtime/workflow/schedules/work-continuation.ts +26 -13
  385. package/src/testing/test-governance.ts +8 -40
  386. package/assets/reference-configs/heartbeat-triage.md +0 -57
  387. package/assets/templates/helpers/harness-trace-grade.sh +0 -150
  388. package/assets/templates/helpers/heartbeat-triage.sh +0 -361
  389. package/assets/templates/helpers/maintenance-triage.sh +0 -167
  390. package/docs/architecture/current/approved-target-architecture.zh-CN.md +0 -1501
  391. package/docs/architecture/current/architecture-invariants.md +0 -331
  392. package/docs/architecture/current/automation-and-schedule-engine.md +0 -459
  393. package/docs/architecture/current/codegraph-context-provider.md +0 -238
  394. package/docs/architecture/current/control-plane-authority-inventory.md +0 -94
  395. package/docs/architecture/current/controller-repository-decoupling.md +0 -148
  396. package/docs/architecture/current/dispatch-and-agent-strategy.md +0 -373
  397. package/docs/architecture/current/entity-model.md +0 -612
  398. package/docs/architecture/current/external-plugin-governance.md +0 -396
  399. package/docs/architecture/current/failure-recovery.md +0 -447
  400. package/docs/architecture/current/governance.md +0 -213
  401. package/docs/architecture/current/human-interaction-plane.md +0 -87
  402. package/docs/architecture/current/implementation-status.md +0 -128
  403. package/docs/architecture/current/job-and-run-lifecycle.md +0 -413
  404. package/docs/architecture/current/legacy-governance.md +0 -58
  405. package/docs/architecture/current/local-workspace-target-grants.md +0 -70
  406. package/docs/architecture/current/migration-roadmap.md +0 -105
  407. package/docs/architecture/current/multi-repository-execution.md +0 -371
  408. package/docs/architecture/current/operations-runbook.md +0 -45
  409. package/docs/architecture/current/peer-supercontroller-runtime.md +0 -32
  410. package/docs/architecture/current/personal-assistant-plugin-baseline.md +0 -206
  411. package/docs/architecture/current/repository-access-modes.md +0 -102
  412. package/docs/architecture/current/route-policy.md +0 -15
  413. package/docs/architecture/current/route-session-concurrency.md +0 -85
  414. package/docs/architecture/current/runtime-architecture-simplification.md +0 -214
  415. package/docs/architecture/current/runtime-directory-map.md +0 -49
  416. package/docs/architecture/current/runtime-health-and-resource-lifecycle.md +0 -85
  417. package/docs/architecture/current/scheduler-and-resource-claims.md +0 -422
  418. package/docs/architecture/current/session-aware-execution-and-authorization.md +0 -77
  419. package/docs/architecture/current/system-overview.md +0 -169
  420. package/docs/architecture/current/target-requirements-traceability.md +0 -202
  421. package/docs/architecture/current/thin-harness-governance-policy.md +0 -32
  422. package/docs/architecture/current/thin-harness-v1.md +0 -321
  423. package/docs/architecture/current/verification-and-release-gates.md +0 -391
  424. package/docs/forge-autonomous-goal-loop.md +0 -9
  425. package/docs/forge-provider-configuration.md +0 -7
  426. package/docs/operations/chatgpt-personal-assistant-runtime.md +0 -93
  427. package/docs/operations/gmail-assistant-routines.md +0 -186
  428. package/docs/operations/personal-assistant-operator-guide.md +0 -61
  429. package/docs/operations/provider-configuration.md +0 -31
  430. package/scripts/harness-trace-grade.sh +0 -150
  431. package/scripts/heartbeat-triage.sh +0 -361
  432. package/scripts/maintenance-triage.sh +0 -167
  433. package/src/cli/local-bridge/frontend/src/features/settings/SettingsView.tsx +0 -2
  434. package/src/cli/repositories/goal-registry.ts +0 -239
  435. package/src/runtime/assistant/action-proposals.ts +0 -279
  436. package/src/runtime/assistant/intent.ts +0 -395
  437. package/src/runtime/assistant/model-provider.ts +0 -460
  438. package/src/runtime/assistant/openapi.ts +0 -223
  439. package/src/runtime/assistant/policy.ts +0 -89
  440. package/src/runtime/assistant/readiness.ts +0 -258
  441. package/src/runtime/assistant/routine-runtime.ts +0 -477
  442. package/src/runtime/assistant/schedule-binding.ts +0 -171
  443. package/src/runtime/assistant/standing-grants.ts +0 -375
  444. package/src/runtime/assistant/store.ts +0 -243
  445. package/src/runtime/assistant/types.ts +0 -135
  446. package/src/runtime/control-plane/goal-loop/config-facade.ts +0 -700
  447. package/src/runtime/control-plane/goal-loop/config-store.ts +0 -570
  448. package/src/runtime/control-plane/goal-loop/config-types.ts +0 -213
  449. package/src/runtime/control-plane/goal-loop/executor-router.ts +0 -109
  450. package/src/runtime/control-plane/goal-loop/failure-taxonomy.ts +0 -149
  451. package/src/runtime/control-plane/goal-loop/goal-contract-store.ts +0 -304
  452. package/src/runtime/control-plane/goal-loop/goal-loop-engine.ts +0 -1001
  453. package/src/runtime/control-plane/goal-loop/handoff-packet.ts +0 -160
  454. package/src/runtime/control-plane/goal-loop/index.ts +0 -13
  455. package/src/runtime/control-plane/goal-loop/local-tools.ts +0 -290
  456. package/src/runtime/control-plane/goal-loop/policy-gates.ts +0 -203
  457. package/src/runtime/control-plane/goal-loop/provider-dispatch.ts +0 -93
  458. package/src/runtime/control-plane/goal-loop/provider-registry.ts +0 -545
  459. package/src/runtime/control-plane/goal-loop/types.ts +0 -378
  460. package/src/runtime/control-plane/startup-recovery.ts +0 -198
  461. package/src/runtime/gateway/mcp/resource-policy.ts +0 -186
  462. package/src/runtime/personal-assistant/gmail-triage-manager.ts +0 -231
  463. package/src/runtime/personal-assistant/reporting-runtime.ts +0 -344
  464. package/src/runtime/personal-assistant/triage-runtime.ts +0 -748
  465. package/src/runtime/workflow/findings/store.ts +0 -204
  466. package/src/runtime/workflow/findings/types.ts +0 -58
  467. package/src/runtime/workflow/portfolio/engine.ts +0 -20
  468. package/src/runtime/workflow/portfolio/store.ts +0 -185
  469. package/src/runtime/workflow/portfolio/types.ts +0 -29
@@ -1,1192 +1,4 @@
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
15
- #
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
19
-
20
2
  set -euo pipefail
21
-
22
3
  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
- }
59
-
60
- run_ts_script() {
61
- local script_path="$1"
62
- 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
941
- 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
1170
- }
1171
-
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"
1188
-
1189
- run_skill_hook "post-migrate"
1190
- }
1191
-
1192
- main "$@"
4
+ exec "$SCRIPT_DIR/lib/run-forge-helper.sh" "migrate-project-template.sh" "$@"