brain-dev 2.2.1 → 2.3.1

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.
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: brain-reviewer
3
+ description: Code quality reviewer — DRY, over-engineering, framework best practices, style consistency
4
+ tools:
5
+ - Read
6
+ - Grep
7
+ - Glob
8
+ - Bash
9
+ model: inherit
10
+ ---
11
+
12
+ You are a code reviewer agent for the Brain workflow system.
13
+
14
+ You will receive:
15
+ - A SUMMARY of executed work (changed files, key decisions)
16
+ - Technology context (framework patterns, anti-patterns, project conventions)
17
+ - An output path for your review
18
+
19
+ Your job: Review the changed files for quality issues using confidence-based filtering (>=80% only). Focus on bugs, over-engineering, DRY violations, and framework convention adherence.
20
+
21
+ Read the changed files fully. Compare with existing project files for style consistency.
22
+ Write your findings to REVIEW.md at the specified output path.
@@ -178,6 +178,10 @@ async function main() {
178
178
  await require('./lib/commands/update.cjs').run(args.slice(1));
179
179
  break;
180
180
 
181
+ case 'review':
182
+ await require('./lib/commands/review.cjs').run(args.slice(1));
183
+ break;
184
+
181
185
  case 'upgrade':
182
186
  await require('./lib/commands/upgrade.cjs').run(args.slice(1), {
183
187
  brainDir: path.join(process.cwd(), '.brain')
@@ -6,7 +6,7 @@
6
6
  * Constant registry with discovery and validation functions.
7
7
  */
8
8
 
9
- const MAX_AGENTS = 8;
9
+ const MAX_AGENTS = 9;
10
10
 
11
11
  const AGENTS = {
12
12
  researcher: {
@@ -59,6 +59,13 @@ const AGENTS = {
59
59
  model: 'inherit',
60
60
  description: 'Combines findings from parallel research agents into a unified SUMMARY.md'
61
61
  },
62
+ reviewer: {
63
+ template: 'reviewer',
64
+ inputs: ['summary_content', 'changed_files', 'stack_expertise'],
65
+ outputs: ['REVIEW.md'],
66
+ model: 'inherit',
67
+ description: 'Reviews code quality: DRY, over-engineering, framework best practices, project style consistency'
68
+ },
62
69
  mapper: {
63
70
  template: 'mapper',
64
71
  inputs: ['focus', 'codebase_root'],
@@ -206,7 +206,7 @@ function buildStepInstructions(taskNum, slug, taskDir, brainDir, mode, research,
206
206
  // VERIFY step
207
207
  if (mode !== 'light') {
208
208
  steps.verify = [
209
- `## Step 4: Verify — Task #${taskNum}`,
209
+ `## Step 5: Verify — Task #${taskNum}`,
210
210
  '',
211
211
  `Verify the execution results against must_haves in: \`${taskDir}/PLAN-1.md\``,
212
212
  '',
@@ -221,9 +221,32 @@ function buildStepInstructions(taskNum, slug, taskDir, brainDir, mode, research,
221
221
  ].join('\n');
222
222
  }
223
223
 
224
+ // REVIEW step
225
+ if (mode !== 'light') {
226
+ steps.review = [
227
+ `## Step 4: Review — Task #${taskNum}`,
228
+ '',
229
+ `Run code review on executed work before verification.`,
230
+ '',
231
+ 'Run: `npx brain-dev review`',
232
+ '',
233
+ 'Brain will spawn a reviewer agent that checks:',
234
+ '- Code quality and DRY (no unnecessary abstractions)',
235
+ '- Framework best practices',
236
+ '- Over-engineering detection',
237
+ '- Project code style consistency',
238
+ '- Confidence-based filtering (only real issues, ≥80%)',
239
+ '',
240
+ 'MANDATORY: Do NOT skip review because changes seem "small" or "trivial".',
241
+ 'There are ZERO valid reasons to skip this step.',
242
+ '',
243
+ 'Then run: `npx brain-dev new-task --continue`'
244
+ ].join('\n');
245
+ }
246
+
224
247
  // COMPLETE step
225
248
  steps.complete = [
226
- `## Step 5: Complete — Task #${taskNum}`,
249
+ `## Step 6: Complete — Task #${taskNum}`,
227
250
  '',
228
251
  'Task completion options:',
229
252
  '',
@@ -276,6 +299,7 @@ function handleContinue(brainDir, state) {
276
299
  const hasResearch = fs.existsSync(path.join(taskDir, 'RESEARCH.md'));
277
300
  const hasPlan = fs.existsSync(path.join(taskDir, 'PLAN-1.md'));
278
301
  const hasSummary = fs.existsSync(path.join(taskDir, 'SUMMARY-1.md'));
302
+ const hasReview = fs.existsSync(path.join(taskDir, 'REVIEW.md'));
279
303
  const hasVerification = fs.existsSync(path.join(taskDir, 'VERIFICATION.md'));
280
304
 
281
305
  const isLight = taskMeta.mode === 'light';
@@ -294,6 +318,9 @@ function handleContinue(brainDir, state) {
294
318
  } else if (!hasSummary) {
295
319
  nextStep = 'execute';
296
320
  newStatus = 'executing';
321
+ } else if (!hasReview && !isLight) {
322
+ nextStep = 'review';
323
+ newStatus = 'reviewing';
297
324
  } else if (!hasVerification && !isLight) {
298
325
  nextStep = 'verify';
299
326
  newStatus = 'verifying';
@@ -49,7 +49,13 @@ function nextAction(state) {
49
49
  case 'executing':
50
50
  return '/brain:execute';
51
51
  case 'executed':
52
+ return '/brain:review';
53
+ case 'reviewing':
54
+ return '/brain:review';
55
+ case 'reviewed':
52
56
  return '/brain:verify';
57
+ case 'review-failed':
58
+ return '/brain:review';
53
59
  case 'verifying':
54
60
  return '/brain:verify';
55
61
  case 'verified':
@@ -0,0 +1,173 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs');
4
+ const path = require('node:path');
5
+ const { readState, writeState } = require('../state.cjs');
6
+ const { loadTemplateWithOverlay, interpolate } = require('../templates.cjs');
7
+ const { getAgent, resolveModel } = require('../agents.cjs');
8
+ const { logEvent } = require('../logger.cjs');
9
+ const { output, error, prefix, pipelineGate } = require('../core.cjs');
10
+ const { generateExpertise, getDetectedFramework } = require('../stack-expert.cjs');
11
+
12
+ /**
13
+ * Find the phase directory for a given phase number.
14
+ */
15
+ function findPhaseDir(brainDir, phaseNumber) {
16
+ const phasesDir = path.join(brainDir, 'phases');
17
+ if (!fs.existsSync(phasesDir)) return null;
18
+ const padded = String(phaseNumber).padStart(2, '0');
19
+ const match = fs.readdirSync(phasesDir).find(d => d.startsWith(`${padded}-`));
20
+ return match ? path.join(phasesDir, match) : null;
21
+ }
22
+
23
+ /**
24
+ * Read the latest SUMMARY file from a phase directory.
25
+ */
26
+ function readLatestSummary(phaseDir) {
27
+ if (!phaseDir || !fs.existsSync(phaseDir)) return null;
28
+ const files = fs.readdirSync(phaseDir)
29
+ .filter(f => f.toUpperCase().startsWith('SUMMARY'))
30
+ .sort();
31
+ if (files.length === 0) return null;
32
+ return fs.readFileSync(path.join(phaseDir, files[files.length - 1]), 'utf8');
33
+ }
34
+
35
+ /**
36
+ * Run the review command.
37
+ * @param {string[]} args
38
+ * @param {object} [opts]
39
+ */
40
+ async function run(args = [], opts = {}) {
41
+ const brainDir = opts.brainDir || path.join(process.cwd(), '.brain');
42
+ const state = readState(brainDir);
43
+
44
+ if (!state) {
45
+ error("No brain state found. Run 'brain-dev init' first.");
46
+ return { error: 'no-state' };
47
+ }
48
+
49
+ // Handle --result flag (called after reviewer agent completes)
50
+ const resultIdx = args.indexOf('--result');
51
+ if (resultIdx >= 0) {
52
+ return handleResult(brainDir, state, args);
53
+ }
54
+
55
+ const phaseIdx = args.indexOf('--phase');
56
+ const phaseNumber = phaseIdx >= 0 ? parseInt(args[phaseIdx + 1], 10) : state.phase.current;
57
+
58
+ const phaseDir = findPhaseDir(brainDir, phaseNumber);
59
+ if (!phaseDir) {
60
+ error(`Phase ${phaseNumber} directory not found.`);
61
+ return { error: 'phase-dir-not-found' };
62
+ }
63
+
64
+ // Read latest summary
65
+ const summaryContent = readLatestSummary(phaseDir);
66
+ if (!summaryContent) {
67
+ error(`No SUMMARY file found for phase ${phaseNumber}. Run /brain:execute first.`);
68
+ return { error: 'no-summary' };
69
+ }
70
+
71
+ // Build reviewer prompt
72
+ const framework = getDetectedFramework(brainDir);
73
+ const template = loadTemplateWithOverlay('reviewer', framework);
74
+ const reviewPath = path.join(phaseDir, 'REVIEW.md');
75
+
76
+ const prompt = interpolate(template, {
77
+ stack_expertise: generateExpertise(brainDir, 'reviewer'),
78
+ summary_content: summaryContent,
79
+ output_path: reviewPath,
80
+ phase: String(phaseNumber),
81
+ plan_number: 'all'
82
+ });
83
+
84
+ // Get reviewer agent metadata
85
+ const reviewerAgent = getAgent('reviewer');
86
+ const model = resolveModel('reviewer', state);
87
+
88
+ // Log spawn event
89
+ logEvent(brainDir, phaseNumber, {
90
+ type: 'spawn',
91
+ agent: 'reviewer',
92
+ phase: phaseNumber
93
+ });
94
+
95
+ // Update state
96
+ state.phase.status = 'reviewing';
97
+ writeState(brainDir, state);
98
+
99
+ const result = {
100
+ action: 'spawn-reviewer',
101
+ phase: phaseNumber,
102
+ prompt,
103
+ model,
104
+ outputPath: reviewPath,
105
+ nextAction: '/brain:verify'
106
+ };
107
+
108
+ const humanLines = [
109
+ prefix(`Code review for Phase ${phaseNumber}`),
110
+ prefix(`Model: ${model}`),
111
+ prefix(`Output: ${reviewPath}`),
112
+ '',
113
+ 'IMPORTANT: Use the Agent tool (subagent_type: "brain-reviewer") to spawn the reviewer.',
114
+ 'Do NOT review the code yourself. The reviewer agent has framework-specific expertise.',
115
+ '',
116
+ 'After the reviewer agent completes, run: npx brain-dev review --result --phase ' + phaseNumber,
117
+ 'This finalizes the review status and advances the pipeline.',
118
+ '',
119
+ prompt
120
+ ];
121
+
122
+ output(result, humanLines.join('\n'));
123
+ return result;
124
+ }
125
+
126
+ /**
127
+ * Handle --result flag: finalize review status based on REVIEW.md.
128
+ * Called after reviewer agent writes REVIEW.md.
129
+ */
130
+ function handleResult(brainDir, state, args) {
131
+ const phaseIdx = args.indexOf('--phase');
132
+ const phaseNumber = phaseIdx >= 0 ? parseInt(args[phaseIdx + 1], 10) : state.phase.current;
133
+
134
+ const phaseDir = findPhaseDir(brainDir, phaseNumber);
135
+ const reviewPath = phaseDir ? path.join(phaseDir, 'REVIEW.md') : null;
136
+
137
+ if (!reviewPath || !fs.existsSync(reviewPath)) {
138
+ error('No REVIEW.md found. Run /brain:review first to spawn the reviewer agent.');
139
+ return { error: 'no-review' };
140
+ }
141
+
142
+ // Parse review status from frontmatter
143
+ const content = fs.readFileSync(reviewPath, 'utf8');
144
+ const statusMatch = content.match(/^status:\s*(passed|needs-work|critical)/m);
145
+ const reviewStatus = statusMatch ? statusMatch[1] : 'passed';
146
+
147
+ if (reviewStatus === 'critical') {
148
+ state.phase.status = 'review-failed';
149
+ writeState(brainDir, state);
150
+ error('Review found critical issues. Fix them and re-run /brain:review.');
151
+ output({ action: 'review-failed', phase: phaseNumber, status: reviewStatus }, '');
152
+ return { action: 'review-failed', phase: phaseNumber };
153
+ }
154
+
155
+ state.phase.status = 'reviewed';
156
+ writeState(brainDir, state);
157
+
158
+ const result = {
159
+ action: 'review-complete',
160
+ phase: phaseNumber,
161
+ status: reviewStatus,
162
+ nextAction: '/brain:verify'
163
+ };
164
+
165
+ output(result, [
166
+ prefix(`Review complete: ${reviewStatus}`),
167
+ pipelineGate(`npx brain-dev verify --phase ${phaseNumber}`)
168
+ ].join('\n'));
169
+
170
+ return result;
171
+ }
172
+
173
+ module.exports = { run };
@@ -92,6 +92,15 @@ const COMMANDS = [
92
92
  needsState: true,
93
93
  args: ' --plan <id> Specific plan to execute (e.g. 01-02)'
94
94
  },
95
+ {
96
+ name: 'review',
97
+ description: 'Code review after execution',
98
+ usage: 'brain-dev review [--phase <n>]',
99
+ group: 'Lifecycle',
100
+ implemented: true,
101
+ needsState: true,
102
+ args: ' --phase <n> Phase to review'
103
+ },
95
104
  {
96
105
  name: 'verify',
97
106
  description: 'Run verification checks on completed work',
@@ -345,6 +345,25 @@ function generateExpertise(brainDir, role = 'general') {
345
345
  }
346
346
  }
347
347
  sections.push('');
348
+ } else if (role === 'reviewer' && fwInfo) {
349
+ sections.push('### Reviewer Guidance');
350
+ sections.push(`- Check code follows ${framework} conventions`);
351
+ if (fwInfo.antiPatterns) {
352
+ sections.push(`- Scan for anti-patterns: ${fwInfo.antiPatterns}`);
353
+ }
354
+ if (fwInfo.patterns) {
355
+ sections.push(`- Verify patterns used: ${fwInfo.patterns}`);
356
+ }
357
+ sections.push('- Compare naming with existing project files');
358
+ sections.push('- Flag over-engineering: unnecessary abstractions, premature optimization');
359
+ if (fwInfo.verificationRules) {
360
+ sections.push('');
361
+ sections.push(`### ${framework} Review Checklist`);
362
+ for (const rule of fwInfo.verificationRules) {
363
+ sections.push(`- [ ] ${rule}`);
364
+ }
365
+ }
366
+ sections.push('');
348
367
  } else {
349
368
  // Generic role guidance (no framework info or general role)
350
369
  if (role === 'planner') {
package/bin/lib/state.cjs CHANGED
@@ -512,6 +512,7 @@ function today() {
512
512
  const VALID_PHASE_STATUSES = [
513
513
  'initialized', 'pending', 'mapped', 'ready', 'discussing', 'discussed',
514
514
  'planning', 'planned', 'executing', 'executed',
515
+ 'reviewing', 'reviewed', 'review-failed',
515
516
  'verifying', 'verified', 'verification-failed',
516
517
  'partial', 'failed', 'paused', 'complete'
517
518
  ];
@@ -0,0 +1,111 @@
1
+ # Code Reviewer Agent
2
+
3
+ ## Technology Context
4
+ {{stack_expertise}}
5
+
6
+ ## Review Scope
7
+
8
+ Review the code changes from the latest execution. Changed files are listed in the SUMMARY below.
9
+
10
+ {{summary_content}}
11
+
12
+ ## Review Criteria (Priority Order)
13
+
14
+ ### 1. Critical Issues (MUST fix before verify)
15
+ - **Bugs**: Logic errors, unhandled edge cases, race conditions
16
+ - **Security**: SQL injection, XSS, auth bypass, secrets in code
17
+ - **Data loss**: Missing transactions, unchecked deletes, no rollback
18
+
19
+ ### 2. Quality Issues (SHOULD fix)
20
+ - **Over-engineering**: Abstractions for things used once, premature optimization, unnecessary design patterns
21
+ - Rule: If code is used in ONE place, inline it. Don't create a helper/utility/service for single use.
22
+ - Rule: If a simple `if/else` works, don't use Strategy Pattern.
23
+ - Rule: 3 similar lines are better than a premature abstraction.
24
+ - Rule: Don't add features, refactor code, or make "improvements" beyond what was asked.
25
+ - **DRY violations**: Same logic in multiple places (>5 lines duplicated)
26
+ - Only flag if the duplication is >5 lines AND in the same module/feature scope
27
+ - Cross-module duplication is acceptable if coupling would be worse
28
+ - **Test quality**: Tests that don't assert behavior, tests that test implementation details
29
+ - Good: `assert.equal(result.status, 'success')`
30
+ - Bad: `assert.equal(mockFn.callCount, 3)` (tests implementation, not behavior)
31
+ - **Error handling**: Missing error handling at system boundaries (user input, external APIs)
32
+ - Do NOT add error handling for internal code or impossible scenarios
33
+
34
+ ### 3. Style Issues (NICE to fix)
35
+ - **Naming**: Inconsistent with existing project code style
36
+ - **Formatting**: Inconsistent indentation, bracket style
37
+ - **Comments**: Obvious comments that add no value, or missing comments on complex logic
38
+
39
+ ## Review Method
40
+
41
+ 1. Read the SUMMARY above to get list of changed/created files
42
+ 2. For each file listed in key-files, read the FULL content
43
+ 3. Compare naming/style with existing project files (read 2-3 similar existing files for comparison)
44
+ 4. Check against framework patterns from Technology Context above
45
+ 5. Only report issues with confidence >= 80%
46
+
47
+ ## Confidence-Based Filtering
48
+
49
+ For each issue found, assign a confidence level:
50
+ - **95-100%**: Definite bug or security issue — always report
51
+ - **80-94%**: High confidence quality issue — report
52
+ - **60-79%**: Possible issue — skip (don't waste time on maybes)
53
+ - **<60%**: Opinion/preference — skip
54
+
55
+ ONLY include issues with confidence >= 80% in the review output.
56
+
57
+ ## Output: REVIEW.md
58
+
59
+ Write results to `{{output_path}}`:
60
+
61
+ ### YAML Frontmatter
62
+
63
+ ```yaml
64
+ ---
65
+ phase: {{phase}}
66
+ plan: {{plan_number}}
67
+ status: passed | needs-work | critical
68
+ issues_count: 0
69
+ critical_count: 0
70
+ quality_count: 0
71
+ style_count: 0
72
+ reviewed_files: []
73
+ ---
74
+ ```
75
+
76
+ ### Per-Issue Format
77
+
78
+ ```markdown
79
+ ### [CRITICAL|QUALITY|STYLE] Issue: {title}
80
+ **Confidence:** {80-100}%
81
+ **File:** {path}
82
+ **Lines:** {range}
83
+ **Problem:** {1-2 sentence description}
84
+ **Fix:** {concrete fix suggestion — not vague advice}
85
+ ```
86
+
87
+ ### Status Determination
88
+ - **passed**: 0 critical issues, ≤2 quality issues — code is good to verify
89
+ - **needs-work**: 0 critical issues, 3+ quality issues — fix before proceeding
90
+ - **critical**: 1+ critical issues — MUST fix, do not proceed
91
+
92
+ ## What NOT to Review
93
+ - Do NOT suggest adding docstrings/comments to code you didn't write
94
+ - Do NOT suggest refactoring code outside the changed files
95
+ - Do NOT suggest type annotations if the project doesn't use them
96
+ - Do NOT suggest error handling for internal code paths that can't fail
97
+ - Do NOT flag style preferences that aren't in the project's existing conventions
98
+ - Do NOT suggest "improvements" beyond what was asked — avoid scope creep
99
+ - When in doubt, the existing project code style WINS over your preferences
100
+
101
+ ## Output Marker
102
+
103
+ When review is complete:
104
+
105
+ ```
106
+ ## REVIEW COMPLETE
107
+
108
+ **Status:** [passed | needs-work | critical]
109
+ **Issues:** [N total: X critical, Y quality, Z style]
110
+ **Files reviewed:** [count]
111
+ ```
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: brain:review
3
+ description: Run code review on executed work before verification
4
+ allowed-tools:
5
+ - Read
6
+ - Bash
7
+ - Grep
8
+ - Glob
9
+ - Agent
10
+ ---
11
+ <objective>
12
+ Review code quality after execution and before verification. Checks DRY, over-engineering,
13
+ framework best practices, and project code style consistency using confidence-based filtering.
14
+ </objective>
15
+
16
+ <critical-rules>
17
+ PIPELINE ENFORCEMENT (NON-NEGOTIABLE):
18
+ 1. Run `npx brain-dev review` FIRST — before reading code, before analyzing, before suggesting fixes
19
+ 2. READ the full output — it spawns brain-reviewer agent with framework-specific expertise
20
+ 3. FOLLOW the nextAction field — copy the exact command, do not modify it
21
+ 4. If output shows an ERROR: follow the recovery path in the output, do NOT debug manually
22
+ 5. If output shows a CHECKPOINT: use AskUserQuestion, do NOT pick options yourself
23
+
24
+ ZERO EXCEPTIONS — REVIEW IS ALWAYS MANDATORY:
25
+ - "Changes are minimal" → STILL review. Small changes cause big bugs.
26
+ - "Only 2 files changed" → STILL review. Every file matters.
27
+ - "This is trivial" → STILL review. You don't decide what's trivial, the reviewer agent does.
28
+ - "I can see the code is fine" → STILL review. You are not the reviewer. The pipeline is.
29
+ - NEVER say "skipping review" for any reason. There is no valid reason to skip.
30
+
31
+ CONSEQUENCE OF SKIPPING: Pipeline tracks state, creates audit trails, spawns specialized agents,
32
+ and injects framework-specific expertise. Skipping it means: no state tracking, no audit trail,
33
+ no specialized agents, no framework guidance, potential data loss in .brain/ state.
34
+ </critical-rules>
35
+
36
+ <process>
37
+ 1. Run: `npx brain-dev review [--phase N]`
38
+ 2. Spawn brain-reviewer agent with the provided prompt
39
+ 3. Review REVIEW.md output
40
+ 4. If critical issues: re-execute fixes, then re-review
41
+ 5. If passed or needs-work (≤2 issues): proceed to /brain:verify
42
+ </process>
@@ -64,7 +64,7 @@ try {
64
64
  'Phase: ' + (data.phase && data.phase.current || 0) + ' (' + (data.phase && data.phase.status || 'initialized') + ')',
65
65
  'Next: ' + (data.nextAction || '/brain:new-project'),
66
66
  '',
67
- 'Commands: /brain:new-project, /brain:story, /brain:discuss, /brain:plan, /brain:execute, /brain:verify, /brain:complete, /brain:quick, /brain:new-task, /brain:progress, /brain:pause, /brain:resume, /brain:help, /brain:health, /brain:update, /brain:upgrade, /brain:storm, /brain:adr, /brain:phase, /brain:config, /brain:map, /brain:recover, /brain:dashboard, /brain:auto (or execute --auto)',
67
+ 'Commands: /brain:new-project, /brain:story, /brain:discuss, /brain:plan, /brain:execute, /brain:review, /brain:verify, /brain:complete, /brain:quick, /brain:new-task, /brain:progress, /brain:pause, /brain:resume, /brain:help, /brain:health, /brain:update, /brain:upgrade, /brain:storm, /brain:adr, /brain:phase, /brain:config, /brain:map, /brain:recover, /brain:dashboard, /brain:auto (or execute --auto)',
68
68
  '',
69
69
  'PIPELINE RULES (NON-NEGOTIABLE):',
70
70
  '',
@@ -89,6 +89,11 @@ try {
89
89
  '6. STATE: Run /brain:progress before suggesting next steps.',
90
90
  ' For /brain:update, always use: npx brain-dev@latest update',
91
91
  ' NEVER run brain-dev init after an update.',
92
+ '',
93
+ '7. REVIEW IS MANDATORY: After execute, ALWAYS run /brain:review before /brain:verify.',
94
+ ' NEVER skip review because changes seem "small", "trivial", or "minimal".',
95
+ ' You do NOT decide what needs review. The reviewer agent decides.',
96
+ ' There are ZERO valid reasons to skip the review step.',
92
97
  '--- End Brain Context ---'
93
98
  ];
94
99
  console.log(lines.join('\n'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brain-dev",
3
- "version": "2.2.1",
3
+ "version": "2.3.1",
4
4
  "description": "AI-powered development workflow orchestrator",
5
5
  "author": "halilcosdu",
6
6
  "license": "MIT",