@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,381 @@
1
+ ---
2
+ name: workflow-context-sync
3
+ description: Execute project-context reconciliation only when the context-sync Stop hook reports CONTEXT_SYNC_REQUIRED, or when the user explicitly requests a context refresh. Consume the hook's changed-file list and Light/Medium/Full verdict, update only the required code index, navigation, or specs, validate, then acknowledge the exact hook session.
4
+ ---
5
+
6
+ # Workflow Context Sync
7
+
8
+ Use this skill to keep project facts trustworthy after code changes. It is a coordinator, not a new indexing system: classify the change, choose the smallest safe sync level, call existing workflow skills or their deterministic commands, validate, and report.
9
+
10
+ ## Trigger Contract
11
+
12
+ Do not activate this skill merely because code changed. The lifecycle hooks own detection and triggering:
13
+
14
+ 1. `PostToolUse` records successful edits and shell activity.
15
+ 2. `Stop` computes the current change set and classifies it as Light, Medium, or Full.
16
+ 3. Light is handled automatically when deterministic code-index refresh succeeds.
17
+ 4. This skill runs only for a `CONTEXT_SYNC_REQUIRED` verdict, a failed Light auto-sync, or an explicit user request.
18
+
19
+ Treat the hook-provided file list, level, and session ID as authoritative inputs. Do not widen the change set unless validation produces concrete stale evidence.
20
+
21
+ ## First Principles
22
+
23
+ The invariant is:
24
+
25
+ ```text
26
+ code facts changed -> project context must remain trustworthy
27
+ ```
28
+
29
+ Preserve these properties:
30
+
31
+ - **Freshness**: `.planning/code-index/`, `.planning/navigation/`, and `.context/spec/` must not describe old routes, APIs, entries, services, commands, or codebase roots.
32
+ - **Minimality**: do not run a full project initialization when changed-file indexing is enough.
33
+ - **Evidence**: do not update navigation/spec from memory or inference alone; read the changed source or manifest evidence first.
34
+ - **Non-destruction**: do not overwrite user-authored business context; append logs or update machine-derived sections only.
35
+ - **Cursor correctness**: after-pull sync must compare each Git repository from the last successfully synced commit to current `HEAD`, not rely only on Git's volatile `ORIG_HEAD`.
36
+
37
+ ## Related Skills
38
+
39
+ | Skill | Role | When to Use |
40
+ |---|---|---|
41
+ | project indexes | Accelerate rule/spec/navigation discovery; fall back to LSP/search/source when stale | Advisory evidence, never a source-read blocker |
42
+ | `workflow-code-index` | Refresh, validate, and audit machine facts | Light, Medium, Full; audit/staleness problems |
43
+ | `workflow-update-navigation` | Update `.planning/navigation/*.md` | Medium route/API/page/service/command changes |
44
+ | `workflow-project-context` | Full reinitialization | Full only |
45
+ | `workflow-bug-fix` | Bug-fix main workflow | Must call this skill after verification and lesson capture |
46
+ | `workflow-execute-phase` | Feature implementation workflow | Must call this skill after implementation verification |
47
+ | `workflow-verify-work` | Validate implementation | Usually before after-bugfix sync |
48
+
49
+ ## Inputs
50
+
51
+ Supported intent flags:
52
+
53
+ - `--after-pull`: sync after pulling external changes.
54
+ - `--after-bugfix`: sync after local bug-fix code changes.
55
+ - `--after-implementation`: sync after normal feature implementation or direct OMP code edits.
56
+ - `--changed-files`: sync explicit files supplied by the user.
57
+ - `--full`: force full project context refresh.
58
+ - `--dry-run`: classify and output a plan without modifying files.
59
+
60
+ If no flag is provided, default to `--dry-run` and infer changed files from git.
61
+
62
+ ## Main Chain
63
+
64
+ ```text
65
+ workflow-context-sync
66
+ -> read .planning/rules/INDEX.md
67
+ -> read .context/spec/index.md
68
+ -> read .planning/navigation/INDEX.md
69
+ -> collect changed files with per-repo cursor
70
+ -> classify files and affected codebases
71
+ -> choose Light / Medium / Full
72
+ -> run selected sync actions
73
+ -> validate / audit
74
+ -> mark per-repo cursor synced after successful after-pull sync
75
+ -> update STATE change log when files were modified
76
+ -> report result and residual risk
77
+ ```
78
+
79
+ ## Cursor State
80
+
81
+ Maintain pull synchronization state in:
82
+
83
+ ```text
84
+ .planning/context-sync-state.json
85
+ ```
86
+
87
+ This file is workflow-owned machine state. It stores one cursor per independently discovered Git repository:
88
+
89
+ ```json
90
+ {
91
+ "version": 1,
92
+ "updated_at": "2026-07-23T10:00:00+00:00",
93
+ "repos": {
94
+ "skit": {
95
+ "path": "skit",
96
+ "last_synced_head": "6f1847b66cbf19d9cf040d6e4e71d4f3d7a9942a",
97
+ "last_synced_branch": "master",
98
+ "last_synced_at": "2026-07-23T10:00:00+00:00",
99
+ "last_mode": "after-pull"
100
+ }
101
+ }
102
+ }
103
+ ```
104
+
105
+ Rules:
106
+
107
+ - Discover repositories from `.planning/navigation/INDEX.md` Codebase Registry, then deduplicate by `git rev-parse --show-toplevel`.
108
+ - For `--after-pull`, diff `last_synced_head..HEAD` per repo.
109
+ - If a repo has no cursor yet, fall back to `ORIG_HEAD..HEAD` for that repo.
110
+ - If the stored cursor is unavailable or not an ancestor of `HEAD`, use the script-reported fallback/warning and prefer a broader sync level.
111
+ - Do not mark a cursor before sync, validation, and audit succeed.
112
+ - On repeat execution with cursor equal to `HEAD`, report no new pull changes and do not reprocess the same commit range.
113
+ - For local uncommitted `--after-bugfix` or `--after-implementation`, keep using worktree diffs; do not advance the pull cursor unless the mode is explicitly after-pull or the changed facts are committed and intentionally marked synced.
114
+
115
+ ## Changed File Collection
116
+
117
+ Use the first reliable source:
118
+
119
+ | Mode | Command |
120
+ |---|---|
121
+ | `--after-pull` | `devflow_context_cursor(args=["--project-root", ".", "collect", "--after-pull"])` |
122
+ | `--after-bugfix` | `git diff --name-only` plus `git diff --cached --name-only` |
123
+ | `--after-implementation` | `git diff --name-only` plus `git diff --cached --name-only` |
124
+ | `--changed-files` | user-provided list |
125
+ | fallback | `git status --short` |
126
+
127
+ For `--after-pull`, parse the script JSON and use its top-level `changed_files`. Paths are already normalized relative to the project root, for example `skit/frontend/h5/src/root.tsx`.
128
+
129
+ The script handles multiple repositories and repeated pulls:
130
+
131
+ ```text
132
+ devflow_context_cursor(args=["--project-root", ".", "collect", "--after-pull"])
133
+ devflow_context_cursor(args=["--project-root", ".", "collect", "--after-pull", "--format", "files"])
134
+ ```
135
+
136
+ If the script is unavailable or fails, fall back to `git -C skit diff --name-only ORIG_HEAD..HEAD`, clearly report the degraded cursor behavior, and prefer Medium or Full when safety is unclear.
137
+
138
+ After a successful `--after-pull` sync, update the cursor:
139
+
140
+ ```text
141
+ devflow_context_cursor(args=["--project-root", ".", "mark-synced", "--mode", "after-pull"])
142
+ ```
143
+
144
+ ## Classification
145
+
146
+ Map paths to codebases:
147
+
148
+ | Codebase | Paths |
149
+ |---|---|
150
+ | skit-admin | `skit/frontend/admin/**` |
151
+ | skit-h5 | `skit/frontend/h5/**` |
152
+ | skit-backend | `skit/internal/**`, `skit/ioc/**`, `skit/pkg/**`, `skit/backend/migrations/**`, `skit/go.mod`, `skit/Makefile`, `skit/main.go` |
153
+ | project context | `.planning/**`, `.context/spec/**`, `.omp/**`, `AGENTS.md` |
154
+
155
+ Classify impact:
156
+
157
+ | Impact | Examples | Default Level |
158
+ |---|---|---|
159
+ | tests-only | `*_test.go`, `*.test.ts`, `*.test.tsx`, `tests/**` | Light |
160
+ | code-only | implementation internals, component-only edits, helper logic | Light |
161
+ | route/api/page | `src/routes.ts`, `src/routes/*.tsx`, `src/lib/api/*.ts`, `src/admin/pages/*.tsx` | Medium |
162
+ | backend boundary | `internal/web/*handler.go`, `ioc/web.go`, `internal/job/**`, public service interfaces | Medium |
163
+ | toolchain/manifest | `package.json`, `go.mod`, `Makefile`, vite/router config | Medium or Full |
164
+ | structure | codebase roots, large directory moves, new top-level/second-level directories | Full |
165
+ | context docs | `.planning/**`, `.context/spec/**` | validate consistency; avoid blind overwrite |
166
+
167
+ ## Sync Levels
168
+
169
+ ### Light
170
+
171
+ Use for ordinary bug fixes, tests-only changes, and internal implementation edits.
172
+
173
+ Actions:
174
+
175
+ ```text
176
+ devflow_code_index(action="scan", changedFiles=["<changed-file>", "..."])
177
+ devflow_code_index(action="validate")
178
+ devflow_code_index(action="audit")
179
+ ```
180
+
181
+ Then append a concise `.planning/STATE.md` change-log line if this skill modified files.
182
+
183
+ ### Medium
184
+
185
+ Use when changed files can alter human navigation or rule docs: routes, API clients, handler registrations, jobs, page inventory, service boundaries, package commands, manifests.
186
+
187
+ Actions:
188
+
189
+ 1. Run Light changed-file indexing.
190
+ 2. Read relevant changed source files.
191
+ 3. Read matching navigation/spec entry for each affected codebase.
192
+ 4. Update only stale sections, usually:
193
+ - `.planning/navigation/{codebase}.md`
194
+ - `.context/spec/frontend|backend/{codebase}.md` only when a codebase rule or stack fact changed
195
+ - `.planning/toolchain.md` only when commands/manifests changed
196
+ - `.planning/STATE.md` change log
197
+ 5. Validate and audit code-index again if navigation/spec edits introduce new files or references.
198
+
199
+ ### Full
200
+
201
+ Use only when minimal sync cannot preserve trust.
202
+
203
+ Triggers:
204
+
205
+ - User passes `--full`.
206
+ - Changed files count exceeds 30 and includes structural or manifest changes.
207
+ - Codebase root or package layout changes.
208
+ - Framework/package-manager major version changes.
209
+ - Full route/controller/page inventory is no longer trustworthy.
210
+ - `code_index.py audit` fails or reports stale/missing facts that changed-file sync cannot resolve.
211
+
212
+ Actions:
213
+
214
+ ```text
215
+ workflow-project-context --with-code-index
216
+ review gate
217
+ STATE update
218
+ ```
219
+
220
+ If Full is not explicitly requested, explain why it is needed before running it unless the user asked for automatic synchronization.
221
+
222
+ ## Escalation Rules
223
+
224
+ Upgrade to at least Medium when any changed path matches:
225
+
226
+ ```text
227
+ skit/internal/web/*handler.go
228
+ skit/ioc/web.go
229
+ skit/internal/job/**
230
+ skit/frontend/h5/src/routes.ts
231
+ skit/frontend/h5/src/routes/*.tsx
232
+ skit/frontend/h5/src/lib/api/*.ts
233
+ skit/frontend/admin/src/admin/pages/*.tsx
234
+ skit/frontend/admin/src/lib/api/*.ts
235
+ skit/frontend/*/package.json
236
+ skit/frontend/*/vite.config.ts
237
+ skit/frontend/h5/react-router.config.ts
238
+ skit/go.mod
239
+ skit/Makefile
240
+ ```
241
+
242
+ Upgrade to Full when:
243
+
244
+ ```text
245
+ changed files > 30 with structural/manifest impact
246
+ new/deleted top-level or second-level source directories
247
+ codebase root changed
248
+ navigation/spec conflicts with source evidence
249
+ code-index audit fails after a Light/Medium sync
250
+ ```
251
+
252
+ ## Adversarial Review
253
+
254
+ Before modifying context files, challenge the plan:
255
+
256
+ - **Over-refresh risk**: Am I about to run Full for a local implementation change? Downgrade to Light unless structure changed.
257
+ - **Under-refresh risk**: Did route/API/handler/page/service/toolchain files change? If yes, do not stop at code-index only.
258
+ - **Evidence risk**: Am I updating navigation/spec without reading the changed source/manifest? Read evidence first.
259
+ - **Context pollution risk**: Am I turning a guess into a rule? Mark inferred facts as `代码推断` or do not write them.
260
+ - **User-content risk**: Am I rewriting business context, requirements, or manual notes? Preserve them; append logs instead.
261
+ - **Dirty tree risk**: Are unrelated user changes present? Do not revert or overwrite them.
262
+
263
+ If any answer is unsafe, stop, report the risk, and choose a narrower action.
264
+
265
+ ## Dry Run Output
266
+
267
+ For `--dry-run`, report:
268
+
269
+ ```text
270
+ Context Sync Plan
271
+
272
+ Mode:
273
+ - after-bugfix | after-implementation | after-pull | changed-files
274
+
275
+ Changed files:
276
+ - ...
277
+
278
+ Classification:
279
+ - affected codebases: ...
280
+ - impacts: ...
281
+ - recommended level: Light|Medium|Full
282
+
283
+ Planned actions:
284
+ - ...
285
+
286
+ Skipped:
287
+ - ...
288
+
289
+ Questions:
290
+ - only if needed
291
+ ```
292
+
293
+ Do not modify files in dry-run.
294
+
295
+ ## Final Report
296
+
297
+ After execution, report:
298
+
299
+ ```text
300
+ Context Sync Report
301
+
302
+ Mode:
303
+ - after-bugfix | after-implementation | after-pull | changed-files
304
+
305
+ Changed files:
306
+ - ...
307
+
308
+ Classification:
309
+ - affected codebases: ...
310
+ - sync level: ...
311
+
312
+ Actions:
313
+ - code-index changed-files: passed
314
+ - navigation checked/updated: ...
315
+ - spec checked/updated: ...
316
+ - cursor state: updated/skipped/fallback
317
+ - STATE change log: appended/skipped
318
+
319
+ Audit:
320
+ - validate passed/failed
321
+ - audit passed/failed
322
+
323
+ Residual:
324
+ - pending command gaps or skipped sync areas
325
+ ```
326
+
327
+ If sync was skipped because the user requested it, state that explicitly.
328
+
329
+ After all required validation succeeds, acknowledge the exact change set through the OMP runtime tool:
330
+
331
+ ```text
332
+ devflow_context_sync(action="ack", level="<Light|Medium|Full>")
333
+ ```
334
+
335
+ Do not acknowledge before the selected sync actions and their validation complete. The acknowledgement stores a content signature, so a later source edit invalidates it and reopens the Stop gate.
336
+
337
+ ## Integration With Other Workflows
338
+
339
+ For bug fixes:
340
+
341
+ ```text
342
+ workflow-bug-fix
343
+ -> implement fix
344
+ -> run verification
345
+ -> capture lessons
346
+ -> workflow-context-sync --after-bugfix
347
+ -> final response
348
+ ```
349
+
350
+ For feature implementation:
351
+
352
+ ```text
353
+ workflow-execute-phase
354
+ -> implement phase tasks
355
+ -> run required verification
356
+ -> update execution state
357
+ -> workflow-context-sync --after-implementation
358
+ -> final response
359
+ ```
360
+
361
+ For direct OMP edits outside a workflow phase:
362
+
363
+ ```text
364
+ direct code edit
365
+ -> run required verification
366
+ -> workflow-context-sync --after-implementation
367
+ -> final response
368
+ ```
369
+
370
+ For external updates:
371
+
372
+ ```text
373
+ git pull
374
+ -> workflow-context-sync --after-pull
375
+ ```
376
+
377
+ For manual repair:
378
+
379
+ ```text
380
+ workflow-context-sync --changed-files <files>
381
+ ```
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Workflow Context Sync"
3
+ short_description: "Sync project context after code changes"
4
+ default_prompt: "Use $workflow-context-sync to sync project context after a pull, bug fix, implementation, or changed files."
@@ -0,0 +1,241 @@
1
+ #!/usr/bin/env python3
2
+ """Collect changed files for workflow-context-sync using per-repo cursors."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import json
8
+ import re
9
+ import subprocess
10
+ import sys
11
+ from datetime import datetime, timezone
12
+ from pathlib import Path
13
+ from typing import Any
14
+
15
+
16
+ DEFAULT_STATE = ".planning/context-sync-state.json"
17
+ NAVIGATION_INDEX = ".planning/navigation/INDEX.md"
18
+
19
+
20
+ def run_git(repo: Path, args: list[str], check: bool = True) -> subprocess.CompletedProcess[str]:
21
+ return subprocess.run(
22
+ ["git", "-C", str(repo), *args],
23
+ check=check,
24
+ text=True,
25
+ stdout=subprocess.PIPE,
26
+ stderr=subprocess.PIPE,
27
+ )
28
+
29
+
30
+ def git_output(repo: Path, args: list[str]) -> str:
31
+ return run_git(repo, args).stdout.strip()
32
+
33
+
34
+ def normalize_rel(path: Path, root: Path) -> str:
35
+ try:
36
+ return path.resolve().relative_to(root.resolve()).as_posix()
37
+ except ValueError:
38
+ return path.resolve().as_posix()
39
+
40
+
41
+ def load_json(path: Path) -> dict[str, Any]:
42
+ if not path.exists():
43
+ return {"version": 1, "repos": {}}
44
+ with path.open("r", encoding="utf-8") as fh:
45
+ data = json.load(fh)
46
+ if not isinstance(data, dict):
47
+ raise ValueError(f"state file is not an object: {path}")
48
+ data.setdefault("version", 1)
49
+ data.setdefault("repos", {})
50
+ return data
51
+
52
+
53
+ def save_json(path: Path, data: dict[str, Any]) -> None:
54
+ path.parent.mkdir(parents=True, exist_ok=True)
55
+ path.write_text(json.dumps(data, ensure_ascii=False, indent=2, sort_keys=True) + "\n", encoding="utf-8")
56
+
57
+
58
+ def codebase_paths_from_navigation(project_root: Path) -> list[Path]:
59
+ index_path = project_root / NAVIGATION_INDEX
60
+ if not index_path.exists():
61
+ return []
62
+ text = index_path.read_text(encoding="utf-8")
63
+ match = re.search(r"^## Codebase Registry\s*$([\s\S]*?)(?=^## |\Z)", text, re.MULTILINE)
64
+ section = match.group(1) if match else text
65
+ paths: list[Path] = []
66
+ for line in section.splitlines():
67
+ if not line.startswith("|") or "`" not in line:
68
+ continue
69
+ cells = [cell.strip() for cell in line.strip().strip("|").split("|")]
70
+ if len(cells) < 2 or cells[0] in {"Name", "---"}:
71
+ continue
72
+ code_path_match = re.search(r"`([^`]+)`", cells[1])
73
+ if code_path_match:
74
+ paths.append(project_root / code_path_match.group(1))
75
+ return paths
76
+
77
+
78
+ def discover_repos(project_root: Path) -> list[dict[str, str]]:
79
+ candidates = codebase_paths_from_navigation(project_root)
80
+ if not candidates:
81
+ candidates = [project_root / "skit", project_root]
82
+
83
+ repos_by_root: dict[str, dict[str, str]] = {}
84
+ for candidate in candidates:
85
+ if not candidate.exists():
86
+ continue
87
+ result = run_git(candidate, ["rev-parse", "--show-toplevel"], check=False)
88
+ if result.returncode != 0:
89
+ continue
90
+ repo_root = Path(result.stdout.strip()).resolve()
91
+ repo_id = normalize_rel(repo_root, project_root)
92
+ repos_by_root[str(repo_root)] = {
93
+ "id": repo_id,
94
+ "path": repo_id,
95
+ "abs_path": str(repo_root),
96
+ }
97
+ return sorted(repos_by_root.values(), key=lambda item: item["id"])
98
+
99
+
100
+ def commit_exists(repo: Path, commit: str) -> bool:
101
+ if not commit:
102
+ return False
103
+ return run_git(repo, ["rev-parse", "--verify", f"{commit}^{{commit}}"], check=False).returncode == 0
104
+
105
+
106
+ def is_ancestor(repo: Path, base: str, head: str) -> bool:
107
+ return run_git(repo, ["merge-base", "--is-ancestor", base, head], check=False).returncode == 0
108
+
109
+
110
+ def merge_base(repo: Path, left: str, right: str) -> str:
111
+ result = run_git(repo, ["merge-base", left, right], check=False)
112
+ return result.stdout.strip() if result.returncode == 0 else ""
113
+
114
+
115
+ def diff_files(repo: Path, project_root: Path, repo_id: str, base: str, head: str) -> list[str]:
116
+ if base == head:
117
+ return []
118
+ output = git_output(repo, ["diff", "--name-only", f"{base}..{head}"])
119
+ files = [line.strip() for line in output.splitlines() if line.strip()]
120
+ prefix = "" if repo_id in {"", "."} else f"{repo_id}/"
121
+ return [f"{prefix}{path}" for path in files]
122
+
123
+
124
+ def select_base(repo: Path, repo_state: dict[str, Any], head: str) -> tuple[str, str, list[str]]:
125
+ warnings: list[str] = []
126
+ cursor = str(repo_state.get("last_synced_head", "")).strip()
127
+ if cursor:
128
+ if not commit_exists(repo, cursor):
129
+ warnings.append("stored cursor commit is unavailable; falling back to ORIG_HEAD")
130
+ elif cursor == head:
131
+ return head, "cursor", warnings
132
+ elif is_ancestor(repo, cursor, head):
133
+ return cursor, "cursor", warnings
134
+ else:
135
+ base = merge_base(repo, cursor, head)
136
+ if base:
137
+ warnings.append("stored cursor is not an ancestor of HEAD; using merge-base")
138
+ return base, "cursor_merge_base", warnings
139
+ warnings.append("stored cursor has no merge-base with HEAD; falling back to ORIG_HEAD")
140
+
141
+ if commit_exists(repo, "ORIG_HEAD"):
142
+ orig_head = git_output(repo, ["rev-parse", "ORIG_HEAD"])
143
+ if orig_head != head:
144
+ return orig_head, "ORIG_HEAD", warnings
145
+ warnings.append("no usable cursor or ORIG_HEAD; treating repository as already synced")
146
+ return head, "none", warnings
147
+
148
+
149
+ def collect(project_root: Path, state_path: Path, output_format: str) -> int:
150
+ state = load_json(state_path)
151
+ repos = discover_repos(project_root)
152
+ changed_files: list[str] = []
153
+ repo_results: list[dict[str, Any]] = []
154
+
155
+ for repo_meta in repos:
156
+ repo = Path(repo_meta["abs_path"])
157
+ repo_id = repo_meta["id"]
158
+ head = git_output(repo, ["rev-parse", "HEAD"])
159
+ branch = run_git(repo, ["branch", "--show-current"], check=False).stdout.strip()
160
+ repo_state = state.get("repos", {}).get(repo_id, {})
161
+ base, source, warnings = select_base(repo, repo_state, head)
162
+ files = diff_files(repo, project_root, repo_id, base, head)
163
+ changed_files.extend(files)
164
+ repo_results.append({
165
+ "id": repo_id,
166
+ "path": repo_meta["path"],
167
+ "branch": branch,
168
+ "base": base,
169
+ "base_source": source,
170
+ "head": head,
171
+ "changed_files": files,
172
+ "warnings": warnings,
173
+ })
174
+
175
+ changed_files = sorted(dict.fromkeys(changed_files))
176
+ payload = {
177
+ "version": 1,
178
+ "state_path": normalize_rel(state_path, project_root),
179
+ "repos": repo_results,
180
+ "changed_files": changed_files,
181
+ }
182
+ if output_format == "files":
183
+ sys.stdout.write("\n".join(changed_files))
184
+ if changed_files:
185
+ sys.stdout.write("\n")
186
+ else:
187
+ sys.stdout.write(json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True) + "\n")
188
+ return 0
189
+
190
+
191
+ def mark_synced(project_root: Path, state_path: Path, mode: str) -> int:
192
+ state = load_json(state_path)
193
+ repos = discover_repos(project_root)
194
+ now = datetime.now(timezone.utc).isoformat()
195
+ state["version"] = 1
196
+ state["updated_at"] = now
197
+ state.setdefault("repos", {})
198
+ for repo_meta in repos:
199
+ repo = Path(repo_meta["abs_path"])
200
+ repo_id = repo_meta["id"]
201
+ state["repos"][repo_id] = {
202
+ "path": repo_meta["path"],
203
+ "last_synced_head": git_output(repo, ["rev-parse", "HEAD"]),
204
+ "last_synced_branch": run_git(repo, ["branch", "--show-current"], check=False).stdout.strip(),
205
+ "last_synced_at": now,
206
+ "last_mode": mode,
207
+ }
208
+ save_json(state_path, state)
209
+ sys.stdout.write(json.dumps({
210
+ "state_path": normalize_rel(state_path, project_root),
211
+ "updated_at": now,
212
+ "repos": state["repos"],
213
+ }, ensure_ascii=False, indent=2, sort_keys=True) + "\n")
214
+ return 0
215
+
216
+
217
+ def main() -> int:
218
+ parser = argparse.ArgumentParser(description=__doc__)
219
+ parser.add_argument("--project-root", default=".", help="workspace/project root")
220
+ parser.add_argument("--state", default=DEFAULT_STATE, help="cursor state file")
221
+ subparsers = parser.add_subparsers(dest="command", required=True)
222
+
223
+ collect_parser = subparsers.add_parser("collect", help="collect changed files since cursor")
224
+ collect_parser.add_argument("--after-pull", action="store_true", help="document after-pull intent")
225
+ collect_parser.add_argument("--format", choices=["json", "files"], default="json")
226
+
227
+ mark_parser = subparsers.add_parser("mark-synced", help="mark all discovered repos synced at HEAD")
228
+ mark_parser.add_argument("--mode", default="after-pull")
229
+
230
+ args = parser.parse_args()
231
+ project_root = Path(args.project_root).resolve()
232
+ state_path = (project_root / args.state).resolve()
233
+ if args.command == "collect":
234
+ return collect(project_root, state_path, args.format)
235
+ if args.command == "mark-synced":
236
+ return mark_synced(project_root, state_path, args.mode)
237
+ return 2
238
+
239
+
240
+ if __name__ == "__main__":
241
+ raise SystemExit(main())