frappe-builder 1.1.0-dev.10
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/.fb/state.db +0 -0
- package/AGENTS.md +167 -0
- package/README.md +89 -0
- package/_bmad/_config/agent-manifest.csv +10 -0
- package/_bmad/_config/agents/bmm-analyst.customize.yaml +41 -0
- package/_bmad/_config/agents/bmm-architect.customize.yaml +41 -0
- package/_bmad/_config/agents/bmm-dev.customize.yaml +41 -0
- package/_bmad/_config/agents/bmm-pm.customize.yaml +41 -0
- package/_bmad/_config/agents/bmm-qa.customize.yaml +41 -0
- package/_bmad/_config/agents/bmm-quick-flow-solo-dev.customize.yaml +41 -0
- package/_bmad/_config/agents/bmm-sm.customize.yaml +41 -0
- package/_bmad/_config/agents/bmm-tech-writer.customize.yaml +41 -0
- package/_bmad/_config/agents/bmm-ux-designer.customize.yaml +41 -0
- package/_bmad/_config/bmad-help.csv +47 -0
- package/_bmad/_config/files-manifest.csv +369 -0
- package/_bmad/_config/ides/claude-code.yaml +5 -0
- package/_bmad/_config/manifest.yaml +28 -0
- package/_bmad/_config/skill-manifest.csv +41 -0
- package/_bmad/_config/task-manifest.csv +1 -0
- package/_bmad/_config/tool-manifest.csv +1 -0
- package/_bmad/_config/workflow-manifest.csv +1 -0
- package/_bmad/_memory/config.yaml +11 -0
- package/_bmad/_memory/tech-writer-sidecar/documentation-standards.md +224 -0
- package/_bmad/bmm/agents/analyst.md +69 -0
- package/_bmad/bmm/agents/architect.md +59 -0
- package/_bmad/bmm/agents/bmad-skill-manifest.yaml +39 -0
- package/_bmad/bmm/agents/dev.md +66 -0
- package/_bmad/bmm/agents/pm.md +63 -0
- package/_bmad/bmm/agents/qa.md +89 -0
- package/_bmad/bmm/agents/quick-flow-solo-dev.md +61 -0
- package/_bmad/bmm/agents/sm.md +67 -0
- package/_bmad/bmm/agents/tech-writer/bmad-skill-manifest.yaml +3 -0
- package/_bmad/bmm/agents/tech-writer/tech-writer.md +67 -0
- package/_bmad/bmm/agents/ux-designer.md +58 -0
- package/_bmad/bmm/config.yaml +16 -0
- package/_bmad/bmm/data/project-context-template.md +26 -0
- package/_bmad/bmm/module-help.csv +32 -0
- package/_bmad/bmm/teams/default-party.csv +20 -0
- package/_bmad/bmm/teams/team-fullstack.yaml +12 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/SKILL.md +6 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/product-brief.template.md +10 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/steps/step-01-init.md +170 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/steps/step-01b-continue.md +158 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/steps/step-02-vision.md +193 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/steps/step-03-users.md +196 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/steps/step-04-metrics.md +199 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/steps/step-05-scope.md +213 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/steps/step-06-complete.md +159 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/workflow.md +55 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/SKILL.md +88 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/agents/artifact-analyzer.md +60 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/agents/opportunity-reviewer.md +44 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/agents/skeptic-reviewer.md +44 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/agents/web-researcher.md +49 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/bmad-manifest.json +17 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/prompts/contextual-discovery.md +57 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/prompts/draft-and-review.md +86 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/prompts/finalize.md +75 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/prompts/guided-elicitation.md +70 -0
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/resources/brief-template.md +60 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/SKILL.md +6 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/domain-steps/step-01-init.md +137 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/domain-steps/step-02-domain-analysis.md +229 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/domain-steps/step-03-competitive-landscape.md +238 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/domain-steps/step-04-regulatory-focus.md +206 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/domain-steps/step-05-technical-trends.md +234 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/domain-steps/step-06-research-synthesis.md +444 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/research.template.md +29 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/workflow.md +49 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/SKILL.md +6 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/research.template.md +29 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-01-init.md +184 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-02-customer-behavior.md +239 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-03-customer-pain-points.md +251 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-04-customer-decisions.md +261 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-05-competitive-analysis.md +173 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-06-research-completion.md +478 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/workflow.md +49 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/SKILL.md +6 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/research.template.md +29 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/technical-steps/step-01-init.md +137 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/technical-steps/step-02-technical-overview.md +239 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/technical-steps/step-03-integration-patterns.md +248 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/technical-steps/step-04-architectural-patterns.md +202 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/technical-steps/step-05-implementation-research.md +233 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/technical-steps/step-06-research-synthesis.md +487 -0
- package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/workflow.md +50 -0
- package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +182 -0
- package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +237 -0
- package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +249 -0
- package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +259 -0
- package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +177 -0
- package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +476 -0
- package/_bmad/bmm/workflows/1-analysis/research/research.template.md +29 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/SKILL.md +6 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-01-init.md +135 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-01b-continue.md +127 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-02-discovery.md +190 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-03-core-experience.md +217 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-04-emotional-response.md +220 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-05-inspiration.md +235 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-06-design-system.md +253 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-07-defining-experience.md +255 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-08-visual-foundation.md +225 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-09-design-directions.md +225 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-10-user-journeys.md +242 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-11-component-strategy.md +249 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-12-ux-patterns.md +238 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-13-responsive-accessibility.md +265 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-14-complete.md +171 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/ux-design-template.md +13 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/workflow.md +36 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/SKILL.md +6 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/steps-e/step-e-01-discovery.md +242 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/steps-e/step-e-01b-legacy-conversion.md +204 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/steps-e/step-e-02-review.md +245 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/steps-e/step-e-03-edit.md +250 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/steps-e/step-e-04-complete.md +165 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/workflow.md +63 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/SKILL.md +6 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/data/domain-complexity.csv +15 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/data/prd-purpose.md +197 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/data/project-types.csv +11 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-01-discovery.md +221 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-02-format-detection.md +188 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-02b-parity-check.md +206 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-03-density-validation.md +171 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-04-brief-coverage-validation.md +211 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-05-measurability-validation.md +225 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-06-traceability-validation.md +214 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-07-implementation-leakage-validation.md +202 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-08-domain-compliance-validation.md +240 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-09-project-type-validation.md +260 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-10-smart-validation.md +206 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-11-holistic-quality-validation.md +261 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-12-completeness-validation.md +239 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-13-report-complete.md +229 -0
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/workflow.md +62 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/data/domain-complexity.csv +15 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/data/prd-purpose.md +197 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/data/project-types.csv +11 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-01-discovery.md +224 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-02-format-detection.md +191 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-02b-parity-check.md +209 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-03-density-validation.md +174 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-04-brief-coverage-validation.md +214 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-05-measurability-validation.md +228 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-06-traceability-validation.md +217 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-07-implementation-leakage-validation.md +205 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-08-domain-compliance-validation.md +243 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-09-project-type-validation.md +263 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-10-smart-validation.md +209 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-11-holistic-quality-validation.md +264 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-12-completeness-validation.md +242 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-13-report-complete.md +232 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/workflow-validate-prd.md +65 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/SKILL.md +6 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/steps/step-01-document-discovery.md +179 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/steps/step-02-prd-analysis.md +168 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/steps/step-03-epic-coverage-validation.md +169 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/steps/step-04-ux-alignment.md +129 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/steps/step-05-epic-quality-review.md +241 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/steps/step-06-final-assessment.md +126 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/templates/readiness-report-template.md +4 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/workflow.md +49 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/SKILL.md +6 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/architecture-decision-template.md +12 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/data/domain-complexity.csv +13 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/data/project-types.csv +7 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-01-init.md +153 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-01b-continue.md +173 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-02-context.md +224 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-03-starter.md +329 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-04-decisions.md +318 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-05-patterns.md +359 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-06-structure.md +379 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-07-validation.md +359 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-08-complete.md +76 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/workflow.md +38 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/SKILL.md +6 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/steps/step-01-validate-prerequisites.md +255 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/steps/step-02-design-epics.md +212 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/steps/step-03-create-stories.md +255 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/steps/step-04-final-validation.md +131 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/templates/epics-template.md +61 -0
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/workflow.md +53 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-code-review/SKILL.md +6 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-code-review/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-code-review/steps/step-01-gather-context.md +61 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-code-review/steps/step-02-review.md +41 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-code-review/steps/step-03-triage.md +50 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-code-review/steps/step-04-present.md +38 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-code-review/workflow.md +54 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-correct-course/SKILL.md +6 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-correct-course/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-correct-course/checklist.md +288 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-correct-course/workflow.md +267 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-create-story/SKILL.md +6 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-create-story/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-create-story/checklist.md +357 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-create-story/discover-inputs.md +88 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-create-story/template.md +49 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-create-story/workflow.md +380 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-dev-story/SKILL.md +6 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-dev-story/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-dev-story/checklist.md +80 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-dev-story/workflow.md +450 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-retrospective/SKILL.md +6 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-retrospective/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-retrospective/workflow.md +1479 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-sprint-planning/SKILL.md +6 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-sprint-planning/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-sprint-planning/checklist.md +33 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-sprint-planning/sprint-status-template.yaml +56 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-sprint-planning/workflow.md +263 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-sprint-status/SKILL.md +6 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-sprint-status/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/4-implementation/bmad-sprint-status/workflow.md +261 -0
- package/_bmad/bmm/workflows/bmad-document-project/SKILL.md +6 -0
- package/_bmad/bmm/workflows/bmad-document-project/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/bmad-document-project/checklist.md +245 -0
- package/_bmad/bmm/workflows/bmad-document-project/documentation-requirements.csv +12 -0
- package/_bmad/bmm/workflows/bmad-document-project/instructions.md +128 -0
- package/_bmad/bmm/workflows/bmad-document-project/templates/deep-dive-template.md +345 -0
- package/_bmad/bmm/workflows/bmad-document-project/templates/index-template.md +169 -0
- package/_bmad/bmm/workflows/bmad-document-project/templates/project-overview-template.md +103 -0
- package/_bmad/bmm/workflows/bmad-document-project/templates/project-scan-report-schema.json +160 -0
- package/_bmad/bmm/workflows/bmad-document-project/templates/source-tree-template.md +135 -0
- package/_bmad/bmm/workflows/bmad-document-project/workflow.md +27 -0
- package/_bmad/bmm/workflows/bmad-document-project/workflows/deep-dive-instructions.md +299 -0
- package/_bmad/bmm/workflows/bmad-document-project/workflows/deep-dive-workflow.md +34 -0
- package/_bmad/bmm/workflows/bmad-document-project/workflows/full-scan-instructions.md +1107 -0
- package/_bmad/bmm/workflows/bmad-document-project/workflows/full-scan-workflow.md +34 -0
- package/_bmad/bmm/workflows/bmad-generate-project-context/SKILL.md +6 -0
- package/_bmad/bmm/workflows/bmad-generate-project-context/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/bmad-generate-project-context/project-context-template.md +21 -0
- package/_bmad/bmm/workflows/bmad-generate-project-context/steps/step-01-discover.md +186 -0
- package/_bmad/bmm/workflows/bmad-generate-project-context/steps/step-02-generate.md +321 -0
- package/_bmad/bmm/workflows/bmad-generate-project-context/steps/step-03-complete.md +278 -0
- package/_bmad/bmm/workflows/bmad-generate-project-context/workflow.md +43 -0
- package/_bmad/bmm/workflows/bmad-qa-generate-e2e-tests/SKILL.md +6 -0
- package/_bmad/bmm/workflows/bmad-qa-generate-e2e-tests/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/bmad-qa-generate-e2e-tests/checklist.md +33 -0
- package/_bmad/bmm/workflows/bmad-qa-generate-e2e-tests/workflow.md +136 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/SKILL.md +6 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/steps/step-01-mode-detection.md +169 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/steps/step-02-context-gathering.md +114 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/steps/step-03-execute.md +107 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/steps/step-04-self-check.md +107 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/steps/step-05-adversarial-review.md +94 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/steps/step-06-resolve-findings.md +144 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/workflow.md +38 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/SKILL.md +6 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/steps/step-01-clarify-and-route.md +51 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/steps/step-02-plan.md +35 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/steps/step-03-implement.md +33 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/steps/step-04-review.md +50 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/steps/step-05-present.md +17 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/tech-spec-template.md +90 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/workflow.md +79 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/SKILL.md +6 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/bmad-skill-manifest.yaml +1 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/steps/step-01-understand.md +185 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/steps/step-02-investigate.md +140 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/steps/step-03-generate.md +123 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/steps/step-04-review.md +195 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/tech-spec-template.md +74 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/workflow.md +73 -0
- package/_bmad/cis/config.yaml +12 -0
- package/_bmad/cis/module-help.csv +6 -0
- package/_bmad/cis/skills/bmad-cis-agent-brainstorming-coach/SKILL.md +51 -0
- package/_bmad/cis/skills/bmad-cis-agent-brainstorming-coach/bmad-skill-manifest.yaml +11 -0
- package/_bmad/cis/skills/bmad-cis-agent-creative-problem-solver/SKILL.md +51 -0
- package/_bmad/cis/skills/bmad-cis-agent-creative-problem-solver/bmad-skill-manifest.yaml +11 -0
- package/_bmad/cis/skills/bmad-cis-agent-design-thinking-coach/SKILL.md +52 -0
- package/_bmad/cis/skills/bmad-cis-agent-design-thinking-coach/bmad-skill-manifest.yaml +11 -0
- package/_bmad/cis/skills/bmad-cis-agent-innovation-strategist/SKILL.md +51 -0
- package/_bmad/cis/skills/bmad-cis-agent-innovation-strategist/bmad-skill-manifest.yaml +11 -0
- package/_bmad/cis/skills/bmad-cis-agent-presentation-master/SKILL.md +62 -0
- package/_bmad/cis/skills/bmad-cis-agent-presentation-master/bmad-skill-manifest.yaml +11 -0
- package/_bmad/cis/skills/bmad-cis-agent-storyteller/SKILL.md +56 -0
- package/_bmad/cis/skills/bmad-cis-agent-storyteller/bmad-skill-manifest.yaml +11 -0
- package/_bmad/cis/skills/bmad-cis-agent-storyteller/stories-told.md +7 -0
- package/_bmad/cis/skills/bmad-cis-agent-storyteller/story-preferences.md +7 -0
- package/_bmad/cis/skills/bmad-cis-design-thinking/SKILL.md +6 -0
- package/_bmad/cis/skills/bmad-cis-design-thinking/bmad-skill-manifest.yaml +1 -0
- package/_bmad/cis/skills/bmad-cis-design-thinking/design-methods.csv +31 -0
- package/_bmad/cis/skills/bmad-cis-design-thinking/template.md +111 -0
- package/_bmad/cis/skills/bmad-cis-design-thinking/workflow.md +242 -0
- package/_bmad/cis/skills/bmad-cis-innovation-strategy/SKILL.md +6 -0
- package/_bmad/cis/skills/bmad-cis-innovation-strategy/bmad-skill-manifest.yaml +1 -0
- package/_bmad/cis/skills/bmad-cis-innovation-strategy/innovation-frameworks.csv +31 -0
- package/_bmad/cis/skills/bmad-cis-innovation-strategy/template.md +189 -0
- package/_bmad/cis/skills/bmad-cis-innovation-strategy/workflow.md +315 -0
- package/_bmad/cis/skills/bmad-cis-problem-solving/SKILL.md +6 -0
- package/_bmad/cis/skills/bmad-cis-problem-solving/bmad-skill-manifest.yaml +1 -0
- package/_bmad/cis/skills/bmad-cis-problem-solving/solving-methods.csv +31 -0
- package/_bmad/cis/skills/bmad-cis-problem-solving/template.md +165 -0
- package/_bmad/cis/skills/bmad-cis-problem-solving/workflow.md +291 -0
- package/_bmad/cis/skills/bmad-cis-storytelling/SKILL.md +6 -0
- package/_bmad/cis/skills/bmad-cis-storytelling/bmad-skill-manifest.yaml +1 -0
- package/_bmad/cis/skills/bmad-cis-storytelling/story-types.csv +26 -0
- package/_bmad/cis/skills/bmad-cis-storytelling/template.md +113 -0
- package/_bmad/cis/skills/bmad-cis-storytelling/workflow.md +321 -0
- package/_bmad/core/config.yaml +9 -0
- package/_bmad/core/module-help.csv +11 -0
- package/_bmad/core/skills/bmad-advanced-elicitation/SKILL.md +6 -0
- package/_bmad/core/skills/bmad-advanced-elicitation/bmad-skill-manifest.yaml +1 -0
- package/_bmad/core/skills/bmad-advanced-elicitation/methods.csv +51 -0
- package/_bmad/core/skills/bmad-advanced-elicitation/workflow.md +135 -0
- package/_bmad/core/skills/bmad-brainstorming/SKILL.md +6 -0
- package/_bmad/core/skills/bmad-brainstorming/bmad-skill-manifest.yaml +1 -0
- package/_bmad/core/skills/bmad-brainstorming/brain-methods.csv +62 -0
- package/_bmad/core/skills/bmad-brainstorming/steps/step-01-session-setup.md +214 -0
- package/_bmad/core/skills/bmad-brainstorming/steps/step-01b-continue.md +124 -0
- package/_bmad/core/skills/bmad-brainstorming/steps/step-02a-user-selected.md +229 -0
- package/_bmad/core/skills/bmad-brainstorming/steps/step-02b-ai-recommended.md +239 -0
- package/_bmad/core/skills/bmad-brainstorming/steps/step-02c-random-selection.md +211 -0
- package/_bmad/core/skills/bmad-brainstorming/steps/step-02d-progressive-flow.md +266 -0
- package/_bmad/core/skills/bmad-brainstorming/steps/step-03-technique-execution.md +401 -0
- package/_bmad/core/skills/bmad-brainstorming/steps/step-04-idea-organization.md +305 -0
- package/_bmad/core/skills/bmad-brainstorming/template.md +15 -0
- package/_bmad/core/skills/bmad-brainstorming/workflow.md +53 -0
- package/_bmad/core/skills/bmad-distillator/SKILL.md +178 -0
- package/_bmad/core/skills/bmad-distillator/agents/distillate-compressor.md +116 -0
- package/_bmad/core/skills/bmad-distillator/agents/round-trip-reconstructor.md +68 -0
- package/_bmad/core/skills/bmad-distillator/bmad-skill-manifest.yaml +15 -0
- package/_bmad/core/skills/bmad-distillator/resources/compression-rules.md +51 -0
- package/_bmad/core/skills/bmad-distillator/resources/distillate-format-reference.md +227 -0
- package/_bmad/core/skills/bmad-distillator/resources/splitting-strategy.md +78 -0
- package/_bmad/core/skills/bmad-editorial-review-prose/SKILL.md +6 -0
- package/_bmad/core/skills/bmad-editorial-review-prose/bmad-skill-manifest.yaml +1 -0
- package/_bmad/core/skills/bmad-editorial-review-prose/workflow.md +81 -0
- package/_bmad/core/skills/bmad-editorial-review-structure/SKILL.md +6 -0
- package/_bmad/core/skills/bmad-editorial-review-structure/bmad-skill-manifest.yaml +1 -0
- package/_bmad/core/skills/bmad-editorial-review-structure/workflow.md +174 -0
- package/_bmad/core/skills/bmad-help/SKILL.md +6 -0
- package/_bmad/core/skills/bmad-help/bmad-skill-manifest.yaml +1 -0
- package/_bmad/core/skills/bmad-help/workflow.md +88 -0
- package/_bmad/core/skills/bmad-index-docs/SKILL.md +6 -0
- package/_bmad/core/skills/bmad-index-docs/bmad-skill-manifest.yaml +1 -0
- package/_bmad/core/skills/bmad-index-docs/workflow.md +61 -0
- package/_bmad/core/skills/bmad-party-mode/SKILL.md +6 -0
- package/_bmad/core/skills/bmad-party-mode/bmad-skill-manifest.yaml +1 -0
- package/_bmad/core/skills/bmad-party-mode/steps/step-01-agent-loading.md +138 -0
- package/_bmad/core/skills/bmad-party-mode/steps/step-02-discussion-orchestration.md +187 -0
- package/_bmad/core/skills/bmad-party-mode/steps/step-03-graceful-exit.md +167 -0
- package/_bmad/core/skills/bmad-party-mode/workflow.md +190 -0
- package/_bmad/core/skills/bmad-review-adversarial-general/SKILL.md +6 -0
- package/_bmad/core/skills/bmad-review-adversarial-general/bmad-skill-manifest.yaml +1 -0
- package/_bmad/core/skills/bmad-review-adversarial-general/workflow.md +32 -0
- package/_bmad/core/skills/bmad-review-edge-case-hunter/SKILL.md +6 -0
- package/_bmad/core/skills/bmad-review-edge-case-hunter/bmad-skill-manifest.yaml +1 -0
- package/_bmad/core/skills/bmad-review-edge-case-hunter/workflow.md +62 -0
- package/_bmad/core/skills/bmad-shard-doc/SKILL.md +6 -0
- package/_bmad/core/skills/bmad-shard-doc/bmad-skill-manifest.yaml +1 -0
- package/_bmad/core/skills/bmad-shard-doc/workflow.md +100 -0
- package/_bmad/core/tasks/bmad-create-prd/SKILL.md +6 -0
- package/_bmad/core/tasks/bmad-create-prd/bmad-skill-manifest.yaml +1 -0
- package/_bmad/core/tasks/bmad-create-prd/data/domain-complexity.csv +15 -0
- package/_bmad/core/tasks/bmad-create-prd/data/prd-purpose.md +197 -0
- package/_bmad/core/tasks/bmad-create-prd/data/project-types.csv +11 -0
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-01-init.md +178 -0
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-01b-continue.md +161 -0
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-02-discovery.md +208 -0
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-02b-vision.md +142 -0
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-02c-executive-summary.md +158 -0
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-03-success.md +214 -0
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-04-journeys.md +201 -0
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-05-domain.md +194 -0
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-06-innovation.md +211 -0
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-07-project-type.md +222 -0
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-08-scoping.md +216 -0
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-09-functional.md +219 -0
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-10-nonfunctional.md +230 -0
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-11-polish.md +221 -0
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-12-complete.md +115 -0
- package/_bmad/core/tasks/bmad-create-prd/templates/prd-template.md +10 -0
- package/_bmad/core/tasks/bmad-create-prd/workflow.md +62 -0
- package/config/allowed-commands.ts +39 -0
- package/config/defaults.ts +19 -0
- package/config/loader.ts +105 -0
- package/dist/cli.mjs +67 -0
- package/dist/init-BYJy3ztn.mjs +159 -0
- package/extensions/frappe-gates.ts +160 -0
- package/extensions/frappe-session.ts +324 -0
- package/extensions/frappe-state.ts +235 -0
- package/extensions/frappe-tools.ts +278 -0
- package/extensions/frappe-ui.ts +119 -0
- package/extensions/frappe-workflow.ts +85 -0
- package/gates/coverage-check.ts +37 -0
- package/gates/frappe-native-check.ts +65 -0
- package/gates/permission-check.ts +65 -0
- package/gates/query-check.ts +40 -0
- package/gates/server-side-check.ts +67 -0
- package/gates/style-check.ts +92 -0
- package/gates/types.ts +13 -0
- package/package.json +47 -0
- package/project-context.md +146 -0
- package/state/db.ts +85 -0
- package/state/fsm.ts +68 -0
- package/state/journal.ts +164 -0
- package/state/schema.ts +41 -0
- package/tools/agent-tools.ts +60 -0
- package/tools/bench-tools.ts +63 -0
- package/tools/context-sandbox.ts +31 -0
- package/tools/debug-tools.ts +12 -0
- package/tools/feature-tools.ts +126 -0
- package/tools/frappe-context7.ts +70 -0
- package/tools/frappe-query-tools.ts +47 -0
- package/tools/project-tools.ts +107 -0
- package/tsdown.config.ts +7 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import type { AfterToolCallContext, AfterToolCallResult } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import type { TextContent } from "@mariozechner/pi-ai";
|
|
3
|
+
import { db, getCurrentPhase } from "../state/db.js";
|
|
4
|
+
import { appendEntry } from "../state/journal.js";
|
|
5
|
+
import { buildStateContext, loadSpecialist, loadDebuggerSpecialist } from "./frappe-session.js";
|
|
6
|
+
import { loadCredentials } from "../config/loader.js";
|
|
7
|
+
|
|
8
|
+
/** Reads current_phase and feature_id from the active session. */
|
|
9
|
+
function readSessionState(): { currentPhase: string; activeFeatureId: string | null } {
|
|
10
|
+
const row = db
|
|
11
|
+
.prepare("SELECT current_phase, feature_id FROM sessions WHERE is_active = 1 LIMIT 1")
|
|
12
|
+
.get() as { current_phase: string; feature_id: string | null } | undefined;
|
|
13
|
+
return {
|
|
14
|
+
currentPhase: row?.current_phase ?? "idle",
|
|
15
|
+
activeFeatureId: row?.feature_id ?? null,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Queries the active session_id from SQLite, or returns a fallback. */
|
|
20
|
+
function getActiveSessionId(): string {
|
|
21
|
+
const row = db
|
|
22
|
+
.prepare("SELECT session_id FROM sessions WHERE is_active = 1 LIMIT 1")
|
|
23
|
+
.get() as { session_id: string } | undefined;
|
|
24
|
+
return row?.session_id ?? "unknown";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Type guard for SpawnAgentResult from agent-tools.ts. */
|
|
28
|
+
function isSpawnAgentResult(value: unknown): value is { status: string; skill: string; trigger: string } {
|
|
29
|
+
return (
|
|
30
|
+
typeof value === "object" &&
|
|
31
|
+
value !== null &&
|
|
32
|
+
"status" in value &&
|
|
33
|
+
"skill" in value &&
|
|
34
|
+
"trigger" in value
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Type guard for the return value of startFeature(). */
|
|
39
|
+
function isStartFeatureResult(value: unknown): value is { mode: string; feature_id: string } {
|
|
40
|
+
return (
|
|
41
|
+
typeof value === "object" &&
|
|
42
|
+
value !== null &&
|
|
43
|
+
"mode" in value &&
|
|
44
|
+
"feature_id" in value &&
|
|
45
|
+
typeof (value as Record<string, unknown>).mode === "string" &&
|
|
46
|
+
typeof (value as Record<string, unknown>).feature_id === "string"
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Atomically updates sessions.current_phase and features.current_phase in state.db.
|
|
52
|
+
* Throws on DB failure — caller (handleAfterToolCall) converts to banner.
|
|
53
|
+
*/
|
|
54
|
+
function applyPhaseTransition(featureId: string, newPhase: string): void {
|
|
55
|
+
db.transaction(() => {
|
|
56
|
+
db.prepare("UPDATE sessions SET current_phase = ? WHERE is_active = 1").run(newPhase);
|
|
57
|
+
db.prepare("UPDATE features SET current_phase = ? WHERE feature_id = ?").run(newPhase, featureId);
|
|
58
|
+
})();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Session start hook — validates gitignore and loads credentials before any session setup.
|
|
63
|
+
* Throws with AC error message if .frappe-builder-config.json is not gitignored.
|
|
64
|
+
* Call this early in the session_start lifecycle; on throw, halt and surface the message.
|
|
65
|
+
* projectRoot defaults to process.cwd() when not supplied by the pi extension system.
|
|
66
|
+
*
|
|
67
|
+
* TODO: wire this into the pi extension system's session_start event once the
|
|
68
|
+
* session_start hook type is confirmed in @mariozechner/pi-agent-core.
|
|
69
|
+
*/
|
|
70
|
+
export function handleSessionStart(projectRoot: string = process.cwd()): void {
|
|
71
|
+
loadCredentials(projectRoot);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* afterToolCall hook — appends a JSONL journal entry and updates the sessions
|
|
76
|
+
* table in a single synchronous transaction after every tool call.
|
|
77
|
+
*
|
|
78
|
+
* Also handles FSM phase transition when start_feature fires (Story 3.3).
|
|
79
|
+
* Mode routing never touches gate execution — quality gates run independently
|
|
80
|
+
* in frappe-gates.ts regardless of mode (full or quick).
|
|
81
|
+
*
|
|
82
|
+
* Never throws. On write failure, appends a [STATE WRITE FAILED] banner to the
|
|
83
|
+
* tool result content instead of crashing the session.
|
|
84
|
+
*/
|
|
85
|
+
export async function handleAfterToolCall(
|
|
86
|
+
context: AfterToolCallContext,
|
|
87
|
+
_signal?: AbortSignal
|
|
88
|
+
): Promise<AfterToolCallResult | undefined> {
|
|
89
|
+
const toolName = context.toolCall.name;
|
|
90
|
+
const phase = getCurrentPhase();
|
|
91
|
+
const sessionId = getActiveSessionId();
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
appendEntry({
|
|
95
|
+
ts: new Date().toISOString(),
|
|
96
|
+
sessionId,
|
|
97
|
+
type: "tool_call",
|
|
98
|
+
payload: {
|
|
99
|
+
tool: toolName,
|
|
100
|
+
phase,
|
|
101
|
+
result: (() => {
|
|
102
|
+
const first = context.result.content.find((c) => c.type === "text") as
|
|
103
|
+
| TextContent
|
|
104
|
+
| undefined;
|
|
105
|
+
return first?.text.slice(0, 200) ?? "";
|
|
106
|
+
})(),
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
db.transaction(() => {
|
|
111
|
+
db.prepare(
|
|
112
|
+
"UPDATE sessions SET last_tool = ? WHERE is_active = 1"
|
|
113
|
+
).run(toolName);
|
|
114
|
+
})();
|
|
115
|
+
|
|
116
|
+
// FSM phase transition for start_feature (Story 3.3)
|
|
117
|
+
if (toolName === "start_feature") {
|
|
118
|
+
const firstText = context.result.content.find((c) => c.type === "text") as
|
|
119
|
+
| TextContent
|
|
120
|
+
| undefined;
|
|
121
|
+
if (firstText) {
|
|
122
|
+
let parsed: unknown = null;
|
|
123
|
+
try {
|
|
124
|
+
parsed = JSON.parse(firstText.text);
|
|
125
|
+
} catch {
|
|
126
|
+
// non-JSON result — skip phase transition silently
|
|
127
|
+
}
|
|
128
|
+
if (isStartFeatureResult(parsed)) {
|
|
129
|
+
const newPhase = parsed.mode === "quick" ? "implementation" : "requirements";
|
|
130
|
+
applyPhaseTransition(parsed.feature_id, newPhase);
|
|
131
|
+
|
|
132
|
+
// Specialist auto-load after phase transition (Story 3.4) — non-fatal
|
|
133
|
+
try {
|
|
134
|
+
const specCtx = buildStateContext(parsed.feature_id, toolName);
|
|
135
|
+
const specialistBlock = loadSpecialist(newPhase, specCtx);
|
|
136
|
+
if (specialistBlock) {
|
|
137
|
+
const specialistContent: TextContent = {
|
|
138
|
+
type: "text",
|
|
139
|
+
text: `\n\n${specialistBlock}`,
|
|
140
|
+
};
|
|
141
|
+
return { content: [...context.result.content, specialistContent] };
|
|
142
|
+
}
|
|
143
|
+
} catch (specialistErr) {
|
|
144
|
+
console.error(`[frappe-state] specialist load failed: ${specialistErr}`);
|
|
145
|
+
// non-fatal — session continues without specialist block
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Debugger specialist invocation (Story 3.5) — no phase transition
|
|
152
|
+
if (toolName === "invoke_debugger") {
|
|
153
|
+
const { currentPhase, activeFeatureId } = readSessionState();
|
|
154
|
+
appendEntry({
|
|
155
|
+
ts: new Date().toISOString(),
|
|
156
|
+
sessionId,
|
|
157
|
+
type: "tool_call",
|
|
158
|
+
payload: { tool: "invoke_debugger", phase_preserved: currentPhase },
|
|
159
|
+
});
|
|
160
|
+
try {
|
|
161
|
+
const specCtx = buildStateContext(activeFeatureId, toolName);
|
|
162
|
+
const debuggerBlock = loadDebuggerSpecialist(specCtx);
|
|
163
|
+
if (debuggerBlock) {
|
|
164
|
+
const content: TextContent = { type: "text", text: `\n\n${debuggerBlock}` };
|
|
165
|
+
return { content: [...context.result.content, content] };
|
|
166
|
+
}
|
|
167
|
+
} catch (debuggerErr) {
|
|
168
|
+
console.error(`[frappe-state] debugger specialist load failed: ${debuggerErr}`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Sub-agent spawn JSONL logging (Story 3.6) — no phase transition, no specialist change
|
|
173
|
+
if (toolName === "spawn_agent") {
|
|
174
|
+
const firstText = context.result.content.find((c) => c.type === "text") as TextContent | undefined;
|
|
175
|
+
if (firstText) {
|
|
176
|
+
let parsed: unknown = null;
|
|
177
|
+
try { parsed = JSON.parse(firstText.text); } catch { /* skip */ }
|
|
178
|
+
if (isSpawnAgentResult(parsed)) {
|
|
179
|
+
try {
|
|
180
|
+
const approved = parsed.status === "spawned";
|
|
181
|
+
const entry: Record<string, unknown> = {
|
|
182
|
+
type: "sub_agent",
|
|
183
|
+
skill: parsed.skill,
|
|
184
|
+
trigger: parsed.trigger,
|
|
185
|
+
approved,
|
|
186
|
+
};
|
|
187
|
+
if (parsed.status === "disabled") entry.reason = "disabled";
|
|
188
|
+
if (parsed.status === "requires_approval") entry.reason = "awaiting_approval";
|
|
189
|
+
appendEntry({
|
|
190
|
+
ts: new Date().toISOString(),
|
|
191
|
+
sessionId,
|
|
192
|
+
type: "tool_call",
|
|
193
|
+
payload: entry,
|
|
194
|
+
});
|
|
195
|
+
} catch (spawnErr) {
|
|
196
|
+
console.error(`[frappe-state] spawn_agent log failed: ${spawnErr}`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// End debug — restore previous phase specialist (Story 3.5) — no phase transition
|
|
203
|
+
if (toolName === "end_debug") {
|
|
204
|
+
const { currentPhase, activeFeatureId } = readSessionState();
|
|
205
|
+
appendEntry({
|
|
206
|
+
ts: new Date().toISOString(),
|
|
207
|
+
sessionId,
|
|
208
|
+
type: "tool_call",
|
|
209
|
+
payload: { tool: "end_debug", phase_restored: currentPhase },
|
|
210
|
+
});
|
|
211
|
+
try {
|
|
212
|
+
const specCtx = buildStateContext(activeFeatureId, toolName);
|
|
213
|
+
const specialistBlock = loadSpecialist(currentPhase, specCtx);
|
|
214
|
+
if (specialistBlock) {
|
|
215
|
+
const content: TextContent = { type: "text", text: `\n\n${specialistBlock}` };
|
|
216
|
+
return { content: [...context.result.content, content] };
|
|
217
|
+
}
|
|
218
|
+
} catch (endDebugErr) {
|
|
219
|
+
console.error(`[frappe-state] end_debug specialist restore failed: ${endDebugErr}`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return undefined;
|
|
224
|
+
} catch (err) {
|
|
225
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
226
|
+
console.error(`[frappe-state] afterToolCall write failed: ${msg}`);
|
|
227
|
+
|
|
228
|
+
const banner: TextContent = {
|
|
229
|
+
type: "text",
|
|
230
|
+
text: `\n\n[STATE WRITE FAILED: ${msg}]`,
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
return { content: [...context.result.content, banner] };
|
|
234
|
+
}
|
|
235
|
+
}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
import { startFeature, completeComponent } from "../tools/feature-tools.js";
|
|
3
|
+
import { setActiveProject, getProjectStatus } from "../tools/project-tools.js";
|
|
4
|
+
import { getAuditLog } from "../state/journal.js";
|
|
5
|
+
import { invokeDebugger, endDebug } from "../tools/debug-tools.js";
|
|
6
|
+
import { spawnAgent } from "../tools/agent-tools.js";
|
|
7
|
+
import { scaffoldDoctype, benchExecute, runTests } from "../tools/bench-tools.js";
|
|
8
|
+
import { frappeQuery } from "../tools/frappe-query-tools.js";
|
|
9
|
+
import { getFrappeDocs } from "../tools/frappe-context7.js";
|
|
10
|
+
|
|
11
|
+
// pi.registerTool's execute callback is untyped (pi is `any`); params are
|
|
12
|
+
// enforced at runtime via TypeBox schemas. One explicit-any alias avoids
|
|
13
|
+
// noImplicitAny errors across all callbacks without per-line suppressions.
|
|
14
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
15
|
+
type ToolParams = any;
|
|
16
|
+
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
18
|
+
export default function (pi: any) {
|
|
19
|
+
pi.registerTool({
|
|
20
|
+
name: "start_feature",
|
|
21
|
+
label: "Start Feature",
|
|
22
|
+
description:
|
|
23
|
+
"Creates and names a new feature within the active project, initialising its state in state.db. Valid only in the 'idle' phase.",
|
|
24
|
+
parameters: Type.Object({
|
|
25
|
+
name: Type.String({ description: "Feature name (e.g. 'PO Approval')" }),
|
|
26
|
+
mode: Type.Union([Type.Literal("full"), Type.Literal("quick")], {
|
|
27
|
+
description: "Workflow mode: 'full' for all phases, 'quick' for rapid delivery",
|
|
28
|
+
}),
|
|
29
|
+
}),
|
|
30
|
+
execute: async (_toolCallId: string, params: ToolParams) => {
|
|
31
|
+
const result = startFeature(params);
|
|
32
|
+
return {
|
|
33
|
+
content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
|
|
34
|
+
details: result,
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
pi.registerTool({
|
|
40
|
+
name: "complete_component",
|
|
41
|
+
label: "Complete Component",
|
|
42
|
+
description:
|
|
43
|
+
"Marks a feature component as complete in state.db and creates an automatic git checkpoint commit. Valid only in the 'implementation' phase.",
|
|
44
|
+
parameters: Type.Object({
|
|
45
|
+
featureId: Type.String({ description: "Feature ID (kebab-case slug, e.g. 'po-approval')" }),
|
|
46
|
+
componentId: Type.String({ description: "Component ID (e.g. 'auth-module')" }),
|
|
47
|
+
}),
|
|
48
|
+
execute: async (_toolCallId: string, params: ToolParams) => {
|
|
49
|
+
const result = await completeComponent(params);
|
|
50
|
+
return {
|
|
51
|
+
content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
|
|
52
|
+
details: result,
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
pi.registerTool({
|
|
58
|
+
name: "set_active_project",
|
|
59
|
+
label: "Set Active Project",
|
|
60
|
+
description:
|
|
61
|
+
"Switches the active Frappe project and site. Flushes current session state, creates a new session for the target project (restoring prior phase if known), and reloads the system prompt context. Available in any phase.",
|
|
62
|
+
parameters: Type.Object({
|
|
63
|
+
projectId: Type.String({ description: "Project identifier (e.g. 'my-frappe-site')" }),
|
|
64
|
+
sitePath: Type.String({ description: "Absolute path to the Frappe bench site (e.g. '/home/user/frappe-bench/sites/site1.local')" }),
|
|
65
|
+
}),
|
|
66
|
+
execute: async (_toolCallId: string, params: ToolParams) => {
|
|
67
|
+
const result = await setActiveProject(params);
|
|
68
|
+
return {
|
|
69
|
+
content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
|
|
70
|
+
details: result,
|
|
71
|
+
};
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
pi.registerTool({
|
|
76
|
+
name: "invoke_debugger",
|
|
77
|
+
label: "Invoke Debugger",
|
|
78
|
+
description:
|
|
79
|
+
"Loads the frappe-debugger specialist without triggering a phase transition. Valid in any phase (FR34).",
|
|
80
|
+
parameters: Type.Object({}),
|
|
81
|
+
execute: async (_toolCallId: string, _params: ToolParams) => {
|
|
82
|
+
const result = invokeDebugger();
|
|
83
|
+
return {
|
|
84
|
+
content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
|
|
85
|
+
details: result,
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
pi.registerTool({
|
|
91
|
+
name: "end_debug",
|
|
92
|
+
label: "End Debug",
|
|
93
|
+
description:
|
|
94
|
+
"Exits the debugger session and restores the specialist for the preserved phase. Valid in any phase.",
|
|
95
|
+
parameters: Type.Object({}),
|
|
96
|
+
execute: async (_toolCallId: string, _params: ToolParams) => {
|
|
97
|
+
const result = endDebug();
|
|
98
|
+
return {
|
|
99
|
+
content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
|
|
100
|
+
details: result,
|
|
101
|
+
};
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
pi.registerTool({
|
|
106
|
+
name: "spawn_agent",
|
|
107
|
+
label: "Spawn Agent",
|
|
108
|
+
description:
|
|
109
|
+
"Spawns a sub-agent for parallel work. Requires explicit user approval when requirePermission is true in config. Valid in any phase.",
|
|
110
|
+
parameters: Type.Object({
|
|
111
|
+
skill: Type.String({ description: "Sub-agent skill name (e.g. 'dev-agent')" }),
|
|
112
|
+
trigger: Type.String({ description: "Trigger reason (e.g. 'scaffold')" }),
|
|
113
|
+
reason: Type.String({ description: "Human-readable reason for spawning" }),
|
|
114
|
+
approved: Type.Optional(Type.Boolean({ description: "User approval decision (set after permission prompt)" })),
|
|
115
|
+
}),
|
|
116
|
+
execute: async (_toolCallId: string, params: ToolParams) => {
|
|
117
|
+
const result = await spawnAgent(params);
|
|
118
|
+
return {
|
|
119
|
+
content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
|
|
120
|
+
details: result,
|
|
121
|
+
};
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
pi.registerTool({
|
|
126
|
+
name: "scaffold_doctype",
|
|
127
|
+
label: "Scaffold DocType",
|
|
128
|
+
description:
|
|
129
|
+
"Creates a new Frappe DocType via bench. Valid only in the 'implementation' phase. (Story 4.2 deferred)",
|
|
130
|
+
parameters: Type.Object({
|
|
131
|
+
name: Type.String({ description: "DocType name in PascalCase (e.g. 'Purchase Order')" }),
|
|
132
|
+
module: Type.String({ description: "Frappe module name (e.g. 'Buying')" }),
|
|
133
|
+
}),
|
|
134
|
+
execute: async (_toolCallId: string, params: ToolParams) => {
|
|
135
|
+
const result = scaffoldDoctype(params);
|
|
136
|
+
return {
|
|
137
|
+
content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
|
|
138
|
+
details: result,
|
|
139
|
+
};
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
pi.registerTool({
|
|
144
|
+
name: "run_tests",
|
|
145
|
+
label: "Run Tests",
|
|
146
|
+
description:
|
|
147
|
+
"Runs the Frappe test suite for the active feature via bench. Valid only in the 'testing' phase. (Epic 6)",
|
|
148
|
+
parameters: Type.Object({
|
|
149
|
+
featureId: Type.Optional(Type.String({ description: "Feature ID to scope tests (optional)" })),
|
|
150
|
+
}),
|
|
151
|
+
execute: async (_toolCallId: string, params: ToolParams) => {
|
|
152
|
+
const result = runTests(params);
|
|
153
|
+
return {
|
|
154
|
+
content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
|
|
155
|
+
details: result,
|
|
156
|
+
};
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
pi.registerTool({
|
|
161
|
+
name: "get_project_status",
|
|
162
|
+
label: "Get Project Status",
|
|
163
|
+
description:
|
|
164
|
+
"Returns a dashboard summary of the active project: features, components, phase, and progress. Available in any phase. (Story 5.2)",
|
|
165
|
+
parameters: Type.Object({}),
|
|
166
|
+
execute: async (_toolCallId: string, _params: ToolParams) => {
|
|
167
|
+
const result = getProjectStatus();
|
|
168
|
+
return {
|
|
169
|
+
content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
|
|
170
|
+
details: result,
|
|
171
|
+
};
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
pi.registerTool({
|
|
176
|
+
name: "frappe_query",
|
|
177
|
+
label: "Frappe Query",
|
|
178
|
+
description:
|
|
179
|
+
"Queries Frappe data via mcp2cli subprocess. Output is routed through the context-mode sandbox — raw payloads never enter the LLM context. Available in any phase.",
|
|
180
|
+
parameters: Type.Object({
|
|
181
|
+
doctype: Type.String({ description: "Frappe DocType to query (e.g. 'Sales Order')" }),
|
|
182
|
+
filters: Type.Optional(Type.Record(Type.String(), Type.Unknown(), {
|
|
183
|
+
description: "Filter key-value pairs (e.g. { status: 'Draft' })",
|
|
184
|
+
})),
|
|
185
|
+
}),
|
|
186
|
+
execute: async (_toolCallId: string, params: ToolParams) => {
|
|
187
|
+
const result = await frappeQuery(params);
|
|
188
|
+
return {
|
|
189
|
+
content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
|
|
190
|
+
details: result,
|
|
191
|
+
};
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// 9th tool — outside the 8 core Frappe-semantic tools; bypasses phase guard via ALWAYS_ALLOWED_TOOLS
|
|
196
|
+
pi.registerTool({
|
|
197
|
+
name: "get_frappe_docs",
|
|
198
|
+
label: "Get Frappe Docs",
|
|
199
|
+
description:
|
|
200
|
+
"Retrieves compressed Frappe/ERPNext documentation via context7 MCP. Raw web content never enters the LLM context (~90% token reduction). Valid in any phase. (Story 4.4)",
|
|
201
|
+
parameters: Type.Object({
|
|
202
|
+
topic: Type.String({ description: "Documentation topic (e.g. 'DocType', 'hooks', 'frappe.db')" }),
|
|
203
|
+
version: Type.Optional(Type.String({ description: "Frappe version to scope docs (e.g. 'v15')" })),
|
|
204
|
+
}),
|
|
205
|
+
execute: async (_toolCallId: string, params: ToolParams) => {
|
|
206
|
+
const result = await getFrappeDocs(params);
|
|
207
|
+
return {
|
|
208
|
+
content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
|
|
209
|
+
details: result,
|
|
210
|
+
};
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
pi.registerTool({
|
|
215
|
+
name: "get_audit_log",
|
|
216
|
+
label: "Get Audit Log",
|
|
217
|
+
description:
|
|
218
|
+
"Queries JSONL audit log entries from session files. Supports filtering by sessionId, featureId, and limit. Available in any phase. (Story 5.3)",
|
|
219
|
+
parameters: Type.Object({
|
|
220
|
+
sessionId: Type.Optional(Type.String({ description: "Session ID to query (omit for all sessions)" })),
|
|
221
|
+
featureId: Type.Optional(Type.String({ description: "Feature ID to filter entries by payload.feature" })),
|
|
222
|
+
limit: Type.Optional(Type.Number({ description: "Maximum number of entries to return (default: all)" })),
|
|
223
|
+
}),
|
|
224
|
+
execute: async (_toolCallId: string, params: ToolParams) => {
|
|
225
|
+
const result = getAuditLog(params);
|
|
226
|
+
return {
|
|
227
|
+
content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
|
|
228
|
+
details: result,
|
|
229
|
+
};
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// /status slash command — displays project dashboard (FR21, Story 5.2)
|
|
234
|
+
// Defensive: pi.registerCommand may not be available in all pi-mono versions
|
|
235
|
+
if (typeof pi.registerCommand === "function") {
|
|
236
|
+
pi.registerCommand("status", {
|
|
237
|
+
description: "Show project dashboard: features, components, phase, and progress",
|
|
238
|
+
handler: async (_args: string, ctx: Record<string, unknown>) => {
|
|
239
|
+
const status = getProjectStatus();
|
|
240
|
+
const lines: string[] = [];
|
|
241
|
+
if (status.message) {
|
|
242
|
+
lines.push(status.message);
|
|
243
|
+
} else {
|
|
244
|
+
for (const f of status.features) {
|
|
245
|
+
lines.push(`[${f.phase}] ${f.name} (${f.componentsDone}/${f.componentsTotal} done)`);
|
|
246
|
+
for (const c of f.components) {
|
|
247
|
+
const mark = c.status === "complete" ? "✓" : "·";
|
|
248
|
+
lines.push(` ${mark} ${c.componentId}`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
const output = lines.join("\n") || "No project data";
|
|
253
|
+
if (ctx.hasUI && ctx.ui && typeof (ctx.ui as Record<string, unknown>).notify === "function") {
|
|
254
|
+
(ctx.ui as { notify: (msg: string, sev: string) => void }).notify(output, "info");
|
|
255
|
+
}
|
|
256
|
+
return output;
|
|
257
|
+
},
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
pi.registerTool({
|
|
262
|
+
name: "bench_execute",
|
|
263
|
+
label: "Bench Execute",
|
|
264
|
+
description:
|
|
265
|
+
"Runs a whitelisted bench command via subprocess. Output sandboxed through context-mode. Valid only in the 'implementation' phase. (Story 4.3)",
|
|
266
|
+
parameters: Type.Object({
|
|
267
|
+
command: Type.String({ description: "Bench command (e.g. 'migrate')" }),
|
|
268
|
+
args: Type.Optional(Type.Array(Type.String(), { description: "Additional arguments" })),
|
|
269
|
+
}),
|
|
270
|
+
execute: async (_toolCallId: string, params: ToolParams) => {
|
|
271
|
+
const result = benchExecute(params);
|
|
272
|
+
return {
|
|
273
|
+
content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
|
|
274
|
+
details: result,
|
|
275
|
+
};
|
|
276
|
+
},
|
|
277
|
+
});
|
|
278
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type { AfterToolCallContext, AfterToolCallResult } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import { db, getCurrentPhase } from "../state/db.js";
|
|
3
|
+
|
|
4
|
+
interface FooterState {
|
|
5
|
+
projectId: string | null;
|
|
6
|
+
featureName: string | null;
|
|
7
|
+
phase: string;
|
|
8
|
+
tokenCount: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function readFooterState(): FooterState {
|
|
12
|
+
try {
|
|
13
|
+
const session = db
|
|
14
|
+
.prepare(
|
|
15
|
+
`SELECT s.project_id, f.name AS feature_name, s.current_phase
|
|
16
|
+
FROM sessions s
|
|
17
|
+
LEFT JOIN features f ON f.feature_id = s.feature_id
|
|
18
|
+
WHERE s.is_active = 1 LIMIT 1`
|
|
19
|
+
)
|
|
20
|
+
.get() as
|
|
21
|
+
| { project_id: string | null; feature_name: string | null; current_phase: string }
|
|
22
|
+
| undefined;
|
|
23
|
+
|
|
24
|
+
// Token count: count journal_entries for active session; table may not exist yet
|
|
25
|
+
let tokenCount = 0;
|
|
26
|
+
try {
|
|
27
|
+
const tokenRow = db
|
|
28
|
+
.prepare(
|
|
29
|
+
`SELECT COUNT(*) as count FROM journal_entries
|
|
30
|
+
WHERE session_id = (SELECT session_id FROM sessions WHERE is_active = 1 LIMIT 1)`
|
|
31
|
+
)
|
|
32
|
+
.get() as { count: number } | undefined;
|
|
33
|
+
tokenCount = tokenRow?.count ?? 0;
|
|
34
|
+
} catch {
|
|
35
|
+
// journal_entries table not yet created — default to 0
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
projectId: session?.project_id ?? null,
|
|
40
|
+
featureName: session?.feature_name ?? null,
|
|
41
|
+
phase: session?.current_phase ?? "idle",
|
|
42
|
+
tokenCount,
|
|
43
|
+
};
|
|
44
|
+
} catch {
|
|
45
|
+
return { projectId: null, featureName: null, phase: "idle", tokenCount: 0 };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Pure formatting function — no I/O, no side effects.
|
|
51
|
+
* Exported for unit testing.
|
|
52
|
+
*/
|
|
53
|
+
export function formatFooter(state: FooterState): string {
|
|
54
|
+
if (!state.projectId) {
|
|
55
|
+
return `No active project | Phase: ${state.phase}`;
|
|
56
|
+
}
|
|
57
|
+
if (!state.featureName) {
|
|
58
|
+
return `Project: ${state.projectId} | No active feature | Phase: ${state.phase}`;
|
|
59
|
+
}
|
|
60
|
+
return `Project: ${state.projectId} | Feature: ${state.featureName} | Phase: ${state.phase} | Tokens: ${state.tokenCount}`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function renderFooter(): void {
|
|
64
|
+
try {
|
|
65
|
+
const state = readFooterState();
|
|
66
|
+
const line = formatFooter(state);
|
|
67
|
+
process.stderr.write(`\r\x1b[2K[frappe-builder] ${line}\n`);
|
|
68
|
+
} catch {
|
|
69
|
+
// Silently swallow all rendering errors — footer is non-critical
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* beforeToolCall announcement hook — writes "→ Calling {tool} [{phase}]" to stderr.
|
|
75
|
+
* Always returns undefined — this hook only announces, never blocks.
|
|
76
|
+
* Wrap in try/catch so announcement failure never crashes the session.
|
|
77
|
+
*
|
|
78
|
+
* Load order note: frappe-ui must load before frappe-workflow so this fires
|
|
79
|
+
* before the FSM guard. Load order is controlled by the pi extension list;
|
|
80
|
+
* package.json "pi" field is currently empty so order is determined by the
|
|
81
|
+
* pi CLI -e flags at startup.
|
|
82
|
+
*/
|
|
83
|
+
export function handleBeforeToolCall(toolName: string): undefined {
|
|
84
|
+
try {
|
|
85
|
+
const phase = getCurrentPhase();
|
|
86
|
+
process.stderr.write(`→ Calling ${toolName} [${phase}]\n`);
|
|
87
|
+
} catch {
|
|
88
|
+
// Swallow — announcement is non-critical, must never block or crash
|
|
89
|
+
}
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* afterToolCall hook — renders the footer and returns undefined so the
|
|
95
|
+
* original tool result passes through unmodified.
|
|
96
|
+
*/
|
|
97
|
+
export async function handleAfterToolCall(
|
|
98
|
+
_context: AfterToolCallContext,
|
|
99
|
+
_signal?: AbortSignal
|
|
100
|
+
): Promise<AfterToolCallResult | undefined> {
|
|
101
|
+
renderFooter();
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
106
|
+
export default function (pi: any) {
|
|
107
|
+
pi.on("session_start", () => {
|
|
108
|
+
renderFooter();
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Announcement hook — fires before FSM guard in frappe-workflow.ts (FR25)
|
|
112
|
+
pi.on("tool_call", (event: { toolName?: string }) => {
|
|
113
|
+
return handleBeforeToolCall(event.toolName ?? "");
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
pi.on("after_tool_call", async (context: AfterToolCallContext) => {
|
|
117
|
+
return await handleAfterToolCall(context);
|
|
118
|
+
});
|
|
119
|
+
}
|