@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.
- package/README.md +164 -0
- package/docs/OMP-NATIVE-ARCHITECTURE.md +104 -0
- package/package.json +40 -0
- package/plugins/devflow-core/extensions/devflow-core.ts +1642 -0
- package/plugins/devflow-core/package.json +14 -0
- package/plugins/devflow-core/runtime/hooks/context_sync_gate.py +174 -0
- package/plugins/devflow-core/runtime/hooks/hook_common.py +696 -0
- package/plugins/devflow-core/runtime/hooks/index_gate.py +63 -0
- package/plugins/devflow-core/runtime/hooks/injection_code_specification.py +7 -0
- package/plugins/devflow-core/runtime/hooks/post_tool.py +44 -0
- package/plugins/devflow-core/runtime/hooks/start.py +288 -0
- package/plugins/devflow-core/skills/workflow-orchestrator/SKILL.md +265 -0
- package/plugins/devflow-core/skills/workflow-orchestrator/agents/openai.yaml +4 -0
- package/plugins/devflow-core/skills/workflow-orchestrator/scripts/advance_state.rb +520 -0
- package/plugins/devflow-core/skills/workflow-orchestrator/scripts/control_io.rb +42 -0
- package/plugins/devflow-core/skills/workflow-orchestrator/scripts/init_state.rb +138 -0
- package/plugins/devflow-core/skills/workflow-orchestrator/scripts/init_workflow.rb +121 -0
- package/plugins/devflow-core/skills/workflow-orchestrator/scripts/inspect_state.rb +553 -0
- package/plugins/devflow-core/skills/workflow-orchestrator/scripts/manage_lessons.rb +219 -0
- package/plugins/devflow-core/skills/workflow-orchestrator/scripts/sync_artifacts.rb +168 -0
- package/plugins/devflow-core/skills/workflow-orchestrator/scripts/update_triage_route.rb +110 -0
- package/plugins/devflow-core/skills/workflow-orchestrator/scripts/validate_state.rb +565 -0
- package/plugins/devflow-core/skills/workflow-orchestrator/templates/feature-development.yaml +783 -0
- package/plugins/devflow-core/skills/workflow-orchestrator/templates/uat-remediation.yaml +143 -0
- package/plugins/devflow-core/skills/workflow-orchestrator/templates/workflows-README.md +10 -0
- package/plugins/devflow-core/skills/workflow-pipeline/SKILL.md +117 -0
- package/plugins/devflow-core/skills/workflow-pipeline/references/pipeline-flow.md +167 -0
- package/plugins/devflow-core/skills/workflow-pipeline/references/slice-safety-guide.md +125 -0
- package/plugins/devflow-core/skills/workflow-project-context/SKILL.md +819 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/agents-md-template.md +25 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/codebase-backend-spec-template.md +68 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/codebase-frontend-spec-template.md +64 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/codebase-navigation-template.md +168 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/context-domain-index-template.md +43 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/context-spec-index-template.md +45 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/execution-contract-template.md +57 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/navigation-index-template.md +40 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/project-initialization-template.md +109 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/rules-index-template.md +80 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/run-manifest-template.json +40 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/backend/directory-structure.md +46 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/backend/engine.md +46 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/backend/errors.md +46 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/backend/locator.md +46 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/backend/model.md +46 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/backend/repository.md +46 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/backend/router.md +46 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/backend/scheduler.md +46 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/backend/schema.md +46 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/backend/service.md +46 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/backend/testing.md +46 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/frontend/api-client.md +46 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/frontend/case-editor.md +46 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/frontend/components.md +46 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/frontend/directory-structure.md +46 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/frontend/forms.md +46 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/frontend/routing.md +46 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/frontend/state.md +46 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/spec-templates/frontend/testing.md +46 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/stack-spec-template.md +106 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/state-template.md +77 -0
- package/plugins/devflow-core/skills/workflow-project-context/assets/toolchain-template.md +37 -0
- package/plugins/devflow-core/skills/workflow-project-context/references/navigation-guide.md +262 -0
- package/plugins/devflow-core/skills/workflow-project-context/scripts/validate_initialization.py +545 -0
- package/plugins/devflow-design/agents/contract-auditor.md +18 -0
- package/plugins/devflow-design/extensions/devflow-design.ts +47 -0
- package/plugins/devflow-design/package.json +14 -0
- package/plugins/devflow-design/skills/workflow-api-call-guide/SKILL.md +142 -0
- package/plugins/devflow-design/skills/workflow-api-contract/SKILL.md +150 -0
- package/plugins/devflow-design/skills/workflow-api-supplement/SKILL.md +121 -0
- package/plugins/devflow-design/skills/workflow-backend-tech-spec/SKILL.md +257 -0
- package/plugins/devflow-design/skills/workflow-backend-tech-spec/assets/adr-template.md +57 -0
- package/plugins/devflow-design/skills/workflow-backend-tech-spec/assets/backend-spec-template.md +205 -0
- package/plugins/devflow-design/skills/workflow-backend-tech-spec/references/affected-module-exploration.md +59 -0
- package/plugins/devflow-design/skills/workflow-backend-tech-spec/references/backend-conventions.md +30 -0
- package/plugins/devflow-design/skills/workflow-backend-tech-spec/references/code-explore-guide.md +40 -0
- package/plugins/devflow-design/skills/workflow-backend-tech-spec/references/project-rule-contract.md +66 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/SKILL.md +91 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/index.md +71 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/recommendations/accessibility.md +31 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/recommendations/component-library.md +31 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/recommendations/design-systems.md +47 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/recommendations/responsive-grid.md +29 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/recommendations/stack-guidelines.md +31 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/recommendations/ux-patterns.md +40 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tokens/project-tokens.md +19 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/SKILL.md +377 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/charts.csv +26 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/colors.csv +97 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/icons.csv +101 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/landing.csv +31 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/products.csv +97 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/styles.csv +68 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/typography.csv +58 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/scripts/core.py +253 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/assets/design/tools/ui-ux-pro-max/scripts/search.py +114 -0
- package/plugins/devflow-design/skills/workflow-design-rule-pack/scripts/install.py +67 -0
- package/plugins/devflow-design/skills/workflow-feature-breakdown/SKILL.md +370 -0
- package/plugins/devflow-design/skills/workflow-feature-breakdown/assets/admin-system-template.md +57 -0
- package/plugins/devflow-design/skills/workflow-feature-breakdown/assets/api-service-template.md +42 -0
- package/plugins/devflow-design/skills/workflow-feature-breakdown/assets/c-end-system-template.md +25 -0
- package/plugins/devflow-design/skills/workflow-feature-breakdown/assets/output-template.md +139 -0
- package/plugins/devflow-design/skills/workflow-feature-breakdown/references/bug-rules.md +12 -0
- package/plugins/devflow-design/skills/workflow-feature-breakdown/references/exception-checklist.md +31 -0
- package/plugins/devflow-design/skills/workflow-feature-breakdown/references/trace-integrity-guide.md +153 -0
- package/plugins/devflow-design/skills/workflow-feature-breakdown/references/writing-guide.md +92 -0
- package/plugins/devflow-design/skills/workflow-frontend-tech-spec/SKILL.md +223 -0
- package/plugins/devflow-design/skills/workflow-frontend-tech-spec/assets/frontend-spec-template.md +204 -0
- package/plugins/devflow-design/skills/workflow-frontend-tech-spec/references/affected-module-exploration.md +58 -0
- package/plugins/devflow-design/skills/workflow-frontend-tech-spec/references/component-patterns.md +42 -0
- package/plugins/devflow-design/skills/workflow-frontend-tech-spec/references/frontend-conventions.md +28 -0
- package/plugins/devflow-design/skills/workflow-frontend-tech-spec/references/frontend-stack-slots/common-web.md +53 -0
- package/plugins/devflow-design/skills/workflow-frontend-tech-spec/references/frontend-stack-slots/next.md +40 -0
- package/plugins/devflow-design/skills/workflow-frontend-tech-spec/references/frontend-stack-slots/react.md +41 -0
- package/plugins/devflow-design/skills/workflow-frontend-tech-spec/references/frontend-stack-slots/vue.md +41 -0
- package/plugins/devflow-design/skills/workflow-frontend-tech-spec/references/project-rule-contract.md +95 -0
- package/plugins/devflow-design/skills/workflow-integration-verify/SKILL.md +172 -0
- package/plugins/devflow-design/skills/workflow-ui-spec/SKILL.md +302 -0
- package/plugins/devflow-design/skills/workflow-ui-spec/assets/ui-spec-template.md +244 -0
- package/plugins/devflow-design/skills/workflow-ui-spec/references/affected-module-exploration.md +55 -0
- package/plugins/devflow-implementation/agents/implementation-worker.md +20 -0
- package/plugins/devflow-implementation/package.json +6 -0
- package/plugins/devflow-implementation/skills/workflow-bug-fix/SKILL.md +124 -0
- package/plugins/devflow-implementation/skills/workflow-bug-fix/references/INDEX.md +13 -0
- package/plugins/devflow-implementation/skills/workflow-bug-fix/references/adversarial-review.md +35 -0
- package/plugins/devflow-implementation/skills/workflow-bug-fix/references/first-principles.md +26 -0
- package/plugins/devflow-implementation/skills/workflow-bug-fix/references/lesson-format.md +28 -0
- package/plugins/devflow-implementation/skills/workflow-bug-fix/references/root-cause-ladder.md +51 -0
- package/plugins/devflow-implementation/skills/workflow-bug-fix/references/seam-analysis.md +30 -0
- package/plugins/devflow-implementation/skills/workflow-change-plan/SKILL.md +160 -0
- package/plugins/devflow-implementation/skills/workflow-change-plan/references/code-conventions.md +33 -0
- package/plugins/devflow-implementation/skills/workflow-change-plan/references/ddl-guidelines.md +60 -0
- package/plugins/devflow-implementation/skills/workflow-change-plan/references/output-template.md +217 -0
- package/plugins/devflow-implementation/skills/workflow-change-plan/references/project-rule-contract.md +55 -0
- package/plugins/devflow-implementation/skills/workflow-execute-phase/SKILL.md +271 -0
- package/plugins/devflow-implementation/skills/workflow-execute-phase/references/execute-phase.md +1251 -0
- package/plugins/devflow-implementation/skills/workflow-execute-phase/references/ui-brand.md +160 -0
- package/plugins/devflow-intel/agents/project-scout.md +27 -0
- package/plugins/devflow-intel/extensions/devflow-intel.ts +104 -0
- package/plugins/devflow-intel/package.json +14 -0
- package/plugins/devflow-intel/skills/code-index-query/SKILL.md +37 -0
- package/plugins/devflow-intel/skills/code-index-query/references/query-patterns.md +27 -0
- package/plugins/devflow-intel/skills/workflow-code-index/SKILL.md +68 -0
- package/plugins/devflow-intel/skills/workflow-code-index/references/adapter-contract.md +38 -0
- package/plugins/devflow-intel/skills/workflow-code-index/references/audit-checklist.md +10 -0
- package/plugins/devflow-intel/skills/workflow-code-index/references/confidence-rules.md +43 -0
- package/plugins/devflow-intel/skills/workflow-code-index/references/data-model.md +74 -0
- package/plugins/devflow-intel/skills/workflow-code-index/references/discovery.md +24 -0
- package/plugins/devflow-intel/skills/workflow-code-index/references/query-guide.md +20 -0
- package/plugins/devflow-intel/skills/workflow-code-index/scripts/adapters/__init__.py +1 -0
- package/plugins/devflow-intel/skills/workflow-code-index/scripts/adapters/base.py +30 -0
- package/plugins/devflow-intel/skills/workflow-code-index/scripts/adapters/generic_text.py +287 -0
- package/plugins/devflow-intel/skills/workflow-code-index/scripts/adapters/registry.py +17 -0
- package/plugins/devflow-intel/skills/workflow-code-index/scripts/code_index.py +437 -0
- package/plugins/devflow-intel/skills/workflow-code-index/scripts/core/__init__.py +1 -0
- package/plugins/devflow-intel/skills/workflow-code-index/scripts/core/discovery.py +139 -0
- package/plugins/devflow-intel/skills/workflow-code-index/scripts/core/hashing.py +11 -0
- package/plugins/devflow-intel/skills/workflow-code-index/scripts/core/scanner.py +115 -0
- package/plugins/devflow-intel/skills/workflow-code-index/scripts/core/schema.py +123 -0
- package/plugins/devflow-intel/skills/workflow-code-index/scripts/validators/__init__.py +1 -0
- package/plugins/devflow-intel/skills/workflow-code-index/scripts/validators/project_binding_check.py +66 -0
- package/plugins/devflow-intel/skills/workflow-code-index/scripts/validators/relation_check.py +36 -0
- package/plugins/devflow-intel/skills/workflow-code-index/scripts/validators/schema_validate.py +11 -0
- package/plugins/devflow-intel/skills/workflow-code-index/scripts/validators/stale_check.py +42 -0
- package/plugins/devflow-intel/skills/workflow-code-index/scripts/writers/__init__.py +1 -0
- package/plugins/devflow-intel/skills/workflow-code-index/scripts/writers/jsonl_writer.py +25 -0
- package/plugins/devflow-intel/skills/workflow-code-index/scripts/writers/markdown_writer.py +106 -0
- package/plugins/devflow-intel/skills/workflow-code-index/scripts/writers/sqlite_writer.py +143 -0
- package/plugins/devflow-intel/skills/workflow-context-sync/SKILL.md +381 -0
- package/plugins/devflow-intel/skills/workflow-context-sync/agents/openai.yaml +4 -0
- package/plugins/devflow-intel/skills/workflow-context-sync/scripts/context_sync_cursor.py +241 -0
- package/plugins/devflow-intel/skills/workflow-update-navigation/SKILL.md +186 -0
- package/plugins/devflow-intel/skills/workflow-update-navigation/references/incremental-update-guide.md +47 -0
- package/plugins/devflow-quality/agents/code-reviewer.md +18 -0
- package/plugins/devflow-quality/agents/verification-runner.md +21 -0
- package/plugins/devflow-quality/extensions/devflow-quality.ts +59 -0
- package/plugins/devflow-quality/package.json +14 -0
- package/plugins/devflow-quality/skills/code-review/SKILL.md +288 -0
- package/plugins/devflow-quality/skills/code-review/references/cross-layer-checklist.md +70 -0
- package/plugins/devflow-quality/skills/code-review/references/dao-checklist.md +70 -0
- package/plugins/devflow-quality/skills/code-review/references/handler-checklist.md +48 -0
- package/plugins/devflow-quality/skills/code-review/references/repository-checklist.md +44 -0
- package/plugins/devflow-quality/skills/code-review/references/service-checklist.md +57 -0
- package/plugins/devflow-quality/skills/code-review/references/spec-checklist.md +34 -0
- package/plugins/devflow-quality/skills/code-review/references/vo-checklist.md +26 -0
- package/plugins/devflow-quality/skills/workflow-audit-milestone/SKILL.md +31 -0
- package/plugins/devflow-quality/skills/workflow-audit-milestone/references/audit-milestone.md +328 -0
- package/plugins/devflow-quality/skills/workflow-complete-milestone/SKILL.md +132 -0
- package/plugins/devflow-quality/skills/workflow-complete-milestone/assets/milestone-archive.md +123 -0
- package/plugins/devflow-quality/skills/workflow-complete-milestone/references/complete-milestone.md +775 -0
- package/plugins/devflow-quality/skills/workflow-complete-milestone/references/milestone-archive.md +123 -0
- package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/SKILL.md +126 -0
- package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/references/api-mainflow-rules.md +27 -0
- package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/references/codebase-discovery.md +54 -0
- package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/references/intermediate-format.md +244 -0
- package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/references/mainflow-selection.md +36 -0
- package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/references/project-dsl-contract.md +190 -0
- package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/references/ui-mainflow-rules.md +110 -0
- package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/scripts/compile_dsl.py +583 -0
- package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/scripts/discover_codebases.py +199 -0
- package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/scripts/normalize_case_payloads.py +177 -0
- package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/scripts/validate_case_payloads.py +370 -0
- package/plugins/devflow-quality/skills/workflow-verify-work/SKILL.md +106 -0
- package/plugins/devflow-quality/skills/workflow-verify-work/assets/UAT.md +265 -0
- package/plugins/devflow-quality/skills/workflow-verify-work/references/verify-work.md +759 -0
- package/plugins/devflow-requirements/agents/requirements-auditor.md +20 -0
- package/plugins/devflow-requirements/package.json +6 -0
- package/plugins/devflow-requirements/skills/requirement-feasibility-review/SKILL.md +219 -0
- package/plugins/devflow-requirements/skills/requirement-feasibility-review/agents/openai.yaml +4 -0
- package/plugins/devflow-requirements/skills/requirement-feasibility-review/references/review-method.md +257 -0
- package/plugins/devflow-requirements/skills/requirement-feasibility-review/references/review-template.md +80 -0
- package/plugins/devflow-requirements/skills/workflow-demand-clarify/SKILL.md +325 -0
- package/plugins/devflow-requirements/skills/workflow-domain-modeling/SKILL.md +163 -0
- package/plugins/devflow-requirements/skills/workflow-requirement-baseline/SKILL.md +748 -0
- package/plugins/devflow-requirements/skills/workflow-requirement-baseline/assets/baseline-template.md +281 -0
- package/plugins/devflow-requirements/skills/workflow-requirement-baseline/references/antipatterns.md +69 -0
- package/plugins/devflow-requirements/skills/workflow-requirement-baseline/references/challenge-review-guide.md +158 -0
- package/plugins/devflow-requirements/skills/workflow-requirement-baseline/references/decomposition-guide.md +115 -0
- package/plugins/devflow-requirements/skills/workflow-requirement-baseline/references/project-context-guide.md +119 -0
- package/plugins/devflow-requirements/skills/workflow-requirement-baseline/references/questioning.md +76 -0
- package/plugins/devflow-requirements/skills/workflow-requirement-baseline/references/requirement-review-checklist.md +115 -0
- package/plugins/devflow-requirements/skills/workflow-requirement-triage/SKILL.md +204 -0
- package/plugins/devflow-requirements/skills/workflow-wayfinder/SKILL.md +183 -0
- package/src/cli.ts +76 -0
- package/src/constants.ts +15 -0
- package/src/doctor.ts +66 -0
- package/src/paths.ts +37 -0
- package/src/platform-extension.ts +46 -0
- package/src/project-context.ts +165 -0
- package/src/runtime.ts +167 -0
- package/src/usage-stats.ts +101 -0
- package/templates/commands/start.md +58 -0
- package/templates/omp/AGENTS.md +36 -0
- package/templates/omp/config.yml +112 -0
- package/templates/omp/hook-config.json +18 -0
- 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,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())
|