@guanlin4924/devflow-pi 0.1.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 (254) hide show
  1. package/README.md +164 -0
  2. package/docs/OMP-NATIVE-ARCHITECTURE.md +104 -0
  3. package/package.json +40 -0
  4. package/plugins/devflow-core/extensions/devflow-core.ts +1642 -0
  5. package/plugins/devflow-core/package.json +14 -0
  6. package/plugins/devflow-core/runtime/hooks/context_sync_gate.py +174 -0
  7. package/plugins/devflow-core/runtime/hooks/hook_common.py +696 -0
  8. package/plugins/devflow-core/runtime/hooks/index_gate.py +63 -0
  9. package/plugins/devflow-core/runtime/hooks/injection_code_specification.py +7 -0
  10. package/plugins/devflow-core/runtime/hooks/post_tool.py +44 -0
  11. package/plugins/devflow-core/runtime/hooks/start.py +288 -0
  12. package/plugins/devflow-core/skills/workflow-orchestrator/SKILL.md +265 -0
  13. package/plugins/devflow-core/skills/workflow-orchestrator/agents/openai.yaml +4 -0
  14. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/advance_state.rb +520 -0
  15. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/control_io.rb +42 -0
  16. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/init_state.rb +138 -0
  17. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/init_workflow.rb +121 -0
  18. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/inspect_state.rb +553 -0
  19. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/manage_lessons.rb +219 -0
  20. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/sync_artifacts.rb +168 -0
  21. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/update_triage_route.rb +110 -0
  22. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/validate_state.rb +565 -0
  23. package/plugins/devflow-core/skills/workflow-orchestrator/templates/feature-development.yaml +783 -0
  24. package/plugins/devflow-core/skills/workflow-orchestrator/templates/uat-remediation.yaml +143 -0
  25. package/plugins/devflow-core/skills/workflow-orchestrator/templates/workflows-README.md +10 -0
  26. package/plugins/devflow-core/skills/workflow-pipeline/SKILL.md +117 -0
  27. package/plugins/devflow-core/skills/workflow-pipeline/references/pipeline-flow.md +167 -0
  28. package/plugins/devflow-core/skills/workflow-pipeline/references/slice-safety-guide.md +125 -0
  29. package/plugins/devflow-core/skills/workflow-project-context/SKILL.md +819 -0
  30. package/plugins/devflow-core/skills/workflow-project-context/assets/agents-md-template.md +25 -0
  31. package/plugins/devflow-core/skills/workflow-project-context/assets/codebase-backend-spec-template.md +68 -0
  32. package/plugins/devflow-core/skills/workflow-project-context/assets/codebase-frontend-spec-template.md +64 -0
  33. package/plugins/devflow-core/skills/workflow-project-context/assets/codebase-navigation-template.md +168 -0
  34. package/plugins/devflow-core/skills/workflow-project-context/assets/context-domain-index-template.md +43 -0
  35. package/plugins/devflow-core/skills/workflow-project-context/assets/context-spec-index-template.md +45 -0
  36. package/plugins/devflow-core/skills/workflow-project-context/assets/execution-contract-template.md +57 -0
  37. package/plugins/devflow-core/skills/workflow-project-context/assets/navigation-index-template.md +40 -0
  38. package/plugins/devflow-core/skills/workflow-project-context/assets/project-initialization-template.md +109 -0
  39. package/plugins/devflow-core/skills/workflow-project-context/assets/rules-index-template.md +80 -0
  40. package/plugins/devflow-core/skills/workflow-project-context/assets/run-manifest-template.json +40 -0
  41. package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/backend/directory-structure.md +46 -0
  42. package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/backend/engine.md +46 -0
  43. package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/backend/errors.md +46 -0
  44. package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/backend/locator.md +46 -0
  45. package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/backend/model.md +46 -0
  46. package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/backend/repository.md +46 -0
  47. package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/backend/router.md +46 -0
  48. package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/backend/scheduler.md +46 -0
  49. package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/backend/schema.md +46 -0
  50. package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/backend/service.md +46 -0
  51. package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/backend/testing.md +46 -0
  52. package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/frontend/api-client.md +46 -0
  53. package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/frontend/case-editor.md +46 -0
  54. package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/frontend/components.md +46 -0
  55. package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/frontend/directory-structure.md +46 -0
  56. package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/frontend/forms.md +46 -0
  57. package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/frontend/routing.md +46 -0
  58. package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/frontend/state.md +46 -0
  59. package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/frontend/testing.md +46 -0
  60. package/plugins/devflow-core/skills/workflow-project-context/assets/stack-spec-template.md +106 -0
  61. package/plugins/devflow-core/skills/workflow-project-context/assets/state-template.md +77 -0
  62. package/plugins/devflow-core/skills/workflow-project-context/assets/toolchain-template.md +37 -0
  63. package/plugins/devflow-core/skills/workflow-project-context/references/navigation-guide.md +262 -0
  64. package/plugins/devflow-core/skills/workflow-project-context/scripts/validate_initialization.py +545 -0
  65. package/plugins/devflow-design/agents/contract-auditor.md +18 -0
  66. package/plugins/devflow-design/extensions/devflow-design.ts +47 -0
  67. package/plugins/devflow-design/package.json +14 -0
  68. package/plugins/devflow-design/skills/workflow-api-call-guide/SKILL.md +142 -0
  69. package/plugins/devflow-design/skills/workflow-api-contract/SKILL.md +150 -0
  70. package/plugins/devflow-design/skills/workflow-api-supplement/SKILL.md +121 -0
  71. package/plugins/devflow-design/skills/workflow-backend-tech-spec/SKILL.md +257 -0
  72. package/plugins/devflow-design/skills/workflow-backend-tech-spec/assets/adr-template.md +57 -0
  73. package/plugins/devflow-design/skills/workflow-backend-tech-spec/assets/backend-spec-template.md +205 -0
  74. package/plugins/devflow-design/skills/workflow-backend-tech-spec/references/affected-module-exploration.md +59 -0
  75. package/plugins/devflow-design/skills/workflow-backend-tech-spec/references/backend-conventions.md +30 -0
  76. package/plugins/devflow-design/skills/workflow-backend-tech-spec/references/code-explore-guide.md +40 -0
  77. package/plugins/devflow-design/skills/workflow-backend-tech-spec/references/project-rule-contract.md +66 -0
  78. package/plugins/devflow-design/skills/workflow-design-rule-pack/SKILL.md +91 -0
  79. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/index.md +71 -0
  80. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/recommendations/accessibility.md +31 -0
  81. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/recommendations/component-library.md +31 -0
  82. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/recommendations/design-systems.md +47 -0
  83. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/recommendations/responsive-grid.md +29 -0
  84. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/recommendations/stack-guidelines.md +31 -0
  85. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/recommendations/ux-patterns.md +40 -0
  86. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tokens/project-tokens.md +19 -0
  87. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/SKILL.md +377 -0
  88. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/charts.csv +26 -0
  89. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/colors.csv +97 -0
  90. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/icons.csv +101 -0
  91. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/landing.csv +31 -0
  92. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/products.csv +97 -0
  93. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/react-performance.csv +45 -0
  94. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/astro.csv +54 -0
  95. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  96. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  97. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  98. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  99. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  100. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  101. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  102. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/react.csv +54 -0
  103. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  104. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  105. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  106. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  107. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/styles.csv +68 -0
  108. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/typography.csv +58 -0
  109. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  110. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  111. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/web-interface.csv +31 -0
  112. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/scripts/core.py +253 -0
  113. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/scripts/design_system.py +1067 -0
  114. package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/scripts/search.py +114 -0
  115. package/plugins/devflow-design/skills/workflow-design-rule-pack/scripts/install.py +67 -0
  116. package/plugins/devflow-design/skills/workflow-feature-breakdown/SKILL.md +370 -0
  117. package/plugins/devflow-design/skills/workflow-feature-breakdown/assets/admin-system-template.md +57 -0
  118. package/plugins/devflow-design/skills/workflow-feature-breakdown/assets/api-service-template.md +42 -0
  119. package/plugins/devflow-design/skills/workflow-feature-breakdown/assets/c-end-system-template.md +25 -0
  120. package/plugins/devflow-design/skills/workflow-feature-breakdown/assets/output-template.md +139 -0
  121. package/plugins/devflow-design/skills/workflow-feature-breakdown/references/bug-rules.md +12 -0
  122. package/plugins/devflow-design/skills/workflow-feature-breakdown/references/exception-checklist.md +31 -0
  123. package/plugins/devflow-design/skills/workflow-feature-breakdown/references/trace-integrity-guide.md +153 -0
  124. package/plugins/devflow-design/skills/workflow-feature-breakdown/references/writing-guide.md +92 -0
  125. package/plugins/devflow-design/skills/workflow-frontend-tech-spec/SKILL.md +223 -0
  126. package/plugins/devflow-design/skills/workflow-frontend-tech-spec/assets/frontend-spec-template.md +204 -0
  127. package/plugins/devflow-design/skills/workflow-frontend-tech-spec/references/affected-module-exploration.md +58 -0
  128. package/plugins/devflow-design/skills/workflow-frontend-tech-spec/references/component-patterns.md +42 -0
  129. package/plugins/devflow-design/skills/workflow-frontend-tech-spec/references/frontend-conventions.md +28 -0
  130. package/plugins/devflow-design/skills/workflow-frontend-tech-spec/references/frontend-stack-slots/common-web.md +53 -0
  131. package/plugins/devflow-design/skills/workflow-frontend-tech-spec/references/frontend-stack-slots/next.md +40 -0
  132. package/plugins/devflow-design/skills/workflow-frontend-tech-spec/references/frontend-stack-slots/react.md +41 -0
  133. package/plugins/devflow-design/skills/workflow-frontend-tech-spec/references/frontend-stack-slots/vue.md +41 -0
  134. package/plugins/devflow-design/skills/workflow-frontend-tech-spec/references/project-rule-contract.md +95 -0
  135. package/plugins/devflow-design/skills/workflow-integration-verify/SKILL.md +172 -0
  136. package/plugins/devflow-design/skills/workflow-ui-spec/SKILL.md +302 -0
  137. package/plugins/devflow-design/skills/workflow-ui-spec/assets/ui-spec-template.md +244 -0
  138. package/plugins/devflow-design/skills/workflow-ui-spec/references/affected-module-exploration.md +55 -0
  139. package/plugins/devflow-implementation/agents/implementation-worker.md +20 -0
  140. package/plugins/devflow-implementation/package.json +6 -0
  141. package/plugins/devflow-implementation/skills/workflow-bug-fix/SKILL.md +124 -0
  142. package/plugins/devflow-implementation/skills/workflow-bug-fix/references/INDEX.md +13 -0
  143. package/plugins/devflow-implementation/skills/workflow-bug-fix/references/adversarial-review.md +35 -0
  144. package/plugins/devflow-implementation/skills/workflow-bug-fix/references/first-principles.md +26 -0
  145. package/plugins/devflow-implementation/skills/workflow-bug-fix/references/lesson-format.md +28 -0
  146. package/plugins/devflow-implementation/skills/workflow-bug-fix/references/root-cause-ladder.md +51 -0
  147. package/plugins/devflow-implementation/skills/workflow-bug-fix/references/seam-analysis.md +30 -0
  148. package/plugins/devflow-implementation/skills/workflow-change-plan/SKILL.md +160 -0
  149. package/plugins/devflow-implementation/skills/workflow-change-plan/references/code-conventions.md +33 -0
  150. package/plugins/devflow-implementation/skills/workflow-change-plan/references/ddl-guidelines.md +60 -0
  151. package/plugins/devflow-implementation/skills/workflow-change-plan/references/output-template.md +217 -0
  152. package/plugins/devflow-implementation/skills/workflow-change-plan/references/project-rule-contract.md +55 -0
  153. package/plugins/devflow-implementation/skills/workflow-execute-phase/SKILL.md +271 -0
  154. package/plugins/devflow-implementation/skills/workflow-execute-phase/references/execute-phase.md +1251 -0
  155. package/plugins/devflow-implementation/skills/workflow-execute-phase/references/ui-brand.md +160 -0
  156. package/plugins/devflow-intel/agents/project-scout.md +27 -0
  157. package/plugins/devflow-intel/extensions/devflow-intel.ts +104 -0
  158. package/plugins/devflow-intel/package.json +14 -0
  159. package/plugins/devflow-intel/skills/code-index-query/SKILL.md +37 -0
  160. package/plugins/devflow-intel/skills/code-index-query/references/query-patterns.md +27 -0
  161. package/plugins/devflow-intel/skills/workflow-code-index/SKILL.md +68 -0
  162. package/plugins/devflow-intel/skills/workflow-code-index/references/adapter-contract.md +38 -0
  163. package/plugins/devflow-intel/skills/workflow-code-index/references/audit-checklist.md +10 -0
  164. package/plugins/devflow-intel/skills/workflow-code-index/references/confidence-rules.md +43 -0
  165. package/plugins/devflow-intel/skills/workflow-code-index/references/data-model.md +74 -0
  166. package/plugins/devflow-intel/skills/workflow-code-index/references/discovery.md +24 -0
  167. package/plugins/devflow-intel/skills/workflow-code-index/references/query-guide.md +20 -0
  168. package/plugins/devflow-intel/skills/workflow-code-index/scripts/adapters/__init__.py +1 -0
  169. package/plugins/devflow-intel/skills/workflow-code-index/scripts/adapters/base.py +30 -0
  170. package/plugins/devflow-intel/skills/workflow-code-index/scripts/adapters/generic_text.py +287 -0
  171. package/plugins/devflow-intel/skills/workflow-code-index/scripts/adapters/registry.py +17 -0
  172. package/plugins/devflow-intel/skills/workflow-code-index/scripts/code_index.py +437 -0
  173. package/plugins/devflow-intel/skills/workflow-code-index/scripts/core/__init__.py +1 -0
  174. package/plugins/devflow-intel/skills/workflow-code-index/scripts/core/discovery.py +139 -0
  175. package/plugins/devflow-intel/skills/workflow-code-index/scripts/core/hashing.py +11 -0
  176. package/plugins/devflow-intel/skills/workflow-code-index/scripts/core/scanner.py +115 -0
  177. package/plugins/devflow-intel/skills/workflow-code-index/scripts/core/schema.py +123 -0
  178. package/plugins/devflow-intel/skills/workflow-code-index/scripts/validators/__init__.py +1 -0
  179. package/plugins/devflow-intel/skills/workflow-code-index/scripts/validators/project_binding_check.py +66 -0
  180. package/plugins/devflow-intel/skills/workflow-code-index/scripts/validators/relation_check.py +36 -0
  181. package/plugins/devflow-intel/skills/workflow-code-index/scripts/validators/schema_validate.py +11 -0
  182. package/plugins/devflow-intel/skills/workflow-code-index/scripts/validators/stale_check.py +42 -0
  183. package/plugins/devflow-intel/skills/workflow-code-index/scripts/writers/__init__.py +1 -0
  184. package/plugins/devflow-intel/skills/workflow-code-index/scripts/writers/jsonl_writer.py +25 -0
  185. package/plugins/devflow-intel/skills/workflow-code-index/scripts/writers/markdown_writer.py +106 -0
  186. package/plugins/devflow-intel/skills/workflow-code-index/scripts/writers/sqlite_writer.py +143 -0
  187. package/plugins/devflow-intel/skills/workflow-context-sync/SKILL.md +381 -0
  188. package/plugins/devflow-intel/skills/workflow-context-sync/agents/openai.yaml +4 -0
  189. package/plugins/devflow-intel/skills/workflow-context-sync/scripts/context_sync_cursor.py +241 -0
  190. package/plugins/devflow-intel/skills/workflow-update-navigation/SKILL.md +186 -0
  191. package/plugins/devflow-intel/skills/workflow-update-navigation/references/incremental-update-guide.md +47 -0
  192. package/plugins/devflow-quality/agents/code-reviewer.md +18 -0
  193. package/plugins/devflow-quality/agents/verification-runner.md +21 -0
  194. package/plugins/devflow-quality/extensions/devflow-quality.ts +59 -0
  195. package/plugins/devflow-quality/package.json +14 -0
  196. package/plugins/devflow-quality/skills/code-review/SKILL.md +288 -0
  197. package/plugins/devflow-quality/skills/code-review/references/cross-layer-checklist.md +70 -0
  198. package/plugins/devflow-quality/skills/code-review/references/dao-checklist.md +70 -0
  199. package/plugins/devflow-quality/skills/code-review/references/handler-checklist.md +48 -0
  200. package/plugins/devflow-quality/skills/code-review/references/repository-checklist.md +44 -0
  201. package/plugins/devflow-quality/skills/code-review/references/service-checklist.md +57 -0
  202. package/plugins/devflow-quality/skills/code-review/references/spec-checklist.md +34 -0
  203. package/plugins/devflow-quality/skills/code-review/references/vo-checklist.md +26 -0
  204. package/plugins/devflow-quality/skills/workflow-audit-milestone/SKILL.md +31 -0
  205. package/plugins/devflow-quality/skills/workflow-audit-milestone/references/audit-milestone.md +328 -0
  206. package/plugins/devflow-quality/skills/workflow-complete-milestone/SKILL.md +132 -0
  207. package/plugins/devflow-quality/skills/workflow-complete-milestone/assets/milestone-archive.md +123 -0
  208. package/plugins/devflow-quality/skills/workflow-complete-milestone/references/complete-milestone.md +775 -0
  209. package/plugins/devflow-quality/skills/workflow-complete-milestone/references/milestone-archive.md +123 -0
  210. package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/SKILL.md +126 -0
  211. package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/references/api-mainflow-rules.md +27 -0
  212. package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/references/codebase-discovery.md +54 -0
  213. package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/references/intermediate-format.md +244 -0
  214. package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/references/mainflow-selection.md +36 -0
  215. package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/references/project-dsl-contract.md +190 -0
  216. package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/references/ui-mainflow-rules.md +110 -0
  217. package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/scripts/compile_dsl.py +583 -0
  218. package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/scripts/discover_codebases.py +199 -0
  219. package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/scripts/normalize_case_payloads.py +177 -0
  220. package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/scripts/validate_case_payloads.py +370 -0
  221. package/plugins/devflow-quality/skills/workflow-verify-work/SKILL.md +106 -0
  222. package/plugins/devflow-quality/skills/workflow-verify-work/assets/UAT.md +265 -0
  223. package/plugins/devflow-quality/skills/workflow-verify-work/references/verify-work.md +759 -0
  224. package/plugins/devflow-requirements/agents/requirements-auditor.md +20 -0
  225. package/plugins/devflow-requirements/package.json +6 -0
  226. package/plugins/devflow-requirements/skills/requirement-feasibility-review/SKILL.md +219 -0
  227. package/plugins/devflow-requirements/skills/requirement-feasibility-review/agents/openai.yaml +4 -0
  228. package/plugins/devflow-requirements/skills/requirement-feasibility-review/references/review-method.md +257 -0
  229. package/plugins/devflow-requirements/skills/requirement-feasibility-review/references/review-template.md +80 -0
  230. package/plugins/devflow-requirements/skills/workflow-demand-clarify/SKILL.md +325 -0
  231. package/plugins/devflow-requirements/skills/workflow-domain-modeling/SKILL.md +163 -0
  232. package/plugins/devflow-requirements/skills/workflow-requirement-baseline/SKILL.md +748 -0
  233. package/plugins/devflow-requirements/skills/workflow-requirement-baseline/assets/baseline-template.md +281 -0
  234. package/plugins/devflow-requirements/skills/workflow-requirement-baseline/references/antipatterns.md +69 -0
  235. package/plugins/devflow-requirements/skills/workflow-requirement-baseline/references/challenge-review-guide.md +158 -0
  236. package/plugins/devflow-requirements/skills/workflow-requirement-baseline/references/decomposition-guide.md +115 -0
  237. package/plugins/devflow-requirements/skills/workflow-requirement-baseline/references/project-context-guide.md +119 -0
  238. package/plugins/devflow-requirements/skills/workflow-requirement-baseline/references/questioning.md +76 -0
  239. package/plugins/devflow-requirements/skills/workflow-requirement-baseline/references/requirement-review-checklist.md +115 -0
  240. package/plugins/devflow-requirements/skills/workflow-requirement-triage/SKILL.md +204 -0
  241. package/plugins/devflow-requirements/skills/workflow-wayfinder/SKILL.md +183 -0
  242. package/src/cli.ts +76 -0
  243. package/src/constants.ts +15 -0
  244. package/src/doctor.ts +66 -0
  245. package/src/paths.ts +37 -0
  246. package/src/platform-extension.ts +46 -0
  247. package/src/project-context.ts +165 -0
  248. package/src/runtime.ts +167 -0
  249. package/src/usage-stats.ts +101 -0
  250. package/templates/commands/start.md +58 -0
  251. package/templates/omp/AGENTS.md +36 -0
  252. package/templates/omp/config.yml +112 -0
  253. package/templates/omp/hook-config.json +18 -0
  254. package/templates/omp/index-policy.json +57 -0
@@ -0,0 +1,553 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "json"
5
+ require "optparse"
6
+ require "yaml"
7
+ require_relative "validate_state"
8
+
9
+ options = { json: false, state: nil }
10
+ OptionParser.new do |opts|
11
+ opts.banner = "Usage: inspect_state.rb [--json] [--state PATH]"
12
+ opts.on("--json", "Print JSON output") { options[:json] = true }
13
+ opts.on("--state PATH", "Read an alternate STATE.md file") { |path| options[:state] = path }
14
+ end.parse!
15
+
16
+ root = Dir.pwd
17
+ state_path = options[:state] ? File.expand_path(options[:state], root) : File.join(root, ".planning", "STATE.md")
18
+
19
+ def fail_result(reason, details = {})
20
+ {
21
+ action: "blocked",
22
+ reason: reason,
23
+ details: details
24
+ }
25
+ end
26
+
27
+ def front_matter(markdown)
28
+ match = markdown.match(/\A---\n(.*?)\n---\n/m)
29
+ match && match[1]
30
+ end
31
+
32
+ def load_yaml_file(path)
33
+ YAML.safe_load(File.read(path), permitted_classes: [], aliases: false)
34
+ end
35
+
36
+ def interpolate_path(path, state)
37
+ path
38
+ .gsub("{feature}", state.fetch("current_feature", "").to_s)
39
+ .gsub("{phase}", state.fetch("current_phase", "").to_s)
40
+ end
41
+
42
+ def load_artifact_registry(root, workflow)
43
+ registry_config = workflow["artifact_registry"]
44
+ registry_path = registry_config && registry_config["source"]
45
+ return [{}, nil, nil] if registry_path.nil?
46
+
47
+ abs_registry_path = File.join(root, registry_path)
48
+ return [{}, registry_path, "missing_artifact_registry"] unless File.exist?(abs_registry_path)
49
+
50
+ registry = load_yaml_file(abs_registry_path)
51
+ artifacts = Array(registry["artifacts"])
52
+ by_path = artifacts.to_h { |artifact| [artifact.fetch("path"), artifact] }
53
+ [by_path, registry_path, nil]
54
+ end
55
+
56
+ def project_context_missing?(root)
57
+ required_paths = [
58
+ File.join(root, ".planning", "PROJECT.md"),
59
+ File.join(root, ".planning", "navigation", "INDEX.md"),
60
+ File.join(root, ".context", "spec", "index.md")
61
+ ]
62
+
63
+ required_paths.any? { |path| !File.exist?(path) }
64
+ end
65
+
66
+ def project_context_result(reason, details = {})
67
+ {
68
+ action: "run_project_context",
69
+ reason: reason,
70
+ skill: "workflow-project-context",
71
+ resume_after: "inspect_state"
72
+ }.merge(details)
73
+ end
74
+
75
+ def attach_artifact(output, artifact_by_path)
76
+ artifact = artifact_by_path[output["resolved_path"]]
77
+ output.merge(
78
+ "artifact_status" => artifact && artifact["status"],
79
+ "artifact_type" => artifact && artifact["type"],
80
+ "artifact_workflow_step" => artifact && artifact["workflow_step"],
81
+ "artifact_checkpoint" => artifact && artifact["checkpoint"],
82
+ "artifact_registered" => !artifact.nil?
83
+ )
84
+ end
85
+
86
+ def artifact_registry_summary(root, artifact_by_path)
87
+ artifacts = artifact_by_path.values
88
+ status_counts = artifacts.each_with_object(Hash.new(0)) do |artifact, counts|
89
+ counts[artifact["status"] || "unknown"] += 1
90
+ end
91
+ missing_paths = artifacts
92
+ .map { |artifact| artifact["path"] }
93
+ .compact
94
+ .reject { |path| File.exist?(File.join(root, path)) }
95
+
96
+ {
97
+ "registered_count" => artifacts.length,
98
+ "status_counts" => status_counts.sort.to_h,
99
+ "missing_paths" => missing_paths
100
+ }
101
+ end
102
+
103
+ def output_payload(output, state, root, artifact_by_path)
104
+ resolved = interpolate_path(output.fetch("path"), state)
105
+ artifact = artifact_by_path[resolved]
106
+ {
107
+ "path" => resolved,
108
+ "type" => output["type"],
109
+ "required" => output["required"],
110
+ "exists" => File.exist?(File.join(root, resolved)),
111
+ "artifact_status" => artifact && artifact["status"],
112
+ "artifact_registered" => !artifact.nil?
113
+ }
114
+ end
115
+
116
+ def step_payload(step, state, root, artifact_by_path)
117
+ return nil if step.nil?
118
+
119
+ {
120
+ "id" => step["id"],
121
+ "label" => step["label"],
122
+ "skill" => step["skill"],
123
+ "action" => step["action"],
124
+ "inputs" => Array(step["inputs"]).map { |path| interpolate_path(path, state) },
125
+ "outputs" => Array(step["outputs"]).map { |output| output_payload(output, state, root, artifact_by_path) }
126
+ }
127
+ end
128
+
129
+ def dependencies_satisfied?(step, completed_ids)
130
+ Array(step["depends_on"]).all? { |dependency| completed_ids.include?(dependency) }
131
+ end
132
+
133
+ def active_track(state)
134
+ track = state["active_track"].to_s
135
+ %w[A B].include?(track) ? track : nil
136
+ end
137
+
138
+ def track_allowed_steps(track)
139
+ case track
140
+ when "A"
141
+ %w[requirement-triage requirement-wayfinder domain-modeling requirement-feasibility-review requirement-baseline api-contract backend-tech-spec api-call-guide]
142
+ when "B"
143
+ %w[requirement-triage requirement-wayfinder domain-modeling requirement-feasibility-review requirement-baseline api-contract ui-spec feature-breakdown frontend-tech-spec api-supplement]
144
+ else
145
+ []
146
+ end
147
+ end
148
+
149
+ def next_pending_step_id(state, pending_ids, step_by_id, completed_ids)
150
+ track = active_track(state)
151
+ return pending_ids.first unless track
152
+
153
+ allowed = track_allowed_steps(track)
154
+ pending_ids.find do |step_id|
155
+ allowed.include?(step_id) &&
156
+ step_by_id[step_id] &&
157
+ dependencies_satisfied?(step_by_id[step_id], completed_ids)
158
+ end
159
+ end
160
+
161
+ def track_boundary(state, pending_ids, completed_ids)
162
+ track = active_track(state)
163
+ return nil unless track
164
+
165
+ allowed = track_allowed_steps(track)
166
+ remaining_allowed = pending_ids & allowed
167
+ return nil if remaining_allowed.any?
168
+
169
+ return nil if pending_ids.empty?
170
+
171
+ {
172
+ "reason" => "track_scope_complete",
173
+ "message" => "Track #{track} output scope is complete. Single-track mode cannot enter integration-verify, change-plan, execute, or archive."
174
+ }
175
+ end
176
+
177
+ def active_parallel_window(workflow, state, root, step_by_id, completed_ids, pending_ids, artifact_by_path)
178
+ Array(workflow["parallel_windows"]).each do |window|
179
+ after_step = window["after_step"]
180
+ branch_map = window["branches"].is_a?(Hash) ? window["branches"] : {}
181
+ branch_ids = branch_map.any? ? branch_map.values.flatten : Array(window["branch_steps"])
182
+ track = active_track(state)
183
+ branch_ids &= track_allowed_steps(track) if track
184
+ next unless completed_ids.include?(after_step)
185
+
186
+ runnable_ids = branch_ids.select do |step_id|
187
+ step = step_by_id[step_id]
188
+ pending_ids.include?(step_id) && step && dependencies_satisfied?(step, completed_ids)
189
+ end
190
+ next unless runnable_ids.length > 1
191
+
192
+ policy = window["execution_policy"] || {}
193
+ return {
194
+ "id" => window["id"],
195
+ "label" => window["label"],
196
+ "after_step" => after_step,
197
+ "join_step" => window["join_step"],
198
+ "checkpoint" => window["checkpoint"],
199
+ "mode" => policy["mode"],
200
+ "serial_fallback_order" => Array(policy["serial_fallback_order"]),
201
+ "branches" => branch_map.transform_values do |step_ids|
202
+ Array(step_ids).map { |step_id| step_payload(step_by_id[step_id], state, root, artifact_by_path) }.compact
203
+ end,
204
+ "join_requires" => Array(policy["join_requires"]).map { |path| interpolate_path(path, state) },
205
+ "branch_steps" => runnable_ids.map { |step_id| step_payload(step_by_id[step_id], state, root, artifact_by_path) }
206
+ }
207
+ end
208
+
209
+ nil
210
+ end
211
+
212
+ def active_failure_branch(workflow, state, current_step, current_outputs, root)
213
+ branch = workflow.fetch("failure_branches", {})[current_step["id"]]
214
+ return nil if branch.nil?
215
+
216
+ conditions = branch["trigger_conditions"] || {}
217
+ reasons = []
218
+
219
+ if Array(conditions["state_statuses"]).include?(state["status"])
220
+ reasons << { "source" => "state.status", "value" => state["status"] }
221
+ end
222
+
223
+ checkpoint_decision = state["checkpoint_decision"]
224
+ if checkpoint_decision && Array(conditions["checkpoint_decisions"]).include?(checkpoint_decision)
225
+ reasons << { "source" => "state.checkpoint_decision", "value" => checkpoint_decision }
226
+ end
227
+
228
+ failed_outputs = current_outputs.select do |output|
229
+ Array(conditions["artifact_statuses"]).include?(output["artifact_status"])
230
+ end
231
+ failed_outputs.each do |output|
232
+ reasons << {
233
+ "source" => "artifact.status",
234
+ "path" => output["resolved_path"],
235
+ "value" => output["artifact_status"]
236
+ }
237
+ end
238
+
239
+ return nil if reasons.empty?
240
+
241
+ workflow_config = branch["workflow_config"]
242
+ abs_workflow_config = workflow_config && File.join(root, workflow_config)
243
+ branch_workflow = abs_workflow_config && File.exist?(abs_workflow_config) ? load_yaml_file(abs_workflow_config) : nil
244
+ branch_steps = Array(branch_workflow && branch_workflow["steps"])
245
+ entry_step_id = branch_workflow&.dig("entry", "initial_step") || branch_steps.first&.fetch("id", nil)
246
+
247
+ {
248
+ "id" => branch["id"],
249
+ "label" => branch["label"],
250
+ "workflow" => branch["workflow"],
251
+ "workflow_config" => workflow_config,
252
+ "workflow_config_exists" => abs_workflow_config ? File.exist?(abs_workflow_config) : false,
253
+ "entry_step" => entry_step_id,
254
+ "reason_signals" => reasons,
255
+ "resume_after_success" => branch["resume_after_success"],
256
+ "steps" => branch_steps.map do |step|
257
+ {
258
+ "id" => step["id"],
259
+ "label" => step["label"],
260
+ "skill" => step["skill"],
261
+ "action" => step["action"],
262
+ "depends_on" => Array(step["depends_on"])
263
+ }
264
+ end
265
+ }
266
+ end
267
+
268
+ result =
269
+ if !File.exist?(state_path)
270
+ if project_context_missing?(root)
271
+ project_context_result(
272
+ "missing_project_context",
273
+ path: state_path,
274
+ missing: [
275
+ ".planning/STATE.md",
276
+ ".planning/PROJECT.md",
277
+ ".planning/navigation/INDEX.md",
278
+ ".context/spec/index.md"
279
+ ]
280
+ )
281
+ else
282
+ fail_result(
283
+ "missing_state_file",
284
+ path: state_path,
285
+ recovery: "Call devflow_bootstrap with feature and phase."
286
+ )
287
+ end
288
+ else
289
+ state_doc = File.read(state_path)
290
+ yaml = front_matter(state_doc)
291
+
292
+ if yaml.nil?
293
+ fail_result(
294
+ "missing_state_front_matter",
295
+ path: state_path,
296
+ recovery: "Call devflow_bootstrap with feature, phase, and force=true after reviewing the invalid state."
297
+ )
298
+ else
299
+ state = YAML.safe_load(yaml, permitted_classes: [], aliases: false)
300
+ required = %w[
301
+ current_flow
302
+ current_feature
303
+ current_phase
304
+ current_step
305
+ status
306
+ completed_steps
307
+ pending_steps
308
+ ]
309
+ missing = required.reject { |key| state.key?(key) }
310
+
311
+ if missing.any?
312
+ fail_result("missing_state_fields", fields: missing)
313
+ elsif project_context_missing?(root)
314
+ project_context_result(
315
+ "incomplete_project_context",
316
+ missing: [
317
+ ".planning/PROJECT.md",
318
+ ".planning/navigation/INDEX.md",
319
+ ".context/spec/index.md"
320
+ ]
321
+ )
322
+ else
323
+ pending_template_blockers = Array(state["blockers"]).select do |blocker|
324
+ blocker.is_a?(Hash) && blocker["type"] == "PENDING_TEMPLATE"
325
+ end
326
+
327
+ if pending_template_blockers.any?
328
+ fail_result(
329
+ "pending_depth_spec_templates",
330
+ blockers: pending_template_blockers,
331
+ recovery: "add the missing template or mark the topic NOT_APPLICABLE, then rerun workflow-project-context"
332
+ )
333
+ else
334
+ workflow_path = state["workflow_config"] ||
335
+ File.join(".planning", "workflows", "#{state["current_flow"]}.yaml")
336
+ abs_workflow_path = File.join(root, workflow_path)
337
+
338
+ if !File.exist?(abs_workflow_path)
339
+ fail_result(
340
+ "missing_workflow_config",
341
+ path: workflow_path,
342
+ recovery: "Call devflow_bootstrap with feature and phase."
343
+ )
344
+ else
345
+ workflow = load_yaml_file(abs_workflow_path)
346
+ artifact_by_path, artifact_registry_path, artifact_registry_error = load_artifact_registry(root, workflow)
347
+ steps = workflow.fetch("steps", [])
348
+ step_by_id = steps.to_h { |step| [step.fetch("id"), step] }
349
+ current_step = step_by_id[state["current_step"]]
350
+ pending_ids = Array(state["pending_steps"])
351
+ completed_ids = Array(state["completed_steps"])
352
+ validation = WorkflowStateValidator.validate(
353
+ root: root,
354
+ state_path: state_path,
355
+ state_override: state,
356
+ workflow_override: workflow,
357
+ strict_artifact_status: true
358
+ )
359
+
360
+ if !validation["ok"]
361
+ {
362
+ current_flow: state["current_flow"],
363
+ current_feature: state["current_feature"],
364
+ current_phase: state["current_phase"],
365
+ status: state["status"],
366
+ completed_steps: completed_ids,
367
+ pending_steps: pending_ids,
368
+ current_step: current_step && {
369
+ id: current_step["id"],
370
+ label: current_step["label"],
371
+ skill: current_step["skill"],
372
+ action: current_step["action"]
373
+ },
374
+ next_step: nil,
375
+ workflow_config: workflow_path,
376
+ artifact_registry: artifact_registry_summary(root, artifact_by_path).merge(
377
+ "path" => artifact_registry_path,
378
+ "error" => artifact_registry_error,
379
+ "recovery" => artifact_registry_error ? "Call devflow_artifact with action=sync." : nil,
380
+ "current_outputs_registered" => 0
381
+ ),
382
+ action: "blocked",
383
+ reason: "state_validation_failed",
384
+ state_validation: validation,
385
+ recovery: "Fix missing/invalid artifacts or call devflow_artifact with action=sync and preserve=false, then call devflow_state with action=inspect."
386
+ }
387
+ elsif current_step.nil?
388
+ fallback_next_id = next_pending_step_id(state, pending_ids, step_by_id, completed_ids)
389
+ fallback_next_step = fallback_next_id && step_by_id[fallback_next_id]
390
+
391
+ if fallback_next_step
392
+ {
393
+ current_flow: state["current_flow"],
394
+ current_feature: state["current_feature"],
395
+ current_phase: state["current_phase"],
396
+ status: state["status"],
397
+ completed_steps: completed_ids,
398
+ pending_steps: pending_ids,
399
+ current_step: nil,
400
+ next_step: step_payload(fallback_next_step, state, root, artifact_by_path),
401
+ workflow_config: workflow_path,
402
+ artifact_registry: artifact_registry_summary(root, artifact_by_path).merge(
403
+ "path" => artifact_registry_path,
404
+ "error" => artifact_registry_error,
405
+ "recovery" => artifact_registry_error ? "Call devflow_artifact with action=sync." : nil,
406
+ "current_outputs_registered" => 0
407
+ ),
408
+ action: "run_next_step",
409
+ reason: "current_step_not_in_workflow_using_pending_step"
410
+ }
411
+ elsif pending_ids.empty? && state["status"] == "completed"
412
+ {
413
+ current_flow: state["current_flow"],
414
+ current_feature: state["current_feature"],
415
+ current_phase: state["current_phase"],
416
+ status: state["status"],
417
+ completed_steps: completed_ids,
418
+ pending_steps: pending_ids,
419
+ current_step: nil,
420
+ next_step: nil,
421
+ workflow_config: workflow_path,
422
+ artifact_registry: artifact_registry_summary(root, artifact_by_path).merge(
423
+ "path" => artifact_registry_path,
424
+ "error" => artifact_registry_error,
425
+ "recovery" => artifact_registry_error ? "Call devflow_artifact with action=sync." : nil,
426
+ "current_outputs_registered" => 0
427
+ ),
428
+ action: "workflow_complete",
429
+ reason: "completed_status_with_no_pending_steps"
430
+ }
431
+ else
432
+ fail_result("unknown_current_step", current_step: state["current_step"])
433
+ end
434
+ else
435
+ current_outputs = Array(current_step["outputs"]).map do |output|
436
+ resolved = interpolate_path(output.fetch("path"), state)
437
+ attach_artifact(
438
+ output.merge("resolved_path" => resolved, "exists" => File.exist?(File.join(root, resolved))),
439
+ artifact_by_path
440
+ )
441
+ end
442
+
443
+ next_id = next_pending_step_id(state, pending_ids, step_by_id, completed_ids)
444
+ next_step = next_id && step_by_id[next_id]
445
+ checkpoint_id = state["checkpoint"] || current_step["checkpoint"]
446
+ checkpoint = checkpoint_id && workflow.fetch("checkpoints", {})[checkpoint_id]
447
+ parallel_window = active_parallel_window(workflow, state, root, step_by_id, completed_ids, pending_ids, artifact_by_path)
448
+ failure_branch = active_failure_branch(workflow, state, current_step, current_outputs, root)
449
+
450
+ base = {
451
+ current_flow: state["current_flow"],
452
+ current_feature: state["current_feature"],
453
+ current_phase: state["current_phase"],
454
+ status: state["status"],
455
+ checkpoint: checkpoint_id,
456
+ checkpoint_label: checkpoint && checkpoint["name"],
457
+ completed_steps: completed_ids,
458
+ pending_steps: pending_ids,
459
+ current_step: {
460
+ id: current_step["id"],
461
+ label: current_step["label"],
462
+ skill: current_step["skill"],
463
+ action: current_step["action"],
464
+ outputs: current_outputs
465
+ },
466
+ next_step: next_step && {
467
+ id: next_step["id"],
468
+ label: next_step["label"],
469
+ skill: next_step["skill"],
470
+ action: next_step["action"],
471
+ inputs: Array(next_step["inputs"]).map { |path| interpolate_path(path, state) },
472
+ outputs: Array(next_step["outputs"]).map do |output|
473
+ resolved = interpolate_path(output.fetch("path"), state)
474
+ artifact = artifact_by_path[resolved]
475
+ {
476
+ path: resolved,
477
+ type: output["type"],
478
+ required: output["required"],
479
+ exists: File.exist?(File.join(root, resolved)),
480
+ artifact_status: artifact && artifact["status"],
481
+ artifact_registered: !artifact.nil?
482
+ }
483
+ end
484
+ },
485
+ parallel_window: parallel_window,
486
+ workflow_config: workflow_path,
487
+ artifact_registry: artifact_registry_summary(root, artifact_by_path).merge(
488
+ "path" => artifact_registry_path,
489
+ "error" => artifact_registry_error,
490
+ "recovery" => artifact_registry_error ? "Call devflow_artifact with action=sync." : nil,
491
+ "current_outputs_registered" => current_outputs.count { |output| output["artifact_registered"] }
492
+ )
493
+ }
494
+
495
+ boundary = track_boundary(state, pending_ids, completed_ids)
496
+
497
+ if artifact_registry_error
498
+ base.merge(
499
+ action: "blocked",
500
+ reason: artifact_registry_error,
501
+ recovery: "Call devflow_artifact with action=sync."
502
+ )
503
+ elsif boundary
504
+ base.merge(
505
+ action: "blocked",
506
+ reason: boundary["reason"],
507
+ message: boundary["message"],
508
+ active_track: active_track(state)
509
+ )
510
+ elsif failure_branch
511
+ base.merge(
512
+ action: "route_failure_branch",
513
+ reason: "failure_branch_triggered",
514
+ failure_branch: failure_branch
515
+ )
516
+ elsif state["status"] == "waiting_checkpoint"
517
+ missing_outputs = current_outputs
518
+ .select { |output| output["required"] && !output["exists"] }
519
+ .map { |output| output["resolved_path"] }
520
+
521
+ base.merge(
522
+ action: missing_outputs.empty? ? "await_user_confirmation" : "blocked",
523
+ reason: missing_outputs.empty? ? nil : "missing_checkpoint_outputs",
524
+ missing_outputs: missing_outputs,
525
+ resume_behavior: checkpoint && checkpoint["resume_behavior"],
526
+ next_intent: ".planning/.next-intent"
527
+ )
528
+ elsif parallel_window
529
+ base.merge(action: "run_parallel_window")
530
+ elsif next_step
531
+ base.merge(action: "run_next_step")
532
+ elsif pending_ids.empty?
533
+ base.merge(action: "workflow_complete")
534
+ else
535
+ base.merge(action: "blocked", reason: "unknown_next_step", next_step_id: next_id)
536
+ end
537
+ end
538
+ end
539
+ end
540
+ end
541
+ end
542
+ end
543
+
544
+ if defined?(state) && state.is_a?(Hash) && result.is_a?(Hash)
545
+ result = result.merge(revision: Integer(state.fetch("revision", 0)))
546
+ end
547
+
548
+ if options[:json]
549
+ puts JSON.pretty_generate(result)
550
+ else
551
+ puts "action: #{result[:action] || result["action"]}"
552
+ puts JSON.pretty_generate(result)
553
+ end