@bantay/cli 0.2.0 → 0.3.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/package.json +3 -3
- package/src/aide/discovery.ts +88 -0
- package/src/aide/index.ts +9 -0
- package/src/cli.ts +44 -2
- package/src/commands/aide.ts +432 -48
- package/src/commands/check.ts +9 -4
- package/src/commands/diff.ts +387 -0
- package/src/commands/init.ts +38 -1
- package/src/commands/status.ts +9 -7
- package/src/commands/tasks.ts +220 -0
- package/src/export/claude.ts +8 -5
- package/src/export/codex.ts +5 -3
- package/src/export/cursor.ts +5 -3
- package/src/export/invariants.ts +7 -5
- package/src/generators/claude-commands.ts +61 -0
- package/src/templates/commands/bantay-check.md +58 -0
- package/src/templates/commands/bantay-interview.md +207 -0
- package/src/templates/commands/bantay-orchestrate.md +164 -0
- package/src/templates/commands/bantay-status.md +39 -0
package/src/export/claude.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { readFile, writeFile, access } from "fs/promises";
|
|
6
6
|
import { join } from "path";
|
|
7
|
-
import { read as readAide } from "../aide";
|
|
7
|
+
import { read as readAide, resolveAidePath } from "../aide";
|
|
8
8
|
import {
|
|
9
9
|
extractConstraints,
|
|
10
10
|
extractFoundations,
|
|
@@ -27,7 +27,8 @@ import {
|
|
|
27
27
|
export function generateClaudeSection(
|
|
28
28
|
constraints: ExtractedConstraint[],
|
|
29
29
|
foundations: ExtractedFoundation[],
|
|
30
|
-
invariants: ExtractedInvariant[]
|
|
30
|
+
invariants: ExtractedInvariant[],
|
|
31
|
+
aideFilename: string = "*.aide"
|
|
31
32
|
): string {
|
|
32
33
|
const lines: string[] = [];
|
|
33
34
|
|
|
@@ -35,7 +36,7 @@ export function generateClaudeSection(
|
|
|
35
36
|
lines.push("");
|
|
36
37
|
lines.push("## Bantay Project Rules");
|
|
37
38
|
lines.push("");
|
|
38
|
-
lines.push(
|
|
39
|
+
lines.push(`*Auto-generated from ${aideFilename}. Do not edit manually.*`);
|
|
39
40
|
lines.push("");
|
|
40
41
|
|
|
41
42
|
// Foundations as principles
|
|
@@ -184,7 +185,9 @@ export async function exportClaude(
|
|
|
184
185
|
projectPath: string,
|
|
185
186
|
options: ExportOptions = {}
|
|
186
187
|
): Promise<ExportResult> {
|
|
187
|
-
|
|
188
|
+
// Discover aide file if not explicitly provided
|
|
189
|
+
const resolved = await resolveAidePath(projectPath, options.aidePath);
|
|
190
|
+
const aidePath = resolved.path;
|
|
188
191
|
const outputPath = options.outputPath || join(projectPath, "CLAUDE.md");
|
|
189
192
|
|
|
190
193
|
// Read the aide tree
|
|
@@ -196,7 +199,7 @@ export async function exportClaude(
|
|
|
196
199
|
const invariants = extractInvariants(tree);
|
|
197
200
|
|
|
198
201
|
// Generate section content
|
|
199
|
-
const section = generateClaudeSection(constraints, foundations, invariants);
|
|
202
|
+
const section = generateClaudeSection(constraints, foundations, invariants, resolved.filename);
|
|
200
203
|
|
|
201
204
|
// Read existing file if it exists
|
|
202
205
|
let existingContent = "";
|
package/src/export/codex.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import { readFile, writeFile, access } from "fs/promises";
|
|
7
7
|
import { join } from "path";
|
|
8
|
-
import { read as readAide } from "../aide";
|
|
8
|
+
import { read as readAide, resolveAidePath } from "../aide";
|
|
9
9
|
import {
|
|
10
10
|
extractConstraints,
|
|
11
11
|
extractFoundations,
|
|
@@ -33,7 +33,9 @@ export async function exportCodex(
|
|
|
33
33
|
projectPath: string,
|
|
34
34
|
options: ExportOptions = {}
|
|
35
35
|
): Promise<ExportResult> {
|
|
36
|
-
|
|
36
|
+
// Discover aide file if not explicitly provided
|
|
37
|
+
const resolved = await resolveAidePath(projectPath, options.aidePath);
|
|
38
|
+
const aidePath = resolved.path;
|
|
37
39
|
const outputPath = options.outputPath || join(projectPath, "AGENTS.md");
|
|
38
40
|
|
|
39
41
|
// Read the aide tree
|
|
@@ -45,7 +47,7 @@ export async function exportCodex(
|
|
|
45
47
|
const invariants = extractInvariants(tree);
|
|
46
48
|
|
|
47
49
|
// Generate section content (same format as claude)
|
|
48
|
-
const section = generateClaudeSection(constraints, foundations, invariants);
|
|
50
|
+
const section = generateClaudeSection(constraints, foundations, invariants, resolved.filename);
|
|
49
51
|
|
|
50
52
|
// Read existing file if it exists
|
|
51
53
|
let existingContent = "";
|
package/src/export/cursor.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { readFile, writeFile, access } from "fs/promises";
|
|
6
6
|
import { join } from "path";
|
|
7
|
-
import { read as readAide } from "../aide";
|
|
7
|
+
import { read as readAide, resolveAidePath } from "../aide";
|
|
8
8
|
import {
|
|
9
9
|
extractConstraints,
|
|
10
10
|
extractFoundations,
|
|
@@ -32,7 +32,9 @@ export async function exportCursor(
|
|
|
32
32
|
projectPath: string,
|
|
33
33
|
options: ExportOptions = {}
|
|
34
34
|
): Promise<ExportResult> {
|
|
35
|
-
|
|
35
|
+
// Discover aide file if not explicitly provided
|
|
36
|
+
const resolved = await resolveAidePath(projectPath, options.aidePath);
|
|
37
|
+
const aidePath = resolved.path;
|
|
36
38
|
const outputPath = options.outputPath || join(projectPath, ".cursorrules");
|
|
37
39
|
|
|
38
40
|
// Read the aide tree
|
|
@@ -44,7 +46,7 @@ export async function exportCursor(
|
|
|
44
46
|
const invariants = extractInvariants(tree);
|
|
45
47
|
|
|
46
48
|
// Generate section content (same format as claude)
|
|
47
|
-
const section = generateClaudeSection(constraints, foundations, invariants);
|
|
49
|
+
const section = generateClaudeSection(constraints, foundations, invariants, resolved.filename);
|
|
48
50
|
|
|
49
51
|
// Read existing file if it exists
|
|
50
52
|
let existingContent = "";
|
package/src/export/invariants.ts
CHANGED
|
@@ -4,19 +4,19 @@
|
|
|
4
4
|
|
|
5
5
|
import { readFile, writeFile } from "fs/promises";
|
|
6
6
|
import { join } from "path";
|
|
7
|
-
import { read as readAide } from "../aide";
|
|
7
|
+
import { read as readAide, resolveAidePath } from "../aide";
|
|
8
8
|
import { extractInvariants, groupBy } from "./aide-reader";
|
|
9
9
|
import type { ExportOptions, ExportResult, ExtractedInvariant } from "./types";
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Generate invariants.md content from the aide tree
|
|
13
13
|
*/
|
|
14
|
-
export function generateInvariantsMd(invariants: ExtractedInvariant[]): string {
|
|
14
|
+
export function generateInvariantsMd(invariants: ExtractedInvariant[], aideFilename: string = "*.aide"): string {
|
|
15
15
|
const lines: string[] = [];
|
|
16
16
|
|
|
17
17
|
lines.push("# Invariants");
|
|
18
18
|
lines.push("");
|
|
19
|
-
lines.push(
|
|
19
|
+
lines.push(`Rules this project must never break. Generated from ${aideFilename}.`);
|
|
20
20
|
lines.push("");
|
|
21
21
|
|
|
22
22
|
// Group by category
|
|
@@ -66,7 +66,9 @@ export async function exportInvariants(
|
|
|
66
66
|
projectPath: string,
|
|
67
67
|
options: ExportOptions = {}
|
|
68
68
|
): Promise<ExportResult> {
|
|
69
|
-
|
|
69
|
+
// Discover aide file if not explicitly provided
|
|
70
|
+
const resolved = await resolveAidePath(projectPath, options.aidePath);
|
|
71
|
+
const aidePath = resolved.path;
|
|
70
72
|
const outputPath = options.outputPath || join(projectPath, "invariants.md");
|
|
71
73
|
|
|
72
74
|
// Read the aide tree
|
|
@@ -76,7 +78,7 @@ export async function exportInvariants(
|
|
|
76
78
|
const invariants = extractInvariants(tree);
|
|
77
79
|
|
|
78
80
|
// Generate content
|
|
79
|
-
const content = generateInvariantsMd(invariants);
|
|
81
|
+
const content = generateInvariantsMd(invariants, resolved.filename);
|
|
80
82
|
|
|
81
83
|
// Write unless dry run
|
|
82
84
|
if (!options.dryRun) {
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generators for Claude Code slash command files
|
|
3
|
+
*
|
|
4
|
+
* These files are placed in .claude/commands/ and appear as
|
|
5
|
+
* slash commands in Claude Code (e.g., /bantay-interview)
|
|
6
|
+
*
|
|
7
|
+
* Prompts are stored as markdown files in src/templates/commands/
|
|
8
|
+
* for readability and easy editing.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { readFileSync } from "fs";
|
|
12
|
+
import { join } from "path";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Generate the bantay-interview.md command
|
|
16
|
+
*
|
|
17
|
+
* This command guides Claude through an interactive session to
|
|
18
|
+
* build out the project's aide structure through conversation.
|
|
19
|
+
*/
|
|
20
|
+
export function generateInterviewCommand(): string {
|
|
21
|
+
return readFileSync(
|
|
22
|
+
join(__dirname, "../templates/commands/bantay-interview.md"),
|
|
23
|
+
"utf-8"
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Generate the bantay-status.md command
|
|
29
|
+
*
|
|
30
|
+
* This command runs bantay status and discusses the results.
|
|
31
|
+
*/
|
|
32
|
+
export function generateStatusCommand(): string {
|
|
33
|
+
return readFileSync(
|
|
34
|
+
join(__dirname, "../templates/commands/bantay-status.md"),
|
|
35
|
+
"utf-8"
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Generate the bantay-check.md command
|
|
41
|
+
*
|
|
42
|
+
* This command runs bantay check and helps fix any failures.
|
|
43
|
+
*/
|
|
44
|
+
export function generateCheckCommand(): string {
|
|
45
|
+
return readFileSync(
|
|
46
|
+
join(__dirname, "../templates/commands/bantay-check.md"),
|
|
47
|
+
"utf-8"
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Generate the bantay-orchestrate.md command
|
|
53
|
+
*
|
|
54
|
+
* This command orchestrates multi-agent builds from the aide task list.
|
|
55
|
+
*/
|
|
56
|
+
export function generateOrchestrateCommand(): string {
|
|
57
|
+
return readFileSync(
|
|
58
|
+
join(__dirname, "../templates/commands/bantay-orchestrate.md"),
|
|
59
|
+
"utf-8"
|
|
60
|
+
);
|
|
61
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Bantay Check
|
|
2
|
+
|
|
3
|
+
Run `bantay check` to verify all invariants, explain any failures, and propose fixes.
|
|
4
|
+
|
|
5
|
+
## What to Do
|
|
6
|
+
|
|
7
|
+
1. Run the check command:
|
|
8
|
+
```bash
|
|
9
|
+
bantay check
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
2. If all checks pass:
|
|
13
|
+
- Confirm that all invariants are satisfied
|
|
14
|
+
- Note the total number of checks run
|
|
15
|
+
|
|
16
|
+
3. If any checks fail:
|
|
17
|
+
- Explain each failure clearly
|
|
18
|
+
- Show the file and line number where the violation occurred
|
|
19
|
+
- Explain WHY this violates the invariant
|
|
20
|
+
- Propose a specific fix
|
|
21
|
+
|
|
22
|
+
## Explaining Failures
|
|
23
|
+
|
|
24
|
+
For each failed invariant, provide:
|
|
25
|
+
|
|
26
|
+
1. **The Rule**: What the invariant requires
|
|
27
|
+
2. **The Violation**: What code breaks the rule
|
|
28
|
+
3. **The Risk**: Why this matters (security, data integrity, etc.)
|
|
29
|
+
4. **The Fix**: Specific code changes to resolve it
|
|
30
|
+
|
|
31
|
+
## Example Response
|
|
32
|
+
|
|
33
|
+
"Bantay check found 1 failure:
|
|
34
|
+
|
|
35
|
+
**inv_auth_required** - FAILED
|
|
36
|
+
- File: src/routes/admin.ts:45
|
|
37
|
+
- Violation: Route `/admin/users` has no authentication middleware
|
|
38
|
+
- Risk: Unauthenticated users could access admin functionality
|
|
39
|
+
- Fix: Add the auth middleware:
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
// Before
|
|
43
|
+
router.get('/admin/users', getUsers);
|
|
44
|
+
|
|
45
|
+
// After
|
|
46
|
+
router.get('/admin/users', requireAuth, requireAdmin, getUsers);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Would you like me to apply this fix?"
|
|
50
|
+
|
|
51
|
+
## Diff Mode
|
|
52
|
+
|
|
53
|
+
For faster checks during development, suggest:
|
|
54
|
+
```bash
|
|
55
|
+
bantay check --diff HEAD
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
This only checks invariants affected by recent changes.
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# Bantay Aide Interview
|
|
2
|
+
|
|
3
|
+
You are helping the user define their project's invariants, critical user journeys (CUJs), and scenarios using Bantay's aide system.
|
|
4
|
+
|
|
5
|
+
## Your Role
|
|
6
|
+
|
|
7
|
+
Guide the user through a structured conversation to understand their project and propose appropriate entities. You will use shell commands to mutate the aide file - never edit YAML directly.
|
|
8
|
+
|
|
9
|
+
## Before Starting
|
|
10
|
+
|
|
11
|
+
First, check if an .aide file exists:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
ls *.aide
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
If no .aide file exists, ask the user for their product name and run:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
bantay aide init --name <product_name>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
If an .aide file already exists, run `bantay aide show` to understand what's already defined, then continue from where it left off.
|
|
24
|
+
|
|
25
|
+
## Interview Flow
|
|
26
|
+
|
|
27
|
+
### 1. Understand the Product
|
|
28
|
+
|
|
29
|
+
Start by asking:
|
|
30
|
+
- "What does your product do in one sentence?"
|
|
31
|
+
- "Who are the primary users?"
|
|
32
|
+
- "What are the most critical actions users take?"
|
|
33
|
+
|
|
34
|
+
### 2. Identify Critical User Journeys (CUJs)
|
|
35
|
+
|
|
36
|
+
Based on their answers, propose CUJs:
|
|
37
|
+
- "Based on what you've described, I think these are your critical user journeys..."
|
|
38
|
+
- List 3-5 proposed CUJs with feature descriptions
|
|
39
|
+
- Ask: "Does this capture the most important things users do? Should I add or modify any?"
|
|
40
|
+
|
|
41
|
+
For each confirmed CUJ, run:
|
|
42
|
+
```bash
|
|
43
|
+
bantay aide add cuj_<name> --parent cujs --prop "feature=<description>" --prop "tier=primary" --prop "area=<area>"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
After all CUJs are added, propose dependencies:
|
|
47
|
+
- "Which of these journeys require another journey to work first?"
|
|
48
|
+
- For example: "Does checkout depend on cart? Does cart depend on browse?"
|
|
49
|
+
|
|
50
|
+
For each dependency, run:
|
|
51
|
+
```bash
|
|
52
|
+
bantay aide link cuj_<dependent> cuj_<dependency> --type depends_on
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 3. Define Scenarios for Each CUJ
|
|
56
|
+
|
|
57
|
+
For each CUJ, propose scenarios:
|
|
58
|
+
- "For the <CUJ> journey, here are the key scenarios I'd propose..."
|
|
59
|
+
- List scenarios with given/when/then structure
|
|
60
|
+
- Ask: "Do these scenarios cover the important cases?"
|
|
61
|
+
|
|
62
|
+
For each confirmed scenario, run:
|
|
63
|
+
```bash
|
|
64
|
+
bantay aide add sc_<name> --parent cuj_<parent> --prop "name=<scenario name>" --prop "given=<given>" --prop "when=<when>" --prop "then=<then>"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 4. Extract Invariants with Threat Signals
|
|
68
|
+
|
|
69
|
+
Ask about rules that must never be broken:
|
|
70
|
+
- "What security rules must always hold? (e.g., all routes require auth)"
|
|
71
|
+
- "What data integrity rules exist? (e.g., balances never go negative)"
|
|
72
|
+
- "What performance requirements exist? (e.g., pages load in under 2s)"
|
|
73
|
+
|
|
74
|
+
For each confirmed invariant:
|
|
75
|
+
|
|
76
|
+
1. First, add the invariant:
|
|
77
|
+
```bash
|
|
78
|
+
bantay aide add inv_<name> --parent invariants --prop "statement=<the rule>" --prop "category=<security|integrity|performance|etc>"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
2. Immediately ask: "What does it look like when this is violated intentionally? What pattern would indicate someone is testing this boundary?"
|
|
82
|
+
|
|
83
|
+
3. Then update with the threat signal:
|
|
84
|
+
```bash
|
|
85
|
+
bantay aide update inv_<name> --prop "threat_signal=<signal>"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 5. Link Scenarios to Invariants
|
|
89
|
+
|
|
90
|
+
For scenarios that are protected by invariants:
|
|
91
|
+
- "Which scenarios would fail if this invariant were violated?"
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
bantay aide link sc_<scenario> inv_<invariant> --type protected_by
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 6. Define Design Foundations
|
|
98
|
+
|
|
99
|
+
Ask about the principles that shape everything:
|
|
100
|
+
- "What are the 4-6 design principles that shape everything in this product?"
|
|
101
|
+
- "These are the poster-worthy truths - the things you'd put on a wall to remind the team what matters."
|
|
102
|
+
- Examples: "Offline-first", "Zero trust", "Convention over configuration", "Fail fast", "Privacy by default"
|
|
103
|
+
|
|
104
|
+
For each confirmed foundation, run:
|
|
105
|
+
```bash
|
|
106
|
+
bantay aide add found_<name> --parent foundations --prop "text=<the principle>"
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 7. Define Architectural Constraints
|
|
110
|
+
|
|
111
|
+
Ask about tech decisions:
|
|
112
|
+
- "What's the tech stack? What architectural decisions have you made and why?"
|
|
113
|
+
- "What patterns must all code follow? What's off-limits?"
|
|
114
|
+
|
|
115
|
+
For each constraint, run:
|
|
116
|
+
```bash
|
|
117
|
+
bantay aide add con_<name> --parent constraints --prop "text=<the decision>" --prop "domain=<stack|security|architecture|etc>" --prop "rationale=<why this decision was made>"
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
After adding each constraint, ask:
|
|
121
|
+
- "Which invariant does this constraint help enforce?"
|
|
122
|
+
|
|
123
|
+
Then link it:
|
|
124
|
+
```bash
|
|
125
|
+
bantay aide link con_<name> inv_<invariant> --type implements
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### 8. Capture Project Wisdom
|
|
129
|
+
|
|
130
|
+
Ask about hard-won lessons:
|
|
131
|
+
- "What lessons have you learned the hard way on this project?"
|
|
132
|
+
- "What do new team members always get wrong at first?"
|
|
133
|
+
- "What decisions seem counterintuitive but are correct for good reasons?"
|
|
134
|
+
|
|
135
|
+
For each wisdom entry, run:
|
|
136
|
+
```bash
|
|
137
|
+
bantay aide add wis_<name> --parent wisdom --prop "text=<the lesson>"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### 9. Validate and Review
|
|
141
|
+
|
|
142
|
+
After completing all sections, validate and show the complete tree:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
bantay aide validate
|
|
146
|
+
bantay aide show
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Confirm with the user:
|
|
150
|
+
- "Here's your complete aide structure. Does this capture everything?"
|
|
151
|
+
- If anything is missing, go back and add it.
|
|
152
|
+
|
|
153
|
+
## Rules
|
|
154
|
+
|
|
155
|
+
1. **Never edit YAML directly** - Always use `bantay aide add`, `bantay aide update`, or `bantay aide link` commands
|
|
156
|
+
2. **Confirm before adding** - Always show the user what you're about to add and get their approval
|
|
157
|
+
3. **Validate after each section** - Run `bantay aide validate` after adding entities to catch errors early
|
|
158
|
+
4. **Use consistent naming** - IDs should be snake_case: `cuj_user_login`, `sc_login_success`, `inv_auth_required`
|
|
159
|
+
5. **Cover all entity types** - CUJs, scenarios, invariants (with threat signals), constraints (with rationale), foundations, wisdom
|
|
160
|
+
6. **Cover all relationship types** - protected_by (scenario→invariant), depends_on (cuj→cuj), implements (constraint→invariant)
|
|
161
|
+
|
|
162
|
+
## Validation
|
|
163
|
+
|
|
164
|
+
After each major section, run:
|
|
165
|
+
```bash
|
|
166
|
+
bantay aide validate
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
If errors are found, fix them before proceeding.
|
|
170
|
+
|
|
171
|
+
## Example Session
|
|
172
|
+
|
|
173
|
+
**User**: "We're building an e-commerce platform"
|
|
174
|
+
|
|
175
|
+
**You**: "Great! Let me understand a bit more. What are the 2-3 most critical things a customer does on your platform?"
|
|
176
|
+
|
|
177
|
+
**User**: "Browse products, add to cart, and checkout"
|
|
178
|
+
|
|
179
|
+
**You**: "Based on that, I'd propose these Critical User Journeys:
|
|
180
|
+
|
|
181
|
+
1. **cuj_browse** - Customer discovers and views products
|
|
182
|
+
2. **cuj_cart** - Customer manages their shopping cart
|
|
183
|
+
3. **cuj_checkout** - Customer completes a purchase
|
|
184
|
+
|
|
185
|
+
Does this capture your core journeys? Should I add or modify any?"
|
|
186
|
+
|
|
187
|
+
**User**: "Yes, let's add those"
|
|
188
|
+
|
|
189
|
+
**You**: "Adding the CUJs now..."
|
|
190
|
+
```bash
|
|
191
|
+
bantay aide add cuj_browse --parent cujs --prop "feature=Customer discovers and views products" --prop "tier=primary" --prop "area=shopping"
|
|
192
|
+
bantay aide add cuj_cart --parent cujs --prop "feature=Customer manages their shopping cart" --prop "tier=primary" --prop "area=shopping"
|
|
193
|
+
bantay aide add cuj_checkout --parent cujs --prop "feature=Customer completes a purchase" --prop "tier=primary" --prop "area=shopping"
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**You**: "Now, which of these journeys depend on another? I'd guess checkout depends on cart, and cart depends on browse. Is that right?"
|
|
197
|
+
|
|
198
|
+
**User**: "Yes"
|
|
199
|
+
|
|
200
|
+
**You**: "Linking the dependencies..."
|
|
201
|
+
```bash
|
|
202
|
+
bantay aide link cuj_checkout cuj_cart --type depends_on
|
|
203
|
+
bantay aide link cuj_cart cuj_browse --type depends_on
|
|
204
|
+
bantay aide validate
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Continue this pattern for scenarios, invariants, constraints, foundations, and wisdom.
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
You are the team lead for a Bantay-orchestrated build.
|
|
2
|
+
|
|
3
|
+
Read CLAUDE.md and the .aide file before doing anything.
|
|
4
|
+
|
|
5
|
+
## Check build state
|
|
6
|
+
|
|
7
|
+
1. Check if `.bantay/builds/current.md` exists.
|
|
8
|
+
- **Exists with in_progress:** Resume from where it left off. Read the file, run `bantay status`, check worktrees with `git log`. Respawn any teammates that were mid-work.
|
|
9
|
+
- **Does not exist:** This is a fresh build or nothing to build. Run `bantay tasks` (diff mode). If no tasks, run `bantay tasks --all`. If still no tasks, report "nothing to build" and stop.
|
|
10
|
+
|
|
11
|
+
## Constraints
|
|
12
|
+
|
|
13
|
+
- Maximum 2 teammates at any time
|
|
14
|
+
- You do Phase 0 (foundation) directly — no teammates
|
|
15
|
+
- Every CUJ gets a written plan before a teammate is spawned
|
|
16
|
+
- No teammate is spawned without a validated and committed `.bantay/plans/<cuj_id>.md`
|
|
17
|
+
- Teammates work in separate git worktrees
|
|
18
|
+
- Run `bantay check` after merging each branch
|
|
19
|
+
- Commit and `git push` after every checkpoint update
|
|
20
|
+
|
|
21
|
+
## Phase 0 — Foundation (you do this directly)
|
|
22
|
+
|
|
23
|
+
1. Read the full aide — all CUJs, scenarios, invariants, constraints
|
|
24
|
+
2. Build the shared foundation: data model, types, database schema, API interfaces
|
|
25
|
+
3. Commit to main: `feat: foundation — data model, types, interfaces`
|
|
26
|
+
4. Run `bantay check`
|
|
27
|
+
5. Write `.bantay/builds/current.md` with Phase 0 complete
|
|
28
|
+
6. Commit and `git push`
|
|
29
|
+
7. `/compact` — shed Phase 0 context before planning Phase 1
|
|
30
|
+
|
|
31
|
+
## For each subsequent phase
|
|
32
|
+
|
|
33
|
+
### Plan (before spawning)
|
|
34
|
+
|
|
35
|
+
For each CUJ in this phase (max 2):
|
|
36
|
+
|
|
37
|
+
1. Read the CUJ scenarios from the aide
|
|
38
|
+
2. Read the existing codebase to understand what's built
|
|
39
|
+
3. Decompose into ordered implementation steps:
|
|
40
|
+
- Database schema / migrations needed
|
|
41
|
+
- API routes / server actions
|
|
42
|
+
- Core business logic
|
|
43
|
+
- UI components
|
|
44
|
+
- Integration between layers
|
|
45
|
+
- Tests mapped to each scenario
|
|
46
|
+
4. Write the plan to `.bantay/plans/<cuj_id>.md`
|
|
47
|
+
|
|
48
|
+
### Validate plan (before committing)
|
|
49
|
+
|
|
50
|
+
Do not commit or spawn until every check passes.
|
|
51
|
+
|
|
52
|
+
1. **Aide coverage** — Run `bantay aide show <cuj_id>`. Compare every
|
|
53
|
+
scenario's given/when/then against the plan. If a scenario is missing
|
|
54
|
+
or its acceptance criteria don't match, the plan is incomplete.
|
|
55
|
+
|
|
56
|
+
2. **File references** — For every file, table, route, type, or function
|
|
57
|
+
the plan references, verify it exists: `ls`, `grep`, or `cat` the
|
|
58
|
+
actual path. If it doesn't exist and the plan doesn't say "create new",
|
|
59
|
+
the plan is hallucinated. Fix it.
|
|
60
|
+
|
|
61
|
+
3. **Interface contracts** — For every function signature, API endpoint,
|
|
62
|
+
or type definition the plan depends on, read the actual source file
|
|
63
|
+
and confirm the signature matches. Don't trust your memory of Phase 0.
|
|
64
|
+
`cat` the file.
|
|
65
|
+
|
|
66
|
+
4. **Dependency check** — Cross-reference the plan against `bantay tasks`.
|
|
67
|
+
If the plan assumes something built in a later phase or an unmerged
|
|
68
|
+
worktree, the plan has a forward dependency. Remove it or reorder.
|
|
69
|
+
|
|
70
|
+
5. **Invariant coverage** — For every invariant linked to this CUJ's
|
|
71
|
+
scenarios (via `protected_by`), confirm the plan includes a step that
|
|
72
|
+
enforces or tests it. Missing invariant coverage = missing step.
|
|
73
|
+
|
|
74
|
+
If any check fails, fix the plan and re-validate. Only after all 5 pass:
|
|
75
|
+
commit the plan.
|
|
76
|
+
|
|
77
|
+
### Spawn teammates (max 2)
|
|
78
|
+
|
|
79
|
+
For each CUJ, spawn a teammate with this prompt:
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
You are building [CUJ feature] in worktree feat/[cuj-name].
|
|
83
|
+
|
|
84
|
+
YOUR PLAN: Read .bantay/plans/[cuj_id].md — execute the steps in order.
|
|
85
|
+
|
|
86
|
+
FIRST: Run bantay status to see what's already done. If scenarios
|
|
87
|
+
are already covered, skip to the first uncovered one.
|
|
88
|
+
|
|
89
|
+
BUILD RULES:
|
|
90
|
+
- Use red/green TDD. Write the test, confirm it fails, implement.
|
|
91
|
+
- Commit after each passing scenario.
|
|
92
|
+
Message: feat([cuj_name]): implement sc_[scenario_name]
|
|
93
|
+
- Run bantay check after each commit.
|
|
94
|
+
- Do not modify files outside your scope.
|
|
95
|
+
|
|
96
|
+
CONTEXT MANAGEMENT:
|
|
97
|
+
- After each scenario, check your context usage.
|
|
98
|
+
- If over 50%, /compact before continuing.
|
|
99
|
+
- If over 80%, commit everything and message the lead:
|
|
100
|
+
"Context full, requesting restart. Progress committed."
|
|
101
|
+
|
|
102
|
+
If you hit a rate limit, wait and retry — don't abandon work.
|
|
103
|
+
If something fails, commit what you have and message the lead.
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Monitor
|
|
107
|
+
|
|
108
|
+
- Check teammate progress periodically
|
|
109
|
+
- If a teammate goes silent for 10+ minutes, check its worktree:
|
|
110
|
+
```
|
|
111
|
+
cd .worktrees/<teammate>
|
|
112
|
+
git log --oneline -5
|
|
113
|
+
bantay status
|
|
114
|
+
```
|
|
115
|
+
- If a teammate dies:
|
|
116
|
+
1. The plan survives in `.bantay/plans/<cuj_id>.md`
|
|
117
|
+
2. Committed work survives in the worktree
|
|
118
|
+
3. `bantay status` shows exactly what's done
|
|
119
|
+
4. Spawn a replacement with the same prompt — it reads the plan and status, picks up from the first incomplete step
|
|
120
|
+
|
|
121
|
+
### Merge gate
|
|
122
|
+
|
|
123
|
+
After both teammates complete:
|
|
124
|
+
|
|
125
|
+
1. Merge both worktrees to main
|
|
126
|
+
2. Run `bantay check` on main
|
|
127
|
+
3. Run `bantay status`
|
|
128
|
+
4. If checks fail, fix on main before proceeding
|
|
129
|
+
5. Update `.bantay/builds/current.md`:
|
|
130
|
+
```
|
|
131
|
+
phase: N
|
|
132
|
+
started: <timestamp>
|
|
133
|
+
completed_cujs:
|
|
134
|
+
- cuj_onboarding
|
|
135
|
+
- cuj_manage_artifact
|
|
136
|
+
in_progress: []
|
|
137
|
+
status: X/Y scenarios covered
|
|
138
|
+
```
|
|
139
|
+
6. Commit and `git push`
|
|
140
|
+
7. `/compact` — shed this phase's context before the next one
|
|
141
|
+
|
|
142
|
+
If remaining CUJs in this phase, plan and spawn the next 2.
|
|
143
|
+
When phase complete, move to next phase.
|
|
144
|
+
|
|
145
|
+
## If you (the lead) need to restart
|
|
146
|
+
|
|
147
|
+
1. Read `.bantay/builds/current.md` — where we are
|
|
148
|
+
2. Read `.bantay/plans/` — what was intended for each CUJ
|
|
149
|
+
3. Run `bantay status` — what's actually built
|
|
150
|
+
4. Check each active worktree with `git log`
|
|
151
|
+
5. Resume orchestration from current state
|
|
152
|
+
6. Respawn any teammates that were mid-work
|
|
153
|
+
|
|
154
|
+
Nothing you know should exist only in your context window.
|
|
155
|
+
If you die, a new lead reading these files is indistinguishable from you.
|
|
156
|
+
|
|
157
|
+
## After all phases
|
|
158
|
+
|
|
159
|
+
1. Run `bantay status` — should show all scenarios covered
|
|
160
|
+
2. Run `bantay check` — should show all invariants passing
|
|
161
|
+
3. Delete `.bantay/builds/current.md` — clean state
|
|
162
|
+
4. Run `bantay aide lock` — snapshot the aide
|
|
163
|
+
5. Commit and `git push`
|
|
164
|
+
6. Report: phases completed, scenarios covered, invariants passing
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Bantay Status
|
|
2
|
+
|
|
3
|
+
Run `bantay status` and explain the results to the user.
|
|
4
|
+
|
|
5
|
+
## What to Do
|
|
6
|
+
|
|
7
|
+
1. Run the status command:
|
|
8
|
+
```bash
|
|
9
|
+
bantay status
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
2. Explain the output:
|
|
13
|
+
- How many scenarios are covered by tests
|
|
14
|
+
- Which scenarios are missing coverage
|
|
15
|
+
- Overall coverage percentage
|
|
16
|
+
|
|
17
|
+
3. If coverage is low, suggest:
|
|
18
|
+
- Which scenarios should be prioritized for testing
|
|
19
|
+
- How to create tests that reference scenarios with `@scenario` tags
|
|
20
|
+
|
|
21
|
+
## Understanding the Output
|
|
22
|
+
|
|
23
|
+
The status command auto-discovers the .aide file in the current directory.
|
|
24
|
+
|
|
25
|
+
The output shows:
|
|
26
|
+
- **Covered**: Scenarios that have at least one test file referencing them via `@scenario sc_<name>`
|
|
27
|
+
- **Uncovered**: Scenarios that exist in the .aide file but have no test coverage
|
|
28
|
+
- **Coverage %**: Ratio of covered to total scenarios
|
|
29
|
+
|
|
30
|
+
## Example Response
|
|
31
|
+
|
|
32
|
+
"Your Bantay status shows 15/20 scenarios covered (75%).
|
|
33
|
+
|
|
34
|
+
The uncovered scenarios are:
|
|
35
|
+
- sc_checkout_payment_failed - No test for payment failure handling
|
|
36
|
+
- sc_cart_item_out_of_stock - No test for inventory checks
|
|
37
|
+
- ...
|
|
38
|
+
|
|
39
|
+
I'd recommend prioritizing sc_checkout_payment_failed since payment handling is critical for user trust."
|