brain-dev 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -136,6 +136,17 @@ Brain auto-detects your project on init:
136
136
  - **Workspace siblings**: Detects `myapp-mobile/`, `myapp-landing/` alongside `myapp/`
137
137
  - **Stack-aware**: Asks "I detected a Laravel (PHP) + Vue.js frontend. What do you want to do?" instead of generic "What are you building?"
138
138
 
139
+ ## Stack Expertise
140
+
141
+ Brain automatically provides technology-specific guidance to all agents based on your detected stack:
142
+
143
+ - **15+ frameworks built-in**: Laravel, Next.js, React Native, Express, Django, Rails, Vue.js, NestJS, Flutter, Spring Boot, FastAPI, Astro, SvelteKit, and more
144
+ - **3-layer expertise**: Static patterns + project-specific codebase analysis + Context7 live documentation
145
+ - **Role-aware**: Planner gets file structure guidance, executor gets CLI commands and anti-patterns, verifier gets convention checks
146
+ - **Any technology works**: Unknown frameworks automatically use Context7 for latest documentation
147
+
148
+ No configuration needed — Brain detects your stack and injects expertise into every pipeline stage.
149
+
139
150
  ## Lifecycle
140
151
 
141
152
  ```
@@ -9,6 +9,7 @@ const { logEvent } = require('../logger.cjs');
9
9
  const { output, error } = require('../core.cjs');
10
10
  const { recordInvocation, estimateTokens } = require('../cost.cjs');
11
11
  const { acquireLock, releaseLock } = require('../lock.cjs');
12
+ const { generateExpertise } = require('../stack-expert.cjs');
12
13
 
13
14
  /**
14
15
  * Find a phase directory under .brain/phases/ matching a phase number.
@@ -354,7 +355,8 @@ async function run(args = [], opts = {}) {
354
355
  plan_content: planContent,
355
356
  phase: phaseMatch ? phaseMatch[1].trim() : String(phaseNumber),
356
357
  plan_number: planNumMatch ? planNumMatch[1].trim() : String(targetPlan.num),
357
- subsystem: phaseMatch ? phaseMatch[1].trim() : String(phaseNumber)
358
+ subsystem: phaseMatch ? phaseMatch[1].trim() : String(phaseNumber),
359
+ stack_expertise: generateExpertise(brainDir, 'executor')
358
360
  });
359
361
 
360
362
  // Append orchestration instructions to prompt
@@ -9,6 +9,7 @@ const { getAgent, resolveModel } = require('../agents.cjs');
9
9
  const { logEvent } = require('../logger.cjs');
10
10
  const { estimateFromPlan, getDefaultBudget, checkBudget } = require('../complexity.cjs');
11
11
  const { output, error, success } = require('../core.cjs');
12
+ const { generateExpertise } = require('../stack-expert.cjs');
12
13
 
13
14
  /**
14
15
  * Find a phase directory under .brain/phases/ matching a phase number.
@@ -90,7 +91,8 @@ function generatePlannerPrompt(phase, brainDir) {
90
91
  research_summary: researchSection,
91
92
  output_dir: outputDir,
92
93
  phase_number_padded: padded,
93
- phase_slug: slug
94
+ phase_slug: slug,
95
+ stack_expertise: generateExpertise(brainDir, 'planner')
94
96
  });
95
97
 
96
98
  return { prompt, output_dir: outputDir };
@@ -7,6 +7,7 @@ const { loadTemplate, interpolate } = require('../templates.cjs');
7
7
  const { resolveModel } = require('../agents.cjs');
8
8
  const { logEvent } = require('../logger.cjs');
9
9
  const { output, error, success } = require('../core.cjs');
10
+ const { generateExpertise } = require('../stack-expert.cjs');
10
11
 
11
12
  /**
12
13
  * Generate a URL-safe slug from a description.
@@ -163,7 +164,8 @@ function handleInit(args, brainDir, state) {
163
164
  research_summary: '_Quick mode: no research phase._',
164
165
  output_dir: taskDir,
165
166
  phase_number_padded: String(nextNum).padStart(3, '0'),
166
- phase_slug: slug
167
+ phase_slug: slug,
168
+ stack_expertise: generateExpertise(brainDir, 'executor')
167
169
  });
168
170
 
169
171
  const quickConstraints = [
@@ -249,7 +251,8 @@ function handleExecute(args, brainDir, state) {
249
251
  plan_content: planContent,
250
252
  phase: `Q${taskNum}`,
251
253
  plan_number: '1',
252
- subsystem: `quick-${taskNum}`
254
+ subsystem: `quick-${taskNum}`,
255
+ stack_expertise: generateExpertise(brainDir, 'executor')
253
256
  });
254
257
 
255
258
  const model = resolveModel('executor', state);
@@ -3,6 +3,7 @@
3
3
  const fs = require('node:fs');
4
4
  const path = require('node:path');
5
5
  const { estimateTokens } = require('./tokens.cjs');
6
+ const { generateExpertise } = require('./stack-expert.cjs');
6
7
 
7
8
  // Token budgets per agent type
8
9
  const CONTEXT_BUDGETS = {
@@ -17,6 +18,7 @@ const CONTEXT_BUDGETS = {
17
18
  const PRIORITY_TIERS = {
18
19
  P0_PLAN: 0,
19
20
  P1_STATE: 1,
21
+ P1_5_STACK_EXPERTISE: 1.5,
20
22
  P2_PHASE_CONTEXT: 2,
21
23
  P3_PRIOR_SUMMARIES: 3,
22
24
  P4_RESEARCH: 4,
@@ -157,6 +159,14 @@ function buildContextManifest(brainDir, phaseDir, planNum) {
157
159
  required: true
158
160
  });
159
161
 
162
+ // P1.5: Stack Expertise (required, synthetic - handled separately)
163
+ manifest.push({
164
+ tier: PRIORITY_TIERS.P1_5_STACK_EXPERTISE,
165
+ label: 'Stack Expertise',
166
+ path: '__SYNTHETIC_STACK_EXPERTISE__',
167
+ required: true
168
+ });
169
+
160
170
  // P2: Phase CONTEXT.md decisions (required)
161
171
  if (phaseDir) {
162
172
  manifest.push({
@@ -255,7 +265,7 @@ function detectStaleContext(manifest, referenceTimestamp) {
255
265
  const staleFiles = [];
256
266
 
257
267
  for (const entry of manifest) {
258
- if (entry.path === '__SYNTHETIC_PRIOR_SUMMARIES__') continue;
268
+ if (entry.path === '__SYNTHETIC_PRIOR_SUMMARIES__' || entry.path === '__SYNTHETIC_STACK_EXPERTISE__') continue;
259
269
  try {
260
270
  const stat = fs.statSync(entry.path);
261
271
  if (stat.mtime.getTime() > refTime) {
@@ -300,7 +310,10 @@ function assembleTaskContext(brainDir, phaseDir, planNum, opts) {
300
310
  let content;
301
311
  let sectionHeader;
302
312
 
303
- if (entry.path === '__SYNTHETIC_PRIOR_SUMMARIES__') {
313
+ if (entry.path === '__SYNTHETIC_STACK_EXPERTISE__') {
314
+ content = generateExpertise(brainDir, agentType);
315
+ sectionHeader = '## Stack Expertise';
316
+ } else if (entry.path === '__SYNTHETIC_PRIOR_SUMMARIES__') {
304
317
  content = collectPriorSummaries(phaseDir, planNum);
305
318
  sectionHeader = '## Prior Plan Results';
306
319
  } else {
@@ -0,0 +1,308 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs');
4
+ const path = require('node:path');
5
+ const { readDetection } = require('./story-helpers.cjs');
6
+
7
+ // Knowledge base: language → framework → expertise rules
8
+ // NOT hardcoded content — generates guidance from PATTERNS
9
+ const STACK_PATTERNS = {
10
+ // Language-level patterns
11
+ languages: {
12
+ php: { testFramework: 'PHPUnit', packageManager: 'composer', naming: 'PSR-4 namespacing, snake_case for DB columns' },
13
+ javascript: { testFramework: 'Jest/Vitest', packageManager: 'npm/yarn', naming: 'camelCase functions, PascalCase components' },
14
+ typescript: { testFramework: 'Jest/Vitest', packageManager: 'npm/yarn', naming: 'camelCase, PascalCase types, interfaces prefixed with I optional' },
15
+ python: { testFramework: 'pytest', packageManager: 'pip/poetry', naming: 'snake_case everywhere, PascalCase classes' },
16
+ go: { testFramework: 'go test', packageManager: 'go mod', naming: 'camelCase private, PascalCase exported' },
17
+ ruby: { testFramework: 'RSpec/Minitest', packageManager: 'bundler', naming: 'snake_case methods, PascalCase classes' },
18
+ rust: { testFramework: 'cargo test', packageManager: 'cargo', naming: 'snake_case, PascalCase types' },
19
+ java: { testFramework: 'JUnit', packageManager: 'maven/gradle', naming: 'camelCase methods, PascalCase classes' },
20
+ swift: { testFramework: 'XCTest', packageManager: 'SPM', naming: 'camelCase, PascalCase types' },
21
+ kotlin: { testFramework: 'JUnit/Kotest', packageManager: 'gradle', naming: 'camelCase, PascalCase classes' }
22
+ },
23
+
24
+ // Framework-level patterns (file structure, key concepts)
25
+ frameworks: {
26
+ 'Laravel': {
27
+ structure: 'app/Models, app/Http/Controllers, routes/api.php, database/migrations',
28
+ keyCommands: 'php artisan make:model, make:controller, make:migration, migrate',
29
+ patterns: 'Eloquent ORM, Form Requests for validation, Resource controllers, Middleware',
30
+ antiPatterns: 'N+1 queries (use eager loading), fat controllers (use Services/Actions), raw SQL in controllers',
31
+ testing: 'Feature tests in tests/Feature, Unit tests in tests/Unit, use RefreshDatabase trait'
32
+ },
33
+ 'Next.js': {
34
+ structure: 'app/ (App Router), components/, lib/, public/, app/api/ for routes',
35
+ keyCommands: 'npx next dev, next build, next start',
36
+ patterns: 'Server Components by default, use client for interactivity, Server Actions, Route Handlers',
37
+ antiPatterns: 'useEffect for data fetching (use Server Components), client-side state for server data, large client bundles',
38
+ testing: 'Jest + React Testing Library, or Vitest, test in __tests__/ or *.test.tsx'
39
+ },
40
+ 'React Native': {
41
+ structure: 'app/ (Expo Router) or src/screens, components/, hooks/, services/',
42
+ keyCommands: 'npx expo start, expo prebuild, eas build',
43
+ patterns: 'Functional components + hooks, React Navigation/Expo Router, AsyncStorage, StyleSheet',
44
+ antiPatterns: 'Inline styles (use StyleSheet), heavy computation on JS thread, large FlatList without optimization',
45
+ testing: 'Jest + React Native Testing Library, detox for E2E'
46
+ },
47
+ 'Express': {
48
+ structure: 'routes/, middleware/, controllers/, models/',
49
+ keyCommands: 'node server.js, npm start',
50
+ patterns: 'Router middleware chain, error handling middleware, async/await handlers',
51
+ antiPatterns: 'Callback hell, no error middleware, sync operations blocking event loop',
52
+ testing: 'Jest/Mocha + supertest for HTTP assertions'
53
+ },
54
+ 'Django': {
55
+ structure: 'apps/<name>/models.py, views.py, urls.py, templates/',
56
+ keyCommands: 'python manage.py runserver, makemigrations, migrate, createsuperuser',
57
+ patterns: 'Class-based views, Django ORM, Forms/Serializers, middleware',
58
+ antiPatterns: 'N+1 queries (use select_related/prefetch_related), logic in views (use services)',
59
+ testing: 'pytest-django or TestCase, factory_boy for fixtures'
60
+ },
61
+ 'Rails': {
62
+ structure: 'app/models, app/controllers, config/routes.rb, db/migrate',
63
+ keyCommands: 'rails generate, rails db:migrate, rails server',
64
+ patterns: 'ActiveRecord, RESTful routes, concerns, service objects',
65
+ antiPatterns: 'Fat models (extract services), callbacks abuse, N+1 (use includes)',
66
+ testing: 'RSpec + FactoryBot, system tests with Capybara'
67
+ },
68
+ 'Vue.js': {
69
+ structure: 'src/components, src/views, src/stores (Pinia), src/router',
70
+ keyCommands: 'npm run dev, npm run build',
71
+ patterns: 'Composition API, Pinia stores, Vue Router, SFC (Single File Components)',
72
+ antiPatterns: 'Options API in new code, mutating props, watchers for everything',
73
+ testing: 'Vitest + Vue Test Utils'
74
+ },
75
+ 'NestJS': {
76
+ structure: 'src/modules/<name>/, <name>.controller.ts, <name>.service.ts, <name>.module.ts',
77
+ keyCommands: 'nest generate, nest start --watch',
78
+ patterns: 'Dependency injection, decorators, guards, interceptors, pipes',
79
+ antiPatterns: 'Business logic in controllers, skipping DTOs, circular dependencies',
80
+ testing: 'Jest with @nestjs/testing, e2e with supertest'
81
+ },
82
+ 'Flutter': {
83
+ structure: 'lib/screens, lib/widgets, lib/models, lib/services',
84
+ keyCommands: 'flutter run, flutter build, flutter test',
85
+ patterns: 'BLoC/Provider/Riverpod state management, Widget composition, Navigator 2.0',
86
+ antiPatterns: 'Deep widget trees (extract widgets), setState everywhere, blocking UI thread',
87
+ testing: 'flutter_test, widget tests, integration_test'
88
+ },
89
+ 'Spring Boot': {
90
+ structure: 'src/main/java/com/example/, controllers/, services/, repositories/',
91
+ keyCommands: 'mvn spring-boot:run, ./gradlew bootRun',
92
+ patterns: '@RestController, @Service, @Repository, JPA entities, @Autowired',
93
+ antiPatterns: 'Field injection (use constructor), business logic in controllers, N+1 JPA',
94
+ testing: 'JUnit 5 + Mockito, @SpringBootTest, @WebMvcTest'
95
+ },
96
+ 'FastAPI': {
97
+ structure: 'app/main.py, app/routers/, app/models/, app/schemas/',
98
+ keyCommands: 'uvicorn app.main:app --reload',
99
+ patterns: 'Pydantic models, dependency injection, async/await, path operations',
100
+ antiPatterns: 'Sync database calls in async endpoints, no Pydantic validation, global state',
101
+ testing: 'pytest + httpx AsyncClient'
102
+ },
103
+ 'Astro': {
104
+ structure: 'src/pages, src/components, src/layouts, public/',
105
+ keyCommands: 'npm run dev, astro build',
106
+ patterns: 'Islands architecture, .astro components, content collections, SSG by default',
107
+ antiPatterns: 'Client-side JS when static works, large island components, ignoring content collections',
108
+ testing: 'Vitest for logic, Playwright for E2E'
109
+ },
110
+ 'SvelteKit': {
111
+ structure: 'src/routes, src/lib, src/lib/components',
112
+ keyCommands: 'npm run dev, npm run build',
113
+ patterns: 'File-based routing, load functions, stores, form actions',
114
+ antiPatterns: 'Client-side fetching in load functions, reactive statements abuse',
115
+ testing: 'Vitest + @testing-library/svelte, Playwright'
116
+ }
117
+ }
118
+ };
119
+
120
+ /**
121
+ * Generate role-specific technology expertise from 3 layers.
122
+ * @param {string} brainDir
123
+ * @param {string} [role='general'] - 'planner' | 'executor' | 'verifier' | 'general'
124
+ * @returns {string} Markdown expertise block for template injection
125
+ */
126
+ function generateExpertise(brainDir, role = 'general') {
127
+ const detection = readDetection(brainDir);
128
+ if (!detection) return '';
129
+
130
+ const sections = [];
131
+ const stack = detection.stack || {};
132
+ const lang = stack.language || stack.primary?.language;
133
+ const framework = stack.framework || stack.primary?.framework;
134
+ const frontend = stack.frontend;
135
+ const features = detection.features || [];
136
+
137
+ sections.push('## Stack Expertise');
138
+ sections.push('');
139
+
140
+ // Language guidance
141
+ const langInfo = lang ? STACK_PATTERNS.languages[lang.toLowerCase()] : null;
142
+ if (langInfo) {
143
+ sections.push(`### Language: ${lang}`);
144
+ sections.push(`- Test framework: ${langInfo.testFramework}`);
145
+ sections.push(`- Package manager: ${langInfo.packageManager}`);
146
+ sections.push(`- Naming: ${langInfo.naming}`);
147
+ sections.push('');
148
+ }
149
+
150
+ // Primary framework guidance
151
+ const fwInfo = framework ? findFrameworkPattern(framework) : null;
152
+ if (fwInfo) {
153
+ sections.push(`### Framework: ${framework}`);
154
+ sections.push(`- **File structure:** ${fwInfo.structure}`);
155
+ sections.push(`- **Key commands:** ${fwInfo.keyCommands}`);
156
+ sections.push(`- **Patterns to follow:** ${fwInfo.patterns}`);
157
+ sections.push(`- **Anti-patterns to AVOID:** ${fwInfo.antiPatterns}`);
158
+ sections.push(`- **Testing:** ${fwInfo.testing}`);
159
+ sections.push('');
160
+ }
161
+
162
+ // Frontend framework (multi-stack)
163
+ if (frontend?.framework) {
164
+ const frontendInfo = findFrameworkPattern(frontend.framework);
165
+ if (frontendInfo) {
166
+ sections.push(`### Frontend: ${frontend.framework}`);
167
+ sections.push(`- **Structure:** ${frontendInfo.structure}`);
168
+ sections.push(`- **Patterns:** ${frontendInfo.patterns}`);
169
+ sections.push(`- **Anti-patterns:** ${frontendInfo.antiPatterns}`);
170
+ if (frontend.css) sections.push(`- **CSS:** ${frontend.css}`);
171
+ if (frontend.bundler) sections.push(`- **Bundler:** ${frontend.bundler}`);
172
+ sections.push('');
173
+ }
174
+ }
175
+
176
+ // Feature-specific guidance
177
+ if (features.length > 0) {
178
+ sections.push(`### Detected Features`);
179
+ sections.push(`This project already has: ${features.join(', ')}`);
180
+ sections.push('When modifying these features, extend existing patterns rather than rebuilding.');
181
+ sections.push('');
182
+ }
183
+
184
+ // Workspace siblings
185
+ if (detection.workspace?.siblings?.length > 0) {
186
+ sections.push(`### Related Projects`);
187
+ for (const s of detection.workspace.siblings) {
188
+ sections.push(`- **${s.name}:** ${s.stack?.framework || s.stack?.language || 'unknown'}`);
189
+ }
190
+ sections.push('Consider API contract compatibility when modifying shared interfaces.');
191
+ sections.push('');
192
+ }
193
+
194
+ // LAYER 2: Codebase analysis (project-specific patterns)
195
+ const codebaseDir = path.join(brainDir, 'codebase');
196
+ if (fs.existsSync(codebaseDir)) {
197
+ const conventionsPath = path.join(codebaseDir, 'CONVENTIONS.md');
198
+ const stackPath = path.join(codebaseDir, 'STACK.md');
199
+
200
+ if (fs.existsSync(conventionsPath)) {
201
+ const conventions = fs.readFileSync(conventionsPath, 'utf8');
202
+ const excerpt = conventions.slice(0, 2000); // Keep concise
203
+ sections.push('### Project-Specific Conventions (from codebase analysis)');
204
+ sections.push(excerpt);
205
+ sections.push('');
206
+ }
207
+
208
+ if (role === 'planner' && fs.existsSync(stackPath)) {
209
+ const stackAnalysis = fs.readFileSync(stackPath, 'utf8');
210
+ const excerpt = stackAnalysis.slice(0, 1500);
211
+ sections.push('### Existing Stack Details');
212
+ sections.push(excerpt);
213
+ sections.push('');
214
+ }
215
+ }
216
+
217
+ // LAYER 3: Context7 live documentation queries
218
+ if (framework || lang) {
219
+ sections.push(generateContext7Queries(brainDir));
220
+ }
221
+
222
+ // Unknown framework: Context7 becomes PRIMARY (not fallback)
223
+ if (!fwInfo && (framework || lang)) {
224
+ sections.push(`### ${framework || lang} Project`);
225
+ sections.push(`IMPORTANT: No built-in patterns for ${framework || lang}.`);
226
+ sections.push('You MUST use Context7 to look up framework conventions BEFORE writing code:');
227
+ sections.push(`1. Use resolve-library-id to find "${framework || lang}"`);
228
+ sections.push('2. Query for: file structure, naming conventions, testing patterns');
229
+ sections.push('3. Follow the retrieved conventions strictly');
230
+ sections.push('');
231
+ }
232
+
233
+ // Role-specific guidance
234
+ if (role === 'planner') {
235
+ sections.push('### Planner Guidance');
236
+ sections.push('- Ensure task file paths match framework directory structure');
237
+ sections.push('- Include test tasks using the detected test framework');
238
+ sections.push('- Set must_haves that reference framework conventions');
239
+ sections.push('');
240
+ } else if (role === 'executor') {
241
+ sections.push('### Executor Guidance');
242
+ sections.push('- Use framework CLI commands (listed above) to scaffold where possible');
243
+ sections.push('- Follow naming conventions strictly');
244
+ sections.push('- AVOID all listed anti-patterns');
245
+ sections.push('- Write tests in the detected test framework');
246
+ sections.push('');
247
+ } else if (role === 'verifier') {
248
+ sections.push('### Verifier Guidance');
249
+ sections.push('- Verify files are in correct framework directories');
250
+ sections.push('- Check naming follows detected conventions');
251
+ sections.push('- Scan for anti-patterns from the list above');
252
+ sections.push('- Verify tests use the correct test framework');
253
+ sections.push('');
254
+ }
255
+
256
+ return sections.join('\n');
257
+ }
258
+
259
+ /**
260
+ * Find a framework pattern by name (case-insensitive, partial match).
261
+ * @param {string} name - Framework name to look up
262
+ * @returns {object|null} Framework pattern object or null
263
+ */
264
+ function findFrameworkPattern(name) {
265
+ // Case-insensitive, partial match
266
+ for (const [key, value] of Object.entries(STACK_PATTERNS.frameworks)) {
267
+ if (key.toLowerCase() === name.toLowerCase() ||
268
+ name.toLowerCase().includes(key.toLowerCase())) {
269
+ return value;
270
+ }
271
+ }
272
+ return null;
273
+ }
274
+
275
+ /**
276
+ * Generate Context7 lookup instructions for the detected stack.
277
+ * @param {string} brainDir
278
+ * @returns {string} Context7 query instructions
279
+ */
280
+ function generateContext7Queries(brainDir) {
281
+ const detection = readDetection(brainDir);
282
+ if (!detection) return '';
283
+
284
+ const framework = detection.stack?.framework || detection.stack?.primary?.framework;
285
+ const lang = detection.stack?.language || detection.stack?.primary?.language;
286
+
287
+ if (!framework && !lang) return '';
288
+
289
+ const lines = [];
290
+ lines.push('### Live Documentation (Context7)');
291
+ lines.push('If Context7 MCP is available, query for latest docs:');
292
+ if (framework) {
293
+ lines.push(`1. resolve-library-id: "${framework}"`);
294
+ lines.push(`2. query-docs with the resolved ID for task-relevant topics`);
295
+ }
296
+ if (lang && lang !== 'javascript' && lang !== 'typescript') {
297
+ lines.push(`- Also check: "${lang} standard library" for core patterns`);
298
+ }
299
+ lines.push('');
300
+ return lines.join('\n');
301
+ }
302
+
303
+ module.exports = {
304
+ generateExpertise,
305
+ generateContext7Queries,
306
+ findFrameworkPattern,
307
+ STACK_PATTERNS
308
+ };
package/bin/lib/state.cjs CHANGED
@@ -4,7 +4,7 @@ const fs = require('node:fs');
4
4
  const path = require('node:path');
5
5
 
6
6
  const CURRENT_SCHEMA = 'brain/v1';
7
- const CURRENT_VERSION = '1.0.0';
7
+ const CURRENT_VERSION = '1.1.0';
8
8
 
9
9
  /**
10
10
  * Atomic write: write to temp file, then rename.
@@ -1,5 +1,14 @@
1
1
  # Executor Agent Instructions
2
2
 
3
+ ## Technology Context
4
+ {{stack_expertise}}
5
+
6
+ When implementing, follow the framework patterns above:
7
+ - Place files in the correct framework directories
8
+ - Use framework-specific naming conventions
9
+ - Avoid the listed anti-patterns
10
+ - Write tests using the detected test framework
11
+
3
12
  ## Plan to Execute
4
13
 
5
14
  **Plan file:** {{plan_path}}
@@ -2,6 +2,12 @@
2
2
 
3
3
  You are a planner agent creating execution plans for **Phase {{phase_number}}: {{phase_name}}**.
4
4
 
5
+ ## Technology Context
6
+ {{stack_expertise}}
7
+
8
+ When creating plans, ensure tasks follow the framework patterns above.
9
+ File paths, naming, and testing approach must match the detected stack.
10
+
5
11
  ## Phase Context
6
12
 
7
13
  **Goal:** {{phase_goal}}
@@ -1,5 +1,14 @@
1
1
  # Verifier Agent Instructions
2
2
 
3
+ ## Technology Context
4
+ {{stack_expertise}}
5
+
6
+ During verification, check:
7
+ - Files are in correct framework directories
8
+ - Naming follows framework conventions
9
+ - No anti-patterns from the list above
10
+ - Tests use the correct test framework
11
+
3
12
  ## Phase Must-Haves
4
13
 
5
14
  {{must_haves}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brain-dev",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "AI-powered development workflow orchestrator",
5
5
  "author": "halilcosdu",
6
6
  "license": "MIT",