agent-bober 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/.claude-plugin/plugin.json +9 -0
  2. package/LICENSE +21 -0
  3. package/README.md +495 -0
  4. package/agents/bober-evaluator.md +323 -0
  5. package/agents/bober-generator.md +245 -0
  6. package/agents/bober-planner.md +248 -0
  7. package/dist/cli/commands/eval.d.ts +6 -0
  8. package/dist/cli/commands/eval.d.ts.map +1 -0
  9. package/dist/cli/commands/eval.js +129 -0
  10. package/dist/cli/commands/eval.js.map +1 -0
  11. package/dist/cli/commands/init.d.ts +5 -0
  12. package/dist/cli/commands/init.d.ts.map +1 -0
  13. package/dist/cli/commands/init.js +547 -0
  14. package/dist/cli/commands/init.js.map +1 -0
  15. package/dist/cli/commands/plan.d.ts +5 -0
  16. package/dist/cli/commands/plan.d.ts.map +1 -0
  17. package/dist/cli/commands/plan.js +87 -0
  18. package/dist/cli/commands/plan.js.map +1 -0
  19. package/dist/cli/commands/run.d.ts +5 -0
  20. package/dist/cli/commands/run.d.ts.map +1 -0
  21. package/dist/cli/commands/run.js +120 -0
  22. package/dist/cli/commands/run.js.map +1 -0
  23. package/dist/cli/commands/sprint.d.ts +6 -0
  24. package/dist/cli/commands/sprint.d.ts.map +1 -0
  25. package/dist/cli/commands/sprint.js +206 -0
  26. package/dist/cli/commands/sprint.js.map +1 -0
  27. package/dist/cli/index.d.ts +3 -0
  28. package/dist/cli/index.d.ts.map +1 -0
  29. package/dist/cli/index.js +124 -0
  30. package/dist/cli/index.js.map +1 -0
  31. package/dist/config/defaults.d.ts +15 -0
  32. package/dist/config/defaults.d.ts.map +1 -0
  33. package/dist/config/defaults.js +226 -0
  34. package/dist/config/defaults.js.map +1 -0
  35. package/dist/config/index.d.ts +4 -0
  36. package/dist/config/index.d.ts.map +1 -0
  37. package/dist/config/index.js +8 -0
  38. package/dist/config/index.js.map +1 -0
  39. package/dist/config/loader.d.ts +18 -0
  40. package/dist/config/loader.d.ts.map +1 -0
  41. package/dist/config/loader.js +189 -0
  42. package/dist/config/loader.js.map +1 -0
  43. package/dist/config/schema.d.ts +904 -0
  44. package/dist/config/schema.d.ts.map +1 -0
  45. package/dist/config/schema.js +181 -0
  46. package/dist/config/schema.js.map +1 -0
  47. package/dist/contracts/eval-result.d.ts +205 -0
  48. package/dist/contracts/eval-result.d.ts.map +1 -0
  49. package/dist/contracts/eval-result.js +87 -0
  50. package/dist/contracts/eval-result.js.map +1 -0
  51. package/dist/contracts/index.d.ts +4 -0
  52. package/dist/contracts/index.d.ts.map +1 -0
  53. package/dist/contracts/index.js +16 -0
  54. package/dist/contracts/index.js.map +1 -0
  55. package/dist/contracts/spec.d.ts +101 -0
  56. package/dist/contracts/spec.d.ts.map +1 -0
  57. package/dist/contracts/spec.js +51 -0
  58. package/dist/contracts/spec.js.map +1 -0
  59. package/dist/contracts/sprint-contract.d.ts +141 -0
  60. package/dist/contracts/sprint-contract.d.ts.map +1 -0
  61. package/dist/contracts/sprint-contract.js +80 -0
  62. package/dist/contracts/sprint-contract.js.map +1 -0
  63. package/dist/evaluators/builtin/api-check.d.ts +13 -0
  64. package/dist/evaluators/builtin/api-check.d.ts.map +1 -0
  65. package/dist/evaluators/builtin/api-check.js +152 -0
  66. package/dist/evaluators/builtin/api-check.js.map +1 -0
  67. package/dist/evaluators/builtin/build-check.d.ts +17 -0
  68. package/dist/evaluators/builtin/build-check.d.ts.map +1 -0
  69. package/dist/evaluators/builtin/build-check.js +155 -0
  70. package/dist/evaluators/builtin/build-check.js.map +1 -0
  71. package/dist/evaluators/builtin/command-runner.d.ts +26 -0
  72. package/dist/evaluators/builtin/command-runner.d.ts.map +1 -0
  73. package/dist/evaluators/builtin/command-runner.js +114 -0
  74. package/dist/evaluators/builtin/command-runner.js.map +1 -0
  75. package/dist/evaluators/builtin/lint.d.ts +17 -0
  76. package/dist/evaluators/builtin/lint.d.ts.map +1 -0
  77. package/dist/evaluators/builtin/lint.js +264 -0
  78. package/dist/evaluators/builtin/lint.js.map +1 -0
  79. package/dist/evaluators/builtin/playwright.d.ts +16 -0
  80. package/dist/evaluators/builtin/playwright.d.ts.map +1 -0
  81. package/dist/evaluators/builtin/playwright.js +238 -0
  82. package/dist/evaluators/builtin/playwright.js.map +1 -0
  83. package/dist/evaluators/builtin/typescript-check.d.ts +12 -0
  84. package/dist/evaluators/builtin/typescript-check.d.ts.map +1 -0
  85. package/dist/evaluators/builtin/typescript-check.js +155 -0
  86. package/dist/evaluators/builtin/typescript-check.js.map +1 -0
  87. package/dist/evaluators/builtin/unit-test.d.ts +18 -0
  88. package/dist/evaluators/builtin/unit-test.d.ts.map +1 -0
  89. package/dist/evaluators/builtin/unit-test.js +279 -0
  90. package/dist/evaluators/builtin/unit-test.js.map +1 -0
  91. package/dist/evaluators/index.d.ts +11 -0
  92. package/dist/evaluators/index.d.ts.map +1 -0
  93. package/dist/evaluators/index.js +13 -0
  94. package/dist/evaluators/index.js.map +1 -0
  95. package/dist/evaluators/plugin-interface.d.ts +50 -0
  96. package/dist/evaluators/plugin-interface.d.ts.map +1 -0
  97. package/dist/evaluators/plugin-interface.js +2 -0
  98. package/dist/evaluators/plugin-interface.js.map +1 -0
  99. package/dist/evaluators/plugin-loader.d.ts +18 -0
  100. package/dist/evaluators/plugin-loader.d.ts.map +1 -0
  101. package/dist/evaluators/plugin-loader.js +107 -0
  102. package/dist/evaluators/plugin-loader.js.map +1 -0
  103. package/dist/evaluators/registry.d.ts +78 -0
  104. package/dist/evaluators/registry.d.ts.map +1 -0
  105. package/dist/evaluators/registry.js +238 -0
  106. package/dist/evaluators/registry.js.map +1 -0
  107. package/dist/index.d.ts +17 -0
  108. package/dist/index.d.ts.map +1 -0
  109. package/dist/index.js +22 -0
  110. package/dist/index.js.map +1 -0
  111. package/dist/orchestrator/context-handoff.d.ts +543 -0
  112. package/dist/orchestrator/context-handoff.d.ts.map +1 -0
  113. package/dist/orchestrator/context-handoff.js +133 -0
  114. package/dist/orchestrator/context-handoff.js.map +1 -0
  115. package/dist/orchestrator/evaluator-agent.d.ts +15 -0
  116. package/dist/orchestrator/evaluator-agent.d.ts.map +1 -0
  117. package/dist/orchestrator/evaluator-agent.js +233 -0
  118. package/dist/orchestrator/evaluator-agent.js.map +1 -0
  119. package/dist/orchestrator/generator-agent.d.ts +16 -0
  120. package/dist/orchestrator/generator-agent.d.ts.map +1 -0
  121. package/dist/orchestrator/generator-agent.js +147 -0
  122. package/dist/orchestrator/generator-agent.js.map +1 -0
  123. package/dist/orchestrator/pipeline.d.ts +24 -0
  124. package/dist/orchestrator/pipeline.d.ts.map +1 -0
  125. package/dist/orchestrator/pipeline.js +290 -0
  126. package/dist/orchestrator/pipeline.js.map +1 -0
  127. package/dist/orchestrator/planner-agent.d.ts +10 -0
  128. package/dist/orchestrator/planner-agent.d.ts.map +1 -0
  129. package/dist/orchestrator/planner-agent.js +187 -0
  130. package/dist/orchestrator/planner-agent.js.map +1 -0
  131. package/dist/state/helpers.d.ts +5 -0
  132. package/dist/state/helpers.d.ts.map +1 -0
  133. package/dist/state/helpers.js +8 -0
  134. package/dist/state/helpers.js.map +1 -0
  135. package/dist/state/history.d.ts +39 -0
  136. package/dist/state/history.d.ts.map +1 -0
  137. package/dist/state/history.js +162 -0
  138. package/dist/state/history.js.map +1 -0
  139. package/dist/state/index.d.ts +8 -0
  140. package/dist/state/index.d.ts.map +1 -0
  141. package/dist/state/index.js +22 -0
  142. package/dist/state/index.js.map +1 -0
  143. package/dist/state/plan-state.d.ts +21 -0
  144. package/dist/state/plan-state.d.ts.map +1 -0
  145. package/dist/state/plan-state.js +108 -0
  146. package/dist/state/plan-state.js.map +1 -0
  147. package/dist/state/sprint-state.d.ts +20 -0
  148. package/dist/state/sprint-state.d.ts.map +1 -0
  149. package/dist/state/sprint-state.js +98 -0
  150. package/dist/state/sprint-state.js.map +1 -0
  151. package/dist/utils/fs.d.ts +31 -0
  152. package/dist/utils/fs.d.ts.map +1 -0
  153. package/dist/utils/fs.js +67 -0
  154. package/dist/utils/fs.js.map +1 -0
  155. package/dist/utils/git.d.ts +35 -0
  156. package/dist/utils/git.d.ts.map +1 -0
  157. package/dist/utils/git.js +84 -0
  158. package/dist/utils/git.js.map +1 -0
  159. package/dist/utils/index.d.ts +4 -0
  160. package/dist/utils/index.d.ts.map +1 -0
  161. package/dist/utils/index.js +4 -0
  162. package/dist/utils/index.js.map +1 -0
  163. package/dist/utils/logger.d.ts +45 -0
  164. package/dist/utils/logger.d.ts.map +1 -0
  165. package/dist/utils/logger.js +73 -0
  166. package/dist/utils/logger.js.map +1 -0
  167. package/hooks/hooks.json +10 -0
  168. package/package.json +67 -0
  169. package/scripts/detect-stack.sh +287 -0
  170. package/scripts/init-project.sh +206 -0
  171. package/scripts/run-eval.sh +175 -0
  172. package/skills/bober.anchor/SKILL.md +365 -0
  173. package/skills/bober.anchor/references/anchor-guide.md +567 -0
  174. package/skills/bober.brownfield/SKILL.md +422 -0
  175. package/skills/bober.brownfield/references/codebase-analysis.md +304 -0
  176. package/skills/bober.eval/SKILL.md +235 -0
  177. package/skills/bober.eval/references/eval-strategies.md +407 -0
  178. package/skills/bober.eval/references/feedback-format.md +182 -0
  179. package/skills/bober.plan/SKILL.md +244 -0
  180. package/skills/bober.plan/references/clarification-guide.md +124 -0
  181. package/skills/bober.plan/references/spec-schema.md +253 -0
  182. package/skills/bober.react/SKILL.md +330 -0
  183. package/skills/bober.react/references/react-scaffold.md +344 -0
  184. package/skills/bober.run/SKILL.md +303 -0
  185. package/skills/bober.solidity/SKILL.md +416 -0
  186. package/skills/bober.solidity/references/solidity-guide.md +487 -0
  187. package/skills/bober.sprint/SKILL.md +280 -0
  188. package/skills/bober.sprint/references/contract-schema.md +251 -0
  189. package/templates/base/CLAUDE.md +20 -0
  190. package/templates/base/bober.config.json +35 -0
  191. package/templates/brownfield/CLAUDE.md +34 -0
  192. package/templates/brownfield/bober.config.json +37 -0
  193. package/templates/presets/anchor/CLAUDE.md +163 -0
  194. package/templates/presets/anchor/bober.config.json +9 -0
  195. package/templates/presets/api-node/CLAUDE.md +153 -0
  196. package/templates/presets/api-node/bober.config.json +10 -0
  197. package/templates/presets/nextjs/CLAUDE.md +82 -0
  198. package/templates/presets/nextjs/bober.config.json +14 -0
  199. package/templates/presets/python-api/CLAUDE.md +202 -0
  200. package/templates/presets/python-api/bober.config.json +9 -0
  201. package/templates/presets/react-vite/CLAUDE.md +71 -0
  202. package/templates/presets/react-vite/bober.config.json +53 -0
  203. package/templates/presets/react-vite/scaffold/package.json +45 -0
  204. package/templates/presets/react-vite/scaffold/server/index.ts +38 -0
  205. package/templates/presets/react-vite/scaffold/server/tsconfig.json +24 -0
  206. package/templates/presets/react-vite/scaffold/src/App.tsx +37 -0
  207. package/templates/presets/react-vite/scaffold/src/index.html +12 -0
  208. package/templates/presets/react-vite/scaffold/src/main.tsx +12 -0
  209. package/templates/presets/react-vite/scaffold/tsconfig.json +27 -0
  210. package/templates/presets/react-vite/scaffold/vite.config.ts +34 -0
  211. package/templates/presets/solidity/CLAUDE.md +106 -0
  212. package/templates/presets/solidity/bober.config.json +9 -0
@@ -0,0 +1,244 @@
1
+ ---
2
+ name: bober.plan
3
+ description: Transform a feature idea into a comprehensive plan with sprint contracts, clarifying questions, and acceptance criteria.
4
+ argument-hint: <feature-description>
5
+ ---
6
+
7
+ # bober.plan — Feature Planning Skill
8
+
9
+ You are running the **bober.plan** skill. Your job is to take a user's feature description and transform it into a structured, sprint-decomposed plan that the Bober Generator-Evaluator harness can execute autonomously.
10
+
11
+ ## Step 1: Check Project Initialization
12
+
13
+ First, check if `bober.config.json` exists in the project root.
14
+
15
+ **If `bober.config.json` does NOT exist:**
16
+
17
+ Guide the user through initialization. Ask open-ended questions to understand what they want to build:
18
+
19
+ ```
20
+ I don't see a bober.config.json in this project. Let me set one up.
21
+
22
+ **Is this a new project or an existing codebase?**
23
+ A) New project (greenfield) -- starting from scratch
24
+ B) Existing codebase (brownfield) -- adding to or modifying existing code
25
+
26
+ **What are you building?** (e.g., "a task management web app", "an ERC-20 token", "a REST API", "a CLI tool", "a Solana NFT marketplace")
27
+
28
+ **What is the project name?** (e.g., "my-todo-app")
29
+ ```
30
+
31
+ Based on the user's answers, determine the appropriate `mode` and `preset`:
32
+ - `mode`: `"greenfield"` for new projects, `"brownfield"` for existing codebases
33
+ - `preset`: Match to a known preset if applicable (`"nextjs"`, `"react-vite"`, `"solidity"`, `"anchor"`, `"api-node"`, `"python-api"`), or omit if the project does not fit a preset
34
+ - `stack`: Infer stack details from the user's description (e.g., `{ "frontend": "react", "backend": "express", "database": "postgresql" }`)
35
+
36
+ The planner should be able to plan ANY type of project -- web apps, APIs, smart contracts, CLI tools, mobile apps, libraries, data pipelines, etc. Do not limit the user to predefined categories.
37
+
38
+ Create `bober.config.json` using the appropriate defaults from the mode and preset. Use the schema defined in `src/config/schema.ts` and defaults from `src/config/defaults.ts` as reference. Auto-detect commands by examining `package.json`, `Cargo.toml`, `Anchor.toml`, `hardhat.config.*`, `foundry.toml`, or other project manifests if available.
39
+
40
+ Then create the `.bober/` directory structure:
41
+ ```bash
42
+ mkdir -p .bober/specs .bober/contracts .bober/handoffs .bober/eval-results
43
+ ```
44
+
45
+ Create `.bober/progress.md` with initial content:
46
+ ```markdown
47
+ # Bober Progress
48
+
49
+ Project: <project-name>
50
+ Mode: <greenfield|brownfield>
51
+ Preset: <preset or "custom">
52
+ Initialized: <date>
53
+
54
+ ---
55
+ ```
56
+
57
+ Create `.bober/history.jsonl` with the initialization event:
58
+ ```json
59
+ {"event":"project-initialized","projectName":"...","mode":"...","preset":"...","timestamp":"..."}
60
+ ```
61
+
62
+ **If `bober.config.json` EXISTS:** Read it and proceed to Step 2.
63
+
64
+ ## Step 2: Gather Codebase Context
65
+
66
+ Read the following files if they exist (skip those that do not):
67
+
68
+ 1. `bober.config.json` — project configuration
69
+ 2. `CLAUDE.md` — project-level instructions and context
70
+ 3. `package.json` — dependencies, scripts, project metadata
71
+ 4. `tsconfig.json` — TypeScript configuration
72
+ 5. Any files listed in `planner.contextFiles` from the config
73
+
74
+ Survey the project structure:
75
+ - Use Glob with patterns appropriate to the stack to understand the file layout (e.g., `src/**/*.ts`, `contracts/**/*.sol`, `programs/**/*.rs`, `app/**/*`, `pages/**/*`)
76
+ - Use Grep to find key patterns relevant to the project type: route definitions, database/ORM usage, state management, smart contract interfaces, program instructions, authentication patterns, etc.
77
+ - Read `.bober/specs/` to check for existing plans
78
+ - Read `.bober/progress.md` to understand current project state
79
+
80
+ Build a concise mental model of:
81
+ - Tech stack (language, framework, database, key libraries)
82
+ - Architecture pattern (monolith, microservices, monorepo, component-based)
83
+ - Existing features and their maturity
84
+ - Test coverage and testing patterns
85
+ - Build and deployment setup
86
+
87
+ ## Step 3: Understand the Feature Request
88
+
89
+ The user provided a feature description as the argument to this skill. If the description is:
90
+ - **Clear and specific** (e.g., "Add user authentication with email/password and Google OAuth"): Proceed to clarifying questions
91
+ - **Vague** (e.g., "make it better"): Ask the user to be more specific about what they want before proceeding
92
+ - **Very detailed** (e.g., a multi-paragraph spec): You may skip some clarifying questions if the user has already answered them
93
+
94
+ ## Step 4: Ask Clarifying Questions
95
+
96
+ Ask **3 to 5** targeted clarifying questions. The number depends on the complexity of the feature and how much context the codebase already provides.
97
+
98
+ **Question format:**
99
+ ```
100
+ I have a few questions to make sure I build the right plan:
101
+
102
+ **Q1: [Category] — [Question]**
103
+ A) [Option] — [Brief explanation]
104
+ B) [Option] — [Brief explanation]
105
+ C) [Option] — [Brief explanation]
106
+ D) Other (please specify)
107
+
108
+ > Based on your codebase, I'd suggest [X] because [reason from codebase analysis].
109
+
110
+ **Q2: [Category] — [Question]**
111
+ ...
112
+ ```
113
+
114
+ **Question selection guidelines:**
115
+
116
+ Draw from the reference file at `skills/bober.plan/references/clarification-guide.md` for question categories and templates. Prioritize questions that:
117
+
118
+ 1. Resolve genuine ambiguity that would cause different implementations
119
+ 2. Clarify scope boundaries (what is IN vs OUT)
120
+ 3. Address technical constraints specific to this codebase
121
+ 4. Establish user-facing behavior that affects acceptance criteria
122
+
123
+ **Do NOT ask questions about:**
124
+ - Things obvious from the codebase (framework choice, language, existing patterns)
125
+ - Implementation details the Generator should decide
126
+ - Things the user explicitly stated in their feature description
127
+
128
+ **Maximum questions:** Respect `planner.maxClarifications` from the config (default: 5).
129
+
130
+ ## Step 5: Generate the PlanSpec
131
+
132
+ After receiving the user's answers, generate a complete PlanSpec. Follow the schema documented in `skills/bober.plan/references/spec-schema.md`.
133
+
134
+ **PlanSpec generation rules:**
135
+
136
+ 1. **Title:** Clear, concise feature title (not a sentence, not a paragraph)
137
+ 2. **Description:** 2-3 sentences explaining what this feature does and the user value it provides
138
+ 3. **Assumptions:** List every assumption you are making. These are things the user did not explicitly say but you inferred. The user should validate these.
139
+ 4. **Out of scope:** Explicitly list what this plan does NOT cover. This prevents scope creep during implementation.
140
+ 5. **Features:** Break the feature into sub-features. Each sub-feature should be independently valuable when possible. Assign priorities: `must-have` (core functionality), `should-have` (important but not blocking), `nice-to-have` (polish and extras).
141
+ 6. **Acceptance criteria:** Each feature needs 2+ acceptance criteria. Each criterion must be:
142
+ - Specific (not "works correctly")
143
+ - Testable (an evaluator can verify it)
144
+ - User-facing when possible (describes behavior, not implementation)
145
+ 7. **Non-functional requirements:** Performance, security, accessibility, reliability considerations
146
+ 8. **Tech notes:** Integration points, data model overview, security considerations
147
+
148
+ ## Step 6: Decompose into Sprint Contracts
149
+
150
+ Decompose the PlanSpec into ordered sprints. This is the most critical step.
151
+
152
+ **Read `sprint.sprintSize` from config to calibrate sprint size:**
153
+ - `small`: 30-60 min, 1-2 files, single concern
154
+ - `medium`: 1-3 hours, 3-8 files, one cohesive feature slice
155
+ - `large`: 3-5 hours, 5-15 files, full feature vertical
156
+
157
+ **Sprint decomposition rules:**
158
+
159
+ 1. **Vertical slices.** Each sprint delivers a working end-to-end feature slice. Do not create horizontal sprints like "Sprint 1: Database schema" followed by "Sprint 2: API endpoints" followed by "Sprint 3: UI." Instead: "Sprint 1: Basic user registration (form + endpoint + DB)."
160
+
161
+ 2. **Working increment after every sprint.** The app must build and run after each sprint. Each sprint demonstrates new visible functionality.
162
+
163
+ 3. **Forward dependencies only.** Sprint N+1 may depend on Sprint N. Sprint N must never depend on Sprint N+1. No circular dependencies.
164
+
165
+ 4. **Clear boundaries.** The contract must make it unambiguous what is included and excluded.
166
+
167
+ 5. **Risk-first ordering.** Architecture decisions, complex integrations, and unknowns come early. Polish, edge cases, and optimizations come later.
168
+
169
+ 6. **Success criteria per sprint.** Each sprint gets 3-8 success criteria that are independently testable. At least one must be a `build` verification. At least one must verify actual functionality.
170
+
171
+ Follow the contract schema documented in `skills/bober.sprint/references/contract-schema.md`.
172
+
173
+ **For each sprint contract, include:**
174
+ - `generatorNotes`: Specific guidance for the Generator -- what patterns to follow, what files to look at, known gotchas
175
+ - `evaluatorNotes`: Specific guidance for the Evaluator -- what to test, how to verify each criterion, what edge cases to check
176
+
177
+ ## Step 7: Save Everything
178
+
179
+ Save all artifacts to the `.bober/` directory:
180
+
181
+ 1. **PlanSpec:** `.bober/specs/<specId>.json`
182
+ - `specId` format: `spec-<YYYYMMDD>-<slug>` where slug is a kebab-case version of the title (max 30 chars)
183
+
184
+ 2. **Sprint Contracts:** `.bober/contracts/<contractId>.json` for each sprint
185
+ - `contractId` format: `sprint-<specId>-<sprint-number>`
186
+
187
+ 3. **Update `.bober/progress.md`:**
188
+ ```markdown
189
+ ## Plan: <title>
190
+ - Spec: <specId>
191
+ - Created: <date>
192
+ - Sprints: <count>
193
+ - Status: planned
194
+
195
+ ### Sprint Breakdown
196
+ 1. [proposed] <Sprint 1 title> -- <1-line description>
197
+ 2. [proposed] <Sprint 2 title> -- <1-line description>
198
+ ...
199
+ ```
200
+
201
+ 4. **Append to `.bober/history.jsonl`:**
202
+ ```json
203
+ {"event":"plan-created","specId":"...","title":"...","sprintCount":N,"timestamp":"..."}
204
+ ```
205
+
206
+ ## Step 8: Output Summary
207
+
208
+ Present a clean, readable summary to the user:
209
+
210
+ ```
211
+ ## Plan Created: <title>
212
+
213
+ <description>
214
+
215
+ ### Assumptions
216
+ - <assumption 1>
217
+ - <assumption 2>
218
+
219
+ ### Out of Scope
220
+ - <excluded item 1>
221
+ - <excluded item 2>
222
+
223
+ ### Sprint Breakdown
224
+
225
+ **Sprint 1: <title>** (estimated: <size>)
226
+ <1-2 sentence description>
227
+ Key criteria: <list 2-3 most important success criteria>
228
+
229
+ **Sprint 2: <title>** (estimated: <size>)
230
+ <1-2 sentence description>
231
+ Key criteria: <list 2-3 most important success criteria>
232
+
233
+ ...
234
+
235
+ ### Next Steps
236
+ Run `/bober.sprint` to begin executing Sprint 1, or `/bober.run` to execute the full pipeline.
237
+ ```
238
+
239
+ ## Error Handling
240
+
241
+ - If the project has no manifest file (`package.json`, `Cargo.toml`, `pyproject.toml`, etc.) and no obvious project structure, ask the user if this is a new project and what they want to build
242
+ - If existing specs conflict with the new feature request, flag the conflict and ask the user how to proceed
243
+ - If the feature is too large for `sprint.maxSprints` sprints, suggest breaking it into multiple PlanSpecs or increasing the sprint size
244
+ - If the user's answers to clarifying questions contradict each other, point out the contradiction and ask for resolution
@@ -0,0 +1,124 @@
1
+ # Clarification Question Guide
2
+
3
+ This reference helps the Planner agent ask effective, targeted clarifying questions that resolve genuine ambiguity in a feature request.
4
+
5
+ ## Principles
6
+
7
+ 1. **Never ask what you can infer.** If `package.json` shows React 18, do not ask "What framework are you using?"
8
+ 2. **Always provide options.** Open-ended questions slow down the process. Offer concrete choices with a recommended default.
9
+ 3. **Include your reasoning.** When you recommend an option, explain WHY based on evidence from the codebase.
10
+ 4. **Fewer questions is better.** Every question is a round trip with the user. Only ask what genuinely changes the plan.
11
+
12
+ ## Question Categories
13
+
14
+ ### 1. Scope Boundaries
15
+
16
+ Resolve what is IN scope vs. explicitly OUT.
17
+
18
+ **Templates:**
19
+ - "Should [feature] include [extended capability], or keep it to [minimal version] for now?"
20
+ - "When you say [user's term], do you mean: A) [interpretation 1], B) [interpretation 2], C) [interpretation 3]?"
21
+ - "Should this feature handle [edge case], or should we defer that to a later sprint?"
22
+
23
+ **When to ask:** When the user's description is ambiguous about boundaries. "Add a chat feature" could mean real-time WebSocket chat, async messaging, or a simple comment thread.
24
+
25
+ **When to skip:** When the user's description is specific enough (e.g., "Add a login page with email and password").
26
+
27
+ ### 2. User Personas and Permissions
28
+
29
+ Clarify who uses the feature and what access control is needed.
30
+
31
+ **Templates:**
32
+ - "Who will use [feature]? A) All users, B) Authenticated users only, C) Admin users only, D) Multiple roles with different permissions"
33
+ - "Does [feature] need role-based access control, or is it accessible to all authenticated users?"
34
+ - "Should [feature] be accessible to anonymous/unauthenticated users?"
35
+
36
+ **When to ask:** When the feature involves data creation, modification, or viewing that might need access control. When the existing codebase already has auth/roles.
37
+
38
+ **When to skip:** When the feature is clearly public-facing (e.g., a landing page) or when the codebase has no auth system and the feature doesn't need one.
39
+
40
+ ### 3. Data Model and Persistence
41
+
42
+ Clarify what data is involved and how it is stored.
43
+
44
+ **Templates:**
45
+ - "What key information should a [entity] include? A) Minimal: [list fields], B) Standard: [list fields], C) Comprehensive: [list fields]"
46
+ - "Should [entity] data be: A) Stored in the database (persistent), B) Stored in session/memory (ephemeral), C) Fetched from an external API (external)"
47
+ - "How should [entity A] relate to [entity B]? A) One-to-one, B) One-to-many, C) Many-to-many"
48
+
49
+ **When to ask:** When the feature involves new data entities or modifies existing ones. When the relationship between entities is ambiguous.
50
+
51
+ **When to skip:** When the data model is straightforward or dictated by an existing schema.
52
+
53
+ ### 4. Technical Constraints
54
+
55
+ Clarify must-use or must-avoid technical choices.
56
+
57
+ **Templates:**
58
+ - "Your project uses [database/ORM]. Should this feature use the same, or is there a reason to use something different?"
59
+ - "I see your project uses [state management]. Should [feature] follow the same pattern?"
60
+ - "Are there any API rate limits, data size constraints, or performance requirements I should know about?"
61
+ - "Does this need to work offline or with poor connectivity?"
62
+
63
+ **When to ask:** When the feature might conflict with existing technical choices, or when performance/scale requirements are unclear.
64
+
65
+ **When to skip:** When the feature clearly fits within existing patterns and the tech stack is obvious.
66
+
67
+ ### 5. Design and UX Preferences
68
+
69
+ Clarify visual and interaction expectations.
70
+
71
+ **Templates:**
72
+ - "For the UI, should this: A) Match your existing design system/components, B) Use a specific design reference (provide link/screenshot), C) Be functional-first (agent decides the layout)"
73
+ - "What should happen after [action]? A) Redirect to [page], B) Show inline confirmation, C) Show a modal/toast notification"
74
+ - "Should [feature] include: A) A simple form/list, B) An interactive dashboard with filtering/sorting, C) A minimal CLI-style interface"
75
+
76
+ **When to ask:** For user-facing features where the interaction model is ambiguous. When the project does not have an established design system.
77
+
78
+ **When to skip:** When the project has a consistent design system and the new feature clearly fits an existing pattern. When the feature is backend-only.
79
+
80
+ ### 6. Integrations and External Dependencies
81
+
82
+ Clarify connections to external services.
83
+
84
+ **Templates:**
85
+ - "Does [feature] need to integrate with any external services? (e.g., payment processor, email service, OAuth provider)"
86
+ - "For [external integration], do you already have API keys/credentials, or should the plan include mock/stub implementations?"
87
+ - "Should [feature] send notifications? A) No, B) Email only, C) In-app notifications, D) Push notifications, E) Multiple channels"
88
+
89
+ **When to ask:** When the feature implies external service usage (payments, email, auth providers, file storage, etc.).
90
+
91
+ **When to skip:** When the feature is entirely self-contained.
92
+
93
+ ### 7. Error Handling and Edge Cases
94
+
95
+ Clarify expected behavior in failure scenarios.
96
+
97
+ **Templates:**
98
+ - "What should happen when [failure scenario]? A) Show error message and retry, B) Graceful degradation, C) Hard failure with redirect to error page"
99
+ - "How should [feature] handle concurrent modifications? A) Last write wins, B) Optimistic locking with conflict resolution, C) Not a concern for this feature"
100
+ - "What is the expected data volume? A) Tens of records, B) Hundreds, C) Thousands+, D) Not sure yet"
101
+
102
+ **When to ask:** When the feature has obvious failure modes that the user might not have considered.
103
+
104
+ **When to skip:** For simple features where error handling is straightforward.
105
+
106
+ ## Inferring Answers from Codebase Analysis
107
+
108
+ Before asking, check if the codebase already answers the question:
109
+
110
+ | Question | Where to Look |
111
+ |----------|--------------|
112
+ | Auth/permissions | Grep for `auth`, `jwt`, `session`, `middleware`, `guard`, `protect` |
113
+ | Database/ORM | Check `package.json` deps for `prisma`, `drizzle`, `knex`, `mongoose`, `typeorm` |
114
+ | State management | Grep for `redux`, `zustand`, `recoil`, `useState`, `useReducer`, `context` |
115
+ | UI framework | Check `package.json` for `react`, `vue`, `svelte`, `angular` |
116
+ | CSS approach | Check for `tailwind`, `styled-components`, `css-modules`, `.scss` files |
117
+ | Testing framework | Check `package.json` for `vitest`, `jest`, `mocha`, `playwright`, `cypress` |
118
+ | API pattern | Grep for `express`, `fastify`, `hono`, `trpc`, `graphql` |
119
+ | Routing | Grep for file-based routing (Next.js `pages/`, `app/`), or `react-router`, `wouter` |
120
+ | Design system | Check for component libraries: `shadcn`, `radix`, `chakra`, `mui`, `antd` |
121
+ | Deployment | Check for `Dockerfile`, `vercel.json`, `fly.toml`, `railway.json`, `netlify.toml` |
122
+
123
+ If the codebase clearly answers a question, do not ask it. Instead, state your observation:
124
+ > "I see your project uses Prisma with PostgreSQL and has an existing User model. I'll plan the new feature to extend this schema."
@@ -0,0 +1,253 @@
1
+ # PlanSpec JSON Schema
2
+
3
+ This document defines the complete schema for PlanSpec documents generated by the Planner agent. PlanSpecs are the authoritative source-of-truth for what will be built.
4
+
5
+ ## Location
6
+
7
+ PlanSpec files are stored at: `.bober/specs/<specId>.json`
8
+
9
+ ## Naming Convention
10
+
11
+ - `specId` format: `spec-<YYYYMMDD>-<slug>`
12
+ - The slug is derived from the title: lowercase, spaces replaced with hyphens, max 30 characters, no special characters
13
+ - Example: `spec-20260326-user-authentication`
14
+
15
+ ## Full Schema
16
+
17
+ ```json
18
+ {
19
+ "specId": "string (required)",
20
+ "version": "number (required, starts at 1, incremented on updates)",
21
+ "createdAt": "string (required, ISO-8601 datetime)",
22
+ "updatedAt": "string (required, ISO-8601 datetime)",
23
+ "title": "string (required, 3-80 characters)",
24
+ "description": "string (required, 2-3 sentences)",
25
+ "mode": "string (required, one of: greenfield, brownfield)",
26
+ "preset": "string (optional, e.g.: nextjs, react-vite, solidity, anchor, api-node, python-api)",
27
+ "status": "string (required, one of: planned, in-progress, completed, archived)",
28
+
29
+ "assumptions": [
30
+ "string — each assumption the planner is making"
31
+ ],
32
+
33
+ "outOfScope": [
34
+ "string — each item explicitly excluded from this plan"
35
+ ],
36
+
37
+ "features": [
38
+ {
39
+ "featureId": "string (required, format: feat-<index>)",
40
+ "title": "string (required)",
41
+ "description": "string (required)",
42
+ "priority": "string (required, one of: must-have, should-have, nice-to-have)",
43
+ "acceptanceCriteria": [
44
+ "string — each criterion prefixed with AC<N>:"
45
+ ],
46
+ "dependencies": ["string — featureId references"],
47
+ "estimatedComplexity": "string (required, one of: low, medium, high)"
48
+ }
49
+ ],
50
+
51
+ "nonFunctionalRequirements": [
52
+ {
53
+ "category": "string (required, one of: performance, security, accessibility, reliability, maintainability)",
54
+ "requirement": "string (required)",
55
+ "verificationMethod": "string (required, how the evaluator verifies this)"
56
+ }
57
+ ],
58
+
59
+ "techNotes": {
60
+ "suggestedStack": "string (optional, only for greenfield projects)",
61
+ "integrationPoints": ["string — external APIs or services"],
62
+ "dataModel": "string (brief description of key entities and relationships)",
63
+ "securityConsiderations": ["string — auth, validation, encryption, etc."],
64
+ "existingPatterns": "string (optional, patterns from the codebase to follow)"
65
+ },
66
+
67
+ "sprints": [
68
+ "string — contractId references, ordered by execution sequence"
69
+ ],
70
+
71
+ "metadata": {
72
+ "estimatedTotalDuration": "string (e.g., '4-6 hours')",
73
+ "riskLevel": "string (one of: low, medium, high)",
74
+ "riskNotes": "string (optional, explanation of risk assessment)"
75
+ }
76
+ }
77
+ ```
78
+
79
+ ## Field Descriptions
80
+
81
+ ### Top-Level Fields
82
+
83
+ | Field | Description |
84
+ |-------|-------------|
85
+ | `specId` | Unique identifier for this spec. Generated once, never changes. |
86
+ | `version` | Integer version number. Incremented if the spec is revised after creation. |
87
+ | `createdAt` | ISO-8601 timestamp of initial creation. |
88
+ | `updatedAt` | ISO-8601 timestamp of last modification. |
89
+ | `title` | Human-readable feature title. Should be concise and descriptive. |
90
+ | `description` | 2-3 sentence summary of the feature and its user value. |
91
+ | `mode` | Must match the `project.mode` in `bober.config.json` (`greenfield` or `brownfield`). |
92
+ | `preset` | Must match the `project.preset` in `bober.config.json`, if set (e.g., `nextjs`, `solidity`, `anchor`). |
93
+ | `status` | Lifecycle state: `planned` (not started), `in-progress` (sprints running), `completed` (all sprints done), `archived` (abandoned or superseded). |
94
+
95
+ ### Features Array
96
+
97
+ Each feature represents a distinct, potentially independently valuable unit of functionality within the plan.
98
+
99
+ | Field | Description |
100
+ |-------|-------------|
101
+ | `featureId` | Unique within this spec. Format: `feat-1`, `feat-2`, etc. |
102
+ | `title` | Short feature name. |
103
+ | `description` | What this feature does and why it matters. |
104
+ | `priority` | `must-have`: Core functionality, plan fails without it. `should-have`: Important, but plan could ship without it. `nice-to-have`: Polish, optimization, extras. |
105
+ | `acceptanceCriteria` | Array of testable criteria. Each MUST be verifiable by the evaluator. Format: `"AC1: When [action], then [expected result]"`. |
106
+ | `dependencies` | Array of `featureId` values that must be implemented before this feature. Empty array if no dependencies. |
107
+ | `estimatedComplexity` | Rough complexity estimate to inform sprint sizing. `low`: straightforward, known patterns. `medium`: some unknowns or moderate logic. `high`: complex logic, integrations, or architectural decisions. |
108
+
109
+ ### Acceptance Criteria Rules
110
+
111
+ Good criteria follow the Given-When-Then pattern:
112
+ - "AC1: When a user submits the registration form with a valid email and password, a new user account is created and the user is redirected to the dashboard."
113
+ - "AC2: When a user submits the form with an email that already exists, an error message 'This email is already registered' is displayed."
114
+
115
+ Bad criteria:
116
+ - "The feature works correctly" (not testable)
117
+ - "The code is clean" (subjective)
118
+ - "Performance is good" (not measurable)
119
+
120
+ ### Non-Functional Requirements
121
+
122
+ | Field | Description |
123
+ |-------|-------------|
124
+ | `category` | One of: `performance`, `security`, `accessibility`, `reliability`, `maintainability`. |
125
+ | `requirement` | Specific, measurable requirement. E.g., "Page loads in under 2 seconds on 3G connection." |
126
+ | `verificationMethod` | How the evaluator can verify this. E.g., "Run Lighthouse audit and check Performance score > 80." |
127
+
128
+ ### Tech Notes
129
+
130
+ | Field | Description |
131
+ |-------|-------------|
132
+ | `suggestedStack` | Only for greenfield projects. Describes the recommended tech stack. |
133
+ | `integrationPoints` | External services the feature depends on (APIs, OAuth providers, payment processors, etc.). |
134
+ | `dataModel` | Brief description of entities, their key fields, and relationships. Not a full schema -- just enough for the Generator to understand the domain. |
135
+ | `securityConsiderations` | Auth requirements, input validation needs, encryption, rate limiting, etc. |
136
+ | `existingPatterns` | For brownfield projects: patterns from the existing codebase that the Generator should follow. |
137
+
138
+ ### Metadata
139
+
140
+ | Field | Description |
141
+ |-------|-------------|
142
+ | `estimatedTotalDuration` | Rough estimate of total implementation time across all sprints. |
143
+ | `riskLevel` | Overall risk assessment. `high` if the feature involves new integrations, architectural changes, or significant unknowns. |
144
+ | `riskNotes` | Explanation of risk factors. |
145
+
146
+ ## Complete Example
147
+
148
+ ```json
149
+ {
150
+ "specId": "spec-20260326-user-auth",
151
+ "version": 1,
152
+ "createdAt": "2026-03-26T10:00:00Z",
153
+ "updatedAt": "2026-03-26T10:00:00Z",
154
+ "title": "User Authentication System",
155
+ "description": "A complete user authentication system supporting email/password registration and login, with session management and protected routes. This enables the application to identify users and restrict access to authorized content.",
156
+ "mode": "greenfield",
157
+ "preset": "react-vite",
158
+ "status": "planned",
159
+ "assumptions": [
160
+ "The application does not currently have any authentication system",
161
+ "PostgreSQL is the database, as configured in the project",
162
+ "Sessions will use HTTP-only cookies rather than localStorage for security",
163
+ "Email verification is not required for initial registration (deferred to later)"
164
+ ],
165
+ "outOfScope": [
166
+ "OAuth/social login (Google, GitHub, etc.)",
167
+ "Two-factor authentication",
168
+ "Password reset via email",
169
+ "User profile management beyond basic info",
170
+ "Admin user management dashboard"
171
+ ],
172
+ "features": [
173
+ {
174
+ "featureId": "feat-1",
175
+ "title": "User Registration",
176
+ "description": "Allow new users to create an account with email and password.",
177
+ "priority": "must-have",
178
+ "acceptanceCriteria": [
179
+ "AC1: When a user navigates to /register, a registration form with email, password, and confirm-password fields is displayed.",
180
+ "AC2: When a user submits valid registration data, a new user record is created in the database with a hashed password.",
181
+ "AC3: When a user submits a registration with an already-used email, the form displays 'This email is already registered.'",
182
+ "AC4: When a user submits a password shorter than 8 characters, the form displays 'Password must be at least 8 characters.'"
183
+ ],
184
+ "dependencies": [],
185
+ "estimatedComplexity": "medium"
186
+ },
187
+ {
188
+ "featureId": "feat-2",
189
+ "title": "User Login",
190
+ "description": "Allow existing users to authenticate with email and password.",
191
+ "priority": "must-have",
192
+ "acceptanceCriteria": [
193
+ "AC1: When a user navigates to /login, a login form with email and password fields is displayed.",
194
+ "AC2: When a user submits valid credentials, they are redirected to the dashboard and a session cookie is set.",
195
+ "AC3: When a user submits invalid credentials, the form displays 'Invalid email or password.'"
196
+ ],
197
+ "dependencies": ["feat-1"],
198
+ "estimatedComplexity": "medium"
199
+ },
200
+ {
201
+ "featureId": "feat-3",
202
+ "title": "Protected Routes",
203
+ "description": "Restrict access to certain pages to authenticated users only.",
204
+ "priority": "must-have",
205
+ "acceptanceCriteria": [
206
+ "AC1: When an unauthenticated user navigates to a protected route, they are redirected to /login.",
207
+ "AC2: When an authenticated user navigates to a protected route, the page renders normally.",
208
+ "AC3: A logout button is visible on all protected pages that destroys the session and redirects to /login."
209
+ ],
210
+ "dependencies": ["feat-2"],
211
+ "estimatedComplexity": "low"
212
+ }
213
+ ],
214
+ "nonFunctionalRequirements": [
215
+ {
216
+ "category": "security",
217
+ "requirement": "Passwords must be hashed using bcrypt with a cost factor of at least 10.",
218
+ "verificationMethod": "Inspect the registration code to verify bcrypt usage with appropriate cost factor."
219
+ },
220
+ {
221
+ "category": "security",
222
+ "requirement": "Session cookies must be HTTP-only, Secure, and SameSite=Strict.",
223
+ "verificationMethod": "Inspect Set-Cookie headers in login response."
224
+ },
225
+ {
226
+ "category": "accessibility",
227
+ "requirement": "All form inputs must have associated labels and the forms must be keyboard-navigable.",
228
+ "verificationMethod": "Verify label-input associations in HTML and test Tab navigation."
229
+ }
230
+ ],
231
+ "techNotes": {
232
+ "integrationPoints": [],
233
+ "dataModel": "Single 'users' table with id (UUID), email (unique), password_hash, created_at, updated_at. Sessions stored server-side with express-session.",
234
+ "securityConsiderations": [
235
+ "Hash passwords with bcrypt before storage",
236
+ "Rate-limit login attempts to prevent brute force",
237
+ "Validate email format on both client and server",
238
+ "Use CSRF protection for state-changing requests"
239
+ ],
240
+ "existingPatterns": "The project uses Express.js with middleware pattern. Follow existing route definition style in src/routes/."
241
+ },
242
+ "sprints": [
243
+ "sprint-spec-20260326-user-auth-1",
244
+ "sprint-spec-20260326-user-auth-2",
245
+ "sprint-spec-20260326-user-auth-3"
246
+ ],
247
+ "metadata": {
248
+ "estimatedTotalDuration": "3-5 hours",
249
+ "riskLevel": "low",
250
+ "riskNotes": "Standard auth implementation with well-known patterns. No external service dependencies."
251
+ }
252
+ }
253
+ ```