@kosuke-ai/cli 0.0.37 → 0.0.39

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.
Files changed (37) hide show
  1. package/dist/index.d.ts +2 -2
  2. package/dist/index.js +101 -70
  3. package/dist/index.js.map +1 -1
  4. package/dist/kosuke/commands/build.d.ts +2 -1
  5. package/dist/kosuke/commands/build.d.ts.map +1 -1
  6. package/dist/kosuke/commands/build.js +158 -57
  7. package/dist/kosuke/commands/build.js.map +1 -1
  8. package/dist/kosuke/commands/test.d.ts +21 -8
  9. package/dist/kosuke/commands/test.d.ts.map +1 -1
  10. package/dist/kosuke/commands/test.js +211 -75
  11. package/dist/kosuke/commands/test.js.map +1 -1
  12. package/dist/kosuke/commands/tickets.d.ts +15 -4
  13. package/dist/kosuke/commands/tickets.d.ts.map +1 -1
  14. package/dist/kosuke/commands/tickets.js +664 -124
  15. package/dist/kosuke/commands/tickets.js.map +1 -1
  16. package/dist/kosuke/types.d.ts +32 -9
  17. package/dist/kosuke/types.d.ts.map +1 -1
  18. package/dist/kosuke/utils/prompt-generator.d.ts +4 -4
  19. package/dist/kosuke/utils/prompt-generator.d.ts.map +1 -1
  20. package/dist/kosuke/utils/prompt-generator.js +22 -11
  21. package/dist/kosuke/utils/prompt-generator.js.map +1 -1
  22. package/dist/kosuke/utils/test-runner.d.ts.map +1 -1
  23. package/dist/kosuke/utils/test-runner.js +13 -4
  24. package/dist/kosuke/utils/test-runner.js.map +1 -1
  25. package/dist/kosuke/utils/tickets-manager.d.ts +0 -4
  26. package/dist/kosuke/utils/tickets-manager.d.ts.map +1 -1
  27. package/dist/kosuke/utils/tickets-manager.js +1 -1
  28. package/dist/kosuke/utils/tickets-manager.js.map +1 -1
  29. package/dist/lib.d.ts +1 -1
  30. package/dist/lib.d.ts.map +1 -1
  31. package/dist/lib.js.map +1 -1
  32. package/dist/package.json +2 -2
  33. package/package.json +2 -2
  34. package/dist/kosuke/utils/browser-agent.d.ts +0 -33
  35. package/dist/kosuke/utils/browser-agent.d.ts.map +0 -1
  36. package/dist/kosuke/utils/browser-agent.js +0 -102
  37. package/dist/kosuke/utils/browser-agent.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -11,7 +11,7 @@
11
11
  * tickets Generate implementation tickets from requirements
12
12
  * build Batch process all tickets from tickets.json
13
13
  * review Review codebase against CLAUDE.md rules
14
- * test Run E2E tests with automated fixing (ticket or custom prompt)
14
+ * test Run atomic tests (web E2E or database validation)
15
15
  *
16
16
  * Usage:
17
17
  * bun run kosuke sync-rules
@@ -22,7 +22,7 @@
22
22
  * bun run kosuke tickets
23
23
  * bun run kosuke build
24
24
  * bun run kosuke review
25
- * bun run kosuke test --ticket=FRONTEND-1 OR --prompt="Test login flow"
25
+ * bun run kosuke test --prompt="Test user login flow" --type=web-test
26
26
  *
27
27
  * Environment Variables:
28
28
  * ANTHROPIC_API_KEY - Required for Claude API
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@
11
11
  * tickets Generate implementation tickets from requirements
12
12
  * build Batch process all tickets from tickets.json
13
13
  * review Review codebase against CLAUDE.md rules
14
- * test Run E2E tests with automated fixing (ticket or custom prompt)
14
+ * test Run atomic tests (web E2E or database validation)
15
15
  *
16
16
  * Usage:
17
17
  * bun run kosuke sync-rules
@@ -22,7 +22,7 @@
22
22
  * bun run kosuke tickets
23
23
  * bun run kosuke build
24
24
  * bun run kosuke review
25
- * bun run kosuke test --ticket=FRONTEND-1 OR --prompt="Test login flow"
25
+ * bun run kosuke test --prompt="Test user login flow" --type=web-test
26
26
  *
27
27
  * Environment Variables:
28
28
  * ANTHROPIC_API_KEY - Required for Claude API
@@ -96,6 +96,8 @@ async function main() {
96
96
  output: args.find((arg) => arg.startsWith('--output='))?.split('=')[1],
97
97
  directory: args.find((arg) => arg.startsWith('--directory='))?.split('=')[1] ||
98
98
  args.find((arg) => arg.startsWith('--dir='))?.split('=')[1],
99
+ scaffold: args.includes('--scaffold'),
100
+ prompt: args.find((arg) => arg.startsWith('--prompt='))?.split('=')[1],
99
101
  noLogs: args.includes('--no-logs'),
100
102
  };
101
103
  await ticketsCommand(options);
@@ -113,8 +115,8 @@ async function main() {
113
115
  review: !args.includes('--no-review'), // Default true, disabled with --no-review
114
116
  test: !args.includes('--no-test'), // Default true, disabled with --no-test
115
117
  url: args.find((arg) => arg.startsWith('--url='))?.split('=')[1],
116
- headed: args.includes('--headed'),
117
- debug: args.includes('--debug'),
118
+ headless: args.includes('--headless'),
119
+ verbose: args.includes('--verbose'),
118
120
  noLogs: args.includes('--no-logs'),
119
121
  };
120
122
  await buildCommand(options);
@@ -128,45 +130,40 @@ async function main() {
128
130
  break;
129
131
  }
130
132
  case 'test': {
131
- const ticketArg = args.find((arg) => arg.startsWith('--ticket='))?.split('=')[1];
132
133
  const promptArg = args.find((arg) => arg.startsWith('--prompt='))?.split('=')[1];
133
- if (!ticketArg && !promptArg) {
134
- console.error('❌ Either --ticket or --prompt flag is required\n');
135
- console.log('Usage: kosuke test --ticket=FRONTEND-1 [OPTIONS] OR kosuke test --prompt="..." [OPTIONS]');
134
+ if (!promptArg) {
135
+ console.error('❌ The --prompt flag is required\n');
136
+ console.log('Usage: kosuke test --prompt="..." [OPTIONS]');
136
137
  console.log('\nOptions:');
137
- console.log(' --ticket=ID Test a specific ticket from tickets.json');
138
- console.log(' --prompt="..." Test with a custom prompt');
139
- console.log(' --url=URL Base URL (default: http://localhost:3000)');
140
- console.log(' --headed Show browser window (default: headless)');
141
- console.log(' --debug Enable Playwright inspector');
142
- console.log(' --update-baseline Update visual baselines');
143
- console.log(' --max-retries=N Max fix attempts (default: 3)');
144
- console.log(' --pr Create PR with fixes');
145
- console.log(' --directory=PATH Directory to test (default: cwd)');
138
+ console.log(' --prompt="..." Test instructions (required)');
139
+ console.log(' --type=TYPE Test type: web-test or db-test (auto-detected if not specified)');
140
+ console.log(' --url=URL Base URL for web tests (default: http://localhost:3000)');
141
+ console.log(' --db-url=URL Database URL for db tests (default: postgres://...)');
142
+ console.log(' --headless Run in headless mode (invisible browser, web-test only)');
143
+ console.log(' --verbose Enable verbose output');
144
+ console.log(' --directory=PATH Directory to test (default: cwd)');
146
145
  console.log('\nExamples:');
147
- console.log(' kosuke test --ticket=FRONTEND-1 # Test ticket');
148
- console.log(' kosuke test --prompt="Test login flow" # Test with prompt');
149
- console.log(' kosuke test --ticket=FRONTEND-1 --headed # Show browser');
150
- console.log(' kosuke test --prompt="..." --pr # Create PR');
146
+ console.log(' kosuke test --prompt="Test user login flow" --type=web-test');
147
+ console.log(' kosuke test --prompt="Validate users table exists" --type=db-test');
148
+ console.log(' kosuke test --prompt="..." --verbose --headless');
149
+ console.log('\nNote: This command is mainly used programmatically from kosuke build.');
150
+ console.log(' For ticket-based testing with retries, use: kosuke build');
151
151
  process.exit(1);
152
152
  }
153
- if (ticketArg && promptArg) {
154
- console.error('❌ Cannot provide both --ticket and --prompt. Use one or the other.\n');
153
+ const typeArg = args.find((arg) => arg.startsWith('--type='))?.split('=')[1];
154
+ if (typeArg && typeArg !== 'web-test' && typeArg !== 'db-test') {
155
+ console.error('❌ Invalid test type. Use: web-test or db-test\n');
155
156
  process.exit(1);
156
157
  }
157
158
  const options = {
158
- ticket: ticketArg,
159
159
  prompt: promptArg,
160
+ type: typeArg,
160
161
  url: args.find((arg) => arg.startsWith('--url='))?.split('=')[1],
161
- headed: args.includes('--headed'),
162
- debug: args.includes('--debug'),
163
- updateBaseline: args.includes('--update-baseline'),
164
- maxRetries: parseInt(args.find((arg) => arg.startsWith('--max-retries='))?.split('=')[1] || '3'),
165
- ticketsFile: args.find((arg) => arg.startsWith('--tickets='))?.split('=')[1],
162
+ dbUrl: args.find((arg) => arg.startsWith('--db-url='))?.split('=')[1],
163
+ headless: args.includes('--headless'),
164
+ verbose: args.includes('--verbose'),
166
165
  directory: args.find((arg) => arg.startsWith('--directory='))?.split('=')[1] ||
167
166
  args.find((arg) => arg.startsWith('--dir='))?.split('=')[1],
168
- pr: args.includes('--pr'),
169
- baseBranch: args.find((arg) => arg.startsWith('--base-branch='))?.split('=')[1],
170
167
  noLogs: args.includes('--no-logs'),
171
168
  };
172
169
  await testCommand(options);
@@ -259,29 +256,61 @@ COMMANDS:
259
256
  kosuke getcode -t "Show me pagination examples"
260
257
 
261
258
  tickets [options]
262
- Generate implementation tickets from requirements document
263
- Analyzes requirements and creates structured tickets in three phases:
264
- 1. Schema tickets (database design)
265
- 2. Backend tickets (API, services, business logic)
266
- 3. Frontend tickets (pages, components, UI)
259
+ Generate implementation tickets from requirements document or inline prompt
260
+ Intelligently determines which layers (schema/backend/frontend) are needed
261
+
262
+ LOGIC-ONLY MODE (default - for existing projects):
263
+ Analyzes requirements and generates only needed tickets:
264
+ - Schema logic (if database changes needed)
265
+ - Backend logic (if API changes needed)
266
+ - Frontend logic (if UI changes needed)
267
+ - DB tests (if schema changes)
268
+ - Web tests (if implementation changes)
269
+
270
+ SCAFFOLD MODE (--scaffold flag - for new projects):
271
+ Generates full infrastructure setup + business logic:
272
+
273
+ SCAFFOLD BATCH:
274
+ 1. Schema scaffold (auth, billing, infrastructure)
275
+ 2. DB test (validate scaffold)
276
+ 3. Backend scaffold (API infrastructure)
277
+ 4. Frontend scaffold (UI infrastructure)
278
+ 5. Web tests (validate scaffold E2E)
279
+
280
+ LOGIC BATCH:
281
+ 1. Schema logic (business entities)
282
+ 2. DB test (validate logic)
283
+ 3. Backend logic (business API)
284
+ 4. Frontend logic (business UI)
285
+ 5. Web tests (validate logic E2E)
267
286
 
268
287
  Options:
269
- --path=<file> Path to requirements document (default: docs.md, relative to project directory)
270
- --output=<file> Output file for tickets (default: tickets.json, relative to project directory)
288
+ --path=<file> Path to requirements document (default: docs.md)
289
+ --prompt="..." Inline requirements (alternative to --path)
290
+ --scaffold Enable scaffold mode for new projects
291
+ --output=<file> Output file for tickets (default: tickets.json)
271
292
  --directory=<path> Directory for Claude to explore (default: current directory)
272
293
  --dir=<path> Alias for --directory
273
294
 
274
295
  Examples:
275
- kosuke tickets # Use docs.md in current directory
276
- kosuke tickets --path=requirements.md # Custom requirements file
277
- kosuke tickets --output=my-tickets.json # Custom output file
278
- kosuke tickets --directory=./projects/my-app # Analyze specific directory
279
- kosuke tickets --dir=./my-app --path=docs/spec.md # Custom directory and requirements path
296
+ # Logic-only mode (existing projects)
297
+ kosuke tickets --prompt="Add dark mode toggle"
298
+ kosuke tickets --prompt="Add user notifications"
299
+ kosuke tickets --path=feature.md
300
+
301
+ # Scaffold mode (new projects)
302
+ kosuke tickets --scaffold --path=docs.md
303
+ kosuke tickets --scaffold --prompt="Build a task manager with teams"
304
+
305
+ # With custom options
306
+ kosuke tickets --directory=./my-app --prompt="Add export to CSV"
307
+ kosuke tickets --output=my-tickets.json --path=requirements.md
280
308
 
281
309
  build [options]
282
310
  Batch process all "Todo" and "Error" tickets from tickets.json
283
- Implements and commits each ticket individually to current branch
284
- Processes tickets in order: Schema → Backend → Frontend
311
+ Implements tickets and runs tests with automatic fixing
312
+ Processes tickets in order: Schema → DB Test → Backend → Frontend → Web Test
313
+ Commits in batches after each web-test completion
285
314
  Frontend tickets automatically include E2E testing (unless --no-test)
286
315
  All tickets include code review by default (unless --no-review)
287
316
 
@@ -296,8 +325,8 @@ COMMANDS:
296
325
  --no-review Skip code review phase (enabled by default)
297
326
  --no-test Skip testing phase for frontend tickets (enabled by default)
298
327
  --url=<URL> Base URL for testing (default: http://localhost:3000)
299
- --headed Show browser during testing (visible GUI window for debugging)
300
- --debug Enable Playwright inspector for tests
328
+ --headless Run tests in headless mode (invisible browser)
329
+ --verbose Enable verbose output for tests
301
330
 
302
331
  Examples:
303
332
  git checkout -b feat/implement-tickets # Create feature branch first
@@ -309,7 +338,8 @@ COMMANDS:
309
338
  kosuke build --ask-commit --ask-confirm # Fully interactive mode
310
339
  kosuke build --reset # Reset all tickets and start from scratch
311
340
  kosuke build --no-review --no-test # Skip review and testing (fastest)
312
- kosuke build --headed # Show browser during tests
341
+ kosuke build --headless # Run tests in headless mode
342
+ kosuke build --verbose # Enable verbose test output
313
343
  kosuke build --tickets=custom.json # Use custom tickets file
314
344
  kosuke build --directory=./my-project # Run build in specific directory
315
345
  kosuke build --db-url=postgres://user:pass@host:5432/db # Custom DB
@@ -324,34 +354,35 @@ COMMANDS:
324
354
  Examples:
325
355
  kosuke review # Review uncommitted changes
326
356
 
327
- test [--ticket=<ID> | --prompt="..."] [options]
328
- Run E2E tests with automated fixing (either ticket or custom prompt)
329
- Uses Playwright for testing, Claude AI for analyzing and fixing issues
330
- Iteratively tests and fixes until passing or max retries reached
357
+ test --prompt="..." [options]
358
+ Run atomic tests (web E2E or database validation, no fixing, no retries)
359
+
360
+ Test types:
361
+ - web-test: Browser E2E testing with Stagehand + Claude AI
362
+ - db-test: Database schema validation with Claude Code
363
+
364
+ For iterative test+fix workflow, use: kosuke build
331
365
 
332
366
  Options:
333
- --ticket=<ID> Ticket ID to test (from tickets.json, e.g., FRONTEND-1)
334
- --prompt="..." Custom test prompt (alternative to --ticket)
335
- --url=<URL> Base URL (default: http://localhost:3000)
336
- --headed Show browser during testing (visible GUI window for debugging)
337
- --debug Enable Playwright inspector
338
- --update-baseline Update visual regression baselines
339
- --max-retries=<N> Maximum fix-retest iterations (default: 3)
340
- --tickets=<file> Path to tickets file (default: tickets.json, relative to directory)
367
+ --prompt="..." Test instructions (required)
368
+ --type=<type> Test type: web-test or db-test (auto-detected if not specified)
369
+ --url=<URL> Base URL for web tests (default: http://localhost:3000)
370
+ --db-url=<URL> Database URL for db tests (default: postgres://postgres:postgres@localhost:5432/postgres)
371
+ --headless Run browser in headless mode (web-test only, invisible)
372
+ --verbose Enable verbose output
341
373
  --directory=<path> Directory to run tests in (default: current directory)
342
374
  --dir=<path> Alias for --directory
343
- --pr Create pull request with fixes
344
- --base-branch=<name> Base branch for PR (default: current branch)
345
375
 
346
376
  Examples:
347
- kosuke test --ticket=FRONTEND-1 # Test with auto-fix
348
- kosuke test --prompt="Test user login flow" # Test with custom prompt
349
- kosuke test --ticket=FRONTEND-1 --url=http://localhost:4000
350
- kosuke test --prompt="..." --headed # Show browser (visible GUI)
351
- kosuke test --ticket=FRONTEND-1 --update-baseline # Update visuals
352
- kosuke test --ticket=FRONTEND-1 --max-retries=5 # More attempts
353
- kosuke test --prompt="..." --pr # Create PR with fixes
354
- kosuke test --ticket=FRONTEND-1 --directory=./my-project # Specific directory
377
+ kosuke test --prompt="Test user login flow" --type=web-test
378
+ kosuke test --prompt="Validate users table exists" --type=db-test
379
+ kosuke test --prompt="..." --url=http://localhost:4000
380
+ kosuke test --prompt="..." --db-url=postgres://...
381
+ kosuke test --prompt="..." --verbose --headless
382
+ kosuke test --prompt="..." --directory=./my-project
383
+
384
+ Note: This command is mainly used programmatically from kosuke build.
385
+ For ticket-based testing with retries, use: kosuke build
355
386
 
356
387
  GLOBAL OPTIONS:
357
388
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
@@ -13,7 +13,8 @@
13
13
  * kosuke build --reset # Reset all tickets to "Todo" and process from scratch
14
14
  * kosuke build --no-review # Skip code review phase
15
15
  * kosuke build --no-test # Skip testing phase for frontend tickets
16
- * kosuke build --headed # Show browser during testing
16
+ * kosuke build --headless # Run tests in headless mode (invisible)
17
+ * kosuke build --verbose # Enable verbose test output
17
18
  * kosuke build --tickets=path/to/tickets.json
18
19
  * kosuke build --db-url=postgres://user:pass@host:5432/db
19
20
  *
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../kosuke/commands/build.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAU,MAAM,aAAa,CAAC;AAwExD;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA2MvE"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../kosuke/commands/build.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAU,MAAM,aAAa,CAAC;AAkGxD;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAkSvE"}
@@ -13,7 +13,8 @@
13
13
  * kosuke build --reset # Reset all tickets to "Todo" and process from scratch
14
14
  * kosuke build --no-review # Skip code review phase
15
15
  * kosuke build --no-test # Skip testing phase for frontend tickets
16
- * kosuke build --headed # Show browser during testing
16
+ * kosuke build --headless # Run tests in headless mode (invisible)
17
+ * kosuke build --verbose # Enable verbose test output
17
18
  * kosuke build --tickets=path/to/tickets.json
18
19
  * kosuke build --db-url=postgres://user:pass@host:5432/db
19
20
  *
@@ -26,9 +27,10 @@ import { existsSync, statSync } from 'fs';
26
27
  import { join, resolve } from 'path';
27
28
  import * as readline from 'readline';
28
29
  import simpleGit from 'simple-git';
30
+ import { generateDBTestPrompt, generateWebTestPrompt } from '../utils/prompt-generator.js';
29
31
  import { loadTicketsFile, saveTicketsFile, updateTicketStatus, } from '../utils/tickets-manager.js';
30
32
  import { shipCore } from './ship.js';
31
- import { runTestsWithRetry } from '../utils/test-runner.js';
33
+ import { testCore } from './test.js';
32
34
  /**
33
35
  * Prompt user for confirmation to continue
34
36
  */
@@ -51,38 +53,62 @@ async function promptConfirmation(message) {
51
53
  function getTicketsToProcess(ticketsData) {
52
54
  // Get all Todo and Error tickets (automatic retry on Error)
53
55
  const tickets = ticketsData.tickets.filter((t) => t.status === 'Todo' || t.status === 'Error');
54
- // Sort by phase: SCHEMA -> BACKEND -> FRONTEND
56
+ // Sort by phase: SCHEMA -> DB-TEST -> BACKEND -> FRONTEND -> WEB-TEST
55
57
  tickets.sort((a, b) => {
56
58
  const getPhaseOrder = (id) => {
57
59
  if (id.startsWith('SCHEMA-'))
58
60
  return 1;
59
- if (id.startsWith('BACKEND-'))
61
+ if (id.startsWith('DB-TEST-'))
60
62
  return 2;
61
- if (id.startsWith('FRONTEND-'))
63
+ if (id.startsWith('BACKEND-'))
62
64
  return 3;
63
- return 4;
65
+ if (id.startsWith('FRONTEND-'))
66
+ return 4;
67
+ if (id.startsWith('WEB-TEST-'))
68
+ return 5;
69
+ return 6;
64
70
  };
65
71
  const phaseComparison = getPhaseOrder(a.id) - getPhaseOrder(b.id);
66
72
  if (phaseComparison !== 0)
67
73
  return phaseComparison;
68
74
  // Within same phase, sort by ticket number
69
- const aNum = parseInt(a.id.split('-')[1] || '0', 10);
70
- const bNum = parseInt(b.id.split('-')[1] || '0', 10);
75
+ const aNum = parseInt(a.id.split('-').slice(-1)[0] || '0', 10);
76
+ const bNum = parseInt(b.id.split('-').slice(-1)[0] || '0', 10);
71
77
  return aNum - bNum;
72
78
  });
73
79
  return tickets;
74
80
  }
75
81
  /**
76
- * Commit ticket changes to current branch
82
+ * Commit batch of tickets to current branch
77
83
  */
78
- async function commitTicket(ticket, cwd) {
84
+ async function commitBatch(batchTickets, cwd) {
79
85
  const git = simpleGit(cwd);
80
86
  // Stage all changes
81
87
  await git.add('.');
82
- // Commit with ticket info
83
- const commitMessage = `feat: ${ticket.id} - ${ticket.title}`;
88
+ // Create commit message with all tickets in batch
89
+ const ticketIds = batchTickets.map((t) => t.id).join(', ');
90
+ const batchType = batchTickets[0].id.startsWith('WEB-TEST-')
91
+ ? batchTickets[0].id.split('-')[2] === '1'
92
+ ? 'scaffold'
93
+ : 'logic'
94
+ : 'implementation';
95
+ const commitMessage = `feat: ${batchType} batch (${ticketIds})`;
84
96
  await git.commit(commitMessage);
85
- console.log(` ✅ Committed: ${commitMessage}`);
97
+ console.log(`\n ✅ Committed batch: ${commitMessage}\n`);
98
+ }
99
+ /**
100
+ * Determine if we should commit after this ticket
101
+ * Commits happen after the last WEB-TEST in a batch
102
+ */
103
+ function shouldCommitAfterTicket(currentTicket, nextTicket) {
104
+ // Always commit after last ticket
105
+ if (!nextTicket)
106
+ return true;
107
+ // Commit if current is WEB-TEST and next is not WEB-TEST (batch boundary)
108
+ if (currentTicket.id.startsWith('WEB-TEST-') && !nextTicket.id.startsWith('WEB-TEST-')) {
109
+ return true;
110
+ }
111
+ return false;
86
112
  }
87
113
  /**
88
114
  * Main build command - processes all tickets and commits each one
@@ -97,7 +123,7 @@ export async function buildCommand(options) {
97
123
  if (!process.env.GITHUB_TOKEN) {
98
124
  throw new Error('GITHUB_TOKEN environment variable is required for build command');
99
125
  }
100
- const { directory, ticketsFile = 'tickets.json', dbUrl = 'postgres://postgres:postgres@localhost:5432/postgres', reset = false, askConfirm = false, askCommit = false, review = true, test = true, url, headed, debug, noLogs = false, } = options;
126
+ const { directory, ticketsFile = 'tickets.json', dbUrl = 'postgres://postgres:postgres@localhost:5432/postgres', reset = false, askConfirm = false, askCommit = false, review = true, url, headless, verbose, noLogs = false, } = options;
101
127
  // 1. Validate and resolve directory
102
128
  const cwd = directory ? resolve(directory) : process.cwd();
103
129
  if (!existsSync(cwd)) {
@@ -140,9 +166,11 @@ export async function buildCommand(options) {
140
166
  console.log(` ${index + 1}. ${ticket.id}: ${ticket.title}`);
141
167
  });
142
168
  console.log('');
143
- // 4. Process each ticket sequentially
169
+ // 4. Process each ticket sequentially with batch tracking
170
+ const batchTickets = []; // Track tickets in current batch
144
171
  for (let i = 0; i < ticketsToProcess.length; i++) {
145
172
  const ticket = ticketsToProcess[i];
173
+ const nextTicket = ticketsToProcess[i + 1];
146
174
  console.log('\n' + '='.repeat(80));
147
175
  console.log(`📦 Processing Ticket ${i + 1}/${ticketsToProcess.length}: ${ticket.id}`);
148
176
  console.log(`📝 ${ticket.title}`);
@@ -152,59 +180,132 @@ export async function buildCommand(options) {
152
180
  console.log('📝 Updating ticket status to InProgress...');
153
181
  updateTicketStatus(ticketsPath, ticket.id, 'InProgress');
154
182
  console.log(' ✅ Status updated\n');
155
- // Step 2: Ship implements the ticket (no ticket lifecycle management)
156
- const shipResult = await shipCore({
157
- ticketData: ticket, // Pass ticket object directly
158
- review, // Controlled by build options
159
- directory: cwd,
160
- dbUrl,
161
- noLogs,
162
- });
163
- if (!shipResult.success) {
164
- throw new Error(shipResult.error || 'Ship failed');
165
- }
166
- console.log(`\n✅ ${ticket.id} implemented successfully`);
167
- console.log(`📊 Implementation fixes: ${shipResult.implementationFixCount}`);
168
- console.log(`🔧 Linting fixes: ${shipResult.lintFixCount}`);
169
- if (shipResult.reviewFixCount > 0) {
170
- console.log(`🔍 Review fixes: ${shipResult.reviewFixCount}`);
171
- }
172
- console.log(`💰 Ship cost: $${shipResult.cost.toFixed(4)}`);
173
- // Step 3: Run tests if frontend ticket and test enabled
174
- const isFrontendTicket = ticket.id.startsWith('FRONTEND-');
175
- if (test && isFrontendTicket) {
183
+ // Step 2: Process ticket based on type
184
+ const isTestTicket = ticket.type === 'db-test' || ticket.type === 'web-test';
185
+ if (isTestTicket) {
186
+ // This is a test ticket - run test with retry
176
187
  console.log(`\n${'='.repeat(60)}`);
177
- console.log(`🧪 Phase: Testing (Iterative)`);
188
+ console.log(`🧪 Running ${ticket.type === 'db-test' ? 'Database' : 'Web'} Test`);
178
189
  console.log(`${'='.repeat(60)}\n`);
179
- const testResult = await runTestsWithRetry({
180
- ticket,
181
- cwd,
190
+ // Generate test prompt from ticket
191
+ const testPrompt = ticket.type === 'db-test'
192
+ ? generateDBTestPrompt(ticket)
193
+ : generateWebTestPrompt(ticket);
194
+ let testResult = await testCore({
195
+ prompt: testPrompt,
196
+ type: ticket.type === 'db-test' ? 'db-test' : 'web-test',
197
+ context: {
198
+ ticketId: ticket.id,
199
+ ticketTitle: ticket.title,
200
+ ticketDescription: ticket.description,
201
+ },
202
+ directory: cwd,
182
203
  url,
183
- headed,
184
- debug,
185
- maxRetries: 3,
204
+ dbUrl,
205
+ headless,
206
+ verbose,
207
+ noLogs,
186
208
  });
187
- console.log(`\n✨ Testing completed (${testResult.fixesApplied} fixes applied over ${testResult.attempts} iterations)`);
188
- console.log(`💰 Testing cost: $${testResult.cost.toFixed(4)}`);
209
+ let retryCount = 0;
210
+ const maxRetries = 3;
211
+ // Retry loop: if test fails, run ship to fix it
212
+ while (!testResult.success && retryCount < maxRetries) {
213
+ retryCount++;
214
+ console.log(`\n⚠️ Test failed (attempt ${retryCount}/${maxRetries})`);
215
+ console.log(`📝 Error: ${testResult.error}\n`);
216
+ console.log(`🔧 Running ship to fix test failures...\n`);
217
+ // Create a fix ticket for ship
218
+ const fixTicket = {
219
+ id: `${ticket.id}-FIX-${retryCount}`,
220
+ title: `Fix ${ticket.id} test failures`,
221
+ description: `Fix the following test failures:\n\n${testResult.error}\n\nOriginal ticket:\n${ticket.description}`,
222
+ type: 'logic', // Use logic type for fix tickets
223
+ estimatedEffort: 5,
224
+ status: 'InProgress',
225
+ category: ticket.category,
226
+ };
227
+ const shipResult = await shipCore({
228
+ ticketData: fixTicket,
229
+ review: false, // Skip review for test fixes
230
+ directory: cwd,
231
+ dbUrl,
232
+ noLogs,
233
+ });
234
+ if (!shipResult.success) {
235
+ console.error(`\n❌ Fix attempt ${retryCount} failed: ${shipResult.error}`);
236
+ continue;
237
+ }
238
+ console.log(`\n✅ Fix applied (attempt ${retryCount})`);
239
+ console.log(`💰 Fix cost: $${shipResult.cost.toFixed(4)}\n`);
240
+ // Re-run test
241
+ console.log(`🔄 Re-running test...\n`);
242
+ testResult = await testCore({
243
+ prompt: testPrompt,
244
+ type: ticket.type === 'db-test' ? 'db-test' : 'web-test',
245
+ context: {
246
+ ticketId: ticket.id,
247
+ ticketTitle: ticket.title,
248
+ ticketDescription: ticket.description,
249
+ },
250
+ directory: cwd,
251
+ url,
252
+ dbUrl,
253
+ headless,
254
+ verbose,
255
+ noLogs,
256
+ });
257
+ }
258
+ if (!testResult.success) {
259
+ throw new Error(`Test failed after ${maxRetries} fix attempts:\n${testResult.error}`);
260
+ }
261
+ console.log(`\n✅ ${ticket.id} test passed`);
262
+ console.log(`💰 Test cost: $${testResult.cost.toFixed(4)}`);
189
263
  }
190
- // Step 4: Update ticket status to Done
264
+ else {
265
+ // Regular implementation ticket - run ship
266
+ const shipResult = await shipCore({
267
+ ticketData: ticket,
268
+ review,
269
+ directory: cwd,
270
+ dbUrl,
271
+ noLogs,
272
+ });
273
+ if (!shipResult.success) {
274
+ throw new Error(shipResult.error || 'Ship failed');
275
+ }
276
+ console.log(`\n✅ ${ticket.id} implemented successfully`);
277
+ console.log(`📊 Implementation fixes: ${shipResult.implementationFixCount}`);
278
+ console.log(`🔧 Linting fixes: ${shipResult.lintFixCount}`);
279
+ if (shipResult.reviewFixCount > 0) {
280
+ console.log(`🔍 Review fixes: ${shipResult.reviewFixCount}`);
281
+ }
282
+ console.log(`💰 Ship cost: $${shipResult.cost.toFixed(4)}`);
283
+ }
284
+ // Step 3: Update ticket status to Done
191
285
  console.log('\n📝 Updating ticket status to Done...');
192
286
  updateTicketStatus(ticketsPath, ticket.id, 'Done');
193
287
  console.log(` ✅ Ticket ${ticket.id} marked as Done\n`);
194
- // Step 5: Commit (if not asking)
195
- if (askCommit) {
196
- // Interactive: ask before committing
197
- const shouldCommit = await promptConfirmation(`\n❓ Commit changes for ${ticket.id}?`);
198
- if (shouldCommit) {
199
- await commitTicket(ticket, cwd);
288
+ // Add to batch tracking
289
+ batchTickets.push(ticket);
290
+ // Step 4: Commit batch if at batch boundary
291
+ const shouldCommit = shouldCommitAfterTicket(ticket, nextTicket);
292
+ if (shouldCommit && batchTickets.length > 0) {
293
+ if (askCommit) {
294
+ // Interactive: ask before committing
295
+ const commitConfirmed = await promptConfirmation(`\n❓ Commit batch of ${batchTickets.length} ticket(s)?`);
296
+ if (commitConfirmed) {
297
+ await commitBatch(batchTickets, cwd);
298
+ }
299
+ else {
300
+ console.log(' ⏭️ Skipped batch commit\n');
301
+ }
200
302
  }
201
303
  else {
202
- console.log(' ⏭️ Skipped commit\n');
304
+ // Default: auto-commit batch
305
+ await commitBatch(batchTickets, cwd);
203
306
  }
204
- }
205
- else {
206
- // Default: auto-commit
207
- await commitTicket(ticket, cwd);
307
+ // Reset batch tracking
308
+ batchTickets.length = 0;
208
309
  }
209
310
  // Ask for confirmation before proceeding to next ticket (if not last ticket)
210
311
  if (askConfirm && i < ticketsToProcess.length - 1) {