bmalph 2.7.6 → 2.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 (448) hide show
  1. package/README.md +4 -4
  2. package/bmad/bmm/agents/analyst.agent.yaml +6 -6
  3. package/bmad/bmm/agents/architect.agent.yaml +2 -2
  4. package/bmad/bmm/agents/bmad-skill-manifest.yaml +39 -0
  5. package/bmad/bmm/agents/dev.agent.yaml +2 -2
  6. package/bmad/bmm/agents/pm.agent.yaml +6 -6
  7. package/bmad/bmm/agents/qa.agent.yaml +1 -1
  8. package/bmad/bmm/agents/quick-flow-solo-dev.agent.yaml +7 -3
  9. package/bmad/bmm/agents/sm.agent.yaml +4 -4
  10. package/bmad/bmm/agents/tech-writer/bmad-skill-manifest.yaml +3 -0
  11. package/bmad/bmm/agents/tech-writer/tech-writer.agent.yaml +1 -1
  12. package/bmad/bmm/agents/ux-designer.agent.yaml +1 -1
  13. package/bmad/bmm/module-help.csv +26 -25
  14. package/bmad/bmm/workflows/1-analysis/bmad-create-product-brief/SKILL.md +6 -0
  15. package/bmad/bmm/workflows/1-analysis/bmad-create-product-brief/bmad-skill-manifest.yaml +1 -0
  16. package/bmad/bmm/workflows/1-analysis/{create-product-brief → bmad-create-product-brief}/product-brief.template.md +2 -2
  17. package/bmad/bmm/workflows/1-analysis/{create-product-brief → bmad-create-product-brief}/steps/step-01-init.md +4 -11
  18. package/bmad/bmm/workflows/1-analysis/{create-product-brief → bmad-create-product-brief}/steps/step-01b-continue.md +0 -3
  19. package/bmad/bmm/workflows/1-analysis/{create-product-brief → bmad-create-product-brief}/steps/step-02-vision.md +5 -11
  20. package/bmad/bmm/workflows/1-analysis/{create-product-brief → bmad-create-product-brief}/steps/step-03-users.md +5 -11
  21. package/bmad/bmm/workflows/1-analysis/{create-product-brief → bmad-create-product-brief}/steps/step-04-metrics.md +5 -11
  22. package/bmad/bmm/workflows/1-analysis/{create-product-brief → bmad-create-product-brief}/steps/step-05-scope.md +5 -11
  23. package/bmad/bmm/workflows/1-analysis/{create-product-brief → bmad-create-product-brief}/steps/step-06-complete.md +1 -4
  24. package/bmad/bmm/workflows/1-analysis/{create-product-brief → bmad-create-product-brief}/workflow.md +4 -6
  25. package/bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/SKILL.md +88 -0
  26. package/bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/agents/artifact-analyzer.md +60 -0
  27. package/bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/agents/opportunity-reviewer.md +44 -0
  28. package/bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/agents/skeptic-reviewer.md +44 -0
  29. package/bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/agents/web-researcher.md +49 -0
  30. package/bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/bmad-manifest.json +17 -0
  31. package/bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/bmad-skill-manifest.yaml +1 -0
  32. package/bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/prompts/contextual-discovery.md +57 -0
  33. package/bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/prompts/draft-and-review.md +86 -0
  34. package/bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/prompts/finalize.md +75 -0
  35. package/bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/prompts/guided-elicitation.md +70 -0
  36. package/bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/resources/brief-template.md +60 -0
  37. package/bmad/bmm/workflows/1-analysis/research/bmad-domain-research/SKILL.md +6 -0
  38. package/bmad/bmm/workflows/1-analysis/research/bmad-domain-research/bmad-skill-manifest.yaml +1 -0
  39. package/bmad/bmm/workflows/1-analysis/research/{domain-steps → bmad-domain-research/domain-steps}/step-06-research-synthesis.md +2 -1
  40. package/bmad/bmm/workflows/1-analysis/research/bmad-domain-research/research.template.md +29 -0
  41. package/bmad/bmm/workflows/1-analysis/research/{workflow-domain-research.md → bmad-domain-research/workflow.md} +0 -5
  42. package/bmad/bmm/workflows/1-analysis/research/bmad-market-research/SKILL.md +6 -0
  43. package/bmad/bmm/workflows/1-analysis/research/bmad-market-research/bmad-skill-manifest.yaml +1 -0
  44. package/bmad/bmm/workflows/1-analysis/research/bmad-market-research/research.template.md +29 -0
  45. package/bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-01-init.md +184 -0
  46. package/bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-02-customer-behavior.md +239 -0
  47. package/bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-03-customer-pain-points.md +251 -0
  48. package/bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-04-customer-decisions.md +261 -0
  49. package/bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-05-competitive-analysis.md +173 -0
  50. package/bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-06-research-completion.md +478 -0
  51. package/bmad/bmm/workflows/1-analysis/research/{workflow-market-research.md → bmad-market-research/workflow.md} +1 -6
  52. package/bmad/bmm/workflows/1-analysis/research/bmad-technical-research/SKILL.md +6 -0
  53. package/bmad/bmm/workflows/1-analysis/research/bmad-technical-research/bmad-skill-manifest.yaml +1 -0
  54. package/bmad/bmm/workflows/1-analysis/research/bmad-technical-research/research.template.md +29 -0
  55. package/bmad/bmm/workflows/1-analysis/research/{technical-steps → bmad-technical-research/technical-steps}/step-06-research-synthesis.md +2 -1
  56. package/bmad/bmm/workflows/1-analysis/research/{workflow-technical-research.md → bmad-technical-research/workflow.md} +0 -4
  57. package/bmad/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +2 -2
  58. package/bmad/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +2 -2
  59. package/bmad/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +2 -2
  60. package/bmad/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +2 -2
  61. package/bmad/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +2 -1
  62. package/bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/SKILL.md +6 -0
  63. package/bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/bmad-skill-manifest.yaml +1 -0
  64. package/bmad/bmm/workflows/2-plan-workflows/{create-ux-design → bmad-create-ux-design}/steps/step-01-init.md +2 -2
  65. package/bmad/bmm/workflows/2-plan-workflows/{create-ux-design → bmad-create-ux-design}/steps/step-01b-continue.md +1 -1
  66. package/bmad/bmm/workflows/2-plan-workflows/{create-ux-design → bmad-create-ux-design}/steps/step-02-discovery.md +2 -2
  67. package/bmad/bmm/workflows/2-plan-workflows/{create-ux-design → bmad-create-ux-design}/steps/step-03-core-experience.md +5 -4
  68. package/bmad/bmm/workflows/2-plan-workflows/{create-ux-design → bmad-create-ux-design}/steps/step-04-emotional-response.md +5 -4
  69. package/bmad/bmm/workflows/2-plan-workflows/{create-ux-design → bmad-create-ux-design}/steps/step-05-inspiration.md +5 -4
  70. package/bmad/bmm/workflows/2-plan-workflows/{create-ux-design → bmad-create-ux-design}/steps/step-06-design-system.md +5 -4
  71. package/bmad/bmm/workflows/2-plan-workflows/{create-ux-design → bmad-create-ux-design}/steps/step-07-defining-experience.md +5 -4
  72. package/bmad/bmm/workflows/2-plan-workflows/{create-ux-design → bmad-create-ux-design}/steps/step-08-visual-foundation.md +5 -4
  73. package/bmad/bmm/workflows/2-plan-workflows/{create-ux-design → bmad-create-ux-design}/steps/step-09-design-directions.md +5 -4
  74. package/bmad/bmm/workflows/2-plan-workflows/{create-ux-design → bmad-create-ux-design}/steps/step-10-user-journeys.md +5 -4
  75. package/bmad/bmm/workflows/2-plan-workflows/{create-ux-design → bmad-create-ux-design}/steps/step-11-component-strategy.md +5 -4
  76. package/bmad/bmm/workflows/2-plan-workflows/{create-ux-design → bmad-create-ux-design}/steps/step-12-ux-patterns.md +5 -4
  77. package/bmad/bmm/workflows/2-plan-workflows/{create-ux-design → bmad-create-ux-design}/steps/step-13-responsive-accessibility.md +5 -4
  78. package/bmad/bmm/workflows/2-plan-workflows/{create-ux-design → bmad-create-ux-design}/steps/step-14-complete.md +3 -3
  79. package/bmad/bmm/workflows/2-plan-workflows/{create-ux-design → bmad-create-ux-design}/workflow.md +2 -8
  80. package/bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/SKILL.md +6 -0
  81. package/bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/bmad-skill-manifest.yaml +1 -0
  82. package/bmad/bmm/workflows/2-plan-workflows/{create-prd → bmad-edit-prd}/steps-e/step-e-01-discovery.md +3 -8
  83. package/bmad/bmm/workflows/2-plan-workflows/{create-prd → bmad-edit-prd}/steps-e/step-e-01b-legacy-conversion.md +1 -5
  84. package/bmad/bmm/workflows/2-plan-workflows/{create-prd → bmad-edit-prd}/steps-e/step-e-02-review.md +5 -9
  85. package/bmad/bmm/workflows/2-plan-workflows/{create-prd → bmad-edit-prd}/steps-e/step-e-03-edit.md +3 -6
  86. package/bmad/bmm/workflows/2-plan-workflows/{create-prd → bmad-edit-prd}/steps-e/step-e-04-complete.md +2 -5
  87. package/bmad/bmm/workflows/2-plan-workflows/{create-prd/workflow-edit-prd.md → bmad-edit-prd/workflow.md} +2 -4
  88. package/bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/SKILL.md +6 -0
  89. package/bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/bmad-skill-manifest.yaml +1 -0
  90. package/bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/data/domain-complexity.csv +15 -0
  91. package/bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/data/prd-purpose.md +197 -0
  92. package/bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/data/project-types.csv +11 -0
  93. package/bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-01-discovery.md +221 -0
  94. package/bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-02-format-detection.md +188 -0
  95. package/bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-02b-parity-check.md +206 -0
  96. package/bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-03-density-validation.md +171 -0
  97. package/bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-04-brief-coverage-validation.md +211 -0
  98. package/bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-05-measurability-validation.md +225 -0
  99. package/bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-06-traceability-validation.md +214 -0
  100. package/bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-07-implementation-leakage-validation.md +202 -0
  101. package/bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-08-domain-compliance-validation.md +240 -0
  102. package/bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-09-project-type-validation.md +260 -0
  103. package/bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-10-smart-validation.md +206 -0
  104. package/bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-11-holistic-quality-validation.md +261 -0
  105. package/bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-12-completeness-validation.md +239 -0
  106. package/bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-13-report-complete.md +229 -0
  107. package/bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/workflow.md +62 -0
  108. package/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-01-discovery.md +2 -4
  109. package/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-10-smart-validation.md +1 -1
  110. package/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-11-holistic-quality-validation.md +3 -3
  111. package/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-13-report-complete.md +3 -2
  112. package/bmad/bmm/workflows/2-plan-workflows/create-prd/workflow-validate-prd.md +3 -1
  113. package/bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/SKILL.md +6 -0
  114. package/bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/bmad-skill-manifest.yaml +1 -0
  115. package/bmad/bmm/workflows/3-solutioning/{check-implementation-readiness → bmad-check-implementation-readiness}/steps/step-01-document-discovery.md +3 -8
  116. package/bmad/bmm/workflows/3-solutioning/{check-implementation-readiness → bmad-check-implementation-readiness}/steps/step-02-prd-analysis.md +1 -5
  117. package/bmad/bmm/workflows/3-solutioning/{check-implementation-readiness → bmad-check-implementation-readiness}/steps/step-03-epic-coverage-validation.md +1 -5
  118. package/bmad/bmm/workflows/3-solutioning/{check-implementation-readiness → bmad-check-implementation-readiness}/steps/step-04-ux-alignment.md +1 -5
  119. package/bmad/bmm/workflows/3-solutioning/{check-implementation-readiness → bmad-check-implementation-readiness}/steps/step-05-epic-quality-review.md +2 -6
  120. package/bmad/bmm/workflows/3-solutioning/{check-implementation-readiness → bmad-check-implementation-readiness}/steps/step-06-final-assessment.md +1 -4
  121. package/bmad/bmm/workflows/3-solutioning/{check-implementation-readiness → bmad-check-implementation-readiness}/workflow.md +1 -6
  122. package/bmad/bmm/workflows/3-solutioning/bmad-create-architecture/SKILL.md +6 -0
  123. package/bmad/bmm/workflows/3-solutioning/bmad-create-architecture/bmad-skill-manifest.yaml +1 -0
  124. package/bmad/bmm/workflows/3-solutioning/{create-architecture → bmad-create-architecture}/steps/step-01-init.md +4 -4
  125. package/bmad/bmm/workflows/3-solutioning/{create-architecture → bmad-create-architecture}/steps/step-01b-continue.md +11 -2
  126. package/bmad/bmm/workflows/3-solutioning/{create-architecture → bmad-create-architecture}/steps/step-02-context.md +4 -4
  127. package/bmad/bmm/workflows/3-solutioning/{create-architecture → bmad-create-architecture}/steps/step-03-starter.md +5 -7
  128. package/bmad/bmm/workflows/3-solutioning/{create-architecture → bmad-create-architecture}/steps/step-04-decisions.md +4 -4
  129. package/bmad/bmm/workflows/3-solutioning/{create-architecture → bmad-create-architecture}/steps/step-05-patterns.md +4 -4
  130. package/bmad/bmm/workflows/3-solutioning/{create-architecture → bmad-create-architecture}/steps/step-06-structure.md +4 -4
  131. package/bmad/bmm/workflows/3-solutioning/{create-architecture → bmad-create-architecture}/steps/step-07-validation.md +4 -4
  132. package/bmad/bmm/workflows/3-solutioning/{create-architecture → bmad-create-architecture}/steps/step-08-complete.md +1 -1
  133. package/bmad/bmm/workflows/3-solutioning/{create-architecture → bmad-create-architecture}/workflow.md +1 -12
  134. package/bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/SKILL.md +6 -0
  135. package/bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/bmad-skill-manifest.yaml +1 -0
  136. package/bmad/bmm/workflows/3-solutioning/{create-epics-and-stories → bmad-create-epics-and-stories}/steps/step-01-validate-prerequisites.md +37 -41
  137. package/bmad/bmm/workflows/3-solutioning/{create-epics-and-stories → bmad-create-epics-and-stories}/steps/step-02-design-epics.md +7 -28
  138. package/bmad/bmm/workflows/3-solutioning/{create-epics-and-stories → bmad-create-epics-and-stories}/steps/step-03-create-stories.md +13 -30
  139. package/bmad/bmm/workflows/3-solutioning/{create-epics-and-stories → bmad-create-epics-and-stories}/steps/step-04-final-validation.md +3 -21
  140. package/bmad/bmm/workflows/3-solutioning/{create-epics-and-stories → bmad-create-epics-and-stories}/templates/epics-template.md +4 -0
  141. package/bmad/bmm/workflows/3-solutioning/{create-epics-and-stories → bmad-create-epics-and-stories}/workflow.md +1 -6
  142. package/bmad/bmm/workflows/4-implementation/bmad-code-review/SKILL.md +6 -0
  143. package/bmad/bmm/workflows/4-implementation/bmad-code-review/bmad-skill-manifest.yaml +1 -0
  144. package/bmad/bmm/workflows/4-implementation/bmad-code-review/steps/step-01-gather-context.md +61 -0
  145. package/bmad/bmm/workflows/4-implementation/bmad-code-review/steps/step-02-review.md +41 -0
  146. package/bmad/bmm/workflows/4-implementation/bmad-code-review/steps/step-03-triage.md +50 -0
  147. package/bmad/bmm/workflows/4-implementation/bmad-code-review/steps/step-04-present.md +38 -0
  148. package/bmad/bmm/workflows/4-implementation/bmad-code-review/workflow.md +54 -0
  149. package/bmad/bmm/workflows/4-implementation/bmad-correct-course/SKILL.md +6 -0
  150. package/bmad/bmm/workflows/4-implementation/bmad-correct-course/bmad-skill-manifest.yaml +1 -0
  151. package/bmad/bmm/workflows/4-implementation/{correct-course → bmad-correct-course}/checklist.md +1 -1
  152. package/bmad/bmm/workflows/4-implementation/{correct-course/instructions.md → bmad-correct-course/workflow.md} +74 -14
  153. package/bmad/bmm/workflows/4-implementation/bmad-create-story/SKILL.md +6 -0
  154. package/bmad/bmm/workflows/4-implementation/bmad-create-story/bmad-skill-manifest.yaml +1 -0
  155. package/bmad/bmm/workflows/4-implementation/{create-story → bmad-create-story}/checklist.md +9 -10
  156. package/bmad/bmm/workflows/4-implementation/bmad-create-story/discover-inputs.md +88 -0
  157. package/bmad/bmm/workflows/4-implementation/bmad-create-story/workflow.md +380 -0
  158. package/bmad/bmm/workflows/4-implementation/bmad-dev-story/SKILL.md +6 -0
  159. package/bmad/bmm/workflows/4-implementation/bmad-dev-story/bmad-skill-manifest.yaml +1 -0
  160. package/bmad/bmm/workflows/4-implementation/{dev-story/instructions.xml → bmad-dev-story/workflow.md} +42 -2
  161. package/bmad/bmm/workflows/4-implementation/bmad-retrospective/SKILL.md +6 -0
  162. package/bmad/bmm/workflows/4-implementation/bmad-retrospective/bmad-skill-manifest.yaml +1 -0
  163. package/bmad/bmm/workflows/4-implementation/{retrospective/instructions.md → bmad-retrospective/workflow.md} +58 -23
  164. package/bmad/bmm/workflows/4-implementation/bmad-sprint-planning/SKILL.md +6 -0
  165. package/bmad/bmm/workflows/4-implementation/bmad-sprint-planning/bmad-skill-manifest.yaml +1 -0
  166. package/bmad/bmm/workflows/4-implementation/{sprint-planning → bmad-sprint-planning}/sprint-status-template.yaml +1 -0
  167. package/bmad/bmm/workflows/4-implementation/{sprint-planning/instructions.md → bmad-sprint-planning/workflow.md} +47 -10
  168. package/bmad/bmm/workflows/4-implementation/bmad-sprint-status/SKILL.md +6 -0
  169. package/bmad/bmm/workflows/4-implementation/bmad-sprint-status/bmad-skill-manifest.yaml +1 -0
  170. package/bmad/bmm/workflows/4-implementation/{sprint-status/instructions.md → bmad-sprint-status/workflow.md} +39 -8
  171. package/bmad/bmm/workflows/bmad-document-project/SKILL.md +6 -0
  172. package/bmad/bmm/workflows/bmad-document-project/bmad-skill-manifest.yaml +1 -0
  173. package/bmad/bmm/workflows/{document-project → bmad-document-project}/instructions.md +6 -8
  174. package/bmad/bmm/workflows/bmad-document-project/workflow.md +27 -0
  175. package/bmad/bmm/workflows/{document-project → bmad-document-project}/workflows/deep-dive-instructions.md +3 -2
  176. package/bmad/bmm/workflows/bmad-document-project/workflows/deep-dive-workflow.md +34 -0
  177. package/bmad/bmm/workflows/{document-project → bmad-document-project}/workflows/full-scan-instructions.md +5 -4
  178. package/bmad/bmm/workflows/bmad-document-project/workflows/full-scan-workflow.md +34 -0
  179. package/bmad/bmm/workflows/bmad-generate-project-context/SKILL.md +6 -0
  180. package/bmad/bmm/workflows/bmad-generate-project-context/bmad-skill-manifest.yaml +1 -0
  181. package/bmad/bmm/workflows/{generate-project-context → bmad-generate-project-context}/steps/step-01-discover.md +3 -1
  182. package/bmad/bmm/workflows/{generate-project-context → bmad-generate-project-context}/steps/step-02-generate.md +7 -4
  183. package/bmad/bmm/workflows/{generate-project-context → bmad-generate-project-context}/workflow.md +2 -8
  184. package/bmad/bmm/workflows/bmad-qa-generate-e2e-tests/SKILL.md +6 -0
  185. package/bmad/bmm/workflows/bmad-qa-generate-e2e-tests/bmad-skill-manifest.yaml +1 -0
  186. package/bmad/bmm/workflows/{qa/automate/instructions.md → bmad-qa-generate-e2e-tests/workflow.md} +33 -7
  187. package/bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/SKILL.md +6 -0
  188. package/bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/bmad-skill-manifest.yaml +1 -0
  189. package/bmad/bmm/workflows/bmad-quick-flow/{quick-dev → bmad-quick-dev}/steps/step-01-mode-detection.md +9 -14
  190. package/bmad/bmm/workflows/bmad-quick-flow/{quick-dev → bmad-quick-dev}/steps/step-02-context-gathering.md +1 -5
  191. package/bmad/bmm/workflows/bmad-quick-flow/{quick-dev → bmad-quick-dev}/steps/step-03-execute.md +1 -5
  192. package/bmad/bmm/workflows/bmad-quick-flow/{quick-dev → bmad-quick-dev}/steps/step-04-self-check.md +1 -5
  193. package/bmad/bmm/workflows/bmad-quick-flow/{quick-dev → bmad-quick-dev}/steps/step-05-adversarial-review.md +8 -18
  194. package/bmad/bmm/workflows/bmad-quick-flow/{quick-dev → bmad-quick-dev}/steps/step-06-resolve-findings.md +0 -2
  195. package/bmad/bmm/workflows/bmad-quick-flow/{quick-dev → bmad-quick-dev}/workflow.md +1 -13
  196. package/bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/SKILL.md +6 -0
  197. package/bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/bmad-skill-manifest.yaml +1 -0
  198. package/bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/steps/step-01-clarify-and-route.md +51 -0
  199. package/bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/steps/step-02-plan.md +35 -0
  200. package/bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/steps/step-03-implement.md +33 -0
  201. package/bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/steps/step-04-review.md +50 -0
  202. package/bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/steps/step-05-present.md +17 -0
  203. package/bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/tech-spec-template.md +90 -0
  204. package/bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/workflow.md +79 -0
  205. package/bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/SKILL.md +6 -0
  206. package/bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/bmad-skill-manifest.yaml +1 -0
  207. package/bmad/bmm/workflows/bmad-quick-flow/{quick-spec → bmad-quick-spec}/steps/step-01-understand.md +7 -13
  208. package/bmad/bmm/workflows/bmad-quick-flow/{quick-spec → bmad-quick-spec}/steps/step-02-investigate.md +3 -7
  209. package/bmad/bmm/workflows/bmad-quick-flow/{quick-spec → bmad-quick-spec}/steps/step-03-generate.md +1 -5
  210. package/bmad/bmm/workflows/bmad-quick-flow/{quick-spec → bmad-quick-spec}/steps/step-04-review.md +9 -14
  211. package/bmad/bmm/workflows/bmad-quick-flow/{quick-spec → bmad-quick-spec}/workflow.md +1 -7
  212. package/bmad/core/module-help.csv +10 -8
  213. package/bmad/core/module.yaml +1 -1
  214. package/bmad/core/skills/bmad-advanced-elicitation/SKILL.md +6 -0
  215. package/bmad/core/skills/bmad-advanced-elicitation/bmad-skill-manifest.yaml +1 -0
  216. package/bmad/core/skills/bmad-advanced-elicitation/workflow.md +135 -0
  217. package/bmad/core/skills/bmad-brainstorming/SKILL.md +6 -0
  218. package/bmad/core/skills/bmad-brainstorming/bmad-skill-manifest.yaml +1 -0
  219. package/bmad/core/{workflows/brainstorming → skills/bmad-brainstorming}/steps/step-01-session-setup.md +35 -18
  220. package/bmad/core/{workflows/brainstorming → skills/bmad-brainstorming}/steps/step-01b-continue.md +4 -2
  221. package/bmad/core/{workflows/brainstorming → skills/bmad-brainstorming}/steps/step-02a-user-selected.md +5 -1
  222. package/bmad/core/{workflows/brainstorming → skills/bmad-brainstorming}/steps/step-02b-ai-recommended.md +3 -1
  223. package/bmad/core/{workflows/brainstorming → skills/bmad-brainstorming}/steps/step-02c-random-selection.md +3 -1
  224. package/bmad/core/{workflows/brainstorming → skills/bmad-brainstorming}/steps/step-02d-progressive-flow.md +3 -1
  225. package/bmad/core/{workflows/brainstorming → skills/bmad-brainstorming}/steps/step-03-technique-execution.md +6 -4
  226. package/bmad/core/{workflows/brainstorming → skills/bmad-brainstorming}/steps/step-04-idea-organization.md +4 -2
  227. package/bmad/core/{workflows/brainstorming → skills/bmad-brainstorming}/workflow.md +4 -9
  228. package/bmad/core/skills/bmad-distillator/SKILL.md +178 -0
  229. package/bmad/core/skills/bmad-distillator/agents/distillate-compressor.md +116 -0
  230. package/bmad/core/skills/bmad-distillator/agents/round-trip-reconstructor.md +68 -0
  231. package/bmad/core/skills/bmad-distillator/bmad-skill-manifest.yaml +15 -0
  232. package/bmad/core/skills/bmad-distillator/resources/compression-rules.md +51 -0
  233. package/bmad/core/skills/bmad-distillator/resources/distillate-format-reference.md +227 -0
  234. package/bmad/core/skills/bmad-distillator/resources/splitting-strategy.md +78 -0
  235. package/bmad/core/skills/bmad-distillator/scripts/analyze_sources.py +300 -0
  236. package/bmad/core/skills/bmad-distillator/scripts/tests/test_analyze_sources.py +204 -0
  237. package/bmad/core/skills/bmad-editorial-review-prose/SKILL.md +6 -0
  238. package/bmad/core/skills/bmad-editorial-review-prose/bmad-skill-manifest.yaml +1 -0
  239. package/bmad/core/skills/bmad-editorial-review-prose/workflow.md +81 -0
  240. package/bmad/core/skills/bmad-editorial-review-structure/SKILL.md +6 -0
  241. package/bmad/core/skills/bmad-editorial-review-structure/bmad-skill-manifest.yaml +1 -0
  242. package/bmad/core/skills/bmad-editorial-review-structure/workflow.md +174 -0
  243. package/bmad/core/skills/bmad-help/SKILL.md +6 -0
  244. package/bmad/core/skills/bmad-help/bmad-skill-manifest.yaml +1 -0
  245. package/bmad/core/{tasks/help.md → skills/bmad-help/workflow.md} +11 -8
  246. package/bmad/core/skills/bmad-index-docs/SKILL.md +6 -0
  247. package/bmad/core/skills/bmad-index-docs/bmad-skill-manifest.yaml +1 -0
  248. package/bmad/core/skills/bmad-index-docs/workflow.md +61 -0
  249. package/bmad/core/skills/bmad-party-mode/SKILL.md +6 -0
  250. package/bmad/core/skills/bmad-party-mode/bmad-skill-manifest.yaml +1 -0
  251. package/bmad/core/{workflows/party-mode → skills/bmad-party-mode}/steps/step-03-graceful-exit.md +0 -1
  252. package/bmad/core/{workflows/party-mode → skills/bmad-party-mode}/workflow.md +0 -4
  253. package/bmad/core/skills/bmad-review-adversarial-general/SKILL.md +6 -0
  254. package/bmad/core/skills/bmad-review-adversarial-general/bmad-skill-manifest.yaml +1 -0
  255. package/bmad/core/skills/bmad-review-adversarial-general/workflow.md +32 -0
  256. package/bmad/core/skills/bmad-review-edge-case-hunter/SKILL.md +6 -0
  257. package/bmad/core/skills/bmad-review-edge-case-hunter/bmad-skill-manifest.yaml +1 -0
  258. package/bmad/core/skills/bmad-review-edge-case-hunter/workflow.md +62 -0
  259. package/bmad/core/skills/bmad-shard-doc/SKILL.md +6 -0
  260. package/bmad/core/skills/bmad-shard-doc/bmad-skill-manifest.yaml +1 -0
  261. package/bmad/core/skills/bmad-shard-doc/workflow.md +100 -0
  262. package/bmad/core/tasks/bmad-create-prd/SKILL.md +6 -0
  263. package/bmad/core/tasks/bmad-create-prd/bmad-skill-manifest.yaml +1 -0
  264. package/bmad/core/tasks/bmad-create-prd/data/domain-complexity.csv +15 -0
  265. package/bmad/core/tasks/bmad-create-prd/data/prd-purpose.md +197 -0
  266. package/bmad/core/tasks/bmad-create-prd/data/project-types.csv +11 -0
  267. package/bmad/{bmm/workflows/2-plan-workflows/create-prd → core/tasks/bmad-create-prd}/steps-c/step-01-init.md +7 -20
  268. package/bmad/{bmm/workflows/2-plan-workflows/create-prd → core/tasks/bmad-create-prd}/steps-c/step-01b-continue.md +29 -21
  269. package/bmad/{bmm/workflows/2-plan-workflows/create-prd → core/tasks/bmad-create-prd}/steps-c/step-02-discovery.md +7 -23
  270. package/bmad/{bmm/workflows/2-plan-workflows/create-prd → core/tasks/bmad-create-prd}/steps-c/step-02b-vision.md +5 -17
  271. package/bmad/{bmm/workflows/2-plan-workflows/create-prd → core/tasks/bmad-create-prd}/steps-c/step-02c-executive-summary.md +5 -17
  272. package/bmad/{bmm/workflows/2-plan-workflows/create-prd → core/tasks/bmad-create-prd}/steps-c/step-03-success.md +4 -16
  273. package/bmad/{bmm/workflows/2-plan-workflows/create-prd → core/tasks/bmad-create-prd}/steps-c/step-04-journeys.md +4 -16
  274. package/bmad/{bmm/workflows/2-plan-workflows/create-prd → core/tasks/bmad-create-prd}/steps-c/step-05-domain.md +7 -20
  275. package/bmad/{bmm/workflows/2-plan-workflows/create-prd → core/tasks/bmad-create-prd}/steps-c/step-06-innovation.md +8 -23
  276. package/bmad/{bmm/workflows/2-plan-workflows/create-prd → core/tasks/bmad-create-prd}/steps-c/step-07-project-type.md +6 -21
  277. package/bmad/{bmm/workflows/2-plan-workflows/create-prd → core/tasks/bmad-create-prd}/steps-c/step-08-scoping.md +5 -17
  278. package/bmad/{bmm/workflows/2-plan-workflows/create-prd → core/tasks/bmad-create-prd}/steps-c/step-09-functional.md +5 -17
  279. package/bmad/{bmm/workflows/2-plan-workflows/create-prd → core/tasks/bmad-create-prd}/steps-c/step-10-nonfunctional.md +5 -17
  280. package/bmad/{bmm/workflows/2-plan-workflows/create-prd → core/tasks/bmad-create-prd}/steps-c/step-11-polish.md +22 -18
  281. package/bmad/{bmm/workflows/2-plan-workflows/create-prd → core/tasks/bmad-create-prd}/steps-c/step-12-complete.md +4 -13
  282. package/bmad/{bmm/workflows/2-plan-workflows/create-prd/workflow-create-prd.md → core/tasks/bmad-create-prd/workflow.md} +3 -4
  283. package/bundled-versions.json +1 -1
  284. package/dist/commands/doctor-checks.js +14 -5
  285. package/dist/commands/doctor-checks.js.map +1 -1
  286. package/dist/commands/doctor.js +13 -4
  287. package/dist/commands/doctor.js.map +1 -1
  288. package/dist/commands/init.js +12 -2
  289. package/dist/commands/init.js.map +1 -1
  290. package/dist/commands/run.js +11 -2
  291. package/dist/commands/run.js.map +1 -1
  292. package/dist/commands/status.js +3 -2
  293. package/dist/commands/status.js.map +1 -1
  294. package/dist/commands/watch.js +5 -0
  295. package/dist/commands/watch.js.map +1 -1
  296. package/dist/installer/commands.js +33 -15
  297. package/dist/installer/commands.js.map +1 -1
  298. package/dist/installer/install.js +1 -1
  299. package/dist/installer/install.js.map +1 -1
  300. package/dist/installer/project-files.js +4 -4
  301. package/dist/installer/project-files.js.map +1 -1
  302. package/dist/installer/template-files.js +72 -6
  303. package/dist/installer/template-files.js.map +1 -1
  304. package/dist/platform/codex.js +6 -1
  305. package/dist/platform/codex.js.map +1 -1
  306. package/dist/platform/detect.js +7 -3
  307. package/dist/platform/detect.js.map +1 -1
  308. package/dist/platform/doctor-checks.js +2 -2
  309. package/dist/platform/doctor-checks.js.map +1 -1
  310. package/dist/platform/guidance.js +66 -0
  311. package/dist/platform/guidance.js.map +1 -0
  312. package/dist/platform/instructions-snippet.js +15 -0
  313. package/dist/platform/instructions-snippet.js.map +1 -1
  314. package/dist/platform/opencode.js +20 -0
  315. package/dist/platform/opencode.js.map +1 -0
  316. package/dist/platform/registry.js +2 -0
  317. package/dist/platform/registry.js.map +1 -1
  318. package/dist/platform/types.js +1 -0
  319. package/dist/platform/types.js.map +1 -1
  320. package/dist/reset.js +3 -3
  321. package/dist/reset.js.map +1 -1
  322. package/dist/run/ralph-process.js +51 -7
  323. package/dist/run/ralph-process.js.map +1 -1
  324. package/dist/run/run-dashboard.js +22 -9
  325. package/dist/run/run-dashboard.js.map +1 -1
  326. package/dist/transition/artifact-scan.js +14 -5
  327. package/dist/transition/artifact-scan.js.map +1 -1
  328. package/dist/transition/context.js +11 -3
  329. package/dist/transition/context.js.map +1 -1
  330. package/dist/utils/constants.js +4 -2
  331. package/dist/utils/constants.js.map +1 -1
  332. package/dist/watch/dashboard.js +36 -21
  333. package/dist/watch/dashboard.js.map +1 -1
  334. package/dist/watch/frame-writer.js +83 -0
  335. package/dist/watch/frame-writer.js.map +1 -0
  336. package/dist/watch/renderer.js +179 -54
  337. package/dist/watch/renderer.js.map +1 -1
  338. package/dist/watch/state-reader.js +8 -0
  339. package/dist/watch/state-reader.js.map +1 -1
  340. package/package.json +1 -1
  341. package/ralph/RALPH-REFERENCE.md +4 -4
  342. package/ralph/drivers/claude-code.sh +4 -2
  343. package/ralph/drivers/opencode.sh +147 -0
  344. package/ralph/lib/enable_core.sh +10 -2
  345. package/ralph/lib/response_analyzer.sh +337 -96
  346. package/ralph/lib/wizard_utils.sh +4 -4
  347. package/ralph/ralph_import.sh +9 -1
  348. package/ralph/ralph_loop.sh +428 -15
  349. package/ralph/templates/PROMPT.md +15 -5
  350. package/ralph/templates/ralphrc.template +31 -5
  351. package/slash-commands/advanced-elicitation.md +1 -1
  352. package/slash-commands/adversarial-review.md +1 -1
  353. package/slash-commands/bmad-help.md +1 -1
  354. package/slash-commands/bmalph.md +1 -1
  355. package/slash-commands/brainstorm-project.md +1 -1
  356. package/slash-commands/brainstorming.md +1 -1
  357. package/slash-commands/correct-course.md +1 -1
  358. package/slash-commands/create-architecture.md +1 -1
  359. package/slash-commands/create-brief.md +1 -1
  360. package/slash-commands/create-epics-stories.md +1 -1
  361. package/slash-commands/create-prd.md +1 -1
  362. package/slash-commands/create-story.md +1 -1
  363. package/slash-commands/create-ux.md +1 -1
  364. package/slash-commands/distillator.md +1 -0
  365. package/slash-commands/document-project.md +1 -1
  366. package/slash-commands/domain-research.md +1 -1
  367. package/slash-commands/edge-case-hunter.md +1 -0
  368. package/slash-commands/edit-prd.md +1 -0
  369. package/slash-commands/editorial-prose.md +1 -1
  370. package/slash-commands/editorial-structure.md +1 -1
  371. package/slash-commands/generate-project-context.md +1 -1
  372. package/slash-commands/implementation-readiness.md +1 -1
  373. package/slash-commands/index-docs.md +1 -1
  374. package/slash-commands/market-research.md +1 -1
  375. package/slash-commands/party-mode.md +1 -1
  376. package/slash-commands/qa-automate.md +1 -1
  377. package/slash-commands/quick-dev-new.md +1 -0
  378. package/slash-commands/quick-dev.md +1 -1
  379. package/slash-commands/retrospective.md +1 -1
  380. package/slash-commands/shard-doc.md +1 -1
  381. package/slash-commands/sprint-planning.md +1 -1
  382. package/slash-commands/sprint-status.md +1 -1
  383. package/slash-commands/tech-spec.md +1 -1
  384. package/slash-commands/technical-research.md +1 -1
  385. package/slash-commands/validate-architecture.md +1 -1
  386. package/slash-commands/validate-brief.md +1 -1
  387. package/slash-commands/validate-epics-stories.md +1 -1
  388. package/slash-commands/validate-prd.md +1 -1
  389. package/slash-commands/validate-story.md +1 -1
  390. package/slash-commands/validate-ux.md +1 -1
  391. package/bmad/bmm/workflows/4-implementation/code-review/checklist.md +0 -23
  392. package/bmad/bmm/workflows/4-implementation/code-review/instructions.xml +0 -227
  393. package/bmad/bmm/workflows/4-implementation/code-review/workflow.yaml +0 -44
  394. package/bmad/bmm/workflows/4-implementation/correct-course/workflow.yaml +0 -54
  395. package/bmad/bmm/workflows/4-implementation/create-story/instructions.xml +0 -346
  396. package/bmad/bmm/workflows/4-implementation/create-story/workflow.yaml +0 -53
  397. package/bmad/bmm/workflows/4-implementation/dev-story/workflow.yaml +0 -21
  398. package/bmad/bmm/workflows/4-implementation/retrospective/workflow.yaml +0 -53
  399. package/bmad/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +0 -47
  400. package/bmad/bmm/workflows/4-implementation/sprint-status/workflow.yaml +0 -25
  401. package/bmad/bmm/workflows/document-project/workflow.yaml +0 -22
  402. package/bmad/bmm/workflows/document-project/workflows/deep-dive.yaml +0 -31
  403. package/bmad/bmm/workflows/document-project/workflows/full-scan.yaml +0 -31
  404. package/bmad/bmm/workflows/qa/automate/workflow.yaml +0 -44
  405. package/bmad/core/agents/bmad-master.agent.yaml +0 -30
  406. package/bmad/core/tasks/editorial-review-prose.xml +0 -102
  407. package/bmad/core/tasks/editorial-review-structure.xml +0 -209
  408. package/bmad/core/tasks/index-docs.xml +0 -65
  409. package/bmad/core/tasks/review-adversarial-general.xml +0 -48
  410. package/bmad/core/tasks/shard-doc.xml +0 -108
  411. package/bmad/core/tasks/workflow.xml +0 -235
  412. package/bmad/core/workflows/advanced-elicitation/workflow.xml +0 -117
  413. package/slash-commands/execute-workflow.md +0 -1
  414. /package/bmad/bmm/workflows/1-analysis/research/{domain-steps → bmad-domain-research/domain-steps}/step-01-init.md +0 -0
  415. /package/bmad/bmm/workflows/1-analysis/research/{domain-steps → bmad-domain-research/domain-steps}/step-02-domain-analysis.md +0 -0
  416. /package/bmad/bmm/workflows/1-analysis/research/{domain-steps → bmad-domain-research/domain-steps}/step-03-competitive-landscape.md +0 -0
  417. /package/bmad/bmm/workflows/1-analysis/research/{domain-steps → bmad-domain-research/domain-steps}/step-04-regulatory-focus.md +0 -0
  418. /package/bmad/bmm/workflows/1-analysis/research/{domain-steps → bmad-domain-research/domain-steps}/step-05-technical-trends.md +0 -0
  419. /package/bmad/bmm/workflows/1-analysis/research/{technical-steps → bmad-technical-research/technical-steps}/step-01-init.md +0 -0
  420. /package/bmad/bmm/workflows/1-analysis/research/{technical-steps → bmad-technical-research/technical-steps}/step-02-technical-overview.md +0 -0
  421. /package/bmad/bmm/workflows/1-analysis/research/{technical-steps → bmad-technical-research/technical-steps}/step-03-integration-patterns.md +0 -0
  422. /package/bmad/bmm/workflows/1-analysis/research/{technical-steps → bmad-technical-research/technical-steps}/step-04-architectural-patterns.md +0 -0
  423. /package/bmad/bmm/workflows/1-analysis/research/{technical-steps → bmad-technical-research/technical-steps}/step-05-implementation-research.md +0 -0
  424. /package/bmad/bmm/workflows/2-plan-workflows/{create-ux-design → bmad-create-ux-design}/ux-design-template.md +0 -0
  425. /package/bmad/bmm/workflows/3-solutioning/{check-implementation-readiness → bmad-check-implementation-readiness}/templates/readiness-report-template.md +0 -0
  426. /package/bmad/bmm/workflows/3-solutioning/{create-architecture → bmad-create-architecture}/architecture-decision-template.md +0 -0
  427. /package/bmad/bmm/workflows/3-solutioning/{create-architecture → bmad-create-architecture}/data/domain-complexity.csv +0 -0
  428. /package/bmad/bmm/workflows/3-solutioning/{create-architecture → bmad-create-architecture}/data/project-types.csv +0 -0
  429. /package/bmad/bmm/workflows/4-implementation/{create-story → bmad-create-story}/template.md +0 -0
  430. /package/bmad/bmm/workflows/4-implementation/{dev-story → bmad-dev-story}/checklist.md +0 -0
  431. /package/bmad/bmm/workflows/4-implementation/{sprint-planning → bmad-sprint-planning}/checklist.md +0 -0
  432. /package/bmad/bmm/workflows/{document-project → bmad-document-project}/checklist.md +0 -0
  433. /package/bmad/bmm/workflows/{document-project → bmad-document-project}/documentation-requirements.csv +0 -0
  434. /package/bmad/bmm/workflows/{document-project → bmad-document-project}/templates/deep-dive-template.md +0 -0
  435. /package/bmad/bmm/workflows/{document-project → bmad-document-project}/templates/index-template.md +0 -0
  436. /package/bmad/bmm/workflows/{document-project → bmad-document-project}/templates/project-overview-template.md +0 -0
  437. /package/bmad/bmm/workflows/{document-project → bmad-document-project}/templates/project-scan-report-schema.json +0 -0
  438. /package/bmad/bmm/workflows/{document-project → bmad-document-project}/templates/source-tree-template.md +0 -0
  439. /package/bmad/bmm/workflows/{generate-project-context → bmad-generate-project-context}/project-context-template.md +0 -0
  440. /package/bmad/bmm/workflows/{generate-project-context → bmad-generate-project-context}/steps/step-03-complete.md +0 -0
  441. /package/bmad/bmm/workflows/{qa/automate → bmad-qa-generate-e2e-tests}/checklist.md +0 -0
  442. /package/bmad/bmm/workflows/bmad-quick-flow/{quick-spec → bmad-quick-spec}/tech-spec-template.md +0 -0
  443. /package/bmad/core/{workflows/advanced-elicitation → skills/bmad-advanced-elicitation}/methods.csv +0 -0
  444. /package/bmad/core/{workflows/brainstorming → skills/bmad-brainstorming}/brain-methods.csv +0 -0
  445. /package/bmad/core/{workflows/brainstorming → skills/bmad-brainstorming}/template.md +0 -0
  446. /package/bmad/core/{workflows/party-mode → skills/bmad-party-mode}/steps/step-01-agent-loading.md +0 -0
  447. /package/bmad/core/{workflows/party-mode → skills/bmad-party-mode}/steps/step-02-discussion-orchestration.md +0 -0
  448. /package/bmad/{bmm/workflows/2-plan-workflows/create-prd → core/tasks/bmad-create-prd}/templates/prd-template.md +0 -0
@@ -97,7 +97,8 @@ contains_permission_denial_signal() {
97
97
  local line
98
98
  while IFS= read -r line; do
99
99
  local trimmed="${line#"${line%%[![:space:]]*}"}"
100
- local normalized="${trimmed,,}"
100
+ local normalized
101
+ normalized="$(printf '%s' "$trimmed" | tr '[:upper:]' '[:lower:]')"
101
102
 
102
103
  if permission_denial_line_matches "$normalized"; then
103
104
  return 0
@@ -225,6 +226,35 @@ normalize_cursor_stream_json_response() {
225
226
  ' "$output_file" > "$normalized_file"
226
227
  }
227
228
 
229
+ # Normalize OpenCode JSON event output into the object shape expected downstream.
230
+ normalize_opencode_jsonl_response() {
231
+ local output_file=$1
232
+ local normalized_file=$2
233
+
234
+ jq -rs '
235
+ def assistant_text($message):
236
+ [($message.parts // [])[]? | select(.type == "text") | .text]
237
+ | join("\n");
238
+
239
+ (map(
240
+ select(
241
+ (.type == "message.updated" or .type == "message.completed")
242
+ and (.message.role // "") == "assistant"
243
+ )
244
+ ) | last | .message // {}) as $assistant_message
245
+ | {
246
+ result: assistant_text($assistant_message),
247
+ sessionId: (
248
+ map(.session.id // .session_id // .sessionId // empty)
249
+ | map(select(length > 0))
250
+ | first
251
+ // ""
252
+ ),
253
+ metadata: {}
254
+ }
255
+ ' "$output_file" > "$normalized_file"
256
+ }
257
+
228
258
  # Detect whether a multi-document stream matches Codex JSONL events.
229
259
  is_codex_jsonl_output() {
230
260
  local output_file=$1
@@ -240,6 +270,25 @@ is_codex_jsonl_output() {
240
270
  ' < "$output_file" 2>/dev/null
241
271
  }
242
272
 
273
+ # Detect whether a multi-document stream matches OpenCode JSON events.
274
+ is_opencode_jsonl_output() {
275
+ local output_file=$1
276
+
277
+ jq -n -j '
278
+ reduce inputs as $item (
279
+ false;
280
+ . or (
281
+ $item.type == "session.created" or
282
+ $item.type == "session.updated" or
283
+ (
284
+ ($item.type == "message.updated" or $item.type == "message.completed")
285
+ and ($item.message.role? != null)
286
+ )
287
+ )
288
+ )
289
+ ' < "$output_file" 2>/dev/null
290
+ }
291
+
243
292
  # Detect whether a multi-document stream matches Cursor stream-json events.
244
293
  is_cursor_stream_json_output() {
245
294
  local output_file=$1
@@ -275,6 +324,14 @@ normalize_json_output() {
275
324
  return $?
276
325
  fi
277
326
 
327
+ local is_opencode_jsonl
328
+ is_opencode_jsonl=$(is_opencode_jsonl_output "$output_file") || return 1
329
+
330
+ if [[ "$is_opencode_jsonl" == "true" ]]; then
331
+ normalize_opencode_jsonl_response "$output_file" "$normalized_file"
332
+ return $?
333
+ fi
334
+
278
335
  local is_cursor_stream_json
279
336
  is_cursor_stream_json=$(is_cursor_stream_json_output "$output_file") || return 1
280
337
 
@@ -372,6 +429,17 @@ detect_output_format() {
372
429
  return
373
430
  fi
374
431
 
432
+ local is_opencode_jsonl
433
+ is_opencode_jsonl=$(is_opencode_jsonl_output "$output_file") || {
434
+ echo "text"
435
+ return
436
+ }
437
+
438
+ if [[ "$is_opencode_jsonl" == "true" ]]; then
439
+ echo "json"
440
+ return
441
+ fi
442
+
375
443
  local is_cursor_stream_json
376
444
  is_cursor_stream_json=$(is_cursor_stream_json_output "$output_file") || {
377
445
  echo "text"
@@ -396,14 +464,84 @@ trim_shell_whitespace() {
396
464
  printf '%s' "$value"
397
465
  }
398
466
 
467
+ extract_ralph_status_block_json() {
468
+ local text=$1
469
+ local normalized="${text//$'\r'/}"
470
+
471
+ if [[ "$normalized" != *"---RALPH_STATUS---"* ]]; then
472
+ return 1
473
+ fi
474
+
475
+ local block="${normalized#*---RALPH_STATUS---}"
476
+ if [[ "$block" == "$normalized" ]]; then
477
+ return 1
478
+ fi
479
+
480
+ if [[ "$block" == *"---END_RALPH_STATUS---"* ]]; then
481
+ block="${block%%---END_RALPH_STATUS---*}"
482
+ fi
483
+
484
+ local status=""
485
+ local exit_signal="false"
486
+ local exit_signal_found="false"
487
+ local tasks_completed_this_loop=0
488
+ local tests_status="UNKNOWN"
489
+ local line=""
490
+ local trimmed=""
491
+ local value=""
492
+
493
+ while IFS= read -r line; do
494
+ trimmed=$(trim_shell_whitespace "$line")
495
+
496
+ case "$trimmed" in
497
+ STATUS:*)
498
+ value=$(trim_shell_whitespace "${trimmed#STATUS:}")
499
+ [[ -n "$value" ]] && status="$value"
500
+ ;;
501
+ EXIT_SIGNAL:*)
502
+ value=$(trim_shell_whitespace "${trimmed#EXIT_SIGNAL:}")
503
+ if [[ "$value" == "true" || "$value" == "false" ]]; then
504
+ exit_signal="$value"
505
+ exit_signal_found="true"
506
+ fi
507
+ ;;
508
+ TASKS_COMPLETED_THIS_LOOP:*)
509
+ value=$(trim_shell_whitespace "${trimmed#TASKS_COMPLETED_THIS_LOOP:}")
510
+ if [[ "$value" =~ ^-?[0-9]+$ ]]; then
511
+ tasks_completed_this_loop=$value
512
+ fi
513
+ ;;
514
+ TESTS_STATUS:*)
515
+ value=$(trim_shell_whitespace "${trimmed#TESTS_STATUS:}")
516
+ [[ -n "$value" ]] && tests_status="$value"
517
+ ;;
518
+ esac
519
+ done <<< "$block"
520
+
521
+ jq -n \
522
+ --arg status "$status" \
523
+ --argjson exit_signal_found "$exit_signal_found" \
524
+ --argjson exit_signal "$exit_signal" \
525
+ --argjson tasks_completed_this_loop "$tasks_completed_this_loop" \
526
+ --arg tests_status "$tests_status" \
527
+ '{
528
+ status: $status,
529
+ exit_signal_found: $exit_signal_found,
530
+ exit_signal: $exit_signal,
531
+ tasks_completed_this_loop: $tasks_completed_this_loop,
532
+ tests_status: $tests_status
533
+ }'
534
+ }
535
+
399
536
  # Parse JSON response and extract structured fields
400
537
  # Creates .ralph/.json_parse_result with normalized analysis data
401
- # Supports FIVE JSON formats:
538
+ # Supports SIX JSON formats:
402
539
  # 1. Flat format: { status, exit_signal, work_type, files_modified, ... }
403
540
  # 2. Claude CLI object format: { result, sessionId, metadata: { files_changed, has_errors, completion_status, ... } }
404
541
  # 3. Claude CLI array format: [ {type: "system", ...}, {type: "assistant", ...}, {type: "result", ...} ]
405
542
  # 4. Codex JSONL format: {"type":"thread.started",...}\n{"type":"item.completed","item":{...}}
406
- # 5. Cursor stream-json format: {"type":"assistant",...}\n{"type":"result",...}
543
+ # 5. OpenCode JSON event format: {"type":"session.created",...}\n{"type":"message.updated",...}
544
+ # 6. Cursor stream-json format: {"type":"assistant",...}\n{"type":"result",...}
407
545
  parse_json_response() {
408
546
  local output_file=$1
409
547
  local result_file="${2:-$RALPH_DIR/.json_parse_result}"
@@ -441,112 +579,173 @@ parse_json_response() {
441
579
  output_file="$normalized_file"
442
580
 
443
581
  if [[ "$response_shape" == "jsonl" ]]; then
444
- if is_codex_jsonl_output "$original_output_file" >/dev/null 2>&1; then
582
+ if [[ "$(is_codex_jsonl_output "$original_output_file")" == "true" ]]; then
445
583
  response_shape="codex_jsonl"
584
+ elif [[ "$(is_opencode_jsonl_output "$original_output_file")" == "true" ]]; then
585
+ response_shape="opencode_jsonl"
446
586
  else
447
587
  response_shape="cursor_stream_jsonl"
448
588
  fi
449
589
  fi
450
590
  fi
451
591
 
452
- # Detect JSON format by checking for Claude CLI fields
453
- local has_result_field=$(jq -r -j 'has("result")' "$output_file" 2>/dev/null)
592
+ local has_result_field="false"
593
+ local status="UNKNOWN"
594
+ local completion_status=""
595
+ local exit_signal="false"
596
+ local explicit_exit_signal_found="false"
597
+ local tasks_completed_this_loop=0
598
+ local tests_status="UNKNOWN"
599
+ local result_text=""
600
+ local work_type="UNKNOWN"
601
+ local files_modified=0
602
+ local error_count=0
603
+ local has_errors="false"
604
+ local summary=""
605
+ local session_id=""
606
+ local loop_number=0
607
+ local confidence=0
608
+ local progress_count=0
609
+ local permission_denial_count=0
610
+ local has_permission_denials="false"
611
+ local denied_commands_json="[]"
454
612
 
455
- # Extract fields - support both flat format and Claude CLI format
456
- # Priority: Claude CLI fields first, then flat format fields
613
+ if [[ "$response_shape" == "codex_jsonl" || "$response_shape" == "opencode_jsonl" || "$response_shape" == "cursor_stream_jsonl" ]]; then
614
+ local driver_fields=""
615
+ driver_fields=$(jq -r '
616
+ [
617
+ (.result // ""),
618
+ (.sessionId // .metadata.session_id // .session_id // ""),
619
+ ((.permission_denials // []) | length),
620
+ ((.permission_denials // []) | map(
621
+ if .tool_name == "Bash" then
622
+ "Bash(\(.tool_input.command // "?" | split("\n")[0] | .[0:60]))"
623
+ else
624
+ .tool_name // "unknown"
625
+ end
626
+ ) | @json)
627
+ ] | @tsv
628
+ ' "$output_file" 2>/dev/null)
629
+
630
+ local denied_commands_field="[]"
631
+ IFS=$'\t' read -r result_text session_id permission_denial_count denied_commands_field <<< "$driver_fields"
632
+
633
+ has_result_field="true"
634
+ summary="$result_text"
635
+ denied_commands_json="${denied_commands_field:-[]}"
636
+
637
+ if [[ ! "$permission_denial_count" =~ ^-?[0-9]+$ ]]; then
638
+ permission_denial_count=0
639
+ fi
457
640
 
458
- # Status: from flat format OR derived from metadata.completion_status
459
- local status=$(jq -r -j '.status // "UNKNOWN"' "$output_file" 2>/dev/null)
460
- local completion_status=$(jq -r -j '.metadata.completion_status // ""' "$output_file" 2>/dev/null)
461
- if [[ "$completion_status" == "complete" || "$completion_status" == "COMPLETE" ]]; then
462
- status="COMPLETE"
463
- fi
641
+ if [[ $permission_denial_count -gt 0 ]]; then
642
+ has_permission_denials="true"
643
+ fi
644
+ else
645
+ # Detect JSON format by checking for Claude CLI fields
646
+ has_result_field=$(jq -r -j 'has("result")' "$output_file" 2>/dev/null)
464
647
 
465
- # Exit signal: from flat format OR derived from completion_status
466
- # Track whether EXIT_SIGNAL was explicitly provided (vs inferred from STATUS)
467
- local exit_signal=$(jq -r -j '.exit_signal // false' "$output_file" 2>/dev/null)
468
- local explicit_exit_signal_found=$(jq -r -j 'has("exit_signal")' "$output_file" 2>/dev/null)
469
-
470
- # Bug #1 Fix: If exit_signal is still false, check for RALPH_STATUS block in .result field
471
- # Claude CLI JSON format embeds the RALPH_STATUS block within the .result text field
472
- if [[ "$exit_signal" == "false" && "$has_result_field" == "true" ]]; then
473
- local result_text=$(jq -r -j '.result // ""' "$output_file" 2>/dev/null)
474
- if [[ -n "$result_text" ]] && echo "$result_text" | grep -q -- "---RALPH_STATUS---"; then
475
- # Extract EXIT_SIGNAL value from RALPH_STATUS block within result text
476
- local embedded_exit_sig
477
- embedded_exit_sig=$(trim_shell_whitespace "$(printf '%s\n' "$result_text" | grep "EXIT_SIGNAL:" | cut -d: -f2)")
478
- if [[ -n "$embedded_exit_sig" ]]; then
479
- # Explicit EXIT_SIGNAL found in RALPH_STATUS block
480
- explicit_exit_signal_found="true"
481
- if [[ "$embedded_exit_sig" == "true" ]]; then
482
- exit_signal="true"
483
- [[ "${VERBOSE_PROGRESS:-}" == "true" ]] && echo "DEBUG: Extracted EXIT_SIGNAL=true from .result RALPH_STATUS block" >&2
484
- else
485
- exit_signal="false"
486
- [[ "${VERBOSE_PROGRESS:-}" == "true" ]] && echo "DEBUG: Extracted EXIT_SIGNAL=false from .result RALPH_STATUS block (respecting explicit intent)" >&2
487
- fi
488
- fi
489
- # Also check STATUS field as fallback ONLY when EXIT_SIGNAL was not specified
490
- # This respects explicit EXIT_SIGNAL: false which means "task complete, continue working"
491
- local embedded_status
492
- embedded_status=$(trim_shell_whitespace "$(printf '%s\n' "$result_text" | grep "STATUS:" | cut -d: -f2)")
493
- if [[ "$embedded_status" == "COMPLETE" && "$explicit_exit_signal_found" != "true" ]]; then
494
- # STATUS: COMPLETE without any EXIT_SIGNAL field implies completion
495
- exit_signal="true"
496
- [[ "${VERBOSE_PROGRESS:-}" == "true" ]] && echo "DEBUG: Inferred EXIT_SIGNAL=true from .result STATUS=COMPLETE (no explicit EXIT_SIGNAL found)" >&2
497
- fi
648
+ # Extract fields - support both flat format and Claude CLI format
649
+ # Priority: Claude CLI fields first, then flat format fields
650
+
651
+ # Status: from flat format OR derived from metadata.completion_status
652
+ status=$(jq -r -j '.status // "UNKNOWN"' "$output_file" 2>/dev/null)
653
+ completion_status=$(jq -r -j '.metadata.completion_status // ""' "$output_file" 2>/dev/null)
654
+ if [[ "$completion_status" == "complete" || "$completion_status" == "COMPLETE" ]]; then
655
+ status="COMPLETE"
498
656
  fi
499
- fi
500
657
 
501
- # Work type: from flat format
502
- local work_type=$(jq -r -j '.work_type // "UNKNOWN"' "$output_file" 2>/dev/null)
503
-
504
- # Files modified: from flat format OR from metadata.files_changed
505
- local files_modified=$(jq -r -j '.metadata.files_changed // .files_modified // 0' "$output_file" 2>/dev/null)
506
-
507
- # Error count: from flat format OR derived from metadata.has_errors
508
- # Note: When only has_errors=true is present (without explicit error_count),
509
- # we set error_count=1 as a minimum. This is defensive programming since
510
- # the stuck detection threshold is >5 errors, so 1 error won't trigger it.
511
- # Actual error count may be higher, but precise count isn't critical for our logic.
512
- local error_count=$(jq -r -j '.error_count // 0' "$output_file" 2>/dev/null)
513
- local has_errors=$(jq -r -j '.metadata.has_errors // false' "$output_file" 2>/dev/null)
514
- if [[ "$has_errors" == "true" && "$error_count" == "0" ]]; then
515
- error_count=1 # At least one error if has_errors is true
516
- fi
658
+ # Exit signal: from flat format OR derived from completion_status
659
+ # Track whether EXIT_SIGNAL was explicitly provided (vs inferred from STATUS)
660
+ exit_signal=$(jq -r -j '.exit_signal // false' "$output_file" 2>/dev/null)
661
+ explicit_exit_signal_found=$(jq -r -j 'has("exit_signal")' "$output_file" 2>/dev/null)
662
+ tasks_completed_this_loop=$(jq -r -j '.tasks_completed_this_loop // 0' "$output_file" 2>/dev/null)
663
+ if [[ ! "$tasks_completed_this_loop" =~ ^-?[0-9]+$ ]]; then
664
+ tasks_completed_this_loop=0
665
+ fi
517
666
 
518
- # Summary: from flat format OR from result field (Claude CLI format)
519
- local summary=$(jq -r -j '.result // .summary // ""' "$output_file" 2>/dev/null)
667
+ if [[ "$has_result_field" == "true" ]]; then
668
+ result_text=$(jq -r -j '.result // ""' "$output_file" 2>/dev/null)
669
+ fi
520
670
 
521
- # Session ID: from Claude CLI format (sessionId) OR from metadata.session_id
522
- local session_id=$(jq -r -j '.sessionId // .metadata.session_id // .session_id // ""' "$output_file" 2>/dev/null)
671
+ # Work type: from flat format
672
+ work_type=$(jq -r -j '.work_type // "UNKNOWN"' "$output_file" 2>/dev/null)
673
+
674
+ # Files modified: from flat format OR from metadata.files_changed
675
+ files_modified=$(jq -r -j '.metadata.files_changed // .files_modified // 0' "$output_file" 2>/dev/null)
676
+
677
+ # Error count: from flat format OR derived from metadata.has_errors
678
+ # Note: When only has_errors=true is present (without explicit error_count),
679
+ # we set error_count=1 as a minimum. This is defensive programming since
680
+ # the stuck detection threshold is >5 errors, so 1 error won't trigger it.
681
+ # Actual error count may be higher, but precise count isn't critical for our logic.
682
+ error_count=$(jq -r -j '.error_count // 0' "$output_file" 2>/dev/null)
683
+ has_errors=$(jq -r -j '.metadata.has_errors // false' "$output_file" 2>/dev/null)
684
+ if [[ "$has_errors" == "true" && "$error_count" == "0" ]]; then
685
+ error_count=1 # At least one error if has_errors is true
686
+ fi
523
687
 
524
- # Loop number: from metadata
525
- local loop_number=$(jq -r -j '.metadata.loop_number // .loop_number // 0' "$output_file" 2>/dev/null)
688
+ # Summary: from flat format OR from result field (Claude CLI format)
689
+ summary=$(jq -r -j '.result // .summary // ""' "$output_file" 2>/dev/null)
526
690
 
527
- # Confidence: from flat format
528
- local confidence=$(jq -r -j '.confidence // 0' "$output_file" 2>/dev/null)
691
+ # Session ID: from Claude CLI format (sessionId) OR from metadata.session_id
692
+ session_id=$(jq -r -j '.sessionId // .metadata.session_id // .session_id // ""' "$output_file" 2>/dev/null)
529
693
 
530
- # Progress indicators: from Claude CLI metadata (optional)
531
- local progress_count=$(jq -r -j '.metadata.progress_indicators | if . then length else 0 end' "$output_file" 2>/dev/null)
694
+ # Loop number: from metadata
695
+ loop_number=$(jq -r -j '.metadata.loop_number // .loop_number // 0' "$output_file" 2>/dev/null)
532
696
 
533
- # Permission denials: from Claude Code output (Issue #101)
534
- # When Claude Code is denied permission to run commands, it outputs a permission_denials array
535
- local permission_denial_count=$(jq -r -j '.permission_denials | if . then length else 0 end' "$output_file" 2>/dev/null)
536
- permission_denial_count=$((permission_denial_count + 0)) # Ensure integer
697
+ # Confidence: from flat format
698
+ confidence=$(jq -r -j '.confidence // 0' "$output_file" 2>/dev/null)
537
699
 
538
- local has_permission_denials="false"
539
- if [[ $permission_denial_count -gt 0 ]]; then
540
- has_permission_denials="true"
700
+ # Progress indicators: from Claude CLI metadata (optional)
701
+ progress_count=$(jq -r -j '.metadata.progress_indicators | if . then length else 0 end' "$output_file" 2>/dev/null)
702
+
703
+ # Permission denials: from Claude Code output (Issue #101)
704
+ # When Claude Code is denied permission to run commands, it outputs a permission_denials array
705
+ permission_denial_count=$(jq -r -j '.permission_denials | if . then length else 0 end' "$output_file" 2>/dev/null)
706
+ permission_denial_count=$((permission_denial_count + 0)) # Ensure integer
707
+
708
+ if [[ $permission_denial_count -gt 0 ]]; then
709
+ has_permission_denials="true"
710
+ fi
711
+
712
+ # Extract denied tool names and commands for logging/display
713
+ # Shows tool_name for non-Bash tools, and for Bash tools shows the command that was denied
714
+ # This handles both cases: AskUserQuestion denial shows "AskUserQuestion",
715
+ # while Bash denial shows "Bash(git commit -m ...)" with truncated command
716
+ if [[ $permission_denial_count -gt 0 ]]; then
717
+ denied_commands_json=$(jq -r -j '[.permission_denials[] | if .tool_name == "Bash" then "Bash(\(.tool_input.command // "?" | split("\n")[0] | .[0:60]))" else .tool_name // "unknown" end]' "$output_file" 2>/dev/null || echo "[]")
718
+ fi
541
719
  fi
542
720
 
543
- # Extract denied tool names and commands for logging/display
544
- # Shows tool_name for non-Bash tools, and for Bash tools shows the command that was denied
545
- # This handles both cases: AskUserQuestion denial shows "AskUserQuestion",
546
- # while Bash denial shows "Bash(git commit -m ...)" with truncated command
547
- local denied_commands_json="[]"
548
- if [[ $permission_denial_count -gt 0 ]]; then
549
- denied_commands_json=$(jq -r -j '[.permission_denials[] | if .tool_name == "Bash" then "Bash(\(.tool_input.command // "?" | split("\n")[0] | .[0:60]))" else .tool_name // "unknown" end]' "$output_file" 2>/dev/null || echo "[]")
721
+ local ralph_status_json=""
722
+ if [[ -n "$result_text" ]] && ralph_status_json=$(extract_ralph_status_block_json "$result_text" 2>/dev/null); then
723
+ local embedded_exit_signal_found
724
+ embedded_exit_signal_found=$(printf '%s' "$ralph_status_json" | jq -r -j '.exit_signal_found' 2>/dev/null)
725
+ local embedded_exit_sig
726
+ embedded_exit_sig=$(printf '%s' "$ralph_status_json" | jq -r -j '.exit_signal' 2>/dev/null)
727
+ local embedded_status
728
+ embedded_status=$(printf '%s' "$ralph_status_json" | jq -r -j '.status' 2>/dev/null)
729
+ local embedded_tasks_completed
730
+ embedded_tasks_completed=$(printf '%s' "$ralph_status_json" | jq -r -j '.tasks_completed_this_loop' 2>/dev/null)
731
+ local embedded_tests_status
732
+ embedded_tests_status=$(printf '%s' "$ralph_status_json" | jq -r -j '.tests_status' 2>/dev/null)
733
+
734
+ if [[ "$embedded_tasks_completed" =~ ^-?[0-9]+$ ]]; then
735
+ tasks_completed_this_loop=$embedded_tasks_completed
736
+ fi
737
+ if [[ -n "$embedded_tests_status" && "$embedded_tests_status" != "null" ]]; then
738
+ tests_status="$embedded_tests_status"
739
+ fi
740
+
741
+ if [[ "$embedded_exit_signal_found" == "true" ]]; then
742
+ explicit_exit_signal_found="true"
743
+ exit_signal="$embedded_exit_sig"
744
+ [[ "${VERBOSE_PROGRESS:-}" == "true" ]] && echo "DEBUG: Extracted EXIT_SIGNAL=$embedded_exit_sig from .result RALPH_STATUS block" >&2
745
+ elif [[ "$embedded_status" == "COMPLETE" && "$explicit_exit_signal_found" != "true" ]]; then
746
+ exit_signal="true"
747
+ [[ "${VERBOSE_PROGRESS:-}" == "true" ]] && echo "DEBUG: Inferred EXIT_SIGNAL=true from .result STATUS=COMPLETE (no explicit EXIT_SIGNAL found)" >&2
748
+ fi
550
749
  fi
551
750
 
552
751
  # Heuristic permission-denial matching is limited to the refusal-shaped
@@ -561,7 +760,7 @@ parse_json_response() {
561
760
  # completion markers are absent. This keeps JSONL analysis aligned with text mode.
562
761
  local summary_has_completion_keyword="false"
563
762
  local summary_has_no_work_pattern="false"
564
- if [[ "$response_shape" == "codex_jsonl" || "$response_shape" == "cursor_stream_jsonl" ]] && [[ "$explicit_exit_signal_found" != "true" && -n "$summary" ]]; then
763
+ if [[ "$response_shape" == "codex_jsonl" || "$response_shape" == "opencode_jsonl" || "$response_shape" == "cursor_stream_jsonl" ]] && [[ "$explicit_exit_signal_found" != "true" && -n "$summary" ]]; then
565
764
  for keyword in "${COMPLETION_KEYWORDS[@]}"; do
566
765
  if echo "$summary" | grep -qi "$keyword"; then
567
766
  summary_has_completion_keyword="true"
@@ -640,9 +839,11 @@ parse_json_response() {
640
839
  --argjson loop_number "$loop_number" \
641
840
  --arg session_id "$session_id" \
642
841
  --argjson confidence "$confidence" \
842
+ --argjson tasks_completed_this_loop "$tasks_completed_this_loop" \
643
843
  --argjson has_permission_denials "$has_permission_denials" \
644
844
  --argjson permission_denial_count "$permission_denial_count" \
645
845
  --argjson denied_commands "$denied_commands_json" \
846
+ --arg tests_status "$tests_status" \
646
847
  '{
647
848
  status: $status,
648
849
  exit_signal: $exit_signal,
@@ -655,6 +856,8 @@ parse_json_response() {
655
856
  loop_number: $loop_number,
656
857
  session_id: $session_id,
657
858
  confidence: $confidence,
859
+ tasks_completed_this_loop: $tasks_completed_this_loop,
860
+ tests_status: $tests_status,
658
861
  has_permission_denials: $has_permission_denials,
659
862
  permission_denial_count: $permission_denial_count,
660
863
  denied_commands: $denied_commands,
@@ -687,6 +890,8 @@ analyze_response() {
687
890
  local exit_signal=false
688
891
  local work_summary=""
689
892
  local files_modified=0
893
+ local tasks_completed_this_loop=0
894
+ local tests_status="UNKNOWN"
690
895
 
691
896
  # Read output file
692
897
  if [[ ! -f "$output_file" ]]; then
@@ -712,6 +917,8 @@ analyze_response() {
712
917
  is_stuck=$(jq -r -j '.is_stuck' "$json_parse_result_file" 2>/dev/null || echo "false")
713
918
  work_summary=$(jq -r -j '.summary' "$json_parse_result_file" 2>/dev/null || echo "")
714
919
  files_modified=$(jq -r -j '.files_modified' "$json_parse_result_file" 2>/dev/null || echo "0")
920
+ tasks_completed_this_loop=$(jq -r -j '.tasks_completed_this_loop // 0' "$json_parse_result_file" 2>/dev/null || echo "0")
921
+ tests_status=$(jq -r -j '.tests_status // "UNKNOWN"' "$json_parse_result_file" 2>/dev/null || echo "UNKNOWN")
715
922
  local json_confidence=$(jq -r -j '.confidence' "$json_parse_result_file" 2>/dev/null || echo "0")
716
923
  local session_id=$(jq -r -j '.session_id' "$json_parse_result_file" 2>/dev/null || echo "")
717
924
 
@@ -733,6 +940,10 @@ analyze_response() {
733
940
  confidence_score=$((json_confidence + 50))
734
941
  fi
735
942
 
943
+ if [[ ! "$tasks_completed_this_loop" =~ ^-?[0-9]+$ ]]; then
944
+ tasks_completed_this_loop=0
945
+ fi
946
+
736
947
  # Check for file changes via git (supplements JSON data)
737
948
  # Fix #141: Detect both uncommitted changes AND committed changes
738
949
  if command -v git &>/dev/null && git rev-parse --git-dir >/dev/null 2>&1; then
@@ -784,11 +995,13 @@ analyze_response() {
784
995
  --argjson files_modified "$files_modified" \
785
996
  --argjson confidence_score "$confidence_score" \
786
997
  --argjson exit_signal "$exit_signal" \
998
+ --argjson tasks_completed_this_loop "$tasks_completed_this_loop" \
787
999
  --arg work_summary "$work_summary" \
788
1000
  --argjson output_length "$output_length" \
789
1001
  --argjson has_permission_denials "$has_permission_denials" \
790
1002
  --argjson permission_denial_count "$permission_denial_count" \
791
1003
  --argjson denied_commands "$denied_commands_json" \
1004
+ --arg tests_status "$tests_status" \
792
1005
  '{
793
1006
  loop_number: $loop_number,
794
1007
  timestamp: $timestamp,
@@ -802,6 +1015,10 @@ analyze_response() {
802
1015
  files_modified: $files_modified,
803
1016
  confidence_score: $confidence_score,
804
1017
  exit_signal: $exit_signal,
1018
+ tasks_completed_this_loop: $tasks_completed_this_loop,
1019
+ tests_status: $tests_status,
1020
+ fix_plan_completed_delta: 0,
1021
+ has_progress_tracking_mismatch: false,
805
1022
  work_summary: $work_summary,
806
1023
  output_length: $output_length,
807
1024
  has_permission_denials: $has_permission_denials,
@@ -823,13 +1040,28 @@ analyze_response() {
823
1040
  local explicit_exit_signal_found=false
824
1041
 
825
1042
  # 1. Check for explicit structured output (if Claude follows schema)
826
- if grep -q -- "---RALPH_STATUS---" "$output_file"; then
827
- # Parse structured output
828
- local status=$(trim_shell_whitespace "$(grep "STATUS:" "$output_file" | cut -d: -f2)")
829
- local exit_sig=$(trim_shell_whitespace "$(grep "EXIT_SIGNAL:" "$output_file" | cut -d: -f2)")
1043
+ local ralph_status_json=""
1044
+ if ralph_status_json=$(extract_ralph_status_block_json "$output_content" 2>/dev/null); then
1045
+ local status
1046
+ status=$(printf '%s' "$ralph_status_json" | jq -r -j '.status' 2>/dev/null)
1047
+ local exit_sig_found
1048
+ exit_sig_found=$(printf '%s' "$ralph_status_json" | jq -r -j '.exit_signal_found' 2>/dev/null)
1049
+ local exit_sig
1050
+ exit_sig=$(printf '%s' "$ralph_status_json" | jq -r -j '.exit_signal' 2>/dev/null)
1051
+ local parsed_tasks_completed
1052
+ parsed_tasks_completed=$(printf '%s' "$ralph_status_json" | jq -r -j '.tasks_completed_this_loop' 2>/dev/null)
1053
+ local parsed_tests_status
1054
+ parsed_tests_status=$(printf '%s' "$ralph_status_json" | jq -r -j '.tests_status' 2>/dev/null)
1055
+
1056
+ if [[ "$parsed_tasks_completed" =~ ^-?[0-9]+$ ]]; then
1057
+ tasks_completed_this_loop=$parsed_tasks_completed
1058
+ fi
1059
+ if [[ -n "$parsed_tests_status" && "$parsed_tests_status" != "null" ]]; then
1060
+ tests_status="$parsed_tests_status"
1061
+ fi
830
1062
 
831
1063
  # If EXIT_SIGNAL is explicitly provided, respect it
832
- if [[ -n "$exit_sig" ]]; then
1064
+ if [[ "$exit_sig_found" == "true" ]]; then
833
1065
  explicit_exit_signal_found=true
834
1066
  if [[ "$exit_sig" == "true" ]]; then
835
1067
  has_completion_signal=true
@@ -1002,11 +1234,13 @@ analyze_response() {
1002
1234
  --argjson files_modified "$files_modified" \
1003
1235
  --argjson confidence_score "$confidence_score" \
1004
1236
  --argjson exit_signal "$exit_signal" \
1237
+ --argjson tasks_completed_this_loop "$tasks_completed_this_loop" \
1005
1238
  --arg work_summary "$work_summary" \
1006
1239
  --argjson output_length "$output_length" \
1007
1240
  --argjson has_permission_denials "$has_permission_denials" \
1008
1241
  --argjson permission_denial_count "$permission_denial_count" \
1009
1242
  --argjson denied_commands "$denied_commands_json" \
1243
+ --arg tests_status "$tests_status" \
1010
1244
  '{
1011
1245
  loop_number: $loop_number,
1012
1246
  timestamp: $timestamp,
@@ -1020,6 +1254,10 @@ analyze_response() {
1020
1254
  files_modified: $files_modified,
1021
1255
  confidence_score: $confidence_score,
1022
1256
  exit_signal: $exit_signal,
1257
+ tasks_completed_this_loop: $tasks_completed_this_loop,
1258
+ tests_status: $tests_status,
1259
+ fix_plan_completed_delta: 0,
1260
+ has_progress_tracking_mismatch: false,
1023
1261
  work_summary: $work_summary,
1024
1262
  output_length: $output_length,
1025
1263
  has_permission_denials: $has_permission_denials,
@@ -1049,6 +1287,7 @@ update_exit_signals() {
1049
1287
  local loop_number=$(jq -r -j '.loop_number' "$analysis_file")
1050
1288
  local has_progress=$(jq -r -j '.analysis.has_progress' "$analysis_file")
1051
1289
  local has_permission_denials=$(jq -r -j '.analysis.has_permission_denials // false' "$analysis_file")
1290
+ local has_progress_tracking_mismatch=$(jq -r -j '.analysis.has_progress_tracking_mismatch // false' "$analysis_file")
1052
1291
 
1053
1292
  # Read current exit signals
1054
1293
  local signals=$(cat "$exit_signals_file" 2>/dev/null || echo '{"test_only_loops": [], "done_signals": [], "completion_indicators": []}')
@@ -1065,7 +1304,7 @@ update_exit_signals() {
1065
1304
 
1066
1305
  # Permission denials are handled in the same loop, so they must not become
1067
1306
  # completion state that can halt the next loop.
1068
- if [[ "$has_permission_denials" != "true" && "$has_completion_signal" == "true" ]]; then
1307
+ if [[ "$has_permission_denials" != "true" && "$has_progress_tracking_mismatch" != "true" && "$has_completion_signal" == "true" ]]; then
1069
1308
  signals=$(echo "$signals" | jq ".done_signals += [$loop_number]")
1070
1309
  fi
1071
1310
 
@@ -1074,7 +1313,7 @@ update_exit_signals() {
1074
1313
  # due to deterministic scoring (+50 for JSON format, +20 for result field).
1075
1314
  # This caused premature exits after 5 loops. Now we respect Claude's explicit intent.
1076
1315
  local exit_signal=$(jq -r -j '.analysis.exit_signal // false' "$analysis_file")
1077
- if [[ "$has_permission_denials" != "true" && "$exit_signal" == "true" ]]; then
1316
+ if [[ "$has_permission_denials" != "true" && "$has_progress_tracking_mismatch" != "true" && "$exit_signal" == "true" ]]; then
1078
1317
  signals=$(echo "$signals" | jq ".completion_indicators += [$loop_number]")
1079
1318
  fi
1080
1319
 
@@ -1294,8 +1533,10 @@ export -f detect_output_format
1294
1533
  export -f count_json_documents
1295
1534
  export -f normalize_cli_array_response
1296
1535
  export -f normalize_codex_jsonl_response
1536
+ export -f normalize_opencode_jsonl_response
1297
1537
  export -f normalize_cursor_stream_json_response
1298
1538
  export -f is_codex_jsonl_output
1539
+ export -f is_opencode_jsonl_output
1299
1540
  export -f is_cursor_stream_json_output
1300
1541
  export -f normalize_json_output
1301
1542
  export -f extract_session_id_from_output
@@ -36,7 +36,7 @@ confirm() {
36
36
  local response
37
37
 
38
38
  local yn_hint="[y/N]"
39
- if [[ "${default,,}" == "y" ]]; then
39
+ if [[ "$default" == [yY] ]]; then
40
40
  yn_hint="[Y/n]"
41
41
  fi
42
42
 
@@ -50,11 +50,11 @@ confirm() {
50
50
  response="$default"
51
51
  fi
52
52
 
53
- case "${response,,}" in
54
- y|yes)
53
+ case "$response" in
54
+ [yY]|[yY][eE][sS])
55
55
  return 0
56
56
  ;;
57
- n|no)
57
+ [nN]|[nN][oO])
58
58
  return 1
59
59
  ;;
60
60
  *)