@bantay/cli 0.1.1 → 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.
@@ -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("Rules this project must never break. Generated from bantay.aide.");
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
- const aidePath = options.aidePath || join(projectPath, "bantay.aide");
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."