brain-dev 2.0.6 → 2.2.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/bin/lib/commands/discuss.cjs +3 -3
- package/bin/lib/commands/execute.cjs +5 -4
- package/bin/lib/commands/plan.cjs +7 -5
- package/bin/lib/commands/story.cjs +41 -3
- package/bin/lib/commands/verify.cjs +5 -4
- package/bin/lib/core.cjs +18 -1
- package/bin/lib/stack-expert.cjs +163 -34
- package/bin/lib/templates.cjs +19 -1
- package/bin/templates/executor.md +12 -0
- package/bin/templates/overlays/laravel/executor-overlay.md +31 -0
- package/bin/templates/overlays/laravel/planner-overlay.md +33 -0
- package/bin/templates/overlays/laravel/verifier-overlay.md +28 -0
- package/bin/templates/overlays/nextjs/executor-overlay.md +24 -0
- package/bin/templates/overlays/nextjs/verifier-overlay.md +21 -0
- package/bin/templates/overlays/react-native/executor-overlay.md +28 -0
- package/bin/templates/overlays/react-native/verifier-overlay.md +20 -0
- package/bin/templates/planner.md +6 -0
- package/bin/templates/verifier.md +7 -0
- package/commands/brain/adr.md +10 -3
- package/commands/brain/auto.md +10 -5
- package/commands/brain/complete.md +10 -3
- package/commands/brain/config.md +10 -3
- package/commands/brain/discuss.md +10 -4
- package/commands/brain/execute.md +10 -4
- package/commands/brain/health.md +10 -3
- package/commands/brain/new-project.md +10 -3
- package/commands/brain/new-task.md +11 -12
- package/commands/brain/pause.md +10 -2
- package/commands/brain/plan.md +10 -4
- package/commands/brain/quick.md +10 -5
- package/commands/brain/recover.md +10 -3
- package/commands/brain/story.md +10 -4
- package/commands/brain/verify.md +10 -4
- package/hooks/bootstrap.sh +23 -8
- package/package.json +1 -1
|
@@ -5,7 +5,7 @@ const path = require('node:path');
|
|
|
5
5
|
const { readState, writeState, atomicWriteSync } = require('../state.cjs');
|
|
6
6
|
const { parseRoadmap } = require('../roadmap.cjs');
|
|
7
7
|
const { loadTemplate, interpolate } = require('../templates.cjs');
|
|
8
|
-
const { output, error, success } = require('../core.cjs');
|
|
8
|
+
const { output, error, success, pipelineGate } = require('../core.cjs');
|
|
9
9
|
const { generateExpertise } = require('../stack-expert.cjs');
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -230,8 +230,8 @@ function handleSave(args, brainDir, state) {
|
|
|
230
230
|
nextAction: '/brain:plan'
|
|
231
231
|
};
|
|
232
232
|
|
|
233
|
-
success("Context captured.
|
|
234
|
-
output(result,
|
|
233
|
+
success("Context captured.");
|
|
234
|
+
output(result, pipelineGate(`npx brain-dev plan --phase ${phaseNumber}`));
|
|
235
235
|
|
|
236
236
|
return result;
|
|
237
237
|
}
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
const fs = require('node:fs');
|
|
4
4
|
const path = require('node:path');
|
|
5
5
|
const { readState, writeState } = require('../state.cjs');
|
|
6
|
-
const { loadTemplate, interpolate } = require('../templates.cjs');
|
|
6
|
+
const { loadTemplate, interpolate, loadTemplateWithOverlay } = require('../templates.cjs');
|
|
7
7
|
const { getAgent, resolveModel } = require('../agents.cjs');
|
|
8
8
|
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
|
+
const { generateExpertise, getDetectedFramework } = require('../stack-expert.cjs');
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Find a phase directory under .brain/phases/ matching a phase number.
|
|
@@ -347,8 +347,9 @@ async function run(args = [], opts = {}) {
|
|
|
347
347
|
const spotCheckInstruction = 'After completing all tasks, the orchestrator will verify SUMMARY.md, file existence, and commit count.';
|
|
348
348
|
const debuggerSpawnInstruction = 'If auto-retry fails, a debugger agent will be spawned with the error context.';
|
|
349
349
|
|
|
350
|
-
// Load executor template
|
|
351
|
-
const
|
|
350
|
+
// Load executor template with framework overlay
|
|
351
|
+
const framework = getDetectedFramework(brainDir);
|
|
352
|
+
const template = loadTemplateWithOverlay('executor', framework);
|
|
352
353
|
const prompt = interpolate(template, {
|
|
353
354
|
plan_path: targetPlan.path,
|
|
354
355
|
summary_path: summaryPath,
|
|
@@ -4,12 +4,12 @@ const fs = require('node:fs');
|
|
|
4
4
|
const path = require('node:path');
|
|
5
5
|
const { readState, writeState } = require('../state.cjs');
|
|
6
6
|
const { parseRoadmap } = require('../roadmap.cjs');
|
|
7
|
-
const { loadTemplate, interpolate } = require('../templates.cjs');
|
|
7
|
+
const { loadTemplate, interpolate, loadTemplateWithOverlay } = require('../templates.cjs');
|
|
8
8
|
const { getAgent, resolveModel } = require('../agents.cjs');
|
|
9
9
|
const { logEvent } = require('../logger.cjs');
|
|
10
10
|
const { estimateFromPlan, getDefaultBudget, checkBudget } = require('../complexity.cjs');
|
|
11
|
-
const { output, error, success } = require('../core.cjs');
|
|
12
|
-
const { generateExpertise } = require('../stack-expert.cjs');
|
|
11
|
+
const { output, error, success, pipelineGate } = require('../core.cjs');
|
|
12
|
+
const { generateExpertise, getDetectedFramework } = require('../stack-expert.cjs');
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Find a phase directory under .brain/phases/ matching a phase number.
|
|
@@ -157,7 +157,8 @@ function getAlternatives(tech) {
|
|
|
157
157
|
* @returns {{ prompt: string, output_dir: string }}
|
|
158
158
|
*/
|
|
159
159
|
function generatePlannerPrompt(phase, brainDir) {
|
|
160
|
-
const
|
|
160
|
+
const framework = getDetectedFramework(brainDir);
|
|
161
|
+
const template = loadTemplateWithOverlay('planner', framework);
|
|
161
162
|
|
|
162
163
|
const contextContent = readContext(brainDir, phase.number);
|
|
163
164
|
const researchContent = readResearchSummary(brainDir, phase.number);
|
|
@@ -316,7 +317,8 @@ function handleSingle(args, brainDir, state) {
|
|
|
316
317
|
`[brain] Checker enabled: true`,
|
|
317
318
|
result.advocate_enabled ? `[brain] Advocate enabled: true` : '',
|
|
318
319
|
'',
|
|
319
|
-
fullPrompt
|
|
320
|
+
fullPrompt,
|
|
321
|
+
pipelineGate(`npx brain-dev execute --phase ${phaseNumber}`)
|
|
320
322
|
].filter(Boolean);
|
|
321
323
|
output(result, humanLines.join('\n'));
|
|
322
324
|
|
|
@@ -8,12 +8,46 @@ const { output, error, prefix } = require('../core.cjs');
|
|
|
8
8
|
const { logEvent } = require('../logger.cjs');
|
|
9
9
|
const { loadTemplate, interpolate } = require('../templates.cjs');
|
|
10
10
|
const { getAgent, resolveModel } = require('../agents.cjs');
|
|
11
|
+
const { generateExpertise } = require('../stack-expert.cjs');
|
|
11
12
|
const {
|
|
12
13
|
RESEARCH_AREAS, CORE_QUESTIONS, buildBrownfieldQuestions,
|
|
13
14
|
readDetection, buildCodebaseContext, generateProjectMd,
|
|
14
15
|
generateRequirementsMd, extractFeatures, extractSection
|
|
15
16
|
} = require('../story-helpers.cjs');
|
|
16
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Get research areas with optional framework-specific additions.
|
|
20
|
+
* @param {Array} baseAreas - Default RESEARCH_AREAS
|
|
21
|
+
* @param {object|null} detection - Detection result
|
|
22
|
+
* @returns {Array} Research areas (may include framework-specific one)
|
|
23
|
+
*/
|
|
24
|
+
function getResearchAreas(baseAreas, detection) {
|
|
25
|
+
const areas = [...baseAreas];
|
|
26
|
+
const framework = detection?.stack?.primary?.framework || detection?.stack?.framework;
|
|
27
|
+
if (!framework) return areas;
|
|
28
|
+
|
|
29
|
+
const fwLower = framework.toLowerCase().replace(/[^a-z]/g, '-');
|
|
30
|
+
|
|
31
|
+
// Add framework-specific research area
|
|
32
|
+
areas.push({
|
|
33
|
+
name: `${framework} Patterns`,
|
|
34
|
+
area: `${framework} best practices`,
|
|
35
|
+
description: `${framework}-specific patterns, conventions, ecosystem tools, and common pitfalls`,
|
|
36
|
+
file: `${fwLower}-patterns.md`
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Enrich architecture area with framework context
|
|
40
|
+
const archIdx = areas.findIndex(a => a.area && a.area.toLowerCase().includes('architecture'));
|
|
41
|
+
if (archIdx >= 0) {
|
|
42
|
+
areas[archIdx] = {
|
|
43
|
+
...areas[archIdx],
|
|
44
|
+
description: `${framework} architecture patterns and ${areas[archIdx].description}`
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return areas;
|
|
49
|
+
}
|
|
50
|
+
|
|
17
51
|
async function run(args = [], opts = {}) {
|
|
18
52
|
const { values, positionals } = parseArgs({
|
|
19
53
|
args,
|
|
@@ -317,8 +351,12 @@ function stepResearch(brainDir, storyDir, storyMeta, state) {
|
|
|
317
351
|
const researchDir = path.join(storyDir, 'research');
|
|
318
352
|
fs.mkdirSync(researchDir, { recursive: true });
|
|
319
353
|
|
|
320
|
-
// Build researcher agent prompts
|
|
321
|
-
const
|
|
354
|
+
// Build researcher agent prompts with framework-aware areas
|
|
355
|
+
const detection = readDetection(brainDir);
|
|
356
|
+
const researchAreas = getResearchAreas(RESEARCH_AREAS, detection);
|
|
357
|
+
const stackContext = generateExpertise(brainDir, 'general');
|
|
358
|
+
|
|
359
|
+
const agents = researchAreas.map(area => {
|
|
322
360
|
const agentDef = getAgent('researcher');
|
|
323
361
|
const model = resolveModel('researcher', state);
|
|
324
362
|
return {
|
|
@@ -330,6 +368,7 @@ function stepResearch(brainDir, storyDir, storyMeta, state) {
|
|
|
330
368
|
prompt: [
|
|
331
369
|
`# Research Focus: ${area.area}`,
|
|
332
370
|
'',
|
|
371
|
+
stackContext ? `## Stack Context\n${stackContext}\n` : '',
|
|
333
372
|
`You are a ${area.description} researcher.`,
|
|
334
373
|
'',
|
|
335
374
|
'## Project Context',
|
|
@@ -346,7 +385,6 @@ function stepResearch(brainDir, storyDir, storyMeta, state) {
|
|
|
346
385
|
});
|
|
347
386
|
|
|
348
387
|
// Check brownfield and build mapper agents if codebase not yet mapped
|
|
349
|
-
const detection = readDetection(brainDir);
|
|
350
388
|
const isBrownfield = detection && detection.type === 'brownfield';
|
|
351
389
|
const codebaseDir = path.join(brainDir, 'codebase');
|
|
352
390
|
const codebaseMapped = fs.existsSync(codebaseDir) &&
|
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
const fs = require('node:fs');
|
|
4
4
|
const path = require('node:path');
|
|
5
5
|
const { readState, writeState, atomicWriteSync } = require('../state.cjs');
|
|
6
|
-
const { loadTemplate, interpolate } = require('../templates.cjs');
|
|
6
|
+
const { loadTemplate, interpolate, loadTemplateWithOverlay } = require('../templates.cjs');
|
|
7
7
|
const { getAgent, resolveModel } = require('../agents.cjs');
|
|
8
8
|
const { logEvent } = require('../logger.cjs');
|
|
9
9
|
const { output, error, success } = require('../core.cjs');
|
|
10
10
|
const antiPatterns = require('../anti-patterns.cjs');
|
|
11
11
|
const { buildDebuggerSpawnInstructions } = require('./execute.cjs');
|
|
12
12
|
const { isPathWithinRoot } = require('../security.cjs');
|
|
13
|
-
const { generateExpertise } = require('../stack-expert.cjs');
|
|
13
|
+
const { generateExpertise, getDetectedFramework } = require('../stack-expert.cjs');
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Find a phase directory under .brain/phases/ matching a phase number.
|
|
@@ -255,8 +255,9 @@ async function run(args = [], opts = {}) {
|
|
|
255
255
|
key_links: combinedMustHaves.key_links.length
|
|
256
256
|
});
|
|
257
257
|
|
|
258
|
-
// Load verifier template
|
|
259
|
-
const
|
|
258
|
+
// Load verifier template with framework overlay
|
|
259
|
+
const framework = getDetectedFramework(brainDir);
|
|
260
|
+
const template = loadTemplateWithOverlay('verifier', framework);
|
|
260
261
|
const mustHavesFormatted = [
|
|
261
262
|
'**Truths:**',
|
|
262
263
|
...combinedMustHaves.truths.map(t => `- ${t}`),
|
package/bin/lib/core.cjs
CHANGED
|
@@ -59,4 +59,21 @@ function success(msg) {
|
|
|
59
59
|
console.log(`${tag} ${msg}`);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
/**
|
|
63
|
+
* Generate a pipeline gate marker for command output.
|
|
64
|
+
* This is a visual signal telling Claude the exact next command to run.
|
|
65
|
+
* @param {string} nextCommand - The exact command to run next
|
|
66
|
+
* @returns {string}
|
|
67
|
+
*/
|
|
68
|
+
function pipelineGate(nextCommand) {
|
|
69
|
+
return [
|
|
70
|
+
'',
|
|
71
|
+
'--- PIPELINE GATE ---',
|
|
72
|
+
`NEXT COMMAND (mandatory): ${nextCommand}`,
|
|
73
|
+
'Do NOT skip this command. Do NOT improvise. Do NOT start coding.',
|
|
74
|
+
'Copy and run the command above.',
|
|
75
|
+
'--- END GATE ---'
|
|
76
|
+
].join('\n');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
module.exports = { isTTY, output, prefix, error, success, pipelineGate };
|
package/bin/lib/stack-expert.cjs
CHANGED
|
@@ -24,39 +24,76 @@ const STACK_PATTERNS = {
|
|
|
24
24
|
// Framework-level patterns (file structure, key concepts)
|
|
25
25
|
frameworks: {
|
|
26
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 (
|
|
31
|
-
testing: 'Feature tests in tests/Feature, Unit tests in tests/Unit, use RefreshDatabase trait'
|
|
27
|
+
structure: 'app/Models, app/Http/Controllers, app/Http/Requests, app/Services, routes/api.php, database/migrations',
|
|
28
|
+
keyCommands: 'php artisan make:model -mf, make:controller --api, make:migration, make:request, make:resource, migrate, test',
|
|
29
|
+
patterns: 'Eloquent ORM, Form Requests for validation, API Resources for serialization, Resource controllers, Middleware, Service classes for business logic, Action classes for single-purpose operations',
|
|
30
|
+
antiPatterns: 'N+1 queries (use eager loading with/load), fat controllers (extract to Services/Actions), raw SQL in controllers, logic in models (use Services), not using Form Requests for validation',
|
|
31
|
+
testing: 'Feature tests in tests/Feature, Unit tests in tests/Unit, use RefreshDatabase trait, factories for test data',
|
|
32
|
+
migration: 'php artisan make:migration create_X_table, php artisan migrate, php artisan migrate:rollback',
|
|
33
|
+
commonBugs: 'N+1 query on relationships (use ->with()), mass assignment vulnerability (use $fillable), missing foreign key constraints, not using transactions for multi-table writes, queue job serialization with deleted models',
|
|
34
|
+
verificationRules: ['Migrations exist for all new models', '.env.example has all required keys', 'Routes registered in routes/api.php or routes/web.php', 'Form Requests validate all user input', 'API Resources used for JSON responses', 'Factories exist for all models'],
|
|
35
|
+
planningHints: ['Plan migration tasks BEFORE model/controller tasks', 'Each model needs: migration, model, factory, controller, request, resource, test', 'Group related migrations in same plan', 'Include seeder tasks for test data'],
|
|
36
|
+
testExamples: {
|
|
37
|
+
unit: "public function test_user_can_be_created(): void {\n $user = User::factory()->create(['email' => 'test@example.com']);\n $this->assertDatabaseHas('users', ['email' => 'test@example.com']);\n}",
|
|
38
|
+
integration: "$response = $this->postJson('/api/users', ['name' => 'Test', 'email' => 'test@example.com']);\n$response->assertStatus(201)->assertJsonStructure(['data' => ['id', 'name', 'email']]);"
|
|
39
|
+
}
|
|
32
40
|
},
|
|
33
41
|
'Next.js': {
|
|
34
|
-
structure: 'app/ (App Router), components/, lib/, public
|
|
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'
|
|
42
|
+
structure: 'app/ (App Router), app/api/ for Route Handlers, components/, lib/, public/',
|
|
43
|
+
keyCommands: 'npx next dev, next build, next start, next lint',
|
|
44
|
+
patterns: 'Server Components by default, use client directive for interactivity, Server Actions for mutations, Route Handlers for API, Metadata API for SEO, Suspense for loading states',
|
|
45
|
+
antiPatterns: 'useEffect for data fetching (use Server Components), client-side state for server data, large client bundles, not using loading.tsx/error.tsx, fetching in client when server component suffices',
|
|
46
|
+
testing: 'Jest + React Testing Library, or Vitest, test in __tests__/ or *.test.tsx',
|
|
47
|
+
commonBugs: 'Hydration mismatch (server vs client render difference), importing server-only code in client components, not handling loading/error states, stale cache in fetch(), middleware running on every request',
|
|
48
|
+
verificationRules: ['Page components exist in app/ directory', 'loading.tsx exists for async pages', 'error.tsx exists for error boundaries', 'API Route Handlers use correct HTTP method exports', 'Client components have "use client" directive', 'Metadata exported for SEO pages'],
|
|
49
|
+
planningHints: ['Plan layout components before page components', 'Server Components first, add "use client" only when needed', 'Plan API Route Handlers separate from page components', 'Include loading.tsx and error.tsx for each route group'],
|
|
50
|
+
testExamples: {
|
|
51
|
+
unit: "import { render, screen } from '@testing-library/react';\nimport Page from './page';\n\ntest('renders heading', () => {\n render(<Page />);\n expect(screen.getByRole('heading')).toBeInTheDocument();\n});",
|
|
52
|
+
integration: "const response = await fetch('/api/users', { method: 'POST', body: JSON.stringify({name: 'Test'}) });\nexpect(response.status).toBe(201);"
|
|
53
|
+
}
|
|
39
54
|
},
|
|
40
55
|
'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
|
|
45
|
-
testing: 'Jest + React Native Testing Library, detox for E2E'
|
|
56
|
+
structure: 'app/ (Expo Router) or src/screens, components/, hooks/, services/, assets/',
|
|
57
|
+
keyCommands: 'npx expo start, expo prebuild, eas build, npx jest',
|
|
58
|
+
patterns: 'Functional components + hooks, React Navigation/Expo Router, AsyncStorage, StyleSheet.create, Platform.select for platform-specific code',
|
|
59
|
+
antiPatterns: 'Inline styles (use StyleSheet.create), heavy computation on JS thread, large FlatList without getItemLayout/keyExtractor, not using Platform.OS for platform checks, synchronous storage calls',
|
|
60
|
+
testing: 'Jest + React Native Testing Library, detox for E2E',
|
|
61
|
+
commonBugs: 'Platform-specific rendering not tested on both OS, keyboard covering inputs (use KeyboardAvoidingView), memory leaks from unsubscribed listeners, navigation state persistence issues, StatusBar behavior differences iOS vs Android',
|
|
62
|
+
verificationRules: ['Platform-specific code uses Platform.OS or Platform.select', 'FlatList has keyExtractor and getItemLayout', 'Navigation screens registered in navigator', 'Assets imported correctly (require() for local)', 'No web-only APIs used (document, window)'],
|
|
63
|
+
planningHints: ['Plan shared components before screen-specific ones', 'Consider both iOS and Android in task descriptions', 'Plan navigation structure before individual screens', 'Include platform-specific testing tasks'],
|
|
64
|
+
testExamples: {
|
|
65
|
+
unit: "import { render, screen } from '@testing-library/react-native';\nimport { Button } from './Button';\n\ntest('renders button text', () => {\n render(<Button title='Press me' />);\n expect(screen.getByText('Press me')).toBeTruthy();\n});",
|
|
66
|
+
integration: "const { getByTestId, getByText } = render(<LoginScreen />);\nfireEvent.changeText(getByTestId('email-input'), 'test@example.com');\nfireEvent.press(getByText('Login'));"
|
|
67
|
+
}
|
|
46
68
|
},
|
|
47
69
|
'Express': {
|
|
48
|
-
structure: 'routes/, middleware/, controllers/, models/',
|
|
49
|
-
keyCommands: 'node server.js, npm start',
|
|
50
|
-
patterns: 'Router middleware chain, error handling middleware, async/await
|
|
51
|
-
antiPatterns: 'Callback hell, no error middleware, sync operations blocking event loop',
|
|
52
|
-
testing: 'Jest/Mocha + supertest for HTTP assertions'
|
|
70
|
+
structure: 'routes/, middleware/, controllers/, models/, validators/',
|
|
71
|
+
keyCommands: 'node server.js, npm start, npm test',
|
|
72
|
+
patterns: 'Router middleware chain, error handling middleware, async/await with express-async-errors, request validation with Joi/Zod, controller-service separation',
|
|
73
|
+
antiPatterns: 'Callback hell, no error middleware, sync operations blocking event loop, not validating request body, try/catch in every route (use express-async-errors)',
|
|
74
|
+
testing: 'Jest/Mocha + supertest for HTTP assertions',
|
|
75
|
+
commonBugs: 'Unhandled promise rejections crashing server, missing error middleware (must have 4 params), route order matters (specific before generic), CORS misconfiguration, not closing DB connections on shutdown',
|
|
76
|
+
verificationRules: ['Error handling middleware exists (4 params: err, req, res, next)', 'Routes validate input before processing', 'Async handlers properly catch errors', 'CORS configured for production origins', 'Graceful shutdown handler exists'],
|
|
77
|
+
planningHints: ['Plan middleware before routes', 'Error handling middleware is a separate task at the end', 'Group related routes in same router file', 'Plan validation schemas alongside route handlers'],
|
|
78
|
+
testExamples: {
|
|
79
|
+
unit: "const request = require('supertest');\nconst app = require('../app');\n\ntest('GET /api/users returns 200', async () => {\n const res = await request(app).get('/api/users');\n expect(res.status).toBe(200);\n});",
|
|
80
|
+
integration: "const res = await request(app).post('/api/users').send({name: 'Test', email: 'test@example.com'});\nexpect(res.status).toBe(201);\nexpect(res.body.data).toHaveProperty('id');"
|
|
81
|
+
}
|
|
53
82
|
},
|
|
54
83
|
'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,
|
|
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'
|
|
84
|
+
structure: 'apps/<name>/models.py, views.py, urls.py, serializers.py, admin.py, templates/',
|
|
85
|
+
keyCommands: 'python manage.py runserver, makemigrations, migrate, createsuperuser, test, shell',
|
|
86
|
+
patterns: 'Class-based views, Django ORM, DRF Serializers, ModelViewSet, middleware, signals, management commands',
|
|
87
|
+
antiPatterns: 'N+1 queries (use select_related/prefetch_related), logic in views (use services), not using serializers for validation, raw SQL without parameterization',
|
|
88
|
+
testing: 'pytest-django or TestCase, factory_boy for fixtures',
|
|
89
|
+
migration: 'python manage.py makemigrations, python manage.py migrate, python manage.py migrate <app> zero (rollback)',
|
|
90
|
+
commonBugs: 'Circular imports between apps, migration conflicts in teams, not using select_related causing N+1, signals firing during tests unexpectedly, timezone-naive datetime comparisons',
|
|
91
|
+
verificationRules: ['Migrations created for all model changes', 'URLs registered in app urls.py and included in root urls.py', 'Admin registered for all models', 'Serializers validate all user input', 'Permissions set on views'],
|
|
92
|
+
planningHints: ['Plan models and migrations before views', 'Each app should be self-contained', 'Plan serializers alongside models', 'Include admin registration tasks', 'Plan management commands for data operations'],
|
|
93
|
+
testExamples: {
|
|
94
|
+
unit: "from django.test import TestCase\nfrom .models import User\n\nclass UserModelTest(TestCase):\n def test_create_user(self):\n user = User.objects.create(email='test@example.com')\n self.assertEqual(user.email, 'test@example.com')",
|
|
95
|
+
integration: "from rest_framework.test import APITestCase\n\nclass UserAPITest(APITestCase):\n def test_create_user(self):\n response = self.client.post('/api/users/', {'email': 'test@example.com'})\n self.assertEqual(response.status_code, 201)"
|
|
96
|
+
}
|
|
60
97
|
},
|
|
61
98
|
'Rails': {
|
|
62
99
|
structure: 'app/models, app/controllers, config/routes.rb, db/migrate',
|
|
@@ -94,11 +131,19 @@ const STACK_PATTERNS = {
|
|
|
94
131
|
testing: 'JUnit 5 + Mockito, @SpringBootTest, @WebMvcTest'
|
|
95
132
|
},
|
|
96
133
|
'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'
|
|
134
|
+
structure: 'app/main.py, app/routers/, app/models/, app/schemas/, app/dependencies.py, app/crud/',
|
|
135
|
+
keyCommands: 'uvicorn app.main:app --reload, pytest, alembic upgrade head',
|
|
136
|
+
patterns: 'Pydantic models for validation, Depends() for dependency injection, async/await, path operations, background tasks, lifespan events',
|
|
137
|
+
antiPatterns: 'Sync database calls in async endpoints, no Pydantic validation, global mutable state, not using Depends() for shared logic, blocking the event loop',
|
|
138
|
+
testing: 'pytest + httpx AsyncClient',
|
|
139
|
+
migration: 'alembic init, alembic revision --autogenerate -m "description", alembic upgrade head',
|
|
140
|
+
commonBugs: 'Mixing sync/async database drivers, Pydantic v2 model_validator vs v1 validator, circular imports in routers, not closing DB connections in lifespan, CORS middleware order matters',
|
|
141
|
+
verificationRules: ['Pydantic schemas exist for all request/response models', 'Dependencies use Depends() injection', 'Async endpoints use async database driver', 'Alembic migrations exist for schema changes', 'Error handlers return consistent JSON format'],
|
|
142
|
+
planningHints: ['Plan Pydantic schemas before routers', 'Plan database models with Alembic migrations', 'Group related endpoints in same router', 'Plan dependency injection for shared resources (DB, auth)'],
|
|
143
|
+
testExamples: {
|
|
144
|
+
unit: "from httpx import AsyncClient, ASGITransport\nfrom app.main import app\n\nasync def test_read_users():\n async with AsyncClient(transport=ASGITransport(app=app), base_url='http://test') as ac:\n response = await ac.get('/users')\n assert response.status_code == 200",
|
|
145
|
+
integration: "async def test_create_user(client: AsyncClient):\n response = await client.post('/users', json={'email': 'test@example.com'})\n assert response.status_code == 201\n assert response.json()['email'] == 'test@example.com'"
|
|
146
|
+
}
|
|
102
147
|
},
|
|
103
148
|
'Astro': {
|
|
104
149
|
structure: 'src/pages, src/components, src/layouts, public/',
|
|
@@ -235,26 +280,90 @@ function generateExpertise(brainDir, role = 'general') {
|
|
|
235
280
|
sections.push('');
|
|
236
281
|
}
|
|
237
282
|
|
|
238
|
-
// Role-specific guidance
|
|
239
|
-
if (role === 'planner') {
|
|
283
|
+
// Role-specific deep guidance with framework-specific content
|
|
284
|
+
if (role === 'planner' && fwInfo) {
|
|
240
285
|
sections.push('### Planner Guidance');
|
|
241
286
|
sections.push('- Ensure task file paths match framework directory structure');
|
|
242
287
|
sections.push('- Include test tasks using the detected test framework');
|
|
243
288
|
sections.push('- Set must_haves that reference framework conventions');
|
|
289
|
+
if (fwInfo.planningHints) {
|
|
290
|
+
sections.push('');
|
|
291
|
+
sections.push(`### ${framework} Planning Rules`);
|
|
292
|
+
for (const hint of fwInfo.planningHints) {
|
|
293
|
+
sections.push(`- ${hint}`);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
if (fwInfo.migration) {
|
|
297
|
+
sections.push(`- Migration commands: ${fwInfo.migration}`);
|
|
298
|
+
}
|
|
299
|
+
if (fwInfo.testExamples) {
|
|
300
|
+
sections.push('');
|
|
301
|
+
sections.push(`### Example must_haves for ${framework}`);
|
|
302
|
+
sections.push('```yaml');
|
|
303
|
+
sections.push('truths:');
|
|
304
|
+
if (fwInfo.verificationRules) {
|
|
305
|
+
for (const rule of fwInfo.verificationRules.slice(0, 3)) {
|
|
306
|
+
sections.push(` - "${rule}"`);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
sections.push('```');
|
|
310
|
+
}
|
|
244
311
|
sections.push('');
|
|
245
|
-
} else if (role === 'executor') {
|
|
312
|
+
} else if (role === 'executor' && fwInfo) {
|
|
246
313
|
sections.push('### Executor Guidance');
|
|
247
314
|
sections.push('- Use framework CLI commands (listed above) to scaffold where possible');
|
|
248
315
|
sections.push('- Follow naming conventions strictly');
|
|
249
316
|
sections.push('- AVOID all listed anti-patterns');
|
|
250
317
|
sections.push('- Write tests in the detected test framework');
|
|
318
|
+
if (fwInfo.commonBugs) {
|
|
319
|
+
sections.push('');
|
|
320
|
+
sections.push(`### Common ${framework} Bugs to Avoid`);
|
|
321
|
+
for (const [i, bug] of fwInfo.commonBugs.split(', ').entries()) {
|
|
322
|
+
sections.push(`${i + 1}. ${bug}`);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
if (fwInfo.testExamples) {
|
|
326
|
+
sections.push('');
|
|
327
|
+
sections.push(`### Example Test (${framework})`);
|
|
328
|
+
sections.push('```');
|
|
329
|
+
sections.push(fwInfo.testExamples.unit);
|
|
330
|
+
sections.push('```');
|
|
331
|
+
}
|
|
251
332
|
sections.push('');
|
|
252
|
-
} else if (role === 'verifier') {
|
|
333
|
+
} else if (role === 'verifier' && fwInfo) {
|
|
253
334
|
sections.push('### Verifier Guidance');
|
|
254
335
|
sections.push('- Verify files are in correct framework directories');
|
|
255
336
|
sections.push('- Check naming follows detected conventions');
|
|
256
337
|
sections.push('- Scan for anti-patterns from the list above');
|
|
257
338
|
sections.push('- Verify tests use the correct test framework');
|
|
339
|
+
if (fwInfo.verificationRules) {
|
|
340
|
+
sections.push('');
|
|
341
|
+
sections.push(`### ${framework} Verification Checklist`);
|
|
342
|
+
for (const rule of fwInfo.verificationRules) {
|
|
343
|
+
sections.push(`- [ ] ${rule}`);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
sections.push('');
|
|
347
|
+
} else {
|
|
348
|
+
// Generic role guidance (no framework info or general role)
|
|
349
|
+
if (role === 'planner') {
|
|
350
|
+
sections.push('### Planner Guidance');
|
|
351
|
+
sections.push('- Ensure task file paths match framework directory structure');
|
|
352
|
+
sections.push('- Include test tasks using the detected test framework');
|
|
353
|
+
sections.push('- Set must_haves that reference framework conventions');
|
|
354
|
+
} else if (role === 'executor') {
|
|
355
|
+
sections.push('### Executor Guidance');
|
|
356
|
+
sections.push('- Use framework CLI commands (listed above) to scaffold where possible');
|
|
357
|
+
sections.push('- Follow naming conventions strictly');
|
|
358
|
+
sections.push('- AVOID all listed anti-patterns');
|
|
359
|
+
sections.push('- Write tests in the detected test framework');
|
|
360
|
+
} else if (role === 'verifier') {
|
|
361
|
+
sections.push('### Verifier Guidance');
|
|
362
|
+
sections.push('- Verify files are in correct framework directories');
|
|
363
|
+
sections.push('- Check naming follows detected conventions');
|
|
364
|
+
sections.push('- Scan for anti-patterns from the list above');
|
|
365
|
+
sections.push('- Verify tests use the correct test framework');
|
|
366
|
+
}
|
|
258
367
|
sections.push('');
|
|
259
368
|
}
|
|
260
369
|
|
|
@@ -312,9 +421,29 @@ function generateContext7Queries(detectionOrBrainDir) {
|
|
|
312
421
|
return lines.join('\n');
|
|
313
422
|
}
|
|
314
423
|
|
|
424
|
+
/**
|
|
425
|
+
* Get the detected framework name mapped to overlay directory name.
|
|
426
|
+
* @param {string} brainDir
|
|
427
|
+
* @returns {string|null} Overlay directory name (e.g., 'laravel', 'nextjs') or null
|
|
428
|
+
*/
|
|
429
|
+
function getDetectedFramework(brainDir) {
|
|
430
|
+
const detection = readDetection(brainDir);
|
|
431
|
+
if (!detection?.stack?.primary?.framework && !detection?.stack?.framework) return null;
|
|
432
|
+
const fw = (detection.stack.primary?.framework || detection.stack.framework).toLowerCase();
|
|
433
|
+
const map = {
|
|
434
|
+
'laravel': 'laravel', 'next.js': 'nextjs', 'react native': 'react-native',
|
|
435
|
+
'express': 'express', 'django': 'django', 'fastapi': 'fastapi',
|
|
436
|
+
'rails': 'rails', 'vue.js': 'vuejs', 'nestjs': 'nestjs',
|
|
437
|
+
'flutter': 'flutter', 'spring boot': 'spring-boot', 'sveltekit': 'sveltekit',
|
|
438
|
+
'astro': 'astro'
|
|
439
|
+
};
|
|
440
|
+
return map[fw] || null;
|
|
441
|
+
}
|
|
442
|
+
|
|
315
443
|
module.exports = {
|
|
316
444
|
generateExpertise,
|
|
317
445
|
generateContext7Queries,
|
|
318
446
|
findFrameworkPattern,
|
|
447
|
+
getDetectedFramework,
|
|
319
448
|
STACK_PATTERNS
|
|
320
449
|
};
|
package/bin/lib/templates.cjs
CHANGED
|
@@ -45,4 +45,22 @@ function resolvePath(obj, dotPath) {
|
|
|
45
45
|
return current;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Load a template with optional framework-specific overlay appended.
|
|
50
|
+
* Overlay files live in bin/templates/overlays/{framework}/{name}-overlay.md.
|
|
51
|
+
* @param {string} name - Template name (without .md)
|
|
52
|
+
* @param {string|null} framework - Framework overlay directory name (e.g., 'laravel', 'nextjs')
|
|
53
|
+
* @returns {string} Template content with overlay appended (if exists)
|
|
54
|
+
*/
|
|
55
|
+
function loadTemplateWithOverlay(name, framework) {
|
|
56
|
+
let template = loadTemplate(name);
|
|
57
|
+
if (framework) {
|
|
58
|
+
const overlayPath = path.join(TEMPLATES_DIR, 'overlays', framework, `${name}-overlay.md`);
|
|
59
|
+
if (fs.existsSync(overlayPath)) {
|
|
60
|
+
template += '\n\n' + fs.readFileSync(overlayPath, 'utf8');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return template;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
module.exports = { loadTemplate, interpolate, loadTemplateWithOverlay };
|
|
@@ -242,3 +242,15 @@ Include sections:
|
|
|
242
242
|
- On successful completion of all tasks: `## EXECUTION COMPLETE`
|
|
243
243
|
- On failure after retry: `## EXECUTION FAILED`
|
|
244
244
|
- On checkpoint (user input needed): `## CHECKPOINT REACHED`
|
|
245
|
+
|
|
246
|
+
## Pipeline Enforcement Reminders
|
|
247
|
+
|
|
248
|
+
**EXECUTION FAILED:** When you output this marker:
|
|
249
|
+
- The orchestrator will handle recovery (debugger agent or re-execution)
|
|
250
|
+
- Do NOT start debugging manually. Do NOT skip to the next plan.
|
|
251
|
+
- Follow the "Suggested actions" field ONLY.
|
|
252
|
+
|
|
253
|
+
**CHECKPOINT REACHED:** When you output this marker:
|
|
254
|
+
- STOP all implementation work immediately
|
|
255
|
+
- The user MUST be asked via AskUserQuestion — do NOT pick an option yourself
|
|
256
|
+
- Checkpoints exist because a HUMAN decision is required. Never skip them.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
## Laravel-Specific Execution Rules
|
|
2
|
+
|
|
3
|
+
### Migrations
|
|
4
|
+
- Always create migration before model: `php artisan make:migration create_X_table`
|
|
5
|
+
- Use `php artisan make:model -mf` to scaffold model + migration + factory together
|
|
6
|
+
- Test migration rollback: `php artisan migrate:rollback --step=1`
|
|
7
|
+
- Never modify existing migrations in production — create new ones
|
|
8
|
+
|
|
9
|
+
### Eloquent
|
|
10
|
+
- Use query scopes for reusable queries: `scopeActive`, `scopeVerified`
|
|
11
|
+
- Never use raw SQL in controllers — use Eloquent or Query Builder
|
|
12
|
+
- Always eager-load relationships: `User::with('posts')->get()` to prevent N+1
|
|
13
|
+
- Use `$fillable` or `$guarded` on every model — never leave mass assignment unprotected
|
|
14
|
+
|
|
15
|
+
### Controllers
|
|
16
|
+
- Use API Resource Controllers: `php artisan make:controller UserController --api`
|
|
17
|
+
- Validate with Form Requests, not inline: `php artisan make:request StoreUserRequest`
|
|
18
|
+
- Return API Resources for JSON: `return new UserResource($user)`
|
|
19
|
+
- Keep controllers thin — extract business logic to Service or Action classes
|
|
20
|
+
|
|
21
|
+
### Queue Jobs
|
|
22
|
+
- Always implement `ShouldQueue` for background tasks
|
|
23
|
+
- Use `$tries` and `$backoff` properties for retry strategy
|
|
24
|
+
- Implement `failed()` method for error handling
|
|
25
|
+
- Never use `resolve()` in job constructor — serialize only IDs
|
|
26
|
+
|
|
27
|
+
### Testing
|
|
28
|
+
- Use `RefreshDatabase` trait for database tests
|
|
29
|
+
- Use factories for test data: `User::factory()->create()`
|
|
30
|
+
- Assert database state: `$this->assertDatabaseHas('users', ['email' => ...])`
|
|
31
|
+
- Use `actingAs($user)` for authenticated requests
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
## Laravel-Specific Planning
|
|
2
|
+
|
|
3
|
+
### Task Ordering
|
|
4
|
+
1. **Database first**: Migrations and models before controllers
|
|
5
|
+
2. **Validation second**: Form Requests before controller logic
|
|
6
|
+
3. **API last**: Resources and routes after business logic
|
|
7
|
+
4. **Tests throughout**: Each task should include its test
|
|
8
|
+
|
|
9
|
+
### Standard Feature Pattern
|
|
10
|
+
For each new feature, plan these tasks in order:
|
|
11
|
+
1. Migration + Model + Factory
|
|
12
|
+
2. Form Request (validation rules)
|
|
13
|
+
3. Service/Action class (business logic)
|
|
14
|
+
4. Controller (thin, delegates to service)
|
|
15
|
+
5. API Resource (JSON serialization)
|
|
16
|
+
6. Route registration + middleware
|
|
17
|
+
7. Feature test
|
|
18
|
+
|
|
19
|
+
### must_haves Template for Laravel
|
|
20
|
+
```yaml
|
|
21
|
+
truths:
|
|
22
|
+
- "Migration creates {table} with all required columns"
|
|
23
|
+
- "Model has $fillable for mass-assignable fields"
|
|
24
|
+
- "Form Request validates all user input with correct rules"
|
|
25
|
+
- "Controller delegates to Service, returns API Resource"
|
|
26
|
+
- "Feature test covers happy path and validation errors"
|
|
27
|
+
artifacts:
|
|
28
|
+
- path: "database/migrations/xxxx_create_{table}_table.php"
|
|
29
|
+
- path: "app/Models/{Model}.php"
|
|
30
|
+
- path: "app/Http/Requests/{StoreModel}Request.php"
|
|
31
|
+
- path: "app/Http/Controllers/{Model}Controller.php"
|
|
32
|
+
- path: "tests/Feature/{Model}Test.php"
|
|
33
|
+
```
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
## Laravel-Specific Verification
|
|
2
|
+
|
|
3
|
+
### Migration Checks
|
|
4
|
+
- [ ] Migration file exists for every new model
|
|
5
|
+
- [ ] Migration has both `up()` and `down()` methods
|
|
6
|
+
- [ ] Foreign key constraints defined with `->constrained()`
|
|
7
|
+
- [ ] Indexes added for frequently queried columns
|
|
8
|
+
|
|
9
|
+
### Model Checks
|
|
10
|
+
- [ ] `$fillable` or `$guarded` property set
|
|
11
|
+
- [ ] Relationships defined (hasMany, belongsTo, etc.)
|
|
12
|
+
- [ ] Factory exists in `database/factories/`
|
|
13
|
+
|
|
14
|
+
### Controller Checks
|
|
15
|
+
- [ ] Form Request used for validation (not inline `$request->validate()`)
|
|
16
|
+
- [ ] API Resource used for JSON responses
|
|
17
|
+
- [ ] No business logic in controller (delegated to Service/Action)
|
|
18
|
+
|
|
19
|
+
### Route Checks
|
|
20
|
+
- [ ] Route registered in `routes/api.php` or `routes/web.php`
|
|
21
|
+
- [ ] Route uses middleware for authentication/authorization
|
|
22
|
+
- [ ] RESTful naming convention followed
|
|
23
|
+
|
|
24
|
+
### Test Checks
|
|
25
|
+
- [ ] Feature test exists in `tests/Feature/`
|
|
26
|
+
- [ ] Uses `RefreshDatabase` trait
|
|
27
|
+
- [ ] Factory used for test data
|
|
28
|
+
- [ ] HTTP assertions used (`assertStatus`, `assertJson`, etc.)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
## Next.js-Specific Execution Rules
|
|
2
|
+
|
|
3
|
+
### App Router
|
|
4
|
+
- Server Components are the default — only add `"use client"` when you need interactivity
|
|
5
|
+
- Use `loading.tsx` for Suspense boundaries on async pages
|
|
6
|
+
- Use `error.tsx` for error boundaries
|
|
7
|
+
- Place shared layouts in `layout.tsx` at each route segment
|
|
8
|
+
|
|
9
|
+
### Data Fetching
|
|
10
|
+
- Fetch data in Server Components, not in client useEffect
|
|
11
|
+
- Use Server Actions for mutations (form submissions, data writes)
|
|
12
|
+
- Cache fetch results with `next.revalidate` or `cache: 'force-cache'`
|
|
13
|
+
- Use `generateStaticParams()` for static generation of dynamic routes
|
|
14
|
+
|
|
15
|
+
### API Route Handlers
|
|
16
|
+
- Export named functions matching HTTP methods: `GET`, `POST`, `PUT`, `DELETE`
|
|
17
|
+
- Use `NextRequest` and `NextResponse` types
|
|
18
|
+
- Place in `app/api/` directory
|
|
19
|
+
|
|
20
|
+
### Testing
|
|
21
|
+
- Use `@testing-library/react` for component tests
|
|
22
|
+
- Mock `next/navigation` hooks in tests
|
|
23
|
+
- Test Server Components as async functions
|
|
24
|
+
- Use `render()` + `screen.getByRole()` pattern
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
## Next.js-Specific Verification
|
|
2
|
+
|
|
3
|
+
### Route Structure
|
|
4
|
+
- [ ] Page components exist in `app/` directory structure
|
|
5
|
+
- [ ] `loading.tsx` exists for pages with async data fetching
|
|
6
|
+
- [ ] `error.tsx` exists for route segments with error-prone operations
|
|
7
|
+
- [ ] `layout.tsx` exists for shared navigation/headers
|
|
8
|
+
|
|
9
|
+
### Component Checks
|
|
10
|
+
- [ ] Client components have `"use client"` directive at top
|
|
11
|
+
- [ ] Server Components do NOT use hooks (useState, useEffect)
|
|
12
|
+
- [ ] No `useEffect` for data fetching in server-renderable pages
|
|
13
|
+
|
|
14
|
+
### API Route Checks
|
|
15
|
+
- [ ] Route Handlers export correct HTTP method functions
|
|
16
|
+
- [ ] Responses use `NextResponse.json()` format
|
|
17
|
+
- [ ] Error responses return appropriate status codes
|
|
18
|
+
|
|
19
|
+
### Metadata
|
|
20
|
+
- [ ] Pages export `metadata` or `generateMetadata()` for SEO
|
|
21
|
+
- [ ] Dynamic routes have `generateStaticParams()` if applicable
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
## React Native-Specific Execution Rules
|
|
2
|
+
|
|
3
|
+
### Platform Handling
|
|
4
|
+
- Use `Platform.OS` or `Platform.select()` for platform-specific code
|
|
5
|
+
- Create `.ios.tsx` and `.android.tsx` files for complex platform differences
|
|
6
|
+
- Always test on both iOS and Android (or document platform limitations)
|
|
7
|
+
|
|
8
|
+
### Navigation
|
|
9
|
+
- Define navigation structure before building screens
|
|
10
|
+
- Use typed navigation with `RootStackParamList`
|
|
11
|
+
- Handle deep linking configuration early
|
|
12
|
+
|
|
13
|
+
### Performance
|
|
14
|
+
- Use `FlatList` with `keyExtractor` and `getItemLayout` for long lists
|
|
15
|
+
- Avoid inline functions in render — use `useCallback`
|
|
16
|
+
- Use `React.memo()` for pure components
|
|
17
|
+
- Move heavy computation off the JS thread with `InteractionManager`
|
|
18
|
+
|
|
19
|
+
### Styling
|
|
20
|
+
- Always use `StyleSheet.create()` — never inline style objects
|
|
21
|
+
- Use `Dimensions` or `useWindowDimensions` for responsive layouts
|
|
22
|
+
- Test on different screen sizes
|
|
23
|
+
|
|
24
|
+
### Testing
|
|
25
|
+
- Use `@testing-library/react-native` for component tests
|
|
26
|
+
- Mock native modules with `jest.mock()`
|
|
27
|
+
- Test user interactions with `fireEvent`
|
|
28
|
+
- Include platform-specific test cases
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
## React Native-Specific Verification
|
|
2
|
+
|
|
3
|
+
### Platform Checks
|
|
4
|
+
- [ ] Platform-specific code uses `Platform.OS` or `Platform.select()`
|
|
5
|
+
- [ ] No web-only APIs used (`document`, `window`, `localStorage`)
|
|
6
|
+
- [ ] Assets imported with `require()` for local files
|
|
7
|
+
|
|
8
|
+
### Component Checks
|
|
9
|
+
- [ ] `FlatList` has `keyExtractor` and optimized rendering
|
|
10
|
+
- [ ] `StyleSheet.create()` used (no inline style objects)
|
|
11
|
+
- [ ] Navigation screens registered in navigator configuration
|
|
12
|
+
|
|
13
|
+
### Performance Checks
|
|
14
|
+
- [ ] No inline arrow functions in JSX render (use `useCallback`)
|
|
15
|
+
- [ ] Heavy lists use `FlatList` not `ScrollView` with `.map()`
|
|
16
|
+
- [ ] Images have explicit dimensions
|
|
17
|
+
|
|
18
|
+
### Testing Checks
|
|
19
|
+
- [ ] Component tests use `@testing-library/react-native`
|
|
20
|
+
- [ ] Native modules properly mocked in jest setup
|
package/bin/templates/planner.md
CHANGED
|
@@ -196,6 +196,12 @@ If you cannot create a valid plan after **2 attempts** (e.g., checker keeps reje
|
|
|
196
196
|
|
|
197
197
|
Do NOT produce incomplete or low-quality plans. Blocking with clear information is better than a plan that will fail during execution.
|
|
198
198
|
|
|
199
|
+
**When PLANNING BLOCKED is output:**
|
|
200
|
+
- Ask the user for the missing information using AskUserQuestion
|
|
201
|
+
- Do NOT attempt to force a plan through
|
|
202
|
+
- Do NOT rewrite requirements yourself
|
|
203
|
+
- Wait for user input, then re-run /brain:plan
|
|
204
|
+
|
|
199
205
|
## Enriched SUMMARY.md
|
|
200
206
|
|
|
201
207
|
After each plan executes, the executor creates a SUMMARY.md with:
|
|
@@ -220,3 +220,10 @@ When verification is complete, output:
|
|
|
220
220
|
**Gaps:** [count of failed must_haves, or "none"]
|
|
221
221
|
**Human items:** [count of items needing human verification, or "none"]
|
|
222
222
|
```
|
|
223
|
+
|
|
224
|
+
## Pipeline Enforcement
|
|
225
|
+
|
|
226
|
+
**When gaps_found or partial:**
|
|
227
|
+
- Run `/brain:execute` with `--gaps-only` flag to fix specific gaps
|
|
228
|
+
- Do NOT manually fix the files — the executor agent has the context to fix gaps properly
|
|
229
|
+
- Do NOT skip to `/brain:complete` with unresolved gaps
|
package/commands/brain/adr.md
CHANGED
|
@@ -23,9 +23,16 @@ Supports creating new ADRs, listing existing ones, and searching decision histor
|
|
|
23
23
|
</context>
|
|
24
24
|
|
|
25
25
|
<critical-rules>
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
|
|
26
|
+
PIPELINE ENFORCEMENT (NON-NEGOTIABLE):
|
|
27
|
+
1. Run `npx brain-dev adr $ARGUMENTS` FIRST — before reading code, before analyzing, before suggesting fixes
|
|
28
|
+
2. READ the full output — it contains step-by-step instructions specific to this project's stack
|
|
29
|
+
3. FOLLOW the nextAction field — copy the exact command, do not modify it
|
|
30
|
+
4. If output shows an ERROR: follow the recovery path in the output, do NOT debug manually
|
|
31
|
+
5. If output shows a CHECKPOINT: use AskUserQuestion, do NOT pick options yourself
|
|
32
|
+
|
|
33
|
+
CONSEQUENCE OF SKIPPING: Pipeline tracks state, creates audit trails, spawns specialized agents,
|
|
34
|
+
and injects framework-specific expertise. Skipping it means: no state tracking, no audit trail,
|
|
35
|
+
no specialized agents, no framework guidance, potential data loss in .brain/ state.
|
|
29
36
|
</critical-rules>
|
|
30
37
|
|
|
31
38
|
<process>
|
package/commands/brain/auto.md
CHANGED
|
@@ -22,11 +22,16 @@ Each step tells you which agent to spawn and what prompt to use.
|
|
|
22
22
|
</context>
|
|
23
23
|
|
|
24
24
|
<critical-rules>
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
PIPELINE ENFORCEMENT (NON-NEGOTIABLE):
|
|
26
|
+
1. Run `npx brain-dev execute --auto` FIRST — before reading code, before analyzing, before suggesting fixes
|
|
27
|
+
2. READ the full output — it contains step-by-step instructions specific to this project's stack
|
|
28
|
+
3. FOLLOW the nextAction field — copy the exact command, do not modify it
|
|
29
|
+
4. If output shows an ERROR: follow the recovery path in the output, do NOT debug manually
|
|
30
|
+
5. If output shows a CHECKPOINT: use AskUserQuestion, do NOT pick options yourself
|
|
31
|
+
|
|
32
|
+
CONSEQUENCE OF SKIPPING: Pipeline tracks state, creates audit trails, spawns specialized agents,
|
|
33
|
+
and injects framework-specific expertise. Skipping it means: no state tracking, no audit trail,
|
|
34
|
+
no specialized agents, no framework guidance, potential data loss in .brain/ state.
|
|
30
35
|
</critical-rules>
|
|
31
36
|
|
|
32
37
|
<process>
|
|
@@ -24,9 +24,16 @@ Ensures all phases are verified before completing.
|
|
|
24
24
|
</context>
|
|
25
25
|
|
|
26
26
|
<critical-rules>
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
PIPELINE ENFORCEMENT (NON-NEGOTIABLE):
|
|
28
|
+
1. Run `npx brain-dev complete $ARGUMENTS` FIRST — before reading code, before analyzing, before suggesting fixes
|
|
29
|
+
2. READ the full output — it contains step-by-step instructions specific to this project's stack
|
|
30
|
+
3. FOLLOW the nextAction field — copy the exact command, do not modify it
|
|
31
|
+
4. If output shows an ERROR: follow the recovery path in the output, do NOT debug manually
|
|
32
|
+
5. If output shows a CHECKPOINT: use AskUserQuestion, do NOT pick options yourself
|
|
33
|
+
|
|
34
|
+
CONSEQUENCE OF SKIPPING: Pipeline tracks state, creates audit trails, spawns specialized agents,
|
|
35
|
+
and injects framework-specific expertise. Skipping it means: no state tracking, no audit trail,
|
|
36
|
+
no specialized agents, no framework guidance, potential data loss in .brain/ state.
|
|
30
37
|
</critical-rules>
|
|
31
38
|
|
|
32
39
|
<process>
|
package/commands/brain/config.md
CHANGED
|
@@ -26,9 +26,16 @@ When no subcommand is given, launches an interactive menu.
|
|
|
26
26
|
</context>
|
|
27
27
|
|
|
28
28
|
<critical-rules>
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
PIPELINE ENFORCEMENT (NON-NEGOTIABLE):
|
|
30
|
+
1. Run `npx brain-dev config $ARGUMENTS` FIRST — before reading code, before analyzing, before suggesting fixes
|
|
31
|
+
2. READ the full output — it contains step-by-step instructions specific to this project's stack
|
|
32
|
+
3. FOLLOW the nextAction field — copy the exact command, do not modify it
|
|
33
|
+
4. If output shows an ERROR: follow the recovery path in the output, do NOT debug manually
|
|
34
|
+
5. If output shows a CHECKPOINT: use AskUserQuestion, do NOT pick options yourself
|
|
35
|
+
|
|
36
|
+
CONSEQUENCE OF SKIPPING: Pipeline tracks state, creates audit trails, spawns specialized agents,
|
|
37
|
+
and injects framework-specific expertise. Skipping it means: no state tracking, no audit trail,
|
|
38
|
+
no specialized agents, no framework guidance, potential data loss in .brain/ state.
|
|
32
39
|
</critical-rules>
|
|
33
40
|
|
|
34
41
|
<process>
|
|
@@ -22,10 +22,16 @@ Creates a CONTEXT.md file that feeds into the planning process.
|
|
|
22
22
|
</context>
|
|
23
23
|
|
|
24
24
|
<critical-rules>
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
PIPELINE ENFORCEMENT (NON-NEGOTIABLE):
|
|
26
|
+
1. Run `npx brain-dev discuss $ARGUMENTS` FIRST — before reading code, before analyzing, before suggesting fixes
|
|
27
|
+
2. READ the full output — it contains step-by-step instructions specific to this project's stack
|
|
28
|
+
3. FOLLOW the nextAction field — copy the exact command, do not modify it
|
|
29
|
+
4. If output shows an ERROR: follow the recovery path in the output, do NOT debug manually
|
|
30
|
+
5. If output shows a CHECKPOINT: use AskUserQuestion, do NOT pick options yourself
|
|
31
|
+
|
|
32
|
+
CONSEQUENCE OF SKIPPING: Pipeline tracks state, creates audit trails, spawns specialized agents,
|
|
33
|
+
and injects framework-specific expertise. Skipping it means: no state tracking, no audit trail,
|
|
34
|
+
no specialized agents, no framework guidance, potential data loss in .brain/ state.
|
|
29
35
|
</critical-rules>
|
|
30
36
|
|
|
31
37
|
<process>
|
|
@@ -23,10 +23,16 @@ Discovers plans, analyzes dependencies, groups into waves, spawns subagents, and
|
|
|
23
23
|
</context>
|
|
24
24
|
|
|
25
25
|
<critical-rules>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
PIPELINE ENFORCEMENT (NON-NEGOTIABLE):
|
|
27
|
+
1. Run `npx brain-dev execute $ARGUMENTS` FIRST — before reading code, before analyzing, before suggesting fixes
|
|
28
|
+
2. READ the full output — it contains step-by-step instructions specific to this project's stack
|
|
29
|
+
3. FOLLOW the nextAction field — copy the exact command, do not modify it
|
|
30
|
+
4. If output shows an ERROR: follow the recovery path in the output, do NOT debug manually
|
|
31
|
+
5. If output shows a CHECKPOINT: use AskUserQuestion, do NOT pick options yourself
|
|
32
|
+
|
|
33
|
+
CONSEQUENCE OF SKIPPING: Pipeline tracks state, creates audit trails, spawns specialized agents,
|
|
34
|
+
and injects framework-specific expertise. Skipping it means: no state tracking, no audit trail,
|
|
35
|
+
no specialized agents, no framework guidance, potential data loss in .brain/ state.
|
|
30
36
|
</critical-rules>
|
|
31
37
|
|
|
32
38
|
<process>
|
package/commands/brain/health.md
CHANGED
|
@@ -22,9 +22,16 @@ Optionally auto-repairs safe issues with --fix.
|
|
|
22
22
|
</context>
|
|
23
23
|
|
|
24
24
|
<critical-rules>
|
|
25
|
-
|
|
26
|
-
-
|
|
27
|
-
|
|
25
|
+
PIPELINE ENFORCEMENT (NON-NEGOTIABLE):
|
|
26
|
+
1. Run `npx brain-dev health $ARGUMENTS` FIRST — before reading code, before analyzing, before suggesting fixes
|
|
27
|
+
2. READ the full output — it contains step-by-step instructions specific to this project's stack
|
|
28
|
+
3. FOLLOW the nextAction field — copy the exact command, do not modify it
|
|
29
|
+
4. If output shows an ERROR: follow the recovery path in the output, do NOT debug manually
|
|
30
|
+
5. If output shows a CHECKPOINT: use AskUserQuestion, do NOT pick options yourself
|
|
31
|
+
|
|
32
|
+
CONSEQUENCE OF SKIPPING: Pipeline tracks state, creates audit trails, spawns specialized agents,
|
|
33
|
+
and injects framework-specific expertise. Skipping it means: no state tracking, no audit trail,
|
|
34
|
+
no specialized agents, no framework guidance, potential data loss in .brain/ state.
|
|
28
35
|
</critical-rules>
|
|
29
36
|
|
|
30
37
|
<process>
|
|
@@ -12,9 +12,16 @@ Set up Brain for an existing or new project. Detects your stack, maps the codeba
|
|
|
12
12
|
</objective>
|
|
13
13
|
|
|
14
14
|
<critical-rules>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
PIPELINE ENFORCEMENT (NON-NEGOTIABLE):
|
|
16
|
+
1. Run `npx brain-dev new-project` FIRST — before reading code, before analyzing, before suggesting fixes
|
|
17
|
+
2. READ the full output — it contains step-by-step instructions specific to this project's stack
|
|
18
|
+
3. FOLLOW the nextAction field — copy the exact command, do not modify it
|
|
19
|
+
4. If output shows an ERROR: follow the recovery path in the output, do NOT debug manually
|
|
20
|
+
5. If output shows a CHECKPOINT: use AskUserQuestion, do NOT pick options yourself
|
|
21
|
+
|
|
22
|
+
CONSEQUENCE OF SKIPPING: Pipeline tracks state, creates audit trails, spawns specialized agents,
|
|
23
|
+
and injects framework-specific expertise. Skipping it means: no state tracking, no audit trail,
|
|
24
|
+
no specialized agents, no framework guidance, potential data loss in .brain/ state.
|
|
18
25
|
</critical-rules>
|
|
19
26
|
|
|
20
27
|
<process>
|
|
@@ -22,20 +22,19 @@ Examples: "add payment integration", "refactor auth to JWT", "fix ATS rescoring
|
|
|
22
22
|
</context>
|
|
23
23
|
|
|
24
24
|
<critical-rules>
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
PIPELINE ENFORCEMENT (NON-NEGOTIABLE):
|
|
26
|
+
1. Run `npx brain-dev new-task "description"` FIRST — before reading code, before analyzing, before suggesting fixes
|
|
27
|
+
2. READ the full output — it contains step-by-step instructions specific to this project's stack
|
|
28
|
+
3. FOLLOW the nextAction field — copy the exact command, do not modify it
|
|
29
|
+
4. If output shows an ERROR: follow the recovery path in the output, do NOT debug manually
|
|
30
|
+
5. If output shows a CHECKPOINT: use AskUserQuestion, do NOT pick options yourself
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
3. The plan step defines the fix + tests
|
|
35
|
-
4. The execute step implements with TDD
|
|
36
|
-
5. The verify step confirms the fix works
|
|
32
|
+
CONSEQUENCE OF SKIPPING: Pipeline tracks state, creates audit trails, spawns specialized agents,
|
|
33
|
+
and injects framework-specific expertise. Skipping it means: no state tracking, no audit trail,
|
|
34
|
+
no specialized agents, no framework guidance, potential data loss in .brain/ state.
|
|
37
35
|
|
|
38
|
-
|
|
36
|
+
BUG WORKFLOW: User describes bug → `npx brain-dev new-task "fix: description"` → discuss (root cause) → plan (fix + tests) → execute (TDD) → verify → complete.
|
|
37
|
+
If too small for full pipeline, suggest `/brain:quick` instead. NEVER skip pipeline silently.
|
|
39
38
|
</critical-rules>
|
|
40
39
|
|
|
41
40
|
<process>
|
package/commands/brain/pause.md
CHANGED
|
@@ -15,8 +15,16 @@ No arguments required. Captures current session state automatically.
|
|
|
15
15
|
</context>
|
|
16
16
|
|
|
17
17
|
<critical-rules>
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
PIPELINE ENFORCEMENT (NON-NEGOTIABLE):
|
|
19
|
+
1. Run `npx brain-dev pause` FIRST — before reading code, before analyzing, before suggesting fixes
|
|
20
|
+
2. READ the full output — it contains step-by-step instructions specific to this project's stack
|
|
21
|
+
3. FOLLOW the nextAction field — copy the exact command, do not modify it
|
|
22
|
+
4. If output shows an ERROR: follow the recovery path in the output, do NOT debug manually
|
|
23
|
+
5. If output shows a CHECKPOINT: use AskUserQuestion, do NOT pick options yourself
|
|
24
|
+
|
|
25
|
+
CONSEQUENCE OF SKIPPING: Pipeline tracks state, creates audit trails, spawns specialized agents,
|
|
26
|
+
and injects framework-specific expertise. Skipping it means: no state tracking, no audit trail,
|
|
27
|
+
no specialized agents, no framework guidance, potential data loss in .brain/ state.
|
|
20
28
|
</critical-rules>
|
|
21
29
|
|
|
22
30
|
<process>
|
package/commands/brain/plan.md
CHANGED
|
@@ -25,10 +25,16 @@ Default flow: Research (if needed) -> Plan -> Verify -> Done.
|
|
|
25
25
|
</context>
|
|
26
26
|
|
|
27
27
|
<critical-rules>
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
PIPELINE ENFORCEMENT (NON-NEGOTIABLE):
|
|
29
|
+
1. Run `npx brain-dev plan $ARGUMENTS` FIRST — before reading code, before analyzing, before suggesting fixes
|
|
30
|
+
2. READ the full output — it contains step-by-step instructions specific to this project's stack
|
|
31
|
+
3. FOLLOW the nextAction field — copy the exact command, do not modify it
|
|
32
|
+
4. If output shows an ERROR: follow the recovery path in the output, do NOT debug manually
|
|
33
|
+
5. If output shows a CHECKPOINT: use AskUserQuestion, do NOT pick options yourself
|
|
34
|
+
|
|
35
|
+
CONSEQUENCE OF SKIPPING: Pipeline tracks state, creates audit trails, spawns specialized agents,
|
|
36
|
+
and injects framework-specific expertise. Skipping it means: no state tracking, no audit trail,
|
|
37
|
+
no specialized agents, no framework guidance, potential data loss in .brain/ state.
|
|
32
38
|
</critical-rules>
|
|
33
39
|
|
|
34
40
|
<process>
|
package/commands/brain/quick.md
CHANGED
|
@@ -28,11 +28,16 @@ Use subagent_type "brain-verifier" for verification (--full mode only).
|
|
|
28
28
|
</agents>
|
|
29
29
|
|
|
30
30
|
<critical-rules>
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
PIPELINE ENFORCEMENT (NON-NEGOTIABLE):
|
|
32
|
+
1. Run `npx brain-dev quick "description"` FIRST — before reading code, before analyzing, before suggesting fixes
|
|
33
|
+
2. READ the full output — it contains step-by-step instructions specific to this project's stack
|
|
34
|
+
3. FOLLOW the nextAction field — copy the exact command, do not modify it
|
|
35
|
+
4. If output shows an ERROR: follow the recovery path in the output, do NOT debug manually
|
|
36
|
+
5. If output shows a CHECKPOINT: use AskUserQuestion, do NOT pick options yourself
|
|
37
|
+
|
|
38
|
+
CONSEQUENCE OF SKIPPING: Pipeline tracks state, creates audit trails, spawns specialized agents,
|
|
39
|
+
and injects framework-specific expertise. Skipping it means: no state tracking, no audit trail,
|
|
40
|
+
no specialized agents, no framework guidance, potential data loss in .brain/ state.
|
|
36
41
|
</critical-rules>
|
|
37
42
|
|
|
38
43
|
<process>
|
|
@@ -13,9 +13,16 @@ Default mode shows what happened. Use --fix to auto-resume or --rollback to reve
|
|
|
13
13
|
</objective>
|
|
14
14
|
|
|
15
15
|
<critical-rules>
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
PIPELINE ENFORCEMENT (NON-NEGOTIABLE):
|
|
17
|
+
1. Run `npx brain-dev recover` FIRST — before reading code, before analyzing, before suggesting fixes
|
|
18
|
+
2. READ the full output — it contains step-by-step instructions specific to this project's stack
|
|
19
|
+
3. FOLLOW the nextAction field — copy the exact command, do not modify it
|
|
20
|
+
4. If output shows an ERROR: follow the recovery path in the output, do NOT debug manually
|
|
21
|
+
5. If output shows a CHECKPOINT: use AskUserQuestion, do NOT pick options yourself
|
|
22
|
+
|
|
23
|
+
CONSEQUENCE OF SKIPPING: Pipeline tracks state, creates audit trails, spawns specialized agents,
|
|
24
|
+
and injects framework-specific expertise. Skipping it means: no state tracking, no audit trail,
|
|
25
|
+
no specialized agents, no framework guidance, potential data loss in .brain/ state.
|
|
19
26
|
</critical-rules>
|
|
20
27
|
|
|
21
28
|
<process>
|
package/commands/brain/story.md
CHANGED
|
@@ -25,10 +25,16 @@ Stories are Brain's primary way to organize significant work. A story creates:
|
|
|
25
25
|
</context>
|
|
26
26
|
|
|
27
27
|
<critical-rules>
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
PIPELINE ENFORCEMENT (NON-NEGOTIABLE):
|
|
29
|
+
1. Run `npx brain-dev story "title"` FIRST — before reading code, before analyzing, before suggesting fixes
|
|
30
|
+
2. READ the full output — it contains step-by-step instructions specific to this project's stack
|
|
31
|
+
3. FOLLOW the nextAction field — copy the exact command, do not modify it
|
|
32
|
+
4. If output shows an ERROR: follow the recovery path in the output, do NOT debug manually
|
|
33
|
+
5. If output shows a CHECKPOINT: use AskUserQuestion, do NOT pick options yourself
|
|
34
|
+
|
|
35
|
+
CONSEQUENCE OF SKIPPING: Pipeline tracks state, creates audit trails, spawns specialized agents,
|
|
36
|
+
and injects framework-specific expertise. Skipping it means: no state tracking, no audit trail,
|
|
37
|
+
no specialized agents, no framework guidance, potential data loss in .brain/ state.
|
|
32
38
|
</critical-rules>
|
|
33
39
|
|
|
34
40
|
<process>
|
package/commands/brain/verify.md
CHANGED
|
@@ -23,10 +23,16 @@ Produces a VERIFICATION.md report with pass/gaps/human_needed status.
|
|
|
23
23
|
</context>
|
|
24
24
|
|
|
25
25
|
<critical-rules>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
PIPELINE ENFORCEMENT (NON-NEGOTIABLE):
|
|
27
|
+
1. Run `npx brain-dev verify $ARGUMENTS` FIRST — before reading code, before analyzing, before suggesting fixes
|
|
28
|
+
2. READ the full output — it contains step-by-step instructions specific to this project's stack
|
|
29
|
+
3. FOLLOW the nextAction field — copy the exact command, do not modify it
|
|
30
|
+
4. If output shows an ERROR: follow the recovery path in the output, do NOT debug manually
|
|
31
|
+
5. If output shows a CHECKPOINT: use AskUserQuestion, do NOT pick options yourself
|
|
32
|
+
|
|
33
|
+
CONSEQUENCE OF SKIPPING: Pipeline tracks state, creates audit trails, spawns specialized agents,
|
|
34
|
+
and injects framework-specific expertise. Skipping it means: no state tracking, no audit trail,
|
|
35
|
+
no specialized agents, no framework guidance, potential data loss in .brain/ state.
|
|
30
36
|
</critical-rules>
|
|
31
37
|
|
|
32
38
|
<process>
|
package/hooks/bootstrap.sh
CHANGED
|
@@ -66,14 +66,29 @@ try {
|
|
|
66
66
|
'',
|
|
67
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)',
|
|
68
68
|
'',
|
|
69
|
-
'
|
|
70
|
-
'
|
|
71
|
-
'
|
|
72
|
-
'
|
|
73
|
-
'
|
|
74
|
-
'
|
|
75
|
-
'
|
|
76
|
-
'
|
|
69
|
+
'PIPELINE RULES (NON-NEGOTIABLE):',
|
|
70
|
+
'',
|
|
71
|
+
'1. ENTRY: When user describes ANY work (bug, feature, task), run the brain command FIRST.',
|
|
72
|
+
' Do NOT read code, run git, or analyze before running: npx brain-dev <command>',
|
|
73
|
+
' If you catch yourself analyzing: STOP, run the CLI, restart with CLI context.',
|
|
74
|
+
'',
|
|
75
|
+
'2. FOLLOW: When brain command outputs, find the nextAction field.',
|
|
76
|
+
' Copy the exact command verbatim. Do NOT interpret, modify, or skip it.',
|
|
77
|
+
' Human text is EXPLANATION. The nextAction field is the INSTRUCTION.',
|
|
78
|
+
'',
|
|
79
|
+
'3. NEVER ESCAPE: If you see EXECUTION FAILED, PLANNING BLOCKED, or gaps_found:',
|
|
80
|
+
' Follow the recovery instructions in that output ONLY.',
|
|
81
|
+
' Do NOT start debugging manually. Do NOT exit the pipeline.',
|
|
82
|
+
'',
|
|
83
|
+
'4. CHECKPOINTS: If you see CHECKPOINT REACHED:',
|
|
84
|
+
' Use AskUserQuestion to ask the user. Do NOT pick an option yourself.',
|
|
85
|
+
'',
|
|
86
|
+
'5. AGENTS: When output says to spawn an agent (brain-planner, brain-executor):',
|
|
87
|
+
' Use the Agent tool with the specified subagent_type. Do NOT execute the prompt yourself.',
|
|
88
|
+
'',
|
|
89
|
+
'6. STATE: Run /brain:progress before suggesting next steps.',
|
|
90
|
+
' For /brain:update, always use: npx brain-dev@latest update',
|
|
91
|
+
' NEVER run brain-dev init after an update.',
|
|
77
92
|
'--- End Brain Context ---'
|
|
78
93
|
];
|
|
79
94
|
console.log(lines.join('\n'));
|