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.
Files changed (425) hide show
  1. package/.fb/state.db +0 -0
  2. package/AGENTS.md +167 -0
  3. package/README.md +89 -0
  4. package/_bmad/_config/agent-manifest.csv +10 -0
  5. package/_bmad/_config/agents/bmm-analyst.customize.yaml +41 -0
  6. package/_bmad/_config/agents/bmm-architect.customize.yaml +41 -0
  7. package/_bmad/_config/agents/bmm-dev.customize.yaml +41 -0
  8. package/_bmad/_config/agents/bmm-pm.customize.yaml +41 -0
  9. package/_bmad/_config/agents/bmm-qa.customize.yaml +41 -0
  10. package/_bmad/_config/agents/bmm-quick-flow-solo-dev.customize.yaml +41 -0
  11. package/_bmad/_config/agents/bmm-sm.customize.yaml +41 -0
  12. package/_bmad/_config/agents/bmm-tech-writer.customize.yaml +41 -0
  13. package/_bmad/_config/agents/bmm-ux-designer.customize.yaml +41 -0
  14. package/_bmad/_config/bmad-help.csv +47 -0
  15. package/_bmad/_config/files-manifest.csv +369 -0
  16. package/_bmad/_config/ides/claude-code.yaml +5 -0
  17. package/_bmad/_config/manifest.yaml +28 -0
  18. package/_bmad/_config/skill-manifest.csv +41 -0
  19. package/_bmad/_config/task-manifest.csv +1 -0
  20. package/_bmad/_config/tool-manifest.csv +1 -0
  21. package/_bmad/_config/workflow-manifest.csv +1 -0
  22. package/_bmad/_memory/config.yaml +11 -0
  23. package/_bmad/_memory/tech-writer-sidecar/documentation-standards.md +224 -0
  24. package/_bmad/bmm/agents/analyst.md +69 -0
  25. package/_bmad/bmm/agents/architect.md +59 -0
  26. package/_bmad/bmm/agents/bmad-skill-manifest.yaml +39 -0
  27. package/_bmad/bmm/agents/dev.md +66 -0
  28. package/_bmad/bmm/agents/pm.md +63 -0
  29. package/_bmad/bmm/agents/qa.md +89 -0
  30. package/_bmad/bmm/agents/quick-flow-solo-dev.md +61 -0
  31. package/_bmad/bmm/agents/sm.md +67 -0
  32. package/_bmad/bmm/agents/tech-writer/bmad-skill-manifest.yaml +3 -0
  33. package/_bmad/bmm/agents/tech-writer/tech-writer.md +67 -0
  34. package/_bmad/bmm/agents/ux-designer.md +58 -0
  35. package/_bmad/bmm/config.yaml +16 -0
  36. package/_bmad/bmm/data/project-context-template.md +26 -0
  37. package/_bmad/bmm/module-help.csv +32 -0
  38. package/_bmad/bmm/teams/default-party.csv +20 -0
  39. package/_bmad/bmm/teams/team-fullstack.yaml +12 -0
  40. package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/SKILL.md +6 -0
  41. package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/bmad-skill-manifest.yaml +1 -0
  42. package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/product-brief.template.md +10 -0
  43. package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/steps/step-01-init.md +170 -0
  44. package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/steps/step-01b-continue.md +158 -0
  45. package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/steps/step-02-vision.md +193 -0
  46. package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/steps/step-03-users.md +196 -0
  47. package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/steps/step-04-metrics.md +199 -0
  48. package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/steps/step-05-scope.md +213 -0
  49. package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/steps/step-06-complete.md +159 -0
  50. package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/workflow.md +55 -0
  51. package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/SKILL.md +88 -0
  52. package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/agents/artifact-analyzer.md +60 -0
  53. package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/agents/opportunity-reviewer.md +44 -0
  54. package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/agents/skeptic-reviewer.md +44 -0
  55. package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/agents/web-researcher.md +49 -0
  56. package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/bmad-manifest.json +17 -0
  57. package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/bmad-skill-manifest.yaml +1 -0
  58. package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/prompts/contextual-discovery.md +57 -0
  59. package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/prompts/draft-and-review.md +86 -0
  60. package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/prompts/finalize.md +75 -0
  61. package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/prompts/guided-elicitation.md +70 -0
  62. package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/resources/brief-template.md +60 -0
  63. package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/SKILL.md +6 -0
  64. package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/bmad-skill-manifest.yaml +1 -0
  65. package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/domain-steps/step-01-init.md +137 -0
  66. package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/domain-steps/step-02-domain-analysis.md +229 -0
  67. package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/domain-steps/step-03-competitive-landscape.md +238 -0
  68. package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/domain-steps/step-04-regulatory-focus.md +206 -0
  69. package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/domain-steps/step-05-technical-trends.md +234 -0
  70. package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/domain-steps/step-06-research-synthesis.md +444 -0
  71. package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/research.template.md +29 -0
  72. package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/workflow.md +49 -0
  73. package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/SKILL.md +6 -0
  74. package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/bmad-skill-manifest.yaml +1 -0
  75. package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/research.template.md +29 -0
  76. package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-01-init.md +184 -0
  77. package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-02-customer-behavior.md +239 -0
  78. package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-03-customer-pain-points.md +251 -0
  79. package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-04-customer-decisions.md +261 -0
  80. package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-05-competitive-analysis.md +173 -0
  81. package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-06-research-completion.md +478 -0
  82. package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/workflow.md +49 -0
  83. package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/SKILL.md +6 -0
  84. package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/bmad-skill-manifest.yaml +1 -0
  85. package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/research.template.md +29 -0
  86. package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/technical-steps/step-01-init.md +137 -0
  87. package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/technical-steps/step-02-technical-overview.md +239 -0
  88. package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/technical-steps/step-03-integration-patterns.md +248 -0
  89. package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/technical-steps/step-04-architectural-patterns.md +202 -0
  90. package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/technical-steps/step-05-implementation-research.md +233 -0
  91. package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/technical-steps/step-06-research-synthesis.md +487 -0
  92. package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/workflow.md +50 -0
  93. package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +182 -0
  94. package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +237 -0
  95. package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +249 -0
  96. package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +259 -0
  97. package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +177 -0
  98. package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +476 -0
  99. package/_bmad/bmm/workflows/1-analysis/research/research.template.md +29 -0
  100. package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/SKILL.md +6 -0
  101. package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/bmad-skill-manifest.yaml +1 -0
  102. package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-01-init.md +135 -0
  103. package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-01b-continue.md +127 -0
  104. package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-02-discovery.md +190 -0
  105. package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-03-core-experience.md +217 -0
  106. package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-04-emotional-response.md +220 -0
  107. package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-05-inspiration.md +235 -0
  108. package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-06-design-system.md +253 -0
  109. package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-07-defining-experience.md +255 -0
  110. package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-08-visual-foundation.md +225 -0
  111. package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-09-design-directions.md +225 -0
  112. package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-10-user-journeys.md +242 -0
  113. package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-11-component-strategy.md +249 -0
  114. package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-12-ux-patterns.md +238 -0
  115. package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-13-responsive-accessibility.md +265 -0
  116. package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-14-complete.md +171 -0
  117. package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/ux-design-template.md +13 -0
  118. package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/workflow.md +36 -0
  119. package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/SKILL.md +6 -0
  120. package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/bmad-skill-manifest.yaml +1 -0
  121. package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/steps-e/step-e-01-discovery.md +242 -0
  122. package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/steps-e/step-e-01b-legacy-conversion.md +204 -0
  123. package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/steps-e/step-e-02-review.md +245 -0
  124. package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/steps-e/step-e-03-edit.md +250 -0
  125. package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/steps-e/step-e-04-complete.md +165 -0
  126. package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/workflow.md +63 -0
  127. package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/SKILL.md +6 -0
  128. package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/bmad-skill-manifest.yaml +1 -0
  129. package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/data/domain-complexity.csv +15 -0
  130. package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/data/prd-purpose.md +197 -0
  131. package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/data/project-types.csv +11 -0
  132. package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-01-discovery.md +221 -0
  133. package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-02-format-detection.md +188 -0
  134. package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-02b-parity-check.md +206 -0
  135. package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-03-density-validation.md +171 -0
  136. package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-04-brief-coverage-validation.md +211 -0
  137. package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-05-measurability-validation.md +225 -0
  138. package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-06-traceability-validation.md +214 -0
  139. package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-07-implementation-leakage-validation.md +202 -0
  140. package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-08-domain-compliance-validation.md +240 -0
  141. package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-09-project-type-validation.md +260 -0
  142. package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-10-smart-validation.md +206 -0
  143. package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-11-holistic-quality-validation.md +261 -0
  144. package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-12-completeness-validation.md +239 -0
  145. package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-13-report-complete.md +229 -0
  146. package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/workflow.md +62 -0
  147. package/_bmad/bmm/workflows/2-plan-workflows/create-prd/data/domain-complexity.csv +15 -0
  148. package/_bmad/bmm/workflows/2-plan-workflows/create-prd/data/prd-purpose.md +197 -0
  149. package/_bmad/bmm/workflows/2-plan-workflows/create-prd/data/project-types.csv +11 -0
  150. package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-01-discovery.md +224 -0
  151. package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-02-format-detection.md +191 -0
  152. package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-02b-parity-check.md +209 -0
  153. package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-03-density-validation.md +174 -0
  154. package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-04-brief-coverage-validation.md +214 -0
  155. package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-05-measurability-validation.md +228 -0
  156. package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-06-traceability-validation.md +217 -0
  157. package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-07-implementation-leakage-validation.md +205 -0
  158. package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-08-domain-compliance-validation.md +243 -0
  159. package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-09-project-type-validation.md +263 -0
  160. package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-10-smart-validation.md +209 -0
  161. package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-11-holistic-quality-validation.md +264 -0
  162. package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-12-completeness-validation.md +242 -0
  163. package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-13-report-complete.md +232 -0
  164. package/_bmad/bmm/workflows/2-plan-workflows/create-prd/workflow-validate-prd.md +65 -0
  165. package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/SKILL.md +6 -0
  166. package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/bmad-skill-manifest.yaml +1 -0
  167. package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/steps/step-01-document-discovery.md +179 -0
  168. package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/steps/step-02-prd-analysis.md +168 -0
  169. package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/steps/step-03-epic-coverage-validation.md +169 -0
  170. package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/steps/step-04-ux-alignment.md +129 -0
  171. package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/steps/step-05-epic-quality-review.md +241 -0
  172. package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/steps/step-06-final-assessment.md +126 -0
  173. package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/templates/readiness-report-template.md +4 -0
  174. package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/workflow.md +49 -0
  175. package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/SKILL.md +6 -0
  176. package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/architecture-decision-template.md +12 -0
  177. package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/bmad-skill-manifest.yaml +1 -0
  178. package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/data/domain-complexity.csv +13 -0
  179. package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/data/project-types.csv +7 -0
  180. package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-01-init.md +153 -0
  181. package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-01b-continue.md +173 -0
  182. package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-02-context.md +224 -0
  183. package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-03-starter.md +329 -0
  184. package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-04-decisions.md +318 -0
  185. package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-05-patterns.md +359 -0
  186. package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-06-structure.md +379 -0
  187. package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-07-validation.md +359 -0
  188. package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-08-complete.md +76 -0
  189. package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/workflow.md +38 -0
  190. package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/SKILL.md +6 -0
  191. package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/bmad-skill-manifest.yaml +1 -0
  192. package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/steps/step-01-validate-prerequisites.md +255 -0
  193. package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/steps/step-02-design-epics.md +212 -0
  194. package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/steps/step-03-create-stories.md +255 -0
  195. package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/steps/step-04-final-validation.md +131 -0
  196. package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/templates/epics-template.md +61 -0
  197. package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/workflow.md +53 -0
  198. package/_bmad/bmm/workflows/4-implementation/bmad-code-review/SKILL.md +6 -0
  199. package/_bmad/bmm/workflows/4-implementation/bmad-code-review/bmad-skill-manifest.yaml +1 -0
  200. package/_bmad/bmm/workflows/4-implementation/bmad-code-review/steps/step-01-gather-context.md +61 -0
  201. package/_bmad/bmm/workflows/4-implementation/bmad-code-review/steps/step-02-review.md +41 -0
  202. package/_bmad/bmm/workflows/4-implementation/bmad-code-review/steps/step-03-triage.md +50 -0
  203. package/_bmad/bmm/workflows/4-implementation/bmad-code-review/steps/step-04-present.md +38 -0
  204. package/_bmad/bmm/workflows/4-implementation/bmad-code-review/workflow.md +54 -0
  205. package/_bmad/bmm/workflows/4-implementation/bmad-correct-course/SKILL.md +6 -0
  206. package/_bmad/bmm/workflows/4-implementation/bmad-correct-course/bmad-skill-manifest.yaml +1 -0
  207. package/_bmad/bmm/workflows/4-implementation/bmad-correct-course/checklist.md +288 -0
  208. package/_bmad/bmm/workflows/4-implementation/bmad-correct-course/workflow.md +267 -0
  209. package/_bmad/bmm/workflows/4-implementation/bmad-create-story/SKILL.md +6 -0
  210. package/_bmad/bmm/workflows/4-implementation/bmad-create-story/bmad-skill-manifest.yaml +1 -0
  211. package/_bmad/bmm/workflows/4-implementation/bmad-create-story/checklist.md +357 -0
  212. package/_bmad/bmm/workflows/4-implementation/bmad-create-story/discover-inputs.md +88 -0
  213. package/_bmad/bmm/workflows/4-implementation/bmad-create-story/template.md +49 -0
  214. package/_bmad/bmm/workflows/4-implementation/bmad-create-story/workflow.md +380 -0
  215. package/_bmad/bmm/workflows/4-implementation/bmad-dev-story/SKILL.md +6 -0
  216. package/_bmad/bmm/workflows/4-implementation/bmad-dev-story/bmad-skill-manifest.yaml +1 -0
  217. package/_bmad/bmm/workflows/4-implementation/bmad-dev-story/checklist.md +80 -0
  218. package/_bmad/bmm/workflows/4-implementation/bmad-dev-story/workflow.md +450 -0
  219. package/_bmad/bmm/workflows/4-implementation/bmad-retrospective/SKILL.md +6 -0
  220. package/_bmad/bmm/workflows/4-implementation/bmad-retrospective/bmad-skill-manifest.yaml +1 -0
  221. package/_bmad/bmm/workflows/4-implementation/bmad-retrospective/workflow.md +1479 -0
  222. package/_bmad/bmm/workflows/4-implementation/bmad-sprint-planning/SKILL.md +6 -0
  223. package/_bmad/bmm/workflows/4-implementation/bmad-sprint-planning/bmad-skill-manifest.yaml +1 -0
  224. package/_bmad/bmm/workflows/4-implementation/bmad-sprint-planning/checklist.md +33 -0
  225. package/_bmad/bmm/workflows/4-implementation/bmad-sprint-planning/sprint-status-template.yaml +56 -0
  226. package/_bmad/bmm/workflows/4-implementation/bmad-sprint-planning/workflow.md +263 -0
  227. package/_bmad/bmm/workflows/4-implementation/bmad-sprint-status/SKILL.md +6 -0
  228. package/_bmad/bmm/workflows/4-implementation/bmad-sprint-status/bmad-skill-manifest.yaml +1 -0
  229. package/_bmad/bmm/workflows/4-implementation/bmad-sprint-status/workflow.md +261 -0
  230. package/_bmad/bmm/workflows/bmad-document-project/SKILL.md +6 -0
  231. package/_bmad/bmm/workflows/bmad-document-project/bmad-skill-manifest.yaml +1 -0
  232. package/_bmad/bmm/workflows/bmad-document-project/checklist.md +245 -0
  233. package/_bmad/bmm/workflows/bmad-document-project/documentation-requirements.csv +12 -0
  234. package/_bmad/bmm/workflows/bmad-document-project/instructions.md +128 -0
  235. package/_bmad/bmm/workflows/bmad-document-project/templates/deep-dive-template.md +345 -0
  236. package/_bmad/bmm/workflows/bmad-document-project/templates/index-template.md +169 -0
  237. package/_bmad/bmm/workflows/bmad-document-project/templates/project-overview-template.md +103 -0
  238. package/_bmad/bmm/workflows/bmad-document-project/templates/project-scan-report-schema.json +160 -0
  239. package/_bmad/bmm/workflows/bmad-document-project/templates/source-tree-template.md +135 -0
  240. package/_bmad/bmm/workflows/bmad-document-project/workflow.md +27 -0
  241. package/_bmad/bmm/workflows/bmad-document-project/workflows/deep-dive-instructions.md +299 -0
  242. package/_bmad/bmm/workflows/bmad-document-project/workflows/deep-dive-workflow.md +34 -0
  243. package/_bmad/bmm/workflows/bmad-document-project/workflows/full-scan-instructions.md +1107 -0
  244. package/_bmad/bmm/workflows/bmad-document-project/workflows/full-scan-workflow.md +34 -0
  245. package/_bmad/bmm/workflows/bmad-generate-project-context/SKILL.md +6 -0
  246. package/_bmad/bmm/workflows/bmad-generate-project-context/bmad-skill-manifest.yaml +1 -0
  247. package/_bmad/bmm/workflows/bmad-generate-project-context/project-context-template.md +21 -0
  248. package/_bmad/bmm/workflows/bmad-generate-project-context/steps/step-01-discover.md +186 -0
  249. package/_bmad/bmm/workflows/bmad-generate-project-context/steps/step-02-generate.md +321 -0
  250. package/_bmad/bmm/workflows/bmad-generate-project-context/steps/step-03-complete.md +278 -0
  251. package/_bmad/bmm/workflows/bmad-generate-project-context/workflow.md +43 -0
  252. package/_bmad/bmm/workflows/bmad-qa-generate-e2e-tests/SKILL.md +6 -0
  253. package/_bmad/bmm/workflows/bmad-qa-generate-e2e-tests/bmad-skill-manifest.yaml +1 -0
  254. package/_bmad/bmm/workflows/bmad-qa-generate-e2e-tests/checklist.md +33 -0
  255. package/_bmad/bmm/workflows/bmad-qa-generate-e2e-tests/workflow.md +136 -0
  256. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/SKILL.md +6 -0
  257. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/bmad-skill-manifest.yaml +1 -0
  258. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/steps/step-01-mode-detection.md +169 -0
  259. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/steps/step-02-context-gathering.md +114 -0
  260. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/steps/step-03-execute.md +107 -0
  261. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/steps/step-04-self-check.md +107 -0
  262. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/steps/step-05-adversarial-review.md +94 -0
  263. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/steps/step-06-resolve-findings.md +144 -0
  264. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/workflow.md +38 -0
  265. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/SKILL.md +6 -0
  266. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/bmad-skill-manifest.yaml +1 -0
  267. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/steps/step-01-clarify-and-route.md +51 -0
  268. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/steps/step-02-plan.md +35 -0
  269. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/steps/step-03-implement.md +33 -0
  270. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/steps/step-04-review.md +50 -0
  271. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/steps/step-05-present.md +17 -0
  272. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/tech-spec-template.md +90 -0
  273. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/workflow.md +79 -0
  274. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/SKILL.md +6 -0
  275. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/bmad-skill-manifest.yaml +1 -0
  276. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/steps/step-01-understand.md +185 -0
  277. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/steps/step-02-investigate.md +140 -0
  278. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/steps/step-03-generate.md +123 -0
  279. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/steps/step-04-review.md +195 -0
  280. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/tech-spec-template.md +74 -0
  281. package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/workflow.md +73 -0
  282. package/_bmad/cis/config.yaml +12 -0
  283. package/_bmad/cis/module-help.csv +6 -0
  284. package/_bmad/cis/skills/bmad-cis-agent-brainstorming-coach/SKILL.md +51 -0
  285. package/_bmad/cis/skills/bmad-cis-agent-brainstorming-coach/bmad-skill-manifest.yaml +11 -0
  286. package/_bmad/cis/skills/bmad-cis-agent-creative-problem-solver/SKILL.md +51 -0
  287. package/_bmad/cis/skills/bmad-cis-agent-creative-problem-solver/bmad-skill-manifest.yaml +11 -0
  288. package/_bmad/cis/skills/bmad-cis-agent-design-thinking-coach/SKILL.md +52 -0
  289. package/_bmad/cis/skills/bmad-cis-agent-design-thinking-coach/bmad-skill-manifest.yaml +11 -0
  290. package/_bmad/cis/skills/bmad-cis-agent-innovation-strategist/SKILL.md +51 -0
  291. package/_bmad/cis/skills/bmad-cis-agent-innovation-strategist/bmad-skill-manifest.yaml +11 -0
  292. package/_bmad/cis/skills/bmad-cis-agent-presentation-master/SKILL.md +62 -0
  293. package/_bmad/cis/skills/bmad-cis-agent-presentation-master/bmad-skill-manifest.yaml +11 -0
  294. package/_bmad/cis/skills/bmad-cis-agent-storyteller/SKILL.md +56 -0
  295. package/_bmad/cis/skills/bmad-cis-agent-storyteller/bmad-skill-manifest.yaml +11 -0
  296. package/_bmad/cis/skills/bmad-cis-agent-storyteller/stories-told.md +7 -0
  297. package/_bmad/cis/skills/bmad-cis-agent-storyteller/story-preferences.md +7 -0
  298. package/_bmad/cis/skills/bmad-cis-design-thinking/SKILL.md +6 -0
  299. package/_bmad/cis/skills/bmad-cis-design-thinking/bmad-skill-manifest.yaml +1 -0
  300. package/_bmad/cis/skills/bmad-cis-design-thinking/design-methods.csv +31 -0
  301. package/_bmad/cis/skills/bmad-cis-design-thinking/template.md +111 -0
  302. package/_bmad/cis/skills/bmad-cis-design-thinking/workflow.md +242 -0
  303. package/_bmad/cis/skills/bmad-cis-innovation-strategy/SKILL.md +6 -0
  304. package/_bmad/cis/skills/bmad-cis-innovation-strategy/bmad-skill-manifest.yaml +1 -0
  305. package/_bmad/cis/skills/bmad-cis-innovation-strategy/innovation-frameworks.csv +31 -0
  306. package/_bmad/cis/skills/bmad-cis-innovation-strategy/template.md +189 -0
  307. package/_bmad/cis/skills/bmad-cis-innovation-strategy/workflow.md +315 -0
  308. package/_bmad/cis/skills/bmad-cis-problem-solving/SKILL.md +6 -0
  309. package/_bmad/cis/skills/bmad-cis-problem-solving/bmad-skill-manifest.yaml +1 -0
  310. package/_bmad/cis/skills/bmad-cis-problem-solving/solving-methods.csv +31 -0
  311. package/_bmad/cis/skills/bmad-cis-problem-solving/template.md +165 -0
  312. package/_bmad/cis/skills/bmad-cis-problem-solving/workflow.md +291 -0
  313. package/_bmad/cis/skills/bmad-cis-storytelling/SKILL.md +6 -0
  314. package/_bmad/cis/skills/bmad-cis-storytelling/bmad-skill-manifest.yaml +1 -0
  315. package/_bmad/cis/skills/bmad-cis-storytelling/story-types.csv +26 -0
  316. package/_bmad/cis/skills/bmad-cis-storytelling/template.md +113 -0
  317. package/_bmad/cis/skills/bmad-cis-storytelling/workflow.md +321 -0
  318. package/_bmad/core/config.yaml +9 -0
  319. package/_bmad/core/module-help.csv +11 -0
  320. package/_bmad/core/skills/bmad-advanced-elicitation/SKILL.md +6 -0
  321. package/_bmad/core/skills/bmad-advanced-elicitation/bmad-skill-manifest.yaml +1 -0
  322. package/_bmad/core/skills/bmad-advanced-elicitation/methods.csv +51 -0
  323. package/_bmad/core/skills/bmad-advanced-elicitation/workflow.md +135 -0
  324. package/_bmad/core/skills/bmad-brainstorming/SKILL.md +6 -0
  325. package/_bmad/core/skills/bmad-brainstorming/bmad-skill-manifest.yaml +1 -0
  326. package/_bmad/core/skills/bmad-brainstorming/brain-methods.csv +62 -0
  327. package/_bmad/core/skills/bmad-brainstorming/steps/step-01-session-setup.md +214 -0
  328. package/_bmad/core/skills/bmad-brainstorming/steps/step-01b-continue.md +124 -0
  329. package/_bmad/core/skills/bmad-brainstorming/steps/step-02a-user-selected.md +229 -0
  330. package/_bmad/core/skills/bmad-brainstorming/steps/step-02b-ai-recommended.md +239 -0
  331. package/_bmad/core/skills/bmad-brainstorming/steps/step-02c-random-selection.md +211 -0
  332. package/_bmad/core/skills/bmad-brainstorming/steps/step-02d-progressive-flow.md +266 -0
  333. package/_bmad/core/skills/bmad-brainstorming/steps/step-03-technique-execution.md +401 -0
  334. package/_bmad/core/skills/bmad-brainstorming/steps/step-04-idea-organization.md +305 -0
  335. package/_bmad/core/skills/bmad-brainstorming/template.md +15 -0
  336. package/_bmad/core/skills/bmad-brainstorming/workflow.md +53 -0
  337. package/_bmad/core/skills/bmad-distillator/SKILL.md +178 -0
  338. package/_bmad/core/skills/bmad-distillator/agents/distillate-compressor.md +116 -0
  339. package/_bmad/core/skills/bmad-distillator/agents/round-trip-reconstructor.md +68 -0
  340. package/_bmad/core/skills/bmad-distillator/bmad-skill-manifest.yaml +15 -0
  341. package/_bmad/core/skills/bmad-distillator/resources/compression-rules.md +51 -0
  342. package/_bmad/core/skills/bmad-distillator/resources/distillate-format-reference.md +227 -0
  343. package/_bmad/core/skills/bmad-distillator/resources/splitting-strategy.md +78 -0
  344. package/_bmad/core/skills/bmad-editorial-review-prose/SKILL.md +6 -0
  345. package/_bmad/core/skills/bmad-editorial-review-prose/bmad-skill-manifest.yaml +1 -0
  346. package/_bmad/core/skills/bmad-editorial-review-prose/workflow.md +81 -0
  347. package/_bmad/core/skills/bmad-editorial-review-structure/SKILL.md +6 -0
  348. package/_bmad/core/skills/bmad-editorial-review-structure/bmad-skill-manifest.yaml +1 -0
  349. package/_bmad/core/skills/bmad-editorial-review-structure/workflow.md +174 -0
  350. package/_bmad/core/skills/bmad-help/SKILL.md +6 -0
  351. package/_bmad/core/skills/bmad-help/bmad-skill-manifest.yaml +1 -0
  352. package/_bmad/core/skills/bmad-help/workflow.md +88 -0
  353. package/_bmad/core/skills/bmad-index-docs/SKILL.md +6 -0
  354. package/_bmad/core/skills/bmad-index-docs/bmad-skill-manifest.yaml +1 -0
  355. package/_bmad/core/skills/bmad-index-docs/workflow.md +61 -0
  356. package/_bmad/core/skills/bmad-party-mode/SKILL.md +6 -0
  357. package/_bmad/core/skills/bmad-party-mode/bmad-skill-manifest.yaml +1 -0
  358. package/_bmad/core/skills/bmad-party-mode/steps/step-01-agent-loading.md +138 -0
  359. package/_bmad/core/skills/bmad-party-mode/steps/step-02-discussion-orchestration.md +187 -0
  360. package/_bmad/core/skills/bmad-party-mode/steps/step-03-graceful-exit.md +167 -0
  361. package/_bmad/core/skills/bmad-party-mode/workflow.md +190 -0
  362. package/_bmad/core/skills/bmad-review-adversarial-general/SKILL.md +6 -0
  363. package/_bmad/core/skills/bmad-review-adversarial-general/bmad-skill-manifest.yaml +1 -0
  364. package/_bmad/core/skills/bmad-review-adversarial-general/workflow.md +32 -0
  365. package/_bmad/core/skills/bmad-review-edge-case-hunter/SKILL.md +6 -0
  366. package/_bmad/core/skills/bmad-review-edge-case-hunter/bmad-skill-manifest.yaml +1 -0
  367. package/_bmad/core/skills/bmad-review-edge-case-hunter/workflow.md +62 -0
  368. package/_bmad/core/skills/bmad-shard-doc/SKILL.md +6 -0
  369. package/_bmad/core/skills/bmad-shard-doc/bmad-skill-manifest.yaml +1 -0
  370. package/_bmad/core/skills/bmad-shard-doc/workflow.md +100 -0
  371. package/_bmad/core/tasks/bmad-create-prd/SKILL.md +6 -0
  372. package/_bmad/core/tasks/bmad-create-prd/bmad-skill-manifest.yaml +1 -0
  373. package/_bmad/core/tasks/bmad-create-prd/data/domain-complexity.csv +15 -0
  374. package/_bmad/core/tasks/bmad-create-prd/data/prd-purpose.md +197 -0
  375. package/_bmad/core/tasks/bmad-create-prd/data/project-types.csv +11 -0
  376. package/_bmad/core/tasks/bmad-create-prd/steps-c/step-01-init.md +178 -0
  377. package/_bmad/core/tasks/bmad-create-prd/steps-c/step-01b-continue.md +161 -0
  378. package/_bmad/core/tasks/bmad-create-prd/steps-c/step-02-discovery.md +208 -0
  379. package/_bmad/core/tasks/bmad-create-prd/steps-c/step-02b-vision.md +142 -0
  380. package/_bmad/core/tasks/bmad-create-prd/steps-c/step-02c-executive-summary.md +158 -0
  381. package/_bmad/core/tasks/bmad-create-prd/steps-c/step-03-success.md +214 -0
  382. package/_bmad/core/tasks/bmad-create-prd/steps-c/step-04-journeys.md +201 -0
  383. package/_bmad/core/tasks/bmad-create-prd/steps-c/step-05-domain.md +194 -0
  384. package/_bmad/core/tasks/bmad-create-prd/steps-c/step-06-innovation.md +211 -0
  385. package/_bmad/core/tasks/bmad-create-prd/steps-c/step-07-project-type.md +222 -0
  386. package/_bmad/core/tasks/bmad-create-prd/steps-c/step-08-scoping.md +216 -0
  387. package/_bmad/core/tasks/bmad-create-prd/steps-c/step-09-functional.md +219 -0
  388. package/_bmad/core/tasks/bmad-create-prd/steps-c/step-10-nonfunctional.md +230 -0
  389. package/_bmad/core/tasks/bmad-create-prd/steps-c/step-11-polish.md +221 -0
  390. package/_bmad/core/tasks/bmad-create-prd/steps-c/step-12-complete.md +115 -0
  391. package/_bmad/core/tasks/bmad-create-prd/templates/prd-template.md +10 -0
  392. package/_bmad/core/tasks/bmad-create-prd/workflow.md +62 -0
  393. package/config/allowed-commands.ts +39 -0
  394. package/config/defaults.ts +19 -0
  395. package/config/loader.ts +105 -0
  396. package/dist/cli.mjs +67 -0
  397. package/dist/init-BYJy3ztn.mjs +159 -0
  398. package/extensions/frappe-gates.ts +160 -0
  399. package/extensions/frappe-session.ts +324 -0
  400. package/extensions/frappe-state.ts +235 -0
  401. package/extensions/frappe-tools.ts +278 -0
  402. package/extensions/frappe-ui.ts +119 -0
  403. package/extensions/frappe-workflow.ts +85 -0
  404. package/gates/coverage-check.ts +37 -0
  405. package/gates/frappe-native-check.ts +65 -0
  406. package/gates/permission-check.ts +65 -0
  407. package/gates/query-check.ts +40 -0
  408. package/gates/server-side-check.ts +67 -0
  409. package/gates/style-check.ts +92 -0
  410. package/gates/types.ts +13 -0
  411. package/package.json +47 -0
  412. package/project-context.md +146 -0
  413. package/state/db.ts +85 -0
  414. package/state/fsm.ts +68 -0
  415. package/state/journal.ts +164 -0
  416. package/state/schema.ts +41 -0
  417. package/tools/agent-tools.ts +60 -0
  418. package/tools/bench-tools.ts +63 -0
  419. package/tools/context-sandbox.ts +31 -0
  420. package/tools/debug-tools.ts +12 -0
  421. package/tools/feature-tools.ts +126 -0
  422. package/tools/frappe-context7.ts +70 -0
  423. package/tools/frappe-query-tools.ts +47 -0
  424. package/tools/project-tools.ts +107 -0
  425. 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
+ }