@jaimevalasek/aioson 1.7.2 → 1.8.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 (362) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +153 -10
  3. package/docs/en/cli-reference.md +56 -1
  4. package/docs/en/i18n.md +18 -18
  5. package/docs/en/schemas/index.json +10 -0
  6. package/docs/en/schemas/parallel-assign.schema.json +9 -0
  7. package/docs/en/schemas/parallel-doctor.schema.json +36 -0
  8. package/docs/en/schemas/parallel-guard.schema.json +63 -0
  9. package/docs/en/schemas/parallel-merge.schema.json +84 -0
  10. package/docs/en/schemas/parallel-status.schema.json +91 -1
  11. package/docs/integrations/apps-publish-marketplace.md +94 -0
  12. package/docs/pt/README.md +9 -0
  13. package/docs/pt/agentes.md +324 -3
  14. package/docs/pt/clientes-ai.md +7 -3
  15. package/docs/pt/comandos-cli.md +160 -13
  16. package/docs/pt/compress-agents.md +304 -0
  17. package/docs/pt/design-docs-governance.md +59 -0
  18. package/docs/pt/feature-archive.md +191 -0
  19. package/docs/pt/genome-3.0-spec.md +115 -4
  20. package/docs/pt/genome-distribution.md +232 -0
  21. package/docs/pt/inicio-rapido.md +1 -0
  22. package/docs/pt/motor-hardening.md +492 -0
  23. package/docs/pt/runner-system.md +113 -0
  24. package/package.json +2 -1
  25. package/src/agent-manifests.js +66 -0
  26. package/src/agents.js +27 -7
  27. package/src/autonomy-policy.js +139 -0
  28. package/src/brain-query.js +161 -0
  29. package/src/cli.js +1377 -1099
  30. package/src/commands/agents.js +102 -7
  31. package/src/commands/artifact-validate.js +33 -4
  32. package/src/commands/auth.js +272 -0
  33. package/src/commands/brain-query.js +44 -0
  34. package/src/commands/briefing.js +344 -0
  35. package/src/commands/commit-prepare.js +547 -0
  36. package/src/commands/compress-agents.js +416 -0
  37. package/src/commands/context-health.js +4 -2
  38. package/src/commands/context-trim.js +17 -11
  39. package/src/commands/design-hybrid-options.js +3 -3
  40. package/src/commands/devlog-process.js +6 -4
  41. package/src/commands/dossier.js +423 -0
  42. package/src/commands/feature-archive.js +513 -0
  43. package/src/commands/feature-close.js +123 -18
  44. package/src/commands/gate-approve.js +198 -0
  45. package/src/commands/gate-check.js +24 -5
  46. package/src/commands/genome-doctor.js +166 -9
  47. package/src/commands/git-guard.js +170 -0
  48. package/src/commands/harness.js +121 -0
  49. package/src/commands/implementation-plan.js +47 -20
  50. package/src/commands/init.js +6 -2
  51. package/src/commands/install.js +6 -2
  52. package/src/commands/live.js +497 -56
  53. package/src/commands/locale-apply.js +9 -6
  54. package/src/commands/locale-diff.js +11 -112
  55. package/src/commands/mcp-doctor.js +2 -1
  56. package/src/commands/mcp-init.js +4 -10
  57. package/src/commands/memory.js +234 -0
  58. package/src/commands/parallel-assign.js +107 -27
  59. package/src/commands/parallel-doctor.js +416 -3
  60. package/src/commands/parallel-guard.js +241 -0
  61. package/src/commands/parallel-init.js +66 -4
  62. package/src/commands/parallel-merge.js +299 -0
  63. package/src/commands/parallel-status.js +147 -3
  64. package/src/commands/preflight.js +63 -4
  65. package/src/commands/qa-init.js +10 -5
  66. package/src/commands/revision.js +235 -0
  67. package/src/commands/scaffold-complete.js +188 -0
  68. package/src/commands/security-audit.js +275 -0
  69. package/src/commands/security-scan.js +376 -0
  70. package/src/commands/self-implement-loop.js +46 -2
  71. package/src/commands/setup-context.js +11 -10
  72. package/src/commands/squad-agent-create.js +51 -9
  73. package/src/commands/squad-investigate.js +53 -0
  74. package/src/commands/squad-plan.js +33 -1
  75. package/src/commands/squad-scaffold.js +4 -3
  76. package/src/commands/squad-score.js +71 -14
  77. package/src/commands/squad-status.js +22 -1
  78. package/src/commands/squad-validate.js +93 -2
  79. package/src/commands/store-genome.js +304 -0
  80. package/src/commands/store-skill.js +247 -0
  81. package/src/commands/store-squad.js +431 -0
  82. package/src/commands/store-system.js +392 -0
  83. package/src/commands/tool-capabilities.js +63 -0
  84. package/src/commands/update.js +3 -3
  85. package/src/commands/verify-gate.js +40 -0
  86. package/src/commands/workflow-execute.js +644 -155
  87. package/src/commands/workflow-harden.js +231 -0
  88. package/src/commands/workflow-heal.js +136 -0
  89. package/src/commands/workflow-next.js +460 -22
  90. package/src/commands/workflow-status.js +328 -138
  91. package/src/commands/workspace.js +144 -0
  92. package/src/constants.js +42 -75
  93. package/src/context-memory.js +133 -4
  94. package/src/context-writer.js +2 -1
  95. package/src/context.js +32 -2
  96. package/src/doctor.js +46 -6
  97. package/src/dossier/codemap-store.js +267 -0
  98. package/src/dossier/dossier-bootstrap.js +222 -0
  99. package/src/dossier/dossier-compact.js +159 -0
  100. package/src/dossier/lock.js +128 -0
  101. package/src/dossier/revision-store.js +313 -0
  102. package/src/dossier/schema.js +155 -0
  103. package/src/dossier/store.js +400 -0
  104. package/src/execution-gateway.js +3 -0
  105. package/src/friction-scanner.js +202 -0
  106. package/src/genome-schema.js +24 -1
  107. package/src/genomes.js +33 -0
  108. package/src/handoff-contract.js +363 -0
  109. package/src/handoff-validator.js +45 -0
  110. package/src/harness/circuit-breaker.js +135 -0
  111. package/src/i18n/messages/en.js +317 -22
  112. package/src/i18n/messages/es.js +259 -18
  113. package/src/i18n/messages/fr.js +260 -18
  114. package/src/i18n/messages/pt-BR.js +313 -22
  115. package/src/install-profile.js +0 -16
  116. package/src/installer.js +70 -6
  117. package/src/lib/git-commit-guard.js +691 -0
  118. package/src/lib/security/artifact-reader.js +167 -0
  119. package/src/lib/security/exit-codes.js +51 -0
  120. package/src/lib/security/findings-writer.js +176 -0
  121. package/src/lib/security/runtime-events.js +77 -0
  122. package/src/lib/security/secrets-regex.js +115 -0
  123. package/src/lib/store/security-scan.js +173 -0
  124. package/src/lib/terminal-checkbox.js +130 -0
  125. package/src/lib/tmux-launcher.js +163 -0
  126. package/src/lib/tool-capabilities.js +102 -0
  127. package/src/locales.js +12 -8
  128. package/src/parallel-workspace.js +756 -0
  129. package/src/parser.js +8 -1
  130. package/src/path-guard.js +47 -0
  131. package/src/preflight-engine.js +237 -26
  132. package/src/self-healing.js +142 -0
  133. package/src/session-handoff.js +111 -1
  134. package/src/squad/squad-scaffold.js +183 -19
  135. package/src/test-briefing.js +226 -0
  136. package/src/updater.js +1 -1
  137. package/src/utils.js +3 -0
  138. package/src/workflow-gates.js +185 -0
  139. package/template/.aioson/agents/analyst.md +76 -130
  140. package/template/.aioson/agents/architect.md +53 -86
  141. package/template/.aioson/agents/committer.md +161 -0
  142. package/template/.aioson/agents/cypher.md +252 -0
  143. package/template/.aioson/agents/dev.md +112 -628
  144. package/template/.aioson/agents/deyvin.md +33 -236
  145. package/template/.aioson/agents/discover.md +235 -0
  146. package/template/.aioson/agents/discovery-design-doc.md +17 -252
  147. package/template/.aioson/agents/genome.md +76 -26
  148. package/template/.aioson/agents/manifests/analyst.manifest.json +26 -0
  149. package/template/.aioson/agents/manifests/architect.manifest.json +23 -0
  150. package/template/.aioson/agents/manifests/committer.manifest.json +23 -0
  151. package/template/.aioson/agents/manifests/dev.manifest.json +37 -0
  152. package/template/.aioson/agents/manifests/orchestrator.manifest.json +30 -0
  153. package/template/.aioson/agents/manifests/pentester.manifest.json +39 -0
  154. package/template/.aioson/agents/manifests/pm.manifest.json +26 -0
  155. package/template/.aioson/agents/manifests/product.manifest.json +23 -0
  156. package/template/.aioson/agents/manifests/qa.manifest.json +25 -0
  157. package/template/.aioson/agents/manifests/setup.manifest.json +20 -0
  158. package/template/.aioson/agents/manifests/ux-ui.manifest.json +24 -0
  159. package/template/.aioson/agents/neo.md +5 -7
  160. package/template/.aioson/agents/orache.md +2 -6
  161. package/template/.aioson/agents/orchestrator.md +81 -182
  162. package/template/.aioson/agents/pentester.md +235 -0
  163. package/template/.aioson/agents/pm.md +40 -104
  164. package/template/.aioson/agents/product.md +99 -344
  165. package/template/.aioson/agents/profiler-enricher.md +57 -6
  166. package/template/.aioson/agents/profiler-forge.md +17 -7
  167. package/template/.aioson/agents/profiler-researcher.md +29 -6
  168. package/template/.aioson/agents/qa.md +168 -514
  169. package/template/.aioson/agents/setup.md +52 -278
  170. package/template/.aioson/agents/sheldon.md +122 -754
  171. package/template/.aioson/agents/site-forge.md +111 -1583
  172. package/template/.aioson/agents/squad.md +139 -2010
  173. package/template/.aioson/agents/tester.md +10 -0
  174. package/template/.aioson/agents/ux-ui.md +104 -812
  175. package/template/.aioson/agents/validator.md +69 -0
  176. package/template/.aioson/brains/scripts/query.js +5 -1
  177. package/template/.aioson/config/autonomy-protocol.json +43 -0
  178. package/template/.aioson/config.md +43 -15
  179. package/template/.aioson/constitution.md +36 -33
  180. package/template/.aioson/context/design-doc.md +136 -0
  181. package/template/.aioson/context/project-map.md +57 -0
  182. package/template/.aioson/design-docs/code-reuse.md +48 -0
  183. package/template/.aioson/design-docs/componentization.md +47 -0
  184. package/template/.aioson/design-docs/file-size.md +52 -0
  185. package/template/.aioson/design-docs/folder-structure.md +51 -0
  186. package/template/.aioson/design-docs/naming.md +54 -0
  187. package/template/.aioson/docs/LAYERS.md +12 -2
  188. package/template/.aioson/docs/dev/execution-discipline.md +106 -0
  189. package/template/.aioson/docs/dev/stack-conventions.md +83 -0
  190. package/template/.aioson/docs/deyvin/continuity-recovery.md +57 -0
  191. package/template/.aioson/docs/deyvin/debugging-escalation.md +30 -0
  192. package/template/.aioson/docs/deyvin/pair-execution.md +44 -0
  193. package/template/.aioson/docs/deyvin/runtime-handoffs.md +36 -0
  194. package/template/.aioson/docs/product/conversation-playbook.md +116 -0
  195. package/template/.aioson/docs/product/prd-contract.md +107 -0
  196. package/template/.aioson/docs/product/quality-lens.md +57 -0
  197. package/template/.aioson/docs/product/research-loop.md +65 -0
  198. package/template/.aioson/docs/sheldon/enrichment-paths.md +134 -0
  199. package/template/.aioson/docs/sheldon/quality-lens.md +57 -0
  200. package/template/.aioson/docs/sheldon/research-loop.md +56 -0
  201. package/template/.aioson/docs/sheldon/web-intelligence.md +75 -0
  202. package/template/.aioson/docs/site-forge-build.md +195 -0
  203. package/template/.aioson/docs/site-forge-extraction.md +135 -0
  204. package/template/.aioson/docs/site-forge-qa.md +155 -0
  205. package/template/.aioson/docs/site-forge-recon.md +434 -0
  206. package/template/.aioson/docs/site-forge-transform.md +249 -0
  207. package/template/.aioson/docs/squad/content-output.md +91 -0
  208. package/template/.aioson/docs/squad/creation-flow.md +135 -0
  209. package/template/.aioson/docs/squad/domain-classification.md +117 -0
  210. package/template/.aioson/docs/squad/genome-bindings.md +47 -0
  211. package/template/.aioson/docs/squad/package-contract.md +234 -0
  212. package/template/.aioson/docs/squad/quality-lens.md +56 -0
  213. package/template/.aioson/docs/squad/research-loop.md +59 -0
  214. package/template/.aioson/docs/squad/session-operations.md +117 -0
  215. package/template/.aioson/docs/squad/workflow-quality.md +165 -0
  216. package/template/.aioson/docs/ux-ui/accessibility-audit.md +55 -0
  217. package/template/.aioson/docs/ux-ui/audit-mode.md +86 -0
  218. package/template/.aioson/docs/ux-ui/component-map.md +35 -0
  219. package/template/.aioson/docs/ux-ui/design-execution.md +111 -0
  220. package/template/.aioson/docs/ux-ui/design-gate.md +27 -0
  221. package/template/.aioson/docs/ux-ui/research-mode.md +39 -0
  222. package/template/.aioson/docs/ux-ui/site-delivery.md +156 -0
  223. package/template/.aioson/docs/ux-ui/token-contract.md +57 -0
  224. package/template/.aioson/genomes/copywriting.meta.json +48 -0
  225. package/template/.aioson/git-guard.json +11 -0
  226. package/template/.aioson/mcp/servers.md +0 -1
  227. package/template/.aioson/rules/agent-language-policy.md +93 -0
  228. package/template/.aioson/rules/aioson-context-boundary.md +63 -0
  229. package/template/.aioson/rules/canonical-path-contract.md +47 -0
  230. package/template/.aioson/rules/data-format-convention.md +24 -86
  231. package/template/.aioson/rules/disk-first-artifacts.md +44 -0
  232. package/template/.aioson/rules/output-brevity.md +44 -0
  233. package/template/.aioson/rules/prd-section-ownership.md +49 -0
  234. package/template/.aioson/rules/security-baseline.md +139 -0
  235. package/template/.aioson/rules/spec-level-ownership.md +61 -0
  236. package/template/.aioson/rules/squad-driver-pattern.md +81 -0
  237. package/template/.aioson/schemas/squad-blueprint.schema.json +24 -0
  238. package/template/.aioson/schemas/squad-manifest.schema.json +44 -0
  239. package/template/.aioson/skills/process/aioson-spec-driven/references/pm.md +30 -0
  240. package/template/.aioson/skills/process/secure-tdd/SKILL.md +97 -0
  241. package/template/.aioson/skills/process/secure-tdd/references/nextjs.md +81 -0
  242. package/template/.aioson/skills/process/secure-tdd/references/node-express.md +91 -0
  243. package/template/.aioson/skills/process/secure-tdd/references/planned-stacks.md +33 -0
  244. package/template/.aioson/skills/static/harness-validate/SKILL.md +46 -0
  245. package/template/.aioson/skills/static/web-research-cache.md +3 -0
  246. package/template/.aioson/tasks/squad-create.md +35 -8
  247. package/template/.aioson/tasks/squad-design.md +50 -2
  248. package/template/.aioson/tasks/squad-investigate.md +14 -1
  249. package/template/.claude/commands/aioson/agent/committer.md +5 -0
  250. package/template/.claude/commands/aioson/agent/copywriter.md +5 -0
  251. package/template/.claude/commands/aioson/agent/cypher.md +5 -0
  252. package/template/.claude/commands/aioson/agent/pair.md +5 -0
  253. package/template/.claude/commands/aioson/agent/validator.md +5 -0
  254. package/template/.gemini/commands/aios-analyst.toml +6 -3
  255. package/template/.gemini/commands/aios-architect.toml +7 -6
  256. package/template/.gemini/commands/aios-committer.toml +7 -0
  257. package/template/.gemini/commands/aios-copywriter.toml +7 -0
  258. package/template/.gemini/commands/aios-cypher.toml +7 -0
  259. package/template/.gemini/commands/aios-dev.toml +8 -7
  260. package/template/.gemini/commands/aios-deyvin.toml +6 -5
  261. package/template/.gemini/commands/aios-discovery-design-doc.toml +6 -3
  262. package/template/.gemini/commands/aios-genome.toml +7 -0
  263. package/template/.gemini/commands/aios-neo.toml +5 -3
  264. package/template/.gemini/commands/aios-orache.toml +7 -0
  265. package/template/.gemini/commands/aios-orchestrator.toml +8 -7
  266. package/template/.gemini/commands/aios-pair.toml +6 -5
  267. package/template/.gemini/commands/aios-pm.toml +8 -7
  268. package/template/.gemini/commands/aios-product.toml +5 -3
  269. package/template/.gemini/commands/aios-qa.toml +6 -5
  270. package/template/.gemini/commands/aios-setup.toml +5 -2
  271. package/template/.gemini/commands/aios-sheldon.toml +7 -0
  272. package/template/.gemini/commands/aios-site-forge.toml +7 -0
  273. package/template/.gemini/commands/aios-squad.toml +7 -0
  274. package/template/.gemini/commands/aios-tester.toml +6 -5
  275. package/template/.gemini/commands/aios-ux-ui.toml +8 -7
  276. package/template/.gemini/commands/aios-validator.toml +7 -0
  277. package/template/AGENTS.md +12 -1
  278. package/template/CLAUDE.md +5 -1
  279. package/template/.aioson/locales/en/agents/analyst.md +0 -244
  280. package/template/.aioson/locales/en/agents/architect.md +0 -245
  281. package/template/.aioson/locales/en/agents/dev.md +0 -397
  282. package/template/.aioson/locales/en/agents/deyvin.md +0 -137
  283. package/template/.aioson/locales/en/agents/discovery-design-doc.md +0 -27
  284. package/template/.aioson/locales/en/agents/genome.md +0 -212
  285. package/template/.aioson/locales/en/agents/neo.md +0 -8
  286. package/template/.aioson/locales/en/agents/orache.md +0 -6
  287. package/template/.aioson/locales/en/agents/orchestrator.md +0 -189
  288. package/template/.aioson/locales/en/agents/pair.md +0 -5
  289. package/template/.aioson/locales/en/agents/pm.md +0 -84
  290. package/template/.aioson/locales/en/agents/product.md +0 -378
  291. package/template/.aioson/locales/en/agents/profiler-enricher.md +0 -5
  292. package/template/.aioson/locales/en/agents/profiler-forge.md +0 -5
  293. package/template/.aioson/locales/en/agents/profiler-researcher.md +0 -5
  294. package/template/.aioson/locales/en/agents/qa.md +0 -270
  295. package/template/.aioson/locales/en/agents/setup.md +0 -421
  296. package/template/.aioson/locales/en/agents/sheldon.md +0 -455
  297. package/template/.aioson/locales/en/agents/squad.md +0 -449
  298. package/template/.aioson/locales/en/agents/tester.md +0 -6
  299. package/template/.aioson/locales/en/agents/ux-ui.md +0 -668
  300. package/template/.aioson/locales/es/agents/analyst.md +0 -225
  301. package/template/.aioson/locales/es/agents/architect.md +0 -245
  302. package/template/.aioson/locales/es/agents/dev.md +0 -370
  303. package/template/.aioson/locales/es/agents/deyvin.md +0 -99
  304. package/template/.aioson/locales/es/agents/discovery-design-doc.md +0 -21
  305. package/template/.aioson/locales/es/agents/genome.md +0 -104
  306. package/template/.aioson/locales/es/agents/neo.md +0 -50
  307. package/template/.aioson/locales/es/agents/orache.md +0 -105
  308. package/template/.aioson/locales/es/agents/orchestrator.md +0 -194
  309. package/template/.aioson/locales/es/agents/pair.md +0 -7
  310. package/template/.aioson/locales/es/agents/pm.md +0 -90
  311. package/template/.aioson/locales/es/agents/product.md +0 -372
  312. package/template/.aioson/locales/es/agents/profiler-enricher.md +0 -7
  313. package/template/.aioson/locales/es/agents/profiler-forge.md +0 -7
  314. package/template/.aioson/locales/es/agents/profiler-researcher.md +0 -7
  315. package/template/.aioson/locales/es/agents/qa.md +0 -198
  316. package/template/.aioson/locales/es/agents/setup.md +0 -405
  317. package/template/.aioson/locales/es/agents/sheldon.md +0 -309
  318. package/template/.aioson/locales/es/agents/squad.md +0 -532
  319. package/template/.aioson/locales/es/agents/tester.md +0 -9
  320. package/template/.aioson/locales/es/agents/ux-ui.md +0 -212
  321. package/template/.aioson/locales/fr/agents/analyst.md +0 -225
  322. package/template/.aioson/locales/fr/agents/architect.md +0 -245
  323. package/template/.aioson/locales/fr/agents/dev.md +0 -370
  324. package/template/.aioson/locales/fr/agents/deyvin.md +0 -99
  325. package/template/.aioson/locales/fr/agents/discovery-design-doc.md +0 -21
  326. package/template/.aioson/locales/fr/agents/genome.md +0 -104
  327. package/template/.aioson/locales/fr/agents/neo.md +0 -50
  328. package/template/.aioson/locales/fr/agents/orache.md +0 -106
  329. package/template/.aioson/locales/fr/agents/orchestrator.md +0 -194
  330. package/template/.aioson/locales/fr/agents/pair.md +0 -7
  331. package/template/.aioson/locales/fr/agents/pm.md +0 -90
  332. package/template/.aioson/locales/fr/agents/product.md +0 -372
  333. package/template/.aioson/locales/fr/agents/profiler-enricher.md +0 -7
  334. package/template/.aioson/locales/fr/agents/profiler-forge.md +0 -7
  335. package/template/.aioson/locales/fr/agents/profiler-researcher.md +0 -7
  336. package/template/.aioson/locales/fr/agents/qa.md +0 -198
  337. package/template/.aioson/locales/fr/agents/setup.md +0 -405
  338. package/template/.aioson/locales/fr/agents/sheldon.md +0 -309
  339. package/template/.aioson/locales/fr/agents/squad.md +0 -532
  340. package/template/.aioson/locales/fr/agents/tester.md +0 -9
  341. package/template/.aioson/locales/fr/agents/ux-ui.md +0 -212
  342. package/template/.aioson/locales/pt-BR/agents/analyst.md +0 -319
  343. package/template/.aioson/locales/pt-BR/agents/architect.md +0 -284
  344. package/template/.aioson/locales/pt-BR/agents/dev.md +0 -483
  345. package/template/.aioson/locales/pt-BR/agents/deyvin.md +0 -184
  346. package/template/.aioson/locales/pt-BR/agents/discovery-design-doc.md +0 -198
  347. package/template/.aioson/locales/pt-BR/agents/genome.md +0 -297
  348. package/template/.aioson/locales/pt-BR/agents/neo.md +0 -208
  349. package/template/.aioson/locales/pt-BR/agents/orache.md +0 -137
  350. package/template/.aioson/locales/pt-BR/agents/orchestrator.md +0 -324
  351. package/template/.aioson/locales/pt-BR/agents/pair.md +0 -5
  352. package/template/.aioson/locales/pt-BR/agents/pm.md +0 -182
  353. package/template/.aioson/locales/pt-BR/agents/product.md +0 -466
  354. package/template/.aioson/locales/pt-BR/agents/profiler-enricher.md +0 -5
  355. package/template/.aioson/locales/pt-BR/agents/profiler-forge.md +0 -5
  356. package/template/.aioson/locales/pt-BR/agents/profiler-researcher.md +0 -5
  357. package/template/.aioson/locales/pt-BR/agents/qa.md +0 -300
  358. package/template/.aioson/locales/pt-BR/agents/setup.md +0 -533
  359. package/template/.aioson/locales/pt-BR/agents/sheldon.md +0 -323
  360. package/template/.aioson/locales/pt-BR/agents/squad.md +0 -1330
  361. package/template/.aioson/locales/pt-BR/agents/tester.md +0 -449
  362. package/template/.aioson/locales/pt-BR/agents/ux-ui.md +0 -669
@@ -0,0 +1,241 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs/promises');
4
+ const path = require('node:path');
5
+ const { exists } = require('../utils');
6
+ const { recordRuntimeOperation } = require('../execution-gateway');
7
+ const {
8
+ PARALLEL_RELATIVE_DIR,
9
+ normalizeProjectRelativePath,
10
+ extractStatusWritePathItems,
11
+ matchWritePathPattern,
12
+ collectWritePathConflicts
13
+ } = require('../parallel-workspace');
14
+
15
+ function parseLaneIndex(fileName) {
16
+ const match = String(fileName || '').match(/^agent-(\d+)\.status\.md$/);
17
+ if (!match) return null;
18
+ const value = Number(match[1]);
19
+ if (!Number.isFinite(value) || value <= 0) return null;
20
+ return Math.floor(value);
21
+ }
22
+
23
+ function extractMetadata(content, key, fallback = '') {
24
+ const regex = new RegExp(`^-\\s*${key}:\\s*(.*)$`, 'im');
25
+ const match = String(content || '').match(regex);
26
+ if (!match) return fallback;
27
+ return String(match[1] || '').trim() || fallback;
28
+ }
29
+
30
+ function parseLaneOption(value) {
31
+ const num = Number(value);
32
+ if (!Number.isFinite(num) || num <= 0) return null;
33
+ return Math.floor(num);
34
+ }
35
+
36
+ function parseRequestedPaths(targetDir, value) {
37
+ const items = String(value || '')
38
+ .split(',')
39
+ .map((item) => String(item || '').trim())
40
+ .filter(Boolean);
41
+
42
+ return items.map((item) => {
43
+ const absolute = path.isAbsolute(item) ? item : path.resolve(targetDir, item);
44
+ const relative = path.isAbsolute(item) ? path.relative(targetDir, absolute) : item;
45
+ return {
46
+ raw: item,
47
+ normalized: normalizeProjectRelativePath(relative)
48
+ };
49
+ });
50
+ }
51
+
52
+ async function readLaneState(parallelDir, index) {
53
+ const absPath = path.join(parallelDir, `agent-${index}.status.md`);
54
+ const content = await fs.readFile(absPath, 'utf8');
55
+ return {
56
+ lane: index,
57
+ owner: extractMetadata(content, 'owner', `lane-${index}`),
58
+ status: extractMetadata(content, 'status', 'pending'),
59
+ writePathItems: extractStatusWritePathItems(content)
60
+ };
61
+ }
62
+
63
+ async function runParallelGuard({ args, options = {}, logger, t }) {
64
+ const targetDir = path.resolve(process.cwd(), args[0] || '.');
65
+ const lane = parseLaneOption(options.lane);
66
+ if (lane === null) {
67
+ throw new Error(t('parallel_guard.invalid_lane'));
68
+ }
69
+
70
+ const requestedPaths = parseRequestedPaths(targetDir, options.paths);
71
+ if (requestedPaths.length === 0) {
72
+ throw new Error(t('parallel_guard.paths_required'));
73
+ }
74
+
75
+ const parallelDir = path.join(targetDir, PARALLEL_RELATIVE_DIR);
76
+ if (!(await exists(parallelDir))) {
77
+ throw new Error(t('parallel_guard.parallel_missing', { path: parallelDir }));
78
+ }
79
+
80
+ const entries = await fs.readdir(parallelDir);
81
+ const laneIndices = entries
82
+ .map(parseLaneIndex)
83
+ .filter((value) => value !== null)
84
+ .sort((a, b) => a - b);
85
+
86
+ if (laneIndices.length === 0) {
87
+ throw new Error(t('parallel_guard.no_lanes'));
88
+ }
89
+
90
+ if (!laneIndices.includes(lane)) {
91
+ throw new Error(t('parallel_guard.lane_missing', { lane }));
92
+ }
93
+
94
+ const lanes = [];
95
+ for (const index of laneIndices) {
96
+ lanes.push(await readLaneState(parallelDir, index));
97
+ }
98
+
99
+ const writeScope = collectWritePathConflicts(lanes);
100
+ const targetLane = lanes.find((item) => item.lane === lane);
101
+ const results = requestedPaths.map((item) => {
102
+ if (!item.normalized) {
103
+ return {
104
+ path: item.raw,
105
+ normalizedPath: null,
106
+ ok: false,
107
+ reason: 'invalid_requested_path',
108
+ matchedLanes: []
109
+ };
110
+ }
111
+
112
+ const matchedLanes = lanes
113
+ .filter((laneState) =>
114
+ laneState.writePathItems.some((pattern) => matchWritePathPattern(item.normalized, pattern))
115
+ )
116
+ .map((laneState) => laneState.lane);
117
+
118
+ if (matchedLanes.length === 0) {
119
+ return {
120
+ path: item.raw,
121
+ normalizedPath: item.normalized,
122
+ ok: false,
123
+ reason: 'unassigned_path',
124
+ matchedLanes
125
+ };
126
+ }
127
+
128
+ if (matchedLanes.length > 1) {
129
+ return {
130
+ path: item.raw,
131
+ normalizedPath: item.normalized,
132
+ ok: false,
133
+ reason: 'ambiguous_path_owner',
134
+ matchedLanes
135
+ };
136
+ }
137
+
138
+ if (matchedLanes[0] !== lane) {
139
+ return {
140
+ path: item.raw,
141
+ normalizedPath: item.normalized,
142
+ ok: false,
143
+ reason: 'owned_by_other_lane',
144
+ ownerLane: matchedLanes[0],
145
+ matchedLanes
146
+ };
147
+ }
148
+
149
+ return {
150
+ path: item.raw,
151
+ normalizedPath: item.normalized,
152
+ ok: true,
153
+ reason: 'allowed',
154
+ ownerLane: lane,
155
+ matchedLanes
156
+ };
157
+ });
158
+
159
+ const denied = results.filter((item) => !item.ok);
160
+ const guardReady =
161
+ writeScope.invalidCount === 0 &&
162
+ writeScope.conflictCount === 0 &&
163
+ Array.isArray(targetLane.writePathItems) &&
164
+ targetLane.writePathItems.length > 0;
165
+
166
+ const output = {
167
+ ok: guardReady && denied.length === 0,
168
+ targetDir,
169
+ parallelDir,
170
+ lane,
171
+ requestedCount: requestedPaths.length,
172
+ laneWritePathCount: targetLane.writePathItems.length,
173
+ writeScope: {
174
+ laneCount: lanes.filter((item) => item.writePathItems.length > 0).length,
175
+ totalPathCount: lanes.reduce((sum, item) => sum + item.writePathItems.length, 0),
176
+ invalidPatternCount: writeScope.invalidCount,
177
+ invalidPatterns: writeScope.invalidPatterns,
178
+ conflictCount: writeScope.conflictCount,
179
+ conflicts: writeScope.conflicts
180
+ },
181
+ results,
182
+ allowedCount: results.length - denied.length,
183
+ deniedCount: denied.length,
184
+ denied
185
+ };
186
+
187
+ output.runtime = await recordRuntimeOperation(targetDir, {
188
+ agentName: 'orchestrator',
189
+ source: 'orchestration',
190
+ sessionKey: 'parallel:workspace',
191
+ title: 'Parallel orchestration workspace',
192
+ goal: 'Prepare and manage parallel development lanes',
193
+ runTitle: 'parallel:guard',
194
+ message: 'Parallel write-scope guard evaluated',
195
+ summary: output.ok
196
+ ? `Lane ${lane} is allowed to write ${output.allowedCount} path(s)`
197
+ : `Lane ${lane} is blocked for ${output.deniedCount} path(s)`,
198
+ eventType: output.ok ? 'parallel.guard_passed' : 'parallel.guard_blocked',
199
+ phase: 'parallel',
200
+ payload: {
201
+ command: 'parallel:guard',
202
+ lane,
203
+ requestedCount: output.requestedCount,
204
+ laneWritePathCount: output.laneWritePathCount,
205
+ writeScope: output.writeScope,
206
+ denied: output.denied
207
+ }
208
+ });
209
+
210
+ if (options.json) {
211
+ return output;
212
+ }
213
+
214
+ logger.log(
215
+ output.ok
216
+ ? t('parallel_guard.allowed', { lane, count: output.allowedCount })
217
+ : t('parallel_guard.blocked', { lane, count: output.deniedCount })
218
+ );
219
+ logger.log(
220
+ t('parallel_guard.write_scope_summary', {
221
+ paths: output.writeScope.totalPathCount,
222
+ conflicts: output.writeScope.conflictCount,
223
+ invalid: output.writeScope.invalidPatternCount
224
+ })
225
+ );
226
+ for (const result of results) {
227
+ logger.log(
228
+ t('parallel_guard.path_line', {
229
+ path: result.normalizedPath || result.path,
230
+ status: result.ok ? 'allowed' : result.reason,
231
+ owners: result.matchedLanes.join(', ') || '-'
232
+ })
233
+ );
234
+ }
235
+
236
+ return output;
237
+ }
238
+
239
+ module.exports = {
240
+ runParallelGuard
241
+ };
@@ -5,6 +5,16 @@ const path = require('node:path');
5
5
  const { validateProjectContextFile } = require('../context');
6
6
  const { ensureDir, exists, toRelativeSafe } = require('../utils');
7
7
  const { recordRuntimeOperation } = require('../execution-gateway');
8
+ const {
9
+ WORKSPACE_MANIFEST_RELATIVE_PATH,
10
+ OWNERSHIP_MAP_RELATIVE_PATH,
11
+ MERGE_PLAN_RELATIVE_PATH,
12
+ buildLaneKey,
13
+ buildLaneOwnershipEntries,
14
+ buildWorkspaceManifest,
15
+ buildOwnershipMap,
16
+ buildMergePlan
17
+ } = require('../parallel-workspace');
8
18
 
9
19
  const MIN_WORKERS = 2;
10
20
  const MAX_WORKERS = 6;
@@ -51,12 +61,13 @@ function renderSharedDecisions(input) {
51
61
 
52
62
  function renderAgentStatus(input) {
53
63
  const lane = `agent-${input.index}`;
64
+ const laneKey = buildLaneKey(input.index);
54
65
  return `# Parallel Lane Status - ${lane}
55
66
 
56
67
  ## Metadata
57
68
  - lane: ${lane}
58
69
  - role: @dev
59
- - owner: [unassigned]
70
+ - owner: ${laneKey}
60
71
  - status: pending
61
72
  - priority: medium
62
73
  - updated_at: ${input.generatedAt}
@@ -64,8 +75,18 @@ function renderAgentStatus(input) {
64
75
  ## Scope
65
76
  - [define module or feature boundary]
66
77
 
78
+ ## Ownership
79
+ - lane_key: ${laneKey}
80
+ - scope_keys: [unassigned]
81
+ - write_scope: assign scopes with \`aioson parallel:assign\`
82
+ - write_paths: [unassigned]
83
+
67
84
  ## Dependencies
68
- - [list dependencies on other lanes or shared decisions]
85
+ - [list dependencies such as lane-1 or shared-decisions]
86
+
87
+ ## Merge
88
+ - merge_rank: ${input.index}
89
+ - merge_strategy: lane-index-asc
69
90
 
70
91
  ## Deliverables
71
92
  - [ ] Code changes completed
@@ -94,7 +115,12 @@ async function collectPrerequisites(targetDir) {
94
115
 
95
116
  function buildTargetFiles(targetDir, workers) {
96
117
  const parallelDir = path.join(targetDir, '.aioson/context/parallel');
97
- const files = [path.join(parallelDir, 'shared-decisions.md')];
118
+ const files = [
119
+ path.join(targetDir, WORKSPACE_MANIFEST_RELATIVE_PATH),
120
+ path.join(targetDir, OWNERSHIP_MAP_RELATIVE_PATH),
121
+ path.join(targetDir, MERGE_PLAN_RELATIVE_PATH),
122
+ path.join(parallelDir, 'shared-decisions.md')
123
+ ];
98
124
  for (let i = 1; i <= workers; i += 1) {
99
125
  files.push(path.join(parallelDir, `agent-${i}.status.md`));
100
126
  }
@@ -163,6 +189,39 @@ async function runParallelInit({ args, options = {}, logger, t }) {
163
189
  if (!dryRun) {
164
190
  const parallelDir = path.join(targetDir, '.aioson/context/parallel');
165
191
  await ensureDir(parallelDir);
192
+ const laneAssignments = [];
193
+ for (let i = 1; i <= workers; i += 1) {
194
+ laneAssignments.push({ lane: i, items: [] });
195
+ }
196
+ const laneEntries = buildLaneOwnershipEntries(laneAssignments);
197
+
198
+ await fs.writeFile(
199
+ path.join(targetDir, WORKSPACE_MANIFEST_RELATIVE_PATH),
200
+ `${JSON.stringify(buildWorkspaceManifest({
201
+ projectName,
202
+ classification: classification || 'MEDIUM',
203
+ workers,
204
+ generatedAt,
205
+ lanes: laneEntries
206
+ }), null, 2)}\n`,
207
+ 'utf8'
208
+ );
209
+ await fs.writeFile(
210
+ path.join(targetDir, OWNERSHIP_MAP_RELATIVE_PATH),
211
+ `${JSON.stringify(buildOwnershipMap({
212
+ generatedAt,
213
+ lanes: laneEntries
214
+ }), null, 2)}\n`,
215
+ 'utf8'
216
+ );
217
+ await fs.writeFile(
218
+ path.join(targetDir, MERGE_PLAN_RELATIVE_PATH),
219
+ `${JSON.stringify(buildMergePlan({
220
+ generatedAt,
221
+ lanes: laneEntries
222
+ }), null, 2)}\n`,
223
+ 'utf8'
224
+ );
166
225
 
167
226
  const sharedContent = renderSharedDecisions({
168
227
  projectName,
@@ -209,7 +268,10 @@ async function runParallelInit({ args, options = {}, logger, t }) {
209
268
  classification: output.classification,
210
269
  workers,
211
270
  files: output.files,
212
- missingPrerequisites
271
+ missingPrerequisites,
272
+ workspaceManifest: WORKSPACE_MANIFEST_RELATIVE_PATH,
273
+ ownershipMap: OWNERSHIP_MAP_RELATIVE_PATH,
274
+ mergePlan: MERGE_PLAN_RELATIVE_PATH
213
275
  }
214
276
  });
215
277
  }
@@ -0,0 +1,299 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs/promises');
4
+ const path = require('node:path');
5
+ const { exists } = require('../utils');
6
+ const { recordRuntimeOperation } = require('../execution-gateway');
7
+ const {
8
+ PARALLEL_RELATIVE_DIR,
9
+ WORKSPACE_MANIFEST_RELATIVE_PATH,
10
+ OWNERSHIP_MAP_RELATIVE_PATH,
11
+ MERGE_PLAN_RELATIVE_PATH,
12
+ buildLaneOwnershipEntries,
13
+ collectOwnershipConflicts,
14
+ collectWritePathConflicts,
15
+ extractStatusScopeItems,
16
+ extractStatusDependencyItems,
17
+ extractStatusMergeRank,
18
+ extractStatusWritePathItems,
19
+ buildMachineSyncReport,
20
+ collectDependencyIssues,
21
+ buildMergeExecutionReport,
22
+ replaceSection,
23
+ replaceMetadataLine
24
+ } = require('../parallel-workspace');
25
+
26
+ function parseLaneIndex(fileName) {
27
+ const match = String(fileName || '').match(/^agent-(\d+)\.status\.md$/);
28
+ if (!match) return null;
29
+ const value = Number(match[1]);
30
+ if (!Number.isFinite(value) || value <= 0) return null;
31
+ return Math.floor(value);
32
+ }
33
+
34
+ function extractMetadata(content, key, fallback = '') {
35
+ const regex = new RegExp(`^-\\s*${key}:\\s*(.*)$`, 'im');
36
+ const match = String(content || '').match(regex);
37
+ if (!match) return fallback;
38
+ return String(match[1] || '').trim() || fallback;
39
+ }
40
+
41
+ async function readJsonIfExists(filePath) {
42
+ if (!(await exists(filePath))) return null;
43
+ try {
44
+ return JSON.parse(await fs.readFile(filePath, 'utf8'));
45
+ } catch {
46
+ return null;
47
+ }
48
+ }
49
+
50
+ async function readLaneState(parallelDir, index) {
51
+ const relPath = path.join(PARALLEL_RELATIVE_DIR, `agent-${index}.status.md`).replace(/\\/g, '/');
52
+ const absPath = path.join(parallelDir, `agent-${index}.status.md`);
53
+ const content = await fs.readFile(absPath, 'utf8');
54
+ return {
55
+ lane: index,
56
+ file: relPath,
57
+ absPath,
58
+ content,
59
+ status: extractMetadata(content, 'status', 'pending'),
60
+ owner: extractMetadata(content, 'owner', `lane-${index}`),
61
+ scopeItems: extractStatusScopeItems(content),
62
+ dependencyItems: extractStatusDependencyItems(content),
63
+ writePathItems: extractStatusWritePathItems(content),
64
+ mergeRank: extractStatusMergeRank(content, index)
65
+ };
66
+ }
67
+
68
+ function appendDecisionRow(content, generatedAt, laneCount, mergeOrder) {
69
+ const row =
70
+ `| ${generatedAt} | Deterministic merge executed | ` +
71
+ `All lanes merged in declared order | lanes=${laneCount}, order=${mergeOrder.join(', ')} |`;
72
+ const text = String(content || '');
73
+
74
+ if (!text.includes('| time | decision | rationale | impact |')) {
75
+ const suffix = text.endsWith('\n') ? '' : '\n';
76
+ return `${text}${suffix}\n## Decision Log\n| time | decision | rationale | impact |\n|------|----------|-----------|--------|\n${row}\n`;
77
+ }
78
+
79
+ return `${text.replace(/\n*$/, '\n')}${row}\n`;
80
+ }
81
+
82
+ function buildStructuralSummary({ sharedExists, machineFiles, sync, ownershipConflicts, dependencies, writeScope }) {
83
+ const missingMachineFiles = Object.entries(machineFiles)
84
+ .filter(([, existsFlag]) => !existsFlag)
85
+ .map(([key]) => key);
86
+
87
+ return {
88
+ sharedDecisionsExists: sharedExists,
89
+ machineFiles,
90
+ missingMachineFiles,
91
+ sync,
92
+ ownershipConflictCount: ownershipConflicts.length,
93
+ writeScopeConflictCount: writeScope.conflictCount,
94
+ invalidWritePathCount: writeScope.invalidCount,
95
+ invalidDependencyCount: dependencies.invalidCount,
96
+ blockedDependencyCount: dependencies.blockedCount,
97
+ orderViolationCount: dependencies.orderViolationCount
98
+ };
99
+ }
100
+
101
+ async function runParallelMerge({ args, options = {}, logger, t }) {
102
+ const targetDir = path.resolve(process.cwd(), args[0] || '.');
103
+ const apply = Boolean(options.apply);
104
+ const generatedAt = new Date().toISOString();
105
+ const parallelDir = path.join(targetDir, PARALLEL_RELATIVE_DIR);
106
+
107
+ if (!(await exists(parallelDir))) {
108
+ throw new Error(t('parallel_merge.parallel_missing', { path: parallelDir }));
109
+ }
110
+
111
+ const entries = await fs.readdir(parallelDir);
112
+ const laneIndices = entries
113
+ .map(parseLaneIndex)
114
+ .filter((value) => value !== null)
115
+ .sort((a, b) => a - b);
116
+
117
+ if (laneIndices.length === 0) {
118
+ throw new Error(t('parallel_merge.no_lanes'));
119
+ }
120
+
121
+ const lanes = [];
122
+ for (const index of laneIndices) {
123
+ lanes.push(await readLaneState(parallelDir, index));
124
+ }
125
+
126
+ const laneEntries = buildLaneOwnershipEntries(
127
+ lanes.map((lane) => ({
128
+ lane: lane.lane,
129
+ items: lane.scopeItems,
130
+ owner: lane.owner,
131
+ dependsOn: lane.dependencyItems,
132
+ writePaths: lane.writePathItems,
133
+ mergeRank: lane.mergeRank
134
+ }))
135
+ );
136
+
137
+ const sharedPath = path.join(parallelDir, 'shared-decisions.md');
138
+ const sharedExists = await exists(sharedPath);
139
+ const workspaceManifestPath = path.join(targetDir, WORKSPACE_MANIFEST_RELATIVE_PATH);
140
+ const ownershipPath = path.join(targetDir, OWNERSHIP_MAP_RELATIVE_PATH);
141
+ const mergePlanPath = path.join(targetDir, MERGE_PLAN_RELATIVE_PATH);
142
+ const workspaceManifest = await readJsonIfExists(workspaceManifestPath);
143
+ const ownershipMap = await readJsonIfExists(ownershipPath);
144
+ const mergePlan = await readJsonIfExists(mergePlanPath);
145
+
146
+ const machineFiles = {
147
+ workspaceManifest: Boolean(workspaceManifest),
148
+ ownershipMap: Boolean(ownershipMap),
149
+ mergePlan: Boolean(mergePlan)
150
+ };
151
+ const sync = buildMachineSyncReport({
152
+ laneEntries,
153
+ workspaceManifest,
154
+ ownershipMap,
155
+ mergePlan
156
+ });
157
+ const ownershipConflicts = collectOwnershipConflicts(ownershipMap);
158
+ const dependencies = collectDependencyIssues({
159
+ lanes,
160
+ mergeOrder: mergePlan && Array.isArray(mergePlan.order) ? mergePlan.order : []
161
+ });
162
+ const writeScope = collectWritePathConflicts(lanes);
163
+ const execution = buildMergeExecutionReport({
164
+ lanes,
165
+ mergeOrder: mergePlan && Array.isArray(mergePlan.order) ? mergePlan.order : []
166
+ });
167
+ const structural = buildStructuralSummary({
168
+ sharedExists,
169
+ machineFiles,
170
+ sync,
171
+ ownershipConflicts,
172
+ dependencies,
173
+ writeScope
174
+ });
175
+
176
+ const mergeReady =
177
+ structural.sharedDecisionsExists &&
178
+ structural.missingMachineFiles.length === 0 &&
179
+ structural.sync.staleFiles.length === 0 &&
180
+ structural.ownershipConflictCount === 0 &&
181
+ structural.writeScopeConflictCount === 0 &&
182
+ structural.invalidWritePathCount === 0 &&
183
+ structural.invalidDependencyCount === 0 &&
184
+ structural.orderViolationCount === 0 &&
185
+ execution.readyToApply;
186
+
187
+ const filesUpdated = [];
188
+ let sharedDecisionUpdated = false;
189
+
190
+ if (apply && mergeReady) {
191
+ for (let index = 0; index < execution.plan.length; index += 1) {
192
+ const item = execution.plan[index];
193
+ if (item.action !== 'merge') continue;
194
+
195
+ const lane = lanes.find((candidate) => candidate.lane === item.lane);
196
+ let next = replaceMetadataLine(lane.content, 'status', 'merged');
197
+ next = replaceMetadataLine(next, 'updated_at', generatedAt);
198
+ next = replaceSection(next, 'Merge', [
199
+ `- merge_rank: ${item.mergeRank}`,
200
+ '- merge_strategy: lane-index-asc',
201
+ `- merged_at: ${generatedAt}`,
202
+ `- merged_order: ${index + 1}`
203
+ ]);
204
+ await fs.writeFile(lane.absPath, next, 'utf8');
205
+ filesUpdated.push(lane.file);
206
+ }
207
+
208
+ if (sharedExists) {
209
+ const sharedContent = await fs.readFile(sharedPath, 'utf8');
210
+ const nextShared = appendDecisionRow(sharedContent, generatedAt, execution.order.length, execution.order);
211
+ await fs.writeFile(sharedPath, nextShared, 'utf8');
212
+ filesUpdated.push(path.join(PARALLEL_RELATIVE_DIR, 'shared-decisions.md').replace(/\\/g, '/'));
213
+ sharedDecisionUpdated = true;
214
+ }
215
+ }
216
+
217
+ const output = {
218
+ ok: mergeReady,
219
+ targetDir,
220
+ apply,
221
+ generatedAt,
222
+ laneCount: lanes.length,
223
+ structural,
224
+ merge: {
225
+ strategy: mergePlan && mergePlan.strategy ? mergePlan.strategy : 'lane-index-asc',
226
+ order: execution.order,
227
+ readyToApply: mergeReady,
228
+ readyLaneCount: execution.readyLaneCount,
229
+ alreadyMergedCount: execution.alreadyMergedCount,
230
+ blockedCount: execution.blockedCount,
231
+ blocked: execution.blocked,
232
+ plan: execution.plan
233
+ },
234
+ filesUpdated,
235
+ sharedDecisionUpdated
236
+ };
237
+
238
+ output.runtime = await recordRuntimeOperation(targetDir, {
239
+ agentName: 'orchestrator',
240
+ source: 'orchestration',
241
+ sessionKey: 'parallel:workspace',
242
+ title: 'Parallel orchestration workspace',
243
+ goal: 'Prepare and manage parallel development lanes',
244
+ runTitle: 'parallel:merge',
245
+ message: apply ? 'Parallel deterministic merge requested' : 'Parallel deterministic merge inspected',
246
+ summary: mergeReady
247
+ ? `Parallel merge ready for ${output.laneCount} lanes`
248
+ : `Parallel merge blocked for ${output.merge.blockedCount} lane(s)`,
249
+ eventType: apply && mergeReady ? 'parallel.merged' : 'parallel.merge_checked',
250
+ phase: 'parallel',
251
+ payload: {
252
+ command: 'parallel:merge',
253
+ apply,
254
+ laneCount: output.laneCount,
255
+ structural: output.structural,
256
+ merge: output.merge,
257
+ filesUpdated
258
+ }
259
+ });
260
+
261
+ if (options.json) {
262
+ return output;
263
+ }
264
+
265
+ logger.log(
266
+ mergeReady
267
+ ? apply
268
+ ? t('parallel_merge.applied', { count: output.merge.readyLaneCount })
269
+ : t('parallel_merge.ready', { count: output.merge.readyLaneCount })
270
+ : t('parallel_merge.blocked', { count: output.merge.blockedCount })
271
+ );
272
+ logger.log(t('parallel_merge.order', { order: output.merge.order.join(', ') }));
273
+ logger.log(
274
+ t('parallel_merge.structural_summary', {
275
+ stale: output.structural.sync.staleFiles.length,
276
+ conflicts: output.structural.ownershipConflictCount,
277
+ writeConflicts: output.structural.writeScopeConflictCount,
278
+ invalidWritePaths: output.structural.invalidWritePathCount,
279
+ invalid: output.structural.invalidDependencyCount,
280
+ blocked: output.structural.blockedDependencyCount,
281
+ orderViolations: output.structural.orderViolationCount
282
+ })
283
+ );
284
+ for (const item of output.merge.plan) {
285
+ logger.log(
286
+ t('parallel_merge.lane_line', {
287
+ lane: item.lane,
288
+ action: item.action,
289
+ status: item.status || 'n/a'
290
+ })
291
+ );
292
+ }
293
+
294
+ return output;
295
+ }
296
+
297
+ module.exports = {
298
+ runParallelMerge
299
+ };