@kosuke-ai/cli 0.0.57 โ†’ 1.0.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.
Files changed (263) hide show
  1. package/README.md +31 -448
  2. package/dist/commands/auth.js +117 -0
  3. package/dist/generated/commands/deploy/cancel.js +17 -0
  4. package/dist/generated/commands/deploy/messages.js +17 -0
  5. package/dist/generated/commands/deploy/run.js +60 -0
  6. package/dist/generated/commands/index.js +132 -0
  7. package/dist/generated/commands/preview/get.js +25 -0
  8. package/dist/generated/commands/preview/health.js +25 -0
  9. package/dist/generated/commands/preview/reset.js +27 -0
  10. package/dist/generated/commands/preview/share-create.js +36 -0
  11. package/dist/generated/commands/preview/share-delete.js +26 -0
  12. package/dist/generated/commands/preview/share-get.js +26 -0
  13. package/dist/generated/commands/preview/shared.js +17 -0
  14. package/dist/generated/commands/projects/create.js +37 -0
  15. package/dist/generated/commands/projects/delete.js +17 -0
  16. package/dist/generated/commands/projects/env-vars-add.js +21 -0
  17. package/dist/generated/commands/projects/env-vars-remove.js +21 -0
  18. package/dist/generated/commands/projects/get.js +17 -0
  19. package/dist/generated/commands/projects/list.js +15 -0
  20. package/dist/generated/commands/projects/services-add.js +87 -0
  21. package/dist/generated/commands/projects/services-list.js +18 -0
  22. package/dist/generated/commands/projects/services-remove.js +19 -0
  23. package/dist/generated/commands/projects/services-update.js +81 -0
  24. package/dist/generated/commands/projects/settings-get.js +18 -0
  25. package/dist/generated/commands/projects/settings-import.js +91 -0
  26. package/dist/generated/commands/projects/settings-update.js +77 -0
  27. package/dist/generated/commands/projects/skills.js +35 -0
  28. package/dist/generated/commands/projects/update.js +27 -0
  29. package/dist/generated/commands/sessions/activate.js +18 -0
  30. package/dist/generated/commands/sessions/checklist-generate.js +19 -0
  31. package/dist/generated/commands/sessions/checklist-get.js +19 -0
  32. package/dist/generated/commands/sessions/comments-add.js +63 -0
  33. package/dist/generated/commands/sessions/comments-delete.js +20 -0
  34. package/dist/generated/commands/sessions/comments-list.js +19 -0
  35. package/dist/generated/commands/sessions/comments-update.js +23 -0
  36. package/dist/generated/commands/sessions/create.js +126 -0
  37. package/dist/generated/commands/sessions/delete.js +18 -0
  38. package/dist/generated/commands/sessions/diff-files.js +19 -0
  39. package/dist/generated/commands/sessions/diff-patch.js +86 -0
  40. package/dist/generated/commands/sessions/edit-prompt.js +59 -0
  41. package/dist/generated/commands/sessions/files-get.js +27 -0
  42. package/dist/generated/commands/sessions/files-list.js +19 -0
  43. package/dist/generated/commands/sessions/files-write.js +41 -0
  44. package/dist/generated/commands/sessions/get.js +18 -0
  45. package/dist/generated/commands/sessions/git-commit-message.js +19 -0
  46. package/dist/generated/commands/sessions/git-commit.js +29 -0
  47. package/dist/generated/commands/sessions/git-push.js +19 -0
  48. package/dist/generated/commands/sessions/git-state.js +19 -0
  49. package/dist/generated/commands/sessions/jobs-cancel.js +20 -0
  50. package/dist/generated/commands/sessions/jobs-get.js +20 -0
  51. package/dist/generated/commands/sessions/list.js +81 -0
  52. package/dist/generated/commands/sessions/messages.js +18 -0
  53. package/dist/generated/commands/sessions/search.js +23 -0
  54. package/dist/generated/commands/sessions/send.js +98 -0
  55. package/dist/generated/commands/sessions/update.js +72 -0
  56. package/dist/generated/commands/workspaces/access-status.js +29 -0
  57. package/dist/generated/commands/workspaces/ai-provider-get.js +18 -0
  58. package/dist/generated/commands/workspaces/ai-provider-remove.js +42 -0
  59. package/dist/generated/commands/workspaces/ai-provider-set.js +21 -0
  60. package/dist/generated/commands/workspaces/credits.js +17 -0
  61. package/dist/generated/commands/workspaces/get.js +17 -0
  62. package/dist/generated/commands/workspaces/getting-started-get.js +18 -0
  63. package/dist/generated/commands/workspaces/getting-started-update.js +32 -0
  64. package/dist/generated/commands/workspaces/list.js +15 -0
  65. package/dist/generated/commands/workspaces/members.js +25 -0
  66. package/dist/generated/commands/workspaces/sandbox-limit.js +17 -0
  67. package/dist/generated/commands/workspaces/stop-sandboxes.js +27 -0
  68. package/dist/generated/commands/workspaces/usage.js +32 -0
  69. package/dist/index.js +5 -595
  70. package/dist/program.js +46 -0
  71. package/dist/runtime/attach.js +139 -0
  72. package/dist/runtime/attachments.js +58 -0
  73. package/dist/runtime/client.js +12 -0
  74. package/dist/runtime/config.js +49 -0
  75. package/dist/runtime/credentials.js +24 -0
  76. package/dist/runtime/descriptor.js +7 -0
  77. package/dist/runtime/invoke.js +152 -0
  78. package/dist/runtime/runtime.js +41 -0
  79. package/dist/runtime/version.js +5 -0
  80. package/openapi.json +5222 -0
  81. package/package.json +21 -79
  82. package/LICENSE +0 -21
  83. package/claude.costs.json +0 -34
  84. package/dist/__tests__/utils/file-discovery.test.d.ts +0 -5
  85. package/dist/__tests__/utils/file-discovery.test.d.ts.map +0 -1
  86. package/dist/__tests__/utils/file-discovery.test.js +0 -51
  87. package/dist/__tests__/utils/file-discovery.test.js.map +0 -1
  88. package/dist/__tests__/utils/logger-nologs.test.d.ts +0 -5
  89. package/dist/__tests__/utils/logger-nologs.test.d.ts.map +0 -1
  90. package/dist/__tests__/utils/logger-nologs.test.js +0 -34
  91. package/dist/__tests__/utils/logger-nologs.test.js.map +0 -1
  92. package/dist/__tests__/utils/logger.test.d.ts +0 -5
  93. package/dist/__tests__/utils/logger.test.d.ts.map +0 -1
  94. package/dist/__tests__/utils/logger.test.js +0 -243
  95. package/dist/__tests__/utils/logger.test.js.map +0 -1
  96. package/dist/__tests__/utils/validator.test.d.ts +0 -5
  97. package/dist/__tests__/utils/validator.test.d.ts.map +0 -1
  98. package/dist/__tests__/utils/validator.test.js +0 -206
  99. package/dist/__tests__/utils/validator.test.js.map +0 -1
  100. package/dist/index.d.ts +0 -37
  101. package/dist/index.d.ts.map +0 -1
  102. package/dist/index.js.map +0 -1
  103. package/dist/kosuke/commands/analyse.d.ts +0 -15
  104. package/dist/kosuke/commands/analyse.d.ts.map +0 -1
  105. package/dist/kosuke/commands/analyse.js +0 -304
  106. package/dist/kosuke/commands/analyse.js.map +0 -1
  107. package/dist/kosuke/commands/build.d.ts +0 -35
  108. package/dist/kosuke/commands/build.d.ts.map +0 -1
  109. package/dist/kosuke/commands/build.js +0 -660
  110. package/dist/kosuke/commands/build.js.map +0 -1
  111. package/dist/kosuke/commands/fix.d.ts +0 -21
  112. package/dist/kosuke/commands/fix.d.ts.map +0 -1
  113. package/dist/kosuke/commands/fix.js +0 -256
  114. package/dist/kosuke/commands/fix.js.map +0 -1
  115. package/dist/kosuke/commands/getcode.d.ts +0 -29
  116. package/dist/kosuke/commands/getcode.d.ts.map +0 -1
  117. package/dist/kosuke/commands/getcode.js +0 -248
  118. package/dist/kosuke/commands/getcode.js.map +0 -1
  119. package/dist/kosuke/commands/lint.d.ts +0 -21
  120. package/dist/kosuke/commands/lint.d.ts.map +0 -1
  121. package/dist/kosuke/commands/lint.js +0 -342
  122. package/dist/kosuke/commands/lint.js.map +0 -1
  123. package/dist/kosuke/commands/migrate.d.ts +0 -38
  124. package/dist/kosuke/commands/migrate.d.ts.map +0 -1
  125. package/dist/kosuke/commands/migrate.js +0 -284
  126. package/dist/kosuke/commands/migrate.js.map +0 -1
  127. package/dist/kosuke/commands/plan.d.ts +0 -28
  128. package/dist/kosuke/commands/plan.d.ts.map +0 -1
  129. package/dist/kosuke/commands/plan.js +0 -684
  130. package/dist/kosuke/commands/plan.js.map +0 -1
  131. package/dist/kosuke/commands/requirements.d.ts +0 -52
  132. package/dist/kosuke/commands/requirements.d.ts.map +0 -1
  133. package/dist/kosuke/commands/requirements.js +0 -615
  134. package/dist/kosuke/commands/requirements.js.map +0 -1
  135. package/dist/kosuke/commands/review.d.ts +0 -26
  136. package/dist/kosuke/commands/review.d.ts.map +0 -1
  137. package/dist/kosuke/commands/review.js +0 -303
  138. package/dist/kosuke/commands/review.js.map +0 -1
  139. package/dist/kosuke/commands/serve.d.ts +0 -9
  140. package/dist/kosuke/commands/serve.d.ts.map +0 -1
  141. package/dist/kosuke/commands/serve.js +0 -17
  142. package/dist/kosuke/commands/serve.js.map +0 -1
  143. package/dist/kosuke/commands/ship.d.ts +0 -37
  144. package/dist/kosuke/commands/ship.d.ts.map +0 -1
  145. package/dist/kosuke/commands/ship.js +0 -375
  146. package/dist/kosuke/commands/ship.js.map +0 -1
  147. package/dist/kosuke/commands/sync-rules.d.ts +0 -9
  148. package/dist/kosuke/commands/sync-rules.d.ts.map +0 -1
  149. package/dist/kosuke/commands/sync-rules.js +0 -414
  150. package/dist/kosuke/commands/sync-rules.js.map +0 -1
  151. package/dist/kosuke/commands/test.d.ts +0 -42
  152. package/dist/kosuke/commands/test.d.ts.map +0 -1
  153. package/dist/kosuke/commands/test.js +0 -540
  154. package/dist/kosuke/commands/test.js.map +0 -1
  155. package/dist/kosuke/commands/tickets.d.ts +0 -43
  156. package/dist/kosuke/commands/tickets.d.ts.map +0 -1
  157. package/dist/kosuke/commands/tickets.js +0 -876
  158. package/dist/kosuke/commands/tickets.js.map +0 -1
  159. package/dist/kosuke/commands/validate-tickets.d.ts +0 -23
  160. package/dist/kosuke/commands/validate-tickets.d.ts.map +0 -1
  161. package/dist/kosuke/commands/validate-tickets.js +0 -360
  162. package/dist/kosuke/commands/validate-tickets.js.map +0 -1
  163. package/dist/kosuke/serve/middleware/error-handler.d.ts +0 -14
  164. package/dist/kosuke/serve/middleware/error-handler.d.ts.map +0 -1
  165. package/dist/kosuke/serve/middleware/error-handler.js +0 -42
  166. package/dist/kosuke/serve/middleware/error-handler.js.map +0 -1
  167. package/dist/kosuke/serve/middleware/validation.d.ts +0 -13
  168. package/dist/kosuke/serve/middleware/validation.d.ts.map +0 -1
  169. package/dist/kosuke/serve/middleware/validation.js +0 -38
  170. package/dist/kosuke/serve/middleware/validation.js.map +0 -1
  171. package/dist/kosuke/serve/routes/build.d.ts +0 -6
  172. package/dist/kosuke/serve/routes/build.d.ts.map +0 -1
  173. package/dist/kosuke/serve/routes/build.js +0 -226
  174. package/dist/kosuke/serve/routes/build.js.map +0 -1
  175. package/dist/kosuke/serve/routes/health.d.ts +0 -6
  176. package/dist/kosuke/serve/routes/health.d.ts.map +0 -1
  177. package/dist/kosuke/serve/routes/health.js +0 -11
  178. package/dist/kosuke/serve/routes/health.js.map +0 -1
  179. package/dist/kosuke/serve/routes/plan.d.ts +0 -6
  180. package/dist/kosuke/serve/routes/plan.d.ts.map +0 -1
  181. package/dist/kosuke/serve/routes/plan.js +0 -106
  182. package/dist/kosuke/serve/routes/plan.js.map +0 -1
  183. package/dist/kosuke/serve/server.d.ts +0 -16
  184. package/dist/kosuke/serve/server.d.ts.map +0 -1
  185. package/dist/kosuke/serve/server.js +0 -67
  186. package/dist/kosuke/serve/server.js.map +0 -1
  187. package/dist/kosuke/serve/validation/build.d.ts +0 -41
  188. package/dist/kosuke/serve/validation/build.d.ts.map +0 -1
  189. package/dist/kosuke/serve/validation/build.js +0 -20
  190. package/dist/kosuke/serve/validation/build.js.map +0 -1
  191. package/dist/kosuke/serve/validation/plan.d.ts +0 -26
  192. package/dist/kosuke/serve/validation/plan.d.ts.map +0 -1
  193. package/dist/kosuke/serve/validation/plan.js +0 -15
  194. package/dist/kosuke/serve/validation/plan.js.map +0 -1
  195. package/dist/kosuke/types.d.ts +0 -539
  196. package/dist/kosuke/types.d.ts.map +0 -1
  197. package/dist/kosuke/types.js +0 -5
  198. package/dist/kosuke/types.js.map +0 -1
  199. package/dist/kosuke/utils/batch-creator.d.ts +0 -14
  200. package/dist/kosuke/utils/batch-creator.d.ts.map +0 -1
  201. package/dist/kosuke/utils/batch-creator.js +0 -76
  202. package/dist/kosuke/utils/batch-creator.js.map +0 -1
  203. package/dist/kosuke/utils/claude-agent.d.ts +0 -140
  204. package/dist/kosuke/utils/claude-agent.d.ts.map +0 -1
  205. package/dist/kosuke/utils/claude-agent.js +0 -388
  206. package/dist/kosuke/utils/claude-agent.js.map +0 -1
  207. package/dist/kosuke/utils/constants.d.ts +0 -40
  208. package/dist/kosuke/utils/constants.d.ts.map +0 -1
  209. package/dist/kosuke/utils/constants.js +0 -54
  210. package/dist/kosuke/utils/constants.js.map +0 -1
  211. package/dist/kosuke/utils/file-discovery.d.ts +0 -15
  212. package/dist/kosuke/utils/file-discovery.d.ts.map +0 -1
  213. package/dist/kosuke/utils/file-discovery.js +0 -80
  214. package/dist/kosuke/utils/file-discovery.js.map +0 -1
  215. package/dist/kosuke/utils/git.d.ts +0 -41
  216. package/dist/kosuke/utils/git.d.ts.map +0 -1
  217. package/dist/kosuke/utils/git.js +0 -145
  218. package/dist/kosuke/utils/git.js.map +0 -1
  219. package/dist/kosuke/utils/github.d.ts +0 -17
  220. package/dist/kosuke/utils/github.d.ts.map +0 -1
  221. package/dist/kosuke/utils/github.js +0 -22
  222. package/dist/kosuke/utils/github.js.map +0 -1
  223. package/dist/kosuke/utils/interactive-input.d.ts +0 -22
  224. package/dist/kosuke/utils/interactive-input.d.ts.map +0 -1
  225. package/dist/kosuke/utils/interactive-input.js +0 -124
  226. package/dist/kosuke/utils/interactive-input.js.map +0 -1
  227. package/dist/kosuke/utils/json-parser.d.ts +0 -14
  228. package/dist/kosuke/utils/json-parser.d.ts.map +0 -1
  229. package/dist/kosuke/utils/json-parser.js +0 -40
  230. package/dist/kosuke/utils/json-parser.js.map +0 -1
  231. package/dist/kosuke/utils/logger.d.ts +0 -161
  232. package/dist/kosuke/utils/logger.d.ts.map +0 -1
  233. package/dist/kosuke/utils/logger.js +0 -234
  234. package/dist/kosuke/utils/logger.js.map +0 -1
  235. package/dist/kosuke/utils/playwright-mcp-client.d.ts +0 -46
  236. package/dist/kosuke/utils/playwright-mcp-client.d.ts.map +0 -1
  237. package/dist/kosuke/utils/playwright-mcp-client.js +0 -135
  238. package/dist/kosuke/utils/playwright-mcp-client.js.map +0 -1
  239. package/dist/kosuke/utils/pr-orchestrator.d.ts +0 -49
  240. package/dist/kosuke/utils/pr-orchestrator.d.ts.map +0 -1
  241. package/dist/kosuke/utils/pr-orchestrator.js +0 -154
  242. package/dist/kosuke/utils/pr-orchestrator.js.map +0 -1
  243. package/dist/kosuke/utils/repository-manager.d.ts +0 -13
  244. package/dist/kosuke/utils/repository-manager.d.ts.map +0 -1
  245. package/dist/kosuke/utils/repository-manager.js +0 -94
  246. package/dist/kosuke/utils/repository-manager.js.map +0 -1
  247. package/dist/kosuke/utils/repository-resolver.d.ts +0 -12
  248. package/dist/kosuke/utils/repository-resolver.d.ts.map +0 -1
  249. package/dist/kosuke/utils/repository-resolver.js +0 -186
  250. package/dist/kosuke/utils/repository-resolver.js.map +0 -1
  251. package/dist/kosuke/utils/tickets-manager.d.ts +0 -34
  252. package/dist/kosuke/utils/tickets-manager.d.ts.map +0 -1
  253. package/dist/kosuke/utils/tickets-manager.js +0 -106
  254. package/dist/kosuke/utils/tickets-manager.js.map +0 -1
  255. package/dist/kosuke/utils/validator.d.ts +0 -45
  256. package/dist/kosuke/utils/validator.d.ts.map +0 -1
  257. package/dist/kosuke/utils/validator.js +0 -248
  258. package/dist/kosuke/utils/validator.js.map +0 -1
  259. package/dist/lib.d.ts +0 -104
  260. package/dist/lib.d.ts.map +0 -1
  261. package/dist/lib.js +0 -104
  262. package/dist/lib.js.map +0 -1
  263. package/dist/package.json +0 -99
@@ -1,876 +0,0 @@
1
- /**
2
- * Tickets command - Generate tickets from requirements document
3
- *
4
- * Generates tickets directly from a requirements document.
5
- * No clarification questions - assumes requirements are complete.
6
- * Best for: New projects with detailed requirements from `kosuke requirements`.
7
- *
8
- * For interactive ticket creation with questions, use: kosuke plan --prompt="..."
9
- *
10
- * SCAFFOLD MODE (--scaffold flag):
11
- * SCAFFOLD BATCH (template adaptation):
12
- * 1. SCAFFOLD-SCHEMA-1 (ONE ticket for ALL database infrastructure changes)
13
- * 2. SCAFFOLD-BACKEND-X โ†’ SCAFFOLD-FRONTEND-X โ†’ SCAFFOLD-TEST-X (feature-by-feature)
14
- *
15
- * LOGIC BATCH (business functionality):
16
- * 1. LOGIC-SCHEMA-1 (ONE ticket for ALL business entities)
17
- * 2. LOGIC-BACKEND-X โ†’ LOGIC-FRONTEND-X โ†’ LOGIC-TEST-X (feature-by-feature)
18
- *
19
- * LOGIC-ONLY MODE (default):
20
- * Only generates LOGIC tickets for new features
21
- * 1. LOGIC-SCHEMA-1 (ONE ticket for ALL business entities)
22
- * 2. LOGIC-BACKEND-X โ†’ LOGIC-FRONTEND-X โ†’ LOGIC-TEST-X (feature-by-feature)
23
- *
24
- * Workflow:
25
- * 1. Claude Code Agent explores codebase and generates tickets
26
- * 2. Review step validates and fixes ticket structure
27
- * 3. Outputs validated tickets.json
28
- *
29
- * Usage:
30
- * kosuke tickets # Use docs.md
31
- * kosuke tickets --scaffold # Scaffold + logic from docs.md
32
- * kosuke tickets --path=custom.md # Custom requirements file
33
- */
34
- import { existsSync, readFileSync, statSync, writeFileSync } from 'fs';
35
- import { join, resolve } from 'path';
36
- import { formatCostBreakdown, runAgentStream } from '../utils/claude-agent.js';
37
- import { extractTicketsJSON } from '../utils/json-parser.js';
38
- import { logger, setupCancellationHandler } from '../utils/logger.js';
39
- import { displayTicketsSummary, loadTicketsFile, writeTicketsFile, } from '../utils/tickets-manager.js';
40
- import { fixCoreStream } from './fix.js';
41
- import { validateTicketsCoreStream } from './validate-tickets.js';
42
- /**
43
- * Build unified system prompt for comprehensive ticket generation
44
- */
45
- function buildTicketPrompt(requirementsContent, projectPath, isScaffoldMode, noTest = false) {
46
- const scaffoldGuidance = isScaffoldMode
47
- ? `
48
- **SCAFFOLD TICKETS - Template Adaptation ONLY:**
49
-
50
- These tickets focus on removing, changing, or customizing the Kosuke Template baseline.
51
- DO NOT add new business logic or features from requirements here.
52
-
53
- Scaffold tickets should:
54
- - โŒ REMOVE unused template features (e.g., organizations, billing, multi-tenancy)
55
- - ๐Ÿ”„ CHANGE existing features (e.g., swap Better Auth for Clerk, simplify billing)
56
- - ๐ŸŽจ CUSTOMIZE infrastructure (landing page, email templates, branding, navigation)
57
-
58
- Examples of SCAFFOLD tickets:
59
- - "Remove organization/multi-tenancy support from auth (backend + frontend)"
60
- - "Simplify billing to single tier (backend + frontend)"
61
- - "Customize landing page for [specific use case]"
62
- - "Remove landing page entirely (internal tool)"
63
- - "Update email templates and backend handlers for [brand name]"
64
-
65
- **SCAFFOLD Ticket Ordering - CRITICAL:**
66
- 1. SCAFFOLD-SCHEMA-1 (ONE ticket for ALL database infrastructure changes, auto-validated)
67
- 2. SCAFFOLD-REFACTOR-1, SCAFFOLD-REFACTOR-2, etc (each refactor touches BOTH backend + frontend)
68
- 3. SCAFFOLD-TEST-1 through SCAFFOLD-TEST-5 (5 separate test tickets at the end)
69
-
70
- **SCAFFOLD Test Structure (5 MANDATORY tickets):**
71
- Create exactly 5 test tickets to validate all scaffold changes:
72
-
73
- 1. **SCAFFOLD-TEST-1: Auth flow validation**
74
- - Sign up without removed features (no org selection)
75
- - Sign in flow works correctly
76
- - Session management works
77
- - No references to removed auth features
78
-
79
- 2. **SCAFFOLD-TEST-2: Navigation validation**
80
- - All navigation links work
81
- - No broken routes from removed pages
82
- - Settings navigation updated
83
- - No 404 errors from removed features
84
-
85
- 3. **SCAFFOLD-TEST-3: Landing page validation**
86
- - Landing page renders with new branding
87
- - Search/filter UI works
88
- - CTAs function correctly
89
- - No template/SaaS references
90
-
91
- 4. **SCAFFOLD-TEST-4: Removed features validation**
92
- - Billing pages removed (no /billing routes)
93
- - Organization pages removed (no /org routes)
94
- - Tasks/orders removed (no /tasks or /orders routes)
95
- - Verify removed features are truly gone
96
-
97
- 5. **SCAFFOLD-TEST-5: Settings and profile validation**
98
- - Settings page loads without removed sections
99
- - Profile updates work
100
- - Email preferences work
101
- - No billing or org settings visible
102
- `
103
- : '';
104
- const webTestGuidance = noTest
105
- ? ''
106
- : `
107
- **TEST TICKETS - Playwright MCP E2E Tests:**
108
-
109
- Test tickets are executed by Playwright MCP with Claude AI and must follow these guidelines:
110
-
111
- **Test User Discovery:**
112
- 1. **ALWAYS read seed files** to find test user credentials:
113
- - Look for files: lib/db/seed.ts, src/lib/db/seed.ts
114
- - Pattern: Any email ending with "+kosuke_test@example.com" uses OTP code "424242"
115
- - Example: john+kosuke_test@example.com โ†’ OTP: 424242
116
- - Include all discovered test users in ticket description
117
-
118
- **Ticket Structure Requirements:**
119
- Each web test ticket MUST include:
120
-
121
- 1. **Test User Credentials** (at the top)
122
- - List all test users with their emails
123
- - Document OTP code (424242)
124
- - Specify user roles if applicable (admin, regular user, etc.)
125
-
126
- 2. **Test Steps** (numbered, detailed natural language)
127
- - Navigation instructions ("Navigate to /sign-in")
128
- - User interactions ("Click button labeled 'New Task'")
129
- - Input actions ("Enter 'Test Task' in title field")
130
- - Expected outcomes after each step ("Expected: Task appears in list")
131
- - Use CLEAR element descriptions (button text, labels, placeholders)
132
- - Use relative paths only (e.g., /sign-in, /tasks) - base URL provided as test argument
133
-
134
- 3. **Acceptance Criteria**
135
- - Final expected state
136
- - Data validation points
137
- - User feedback confirmation
138
-
139
- **Playwright MCP Best Practices:**
140
- - Use natural language, NOT code
141
- - Be SPECIFIC about element identification (button text, input labels, exact URLs)
142
- - Include EXPECTED OUTCOMES after each major action
143
- - Combine related flows into ONE ticket (signup โ†’ create โ†’ invite = 1 ticket)
144
- - Authentication steps MUST be explicit:
145
- 1. Navigate to /sign-in
146
- 2. Enter email: {test_user}+kosuke_test@example.com
147
- 3. Click "Send Code" button
148
- 4. Enter OTP: 424242
149
- 5. Click "Verify" button
150
- 6. Expected: Redirected to dashboard/main app
151
-
152
- **Example Test Ticket:**
153
-
154
- {
155
- "id": "LOGIC-TEST-1",
156
- "title": "E2E: User signup and create first task",
157
- "description": "**Test User Credentials:**\\n- Email: john+kosuke_test@example.com\\n- OTP Code: 424242\\n\\n**Test Steps:**\\n\\n1. **Sign in with test user**\\n - Navigate to /sign-in\\n - Enter email: john+kosuke_test@example.com\\n - Click button labeled 'Send Code'\\n - Enter OTP code: 424242\\n - Click button labeled 'Verify'\\n - Expected: Redirected to /tasks\\n\\n2. **Create new task**\\n - Click button with text 'New Task'\\n - Enter 'My First Task' in the Title field\\n - Select 'High' from Priority dropdown\\n - Click 'Create Task' button\\n - Expected: Task appears in task list\\n - Expected: Success message shown\\n\\n3. **Verify task persistence**\\n - Refresh the page\\n - Expected: Task 'My First Task' still visible\\n - Expected: Priority shows 'High'\\n\\n**Acceptance Criteria:**\\n- User successfully authenticates with OTP\\n- Task is created and visible\\n- Task persists after page refresh\\n- UI shows appropriate feedback",
158
- "type": "test",
159
- "estimatedEffort": 4,
160
- "status": "Todo",
161
- "category": "tasks"
162
- }`;
163
- return `You are an expert software architect generating implementation tickets.
164
-
165
- **Requirements Document:**
166
- ${requirementsContent}
167
-
168
- **Project Context:**
169
- You have access to the project directory at: ${projectPath}
170
-
171
- ${scaffoldGuidance}
172
- ${webTestGuidance}
173
-
174
- **LOGIC TICKETS - Business Functionality:**
175
-
176
- These tickets implement the actual features and requirements from the document.
177
-
178
- Logic tickets should:
179
- - ๐Ÿ—„๏ธ Create schema for business entities (tasks, projects, posts, etc.)
180
- - ๐Ÿ Create Python engine endpoints for algorithms/calculations
181
- - โš™๏ธ Build backend APIs for business features
182
- - ๐ŸŽจ Create frontend UI for business features
183
-
184
- Scaffold tickets (refactor type):
185
- - ๐Ÿ”„ Each REFACTOR ticket should handle BOTH backend AND frontend changes together
186
- - Don't split refactoring work across separate backend/frontend tickets
187
- - Example: SCAFFOLD-REFACTOR-1 removes billing feature (database operations + API routes + UI pages)
188
-
189
- **LOGIC Ticket Ordering - CRITICAL RULES:**
190
-
191
- **RULE 1: LOGIC-SCHEMA-1 is MANDATORY and MUST be FIRST**
192
- - The VERY FIRST LOGIC ticket MUST be LOGIC-SCHEMA-1
193
- - This ticket combines ALL business entities into ONE schema ticket
194
- - โŒ WRONG: Starting with LOGIC-BACKEND-1 (missing schema!)
195
- - โŒ WRONG: LOGIC-SCHEMA-1, LOGIC-SCHEMA-2, LOGIC-SCHEMA-3 (only ONE schema ticket!)
196
- - โœ… CORRECT: LOGIC-SCHEMA-1 (combines all database entities in one ticket)
197
-
198
- **RULE 2: Feature-by-Feature Pattern (MANDATORY) - NEVER GROUP BY TYPE**
199
-
200
- After LOGIC-SCHEMA-1, you MUST follow this STRICT pattern for EVERY feature:
201
- **BACKEND โ†’ FRONTEND โ†’ TEST** (complete each feature before starting next)
202
-
203
- โš ๏ธ **YOU WILL GENERATE TICKETS GROUPED BY TYPE IF YOU'RE NOT CAREFUL!**
204
-
205
- The NATURAL INSTINCT is to group by type, but this is ABSOLUTELY FORBIDDEN:
206
-
207
- โŒ **ABSOLUTELY FORBIDDEN - Grouping by Type (COMMON MISTAKE):**
208
- LOGIC-SCHEMA-1 โ† schema (correct)
209
- LOGIC-BACKEND-1 โ† properties backend
210
- LOGIC-BACKEND-2 โ† favorites backend โŒ STOP! This is type grouping!
211
- LOGIC-BACKEND-3 โ† inquiries backend โŒ All backends together is WRONG!
212
- LOGIC-BACKEND-4 โ† dashboard backend
213
- LOGIC-FRONTEND-1 โ† properties frontend โŒ All frontends grouped!
214
- LOGIC-FRONTEND-2 โ† favorites frontend
215
- LOGIC-FRONTEND-3 โ† inquiries frontend
216
- LOGIC-FRONTEND-4 โ† dashboard frontend
217
- LOGIC-TEST-1 โ† properties test โŒ All tests grouped!
218
- LOGIC-TEST-2 โ† favorites test
219
- LOGIC-TEST-3 โ† inquiries test
220
-
221
- This is WRONG! All backends grouped together, then all frontends, then all tests.
222
- THIS IS THE MOST COMMON MISTAKE - DO NOT MAKE IT!
223
-
224
- โœ… **REQUIRED - Feature-by-Feature (ONE FEATURE AT A TIME):**
225
- LOGIC-SCHEMA-1 (schemas for ALL features - ALWAYS FIRST)
226
- LOGIC-BACKEND-1 (properties backend API) โ† Feature 1 backend
227
- LOGIC-FRONTEND-1 (properties frontend UI) โ† Feature 1 frontend
228
- LOGIC-TEST-1 (properties test) โ† Feature 1 test โœ“ Complete!
229
- LOGIC-BACKEND-2 (favorites backend API) โ† Feature 2 backend
230
- LOGIC-FRONTEND-2 (favorites frontend UI) โ† Feature 2 frontend
231
- LOGIC-TEST-2 (favorites test) โ† Feature 2 test โœ“ Complete!
232
- LOGIC-BACKEND-3 (inquiries backend API) โ† Feature 3 backend
233
- LOGIC-FRONTEND-3 (inquiries frontend UI) โ† Feature 3 frontend
234
- LOGIC-TEST-3 (inquiries test) โ† Feature 3 test โœ“ Complete!
235
-
236
- This is CORRECT! Each feature completed (backend โ†’ frontend โ†’ test) before next feature.
237
-
238
- **WHY THIS MATTERS:**
239
- - Each complete feature can be developed and tested independently
240
- - Clear progress tracking (3 features done vs 0 features done)
241
- - Natural development workflow (build API, then UI, then test)
242
- - Avoids having half-built features scattered across ticket list
243
-
244
- **WHY Feature-by-Feature?**
245
- - Each feature can be developed and tested independently
246
- - Clear dependency chains (backend ready โ†’ build frontend โ†’ test both)
247
- - Easier to track progress per feature
248
- - Natural workflow for developers
249
-
250
- **RULE 3: Engine tickets (optional, only if needed)**
251
- If Python engine endpoints are needed, insert AFTER schema, BEFORE first backend:
252
- 1. LOGIC-SCHEMA-1
253
- 2. LOGIC-ENGINE-1 (if needed for complex algorithms)
254
- 3. LOGIC-BACKEND-1 โ†’ LOGIC-FRONTEND-1 โ†’ LOGIC-TEST-1
255
- 4. LOGIC-BACKEND-2 โ†’ LOGIC-FRONTEND-2 โ†’ LOGIC-TEST-2
256
-
257
- **Ticket Granularity:**
258
- - Schema: EXACTLY ONE ticket for LOGIC batch (combines ALL entities)
259
- - Engine: One ticket per distinct algorithm/endpoint (could be 0-3 tickets)
260
- - Backend: Let complexity decide (could be 1-5 tickets per batch)
261
- - Frontend: Let complexity decide (could be 1-5 tickets per batch)
262
- - Web Tests: 1 test per major user flow (matches feature grouping)
263
-
264
- **Your Task:**
265
- 1. **Explore the codebase** using read_file, grep, codebase_search to understand:
266
- - Current tech stack and framework versions
267
- - Existing architecture patterns
268
- - Database schema structure
269
- - API route patterns
270
- - UI component library and styling
271
- ${isScaffoldMode ? ' - What template features are currently present\n - What needs to be removed, changed, or customized' : ''}
272
-
273
- 2. **Discover test users** for web testing:
274
- - Read seed files: lib/db/seed.ts, src/lib/db/seed.ts (use read_file or grep)
275
- - Look for test user pattern: {name}+kosuke_test@example.com
276
- - Document all test users found (email addresses)
277
- - Note: All test users use OTP code 424242 for Better Auth
278
- - Include test user credentials in ALL web test tickets
279
-
280
- 3. **Analyze requirements** to determine:
281
- - Which layers are needed (schema/backend/frontend)
282
- - How to break down features into logical batches
283
- - What user flows need E2E web tests
284
-
285
- 4. **Generate ALL tickets** in the correct order:
286
- ${isScaffoldMode ? ' - SCAFFOLD batch first (template adaptation)\n - LOGIC batches second (business features)' : ' - LOGIC batches only (business features)'}
287
- - Follow the ticket ordering structure above
288
- - Schema tickets are automatically validated during build (no separate test tickets needed)
289
- - For web tests: Include test user credentials, detailed steps, and expected outcomes
290
-
291
- **When to use ENGINE vs BACKEND:**
292
- - **Use BACKEND (Next.js)** for: CRUD operations, auth logic, business rules, anything TypeScript handles well (90% of features)
293
- - **Use ENGINE (Python)** for: ML/AI, data science (numpy/pandas), complex algorithms, PDF/document parsing, image processing, or when Python libraries are required
294
-
295
- **Ticket Structure (CRITICAL - CORRECT ID FORMAT REQUIRED):**
296
-
297
- Each ticket MUST have an ID in the format: {BATCH}-{TYPE}-{NUMBER}
298
- - Global sequential numbering within each batch
299
- - โŒ WRONG: "SCAFFOLD-1", "SCAFFOLD-2", "LOGIC-1", "LOGIC-2"
300
- - โœ… CORRECT: "SCAFFOLD-SCHEMA-1", "SCAFFOLD-REFACTOR-2", "LOGIC-BACKEND-1", "LOGIC-FRONTEND-2"
301
-
302
- Valid ID patterns:
303
- - SCAFFOLD batch: SCAFFOLD-SCHEMA-{n}, SCAFFOLD-REFACTOR-{n}, SCAFFOLD-TEST-{n}
304
- - LOGIC batch: LOGIC-SCHEMA-{n}, LOGIC-ENGINE-{n}, LOGIC-BACKEND-{n}, LOGIC-FRONTEND-{n}, LOGIC-TEST-{n}
305
-
306
- Examples with global numbering:
307
- - [SCAFFOLD-SCHEMA-1, SCAFFOLD-REFACTOR-2, SCAFFOLD-REFACTOR-3, SCAFFOLD-TEST-4, SCAFFOLD-TEST-5]
308
- - [LOGIC-SCHEMA-1, LOGIC-BACKEND-2, LOGIC-FRONTEND-3, LOGIC-TEST-4, LOGIC-BACKEND-5, LOGIC-FRONTEND-6]
309
-
310
- Each ticket must be a JSON object with:
311
- - id: string (MUST include type: "SCAFFOLD-SCHEMA-1", "LOGIC-BACKEND-2", etc.)
312
- - title: string (clear, concise title)
313
- - description: string (detailed description with acceptance criteria)
314
- - type: "schema" | "refactor" | "engine" | "backend" | "frontend" | "test"
315
- - estimatedEffort: number (1-10, where 1=very easy, 10=very complex)
316
- - status: "Todo"
317
- - category: string (e.g., "auth", "billing", "user-management", "tasks")
318
-
319
- **Type Guidelines:**
320
- - "schema": Database schema changes only
321
- - "refactor": Template adaptation (SCAFFOLD only) - touches BOTH backend + frontend
322
- - "engine": Python engine endpoints (LOGIC only)
323
- - "backend": Backend/API implementation (LOGIC only)
324
- - "frontend": Frontend UI implementation (LOGIC only)
325
- - "test": E2E web tests (both SCAFFOLD and LOGIC)
326
-
327
- **Output Format:**
328
- Return ONLY a valid JSON array of ALL tickets in the correct order. No markdown, no code blocks, just raw JSON.
329
-
330
- Example (Full Ordering Structure - Scaffold Mode with 2 LOGIC features):
331
- [
332
- {
333
- "id": "SCAFFOLD-SCHEMA-1",
334
- "title": "Remove unused template features from schema",
335
- "description": "Remove template features from database:\\n- Drop unused tables\\n- Remove foreign keys from users table\\n- Simplify schema\\n\\nAcceptance Criteria:\\n- Unused tables removed\\n- Schema simplified\\n- Migrations validated automatically\\n- No schema errors",
336
- "type": "schema",
337
- "estimatedEffort": 5,
338
- "status": "Todo",
339
- "category": "cleanup"
340
- },
341
- {
342
- "id": "SCAFFOLD-REFACTOR-1",
343
- "title": "Remove organization/multi-tenancy feature (backend + frontend)",
344
- "description": "Remove organization feature from entire stack:\\n\\nBackend:\\n- Delete organization tRPC routers\\n- Remove org-related schemas\\n- Clean up auth middleware\\n\\nFrontend:\\n- Delete organization pages\\n- Remove org selection from signup\\n- Update navigation\\n- Simplify user settings\\n\\nAcceptance Criteria:\\n- All org-related code removed\\n- Auth flow works without orgs\\n- Navigation simplified\\n- No broken links or imports\\n- Type safety maintained",
345
- "type": "refactor",
346
- "estimatedEffort": 7,
347
- "status": "Todo",
348
- "category": "cleanup"
349
- },
350
- {
351
- "id": "SCAFFOLD-REFACTOR-2",
352
- "title": "Simplify billing to single tier (backend + frontend)",
353
- "description": "Simplify billing system:\\n\\nBackend:\\n- Remove tier logic from routers\\n- Simplify subscription schemas\\n- Update billing webhooks\\n\\nFrontend:\\n- Remove pricing page\\n- Simplify settings billing section\\n- Update subscription UI\\n\\nAcceptance Criteria:\\n- Single tier billing works\\n- No pro/business tier references\\n- Settings page simplified\\n- Webhooks handle new structure",
354
- "type": "refactor",
355
- "estimatedEffort": 6,
356
- "status": "Todo",
357
- "category": "billing"
358
- },
359
- {
360
- "id": "SCAFFOLD-TEST-1",
361
- "title": "E2E: Auth flow validation",
362
- "description": "**Test User Credentials:**\\n- Email: john+kosuke_test@example.com\\n- OTP Code: 424242\\n\\n**Test Steps:**\\n\\n1. **Sign up flow**\\n - Navigate to /sign-up\\n - Enter test email\\n - Enter OTP code\\n - Expected: Successful signup\\n\\n2. **Sign in flow**\\n - Navigate to /sign-in\\n - Enter test credentials\\n - Expected: Successful login\\n\\n**Acceptance Criteria:**\\n- Auth flows work correctly\\n- No errors in removed features",
363
- "type": "test",
364
- "estimatedEffort": 3,
365
- "status": "Todo",
366
- "category": "auth"
367
- },
368
- {
369
- "id": "SCAFFOLD-TEST-2",
370
- "title": "E2E: Navigation validation",
371
- "description": "**Test Steps:**\\n\\n1. **Verify navigation**\\n - Check navigation structure\\n - Click each navigation link\\n - Expected: No 404 errors\\n\\n**Acceptance Criteria:**\\n- Navigation works correctly\\n- No broken links from removed features",
372
- "type": "test",
373
- "estimatedEffort": 2,
374
- "status": "Todo",
375
- "category": "navigation"
376
- },
377
- {
378
- "id": "SCAFFOLD-TEST-3",
379
- "title": "E2E: Landing page validation",
380
- "description": "**Test Steps:**\\n\\n1. **Verify landing page**\\n - Navigate to /\\n - Check page content\\n - Test CTAs\\n\\n**Acceptance Criteria:**\\n- Landing page works\\n- All CTAs functional",
381
- "type": "test",
382
- "estimatedEffort": 2,
383
- "status": "Todo",
384
- "category": "landing"
385
- },
386
- {
387
- "id": "SCAFFOLD-TEST-4",
388
- "title": "E2E: Removed features validation",
389
- "description": "**Test Steps:**\\n\\n1. **Verify removed routes**\\n - Try accessing removed routes\\n - Expected: 404 errors\\n\\n**Acceptance Criteria:**\\n- Removed features truly gone\\n- No accessible old routes",
390
- "type": "test",
391
- "estimatedEffort": 2,
392
- "status": "Todo",
393
- "category": "cleanup"
394
- },
395
- {
396
- "id": "SCAFFOLD-TEST-5",
397
- "title": "E2E: Settings validation",
398
- "description": "**Test User Credentials:**\\n- Email: john+kosuke_test@example.com\\n- OTP Code: 424242\\n\\n**Test Steps:**\\n\\n1. **Access settings**\\n - Sign in as test user\\n - Navigate to /settings\\n - Test profile updates\\n\\n**Acceptance Criteria:**\\n- Settings work correctly\\n- Profile management functional",
399
- "type": "test",
400
- "estimatedEffort": 3,
401
- "status": "Todo",
402
- "category": "settings"
403
- },
404
- {
405
- "id": "LOGIC-SCHEMA-1",
406
- "title": "Create database schema for business entities",
407
- "description": "Create database schema for ALL business entities:\\n- Create enums for entity types\\n- Create main entity tables\\n- Create relationship tables\\n- Export inferred types\\n\\nAcceptance Criteria:\\n- All tables created\\n- Enums defined at database level\\n- Migrations validated automatically\\n- No schema errors",
408
- "type": "schema",
409
- "estimatedEffort": 8,
410
- "status": "Todo",
411
- "category": "schema"
412
- },
413
- {
414
- "id": "LOGIC-BACKEND-1",
415
- "title": "Create feature A tRPC router",
416
- "description": "Create backend API for feature A:\\n- Create schemas\\n- Create router\\n- Implement CRUD operations\\n- Server-side filtering and pagination\\n\\nAcceptance Criteria:\\n- All CRUD operations work\\n- Authorization enforced\\n- Type-safe implementation",
417
- "type": "backend",
418
- "estimatedEffort": 7,
419
- "status": "Todo",
420
- "category": "feature-a"
421
- },
422
- {
423
- "id": "LOGIC-FRONTEND-1",
424
- "title": "Create feature A UI",
425
- "description": "Create UI for feature A:\\n- Create page components\\n- Add list view with filters\\n- Add search functionality\\n- Add pagination\\n\\nAcceptance Criteria:\\n- UI displays correctly\\n- Filters work server-side\\n- Search functional\\n- Responsive design",
426
- "type": "frontend",
427
- "estimatedEffort": 8,
428
- "status": "Todo",
429
- "category": "feature-a"
430
- },
431
- {
432
- "id": "LOGIC-TEST-1",
433
- "title": "E2E: Feature A workflow",
434
- "description": "**Test User Credentials:**\\n- Email: john+kosuke_test@example.com\\n- OTP Code: 424242\\n\\n**Test Steps:**\\n\\n1. **Test main workflow**\\n - Navigate to feature page\\n - Test CRUD operations\\n - Test filters and search\\n\\n**Acceptance Criteria:**\\n- All operations work\\n- UI behaves correctly",
435
- "type": "test",
436
- "estimatedEffort": 4,
437
- "status": "Todo",
438
- "category": "feature-a"
439
- },
440
- {
441
- "id": "LOGIC-BACKEND-2",
442
- "title": "Create feature B tRPC router",
443
- "description": "Create backend API for feature B:\\n- Create schemas\\n- Create router\\n- Implement operations\\n\\nAcceptance Criteria:\\n- Operations work\\n- Authorization enforced",
444
- "type": "backend",
445
- "estimatedEffort": 4,
446
- "status": "Todo",
447
- "category": "feature-b"
448
- },
449
- {
450
- "id": "LOGIC-FRONTEND-2",
451
- "title": "Create feature B UI",
452
- "description": "Create UI for feature B:\\n- Create page components\\n- Add main functionality\\n\\nAcceptance Criteria:\\n- UI works correctly\\n- Responsive design",
453
- "type": "frontend",
454
- "estimatedEffort": 5,
455
- "status": "Todo",
456
- "category": "feature-b"
457
- },
458
- {
459
- "id": "LOGIC-TEST-2",
460
- "title": "E2E: Feature B workflow",
461
- "description": "**Test User Credentials:**\\n- Email: john+kosuke_test@example.com\\n- OTP Code: 424242\\n\\n**Test Steps:**\\n\\n1. **Test feature B**\\n - Navigate to feature page\\n - Test main operations\\n\\n**Acceptance Criteria:**\\n- Operations work correctly",
462
- "type": "test",
463
- "estimatedEffort": 5,
464
- "status": "Todo",
465
- "category": "feature-b"
466
- }
467
- ]
468
-
469
- **Critical Instructions:**
470
-
471
- 1. **Explore the project directory thoroughly** before generating tickets
472
- - Read seed files (lib/db/seed.ts or src/lib/db/seed.ts) to discover test users
473
- - Understand current tech stack, architecture, database schema
474
- ${isScaffoldMode ? '- Identify what template features need to be removed/changed/customized' : ''}
475
-
476
- 2. **SCAFFOLD Tickets (if in scaffold mode):**
477
- ${isScaffoldMode ? '- Focus on template adaptation ONLY (remove/change/customize)\n - Use REFACTOR type (not backend/frontend) - each ticket touches BOTH layers\n - MUST create exactly 5 SCAFFOLD-TEST tickets (numbered 1-5)\n - Tests validate: auth flow, navigation, landing page, removed features, settings' : '- Not applicable in logic-only mode'}
478
-
479
- 3. **LOGIC Tickets (MANDATORY ordering - FEATURE-BY-FEATURE ONLY):**
480
- - **FIRST TICKET MUST BE LOGIC-SCHEMA-1** (combines ALL business entities)
481
- - After schema, follow STRICT feature-by-feature pattern for EVERY feature:
482
- - LOGIC-BACKEND-1 โ†’ LOGIC-FRONTEND-1 โ†’ LOGIC-TEST-1 (complete feature 1)
483
- - LOGIC-BACKEND-2 โ†’ LOGIC-FRONTEND-2 โ†’ LOGIC-TEST-2 (complete feature 2)
484
- - LOGIC-BACKEND-3 โ†’ LOGIC-FRONTEND-3 โ†’ LOGIC-TEST-3 (complete feature 3)
485
- - โŒ ABSOLUTELY FORBIDDEN: Grouping by type
486
- - BACKEND-1, BACKEND-2, BACKEND-3, FRONTEND-1, FRONTEND-2 โ† WRONG!
487
- - โœ… REQUIRED: Complete each feature before next
488
- - BACKEND-1, FRONTEND-1, TEST-1, BACKEND-2, FRONTEND-2, TEST-2 โ† CORRECT!
489
-
490
- 4. **Schema and Refactor Tickets:**
491
- - SCAFFOLD-SCHEMA-1: ONE ticket for ALL infrastructure changes
492
- - SCAFFOLD-REFACTOR-X: Each refactor ticket touches BOTH backend + frontend (don't split)
493
- - LOGIC-SCHEMA-1: ONE ticket for ALL business entities (MANDATORY!)
494
- - No separate test tickets needed for schema - validation is automatic
495
-
496
- 5. **Test Tickets:**
497
- - ${isScaffoldMode ? 'Exactly 5 SCAFFOLD-TEST tickets (mandatory)\n - ' : ''}One LOGIC-TEST per feature (matches frontend tickets)
498
- - MUST include test user credentials at the top
499
- - Clear numbered steps with natural language
500
- - Expected outcomes after each step
501
- - Specific element descriptions (button text, labels, URLs)
502
-
503
- 6. **Ticket Quality:**
504
- - Detailed descriptions with clear acceptance criteria
505
- - Realistic effort estimates (1-10 scale)
506
- - Proper categorization
507
- - Sequential IDs matching ordering structure
508
-
509
- 7. **Output Format:**
510
- - Return ONLY valid JSON array
511
- - No markdown, no code blocks, no explanations
512
- - All tickets in correct order
513
-
514
- **VALIDATION CHECKLIST before returning tickets:**
515
-
516
- ๐Ÿ”ด **CRITICAL - VERIFY LOGIC TICKET ORDERING:**
517
- Read through your LOGIC tickets. Are they in this pattern?
518
- BACKEND-1, BACKEND-2, BACKEND-3, FRONTEND-1, FRONTEND-2, FRONTEND-3, TEST-1, TEST-2
519
- If YES โ†’ YOU MADE THE GROUPING MISTAKE! Fix it now!
520
-
521
- โœ… Correct pattern should be:
522
- SCHEMA-1, BACKEND-1, FRONTEND-1, TEST-1, BACKEND-2, FRONTEND-2, TEST-2
523
-
524
- Other checks:
525
- - โœ… ALL ticket IDs follow {BATCH}-{TYPE}-{NUMBER} format (e.g., SCAFFOLD-SCHEMA-1, LOGIC-BACKEND-2)
526
- - โœ… Global sequential numbering within each batch (no gaps, sequential: 1, 2, 3, 4...)
527
- - โœ… ${isScaffoldMode ? 'SCAFFOLD-SCHEMA-1 is first scaffold ticket' : 'N/A for logic-only mode'}
528
- - โœ… ${isScaffoldMode ? 'SCAFFOLD tickets use REFACTOR type (not backend/frontend split)' : 'N/A for logic-only mode'}
529
- - โœ… ${isScaffoldMode ? 'Exactly 5 SCAFFOLD-TEST tickets (with proper IDs like SCAFFOLD-TEST-4, SCAFFOLD-TEST-5)' : 'N/A for logic-only mode'}
530
- - โœ… LOGIC-SCHEMA-1 is first LOGIC ticket (MANDATORY!)
531
- - โœ… LOGIC tickets are feature-by-feature (BACKEND-1 โ†’ FRONTEND-1 โ†’ TEST-1 โ†’ BACKEND-2 โ†’ FRONTEND-2 โ†’ TEST-2)
532
- - โœ… NO grouping by type for LOGIC tickets (verify tickets are NOT: all backends, then frontends, then tests)
533
- - โœ… Each web test includes test user credentials
534
- - โœ… Ticket IDs match their type field (BACKEND ticket has BACKEND in ID, FRONTEND has FRONTEND in ID)
535
-
536
- **CRITICAL REMINDERS:**
537
-
538
- 1. **ID FORMAT (MOST IMPORTANT):**
539
- - EVERY ticket ID MUST include the type: {BATCH}-{TYPE}-{NUMBER}
540
- - โŒ WRONG: SCAFFOLD-1, SCAFFOLD-2, LOGIC-1, LOGIC-2
541
- - โœ… CORRECT: SCAFFOLD-SCHEMA-1, SCAFFOLD-REFACTOR-2, LOGIC-BACKEND-1, LOGIC-FRONTEND-2
542
-
543
- 2. **ORDERING:**
544
- - LOGIC tickets MUST be feature-by-feature, NOT grouped by type!
545
- - โŒ WRONG: BACKEND-1, BACKEND-2, BACKEND-3, FRONTEND-1, FRONTEND-2, FRONTEND-3
546
- - โœ… CORRECT: BACKEND-1, FRONTEND-1, TEST-1, BACKEND-2, FRONTEND-2, TEST-2
547
-
548
- Begin now:
549
- 1. Read seed files to discover test users
550
- 2. Explore project directory structure
551
- 3. Generate ALL tickets with CORRECT ID format ({BATCH}-{TYPE}-{NUMBER})
552
- 4. Follow STRICT feature-by-feature ordering (NEVER group by type!)`;
553
- }
554
- /**
555
- * Core tickets logic - Streaming version (exported for programmatic use)
556
- */
557
- export async function* ticketsCoreStream(options) {
558
- const { directory, scaffold = false } = options;
559
- const isScaffoldMode = scaffold;
560
- try {
561
- // 1. Validate and resolve project directory
562
- const projectPath = directory ? resolve(directory) : process.cwd();
563
- if (!existsSync(projectPath)) {
564
- yield {
565
- type: 'done',
566
- data: {
567
- status: 'error',
568
- ticketsFile: null,
569
- totalTickets: 0,
570
- tokensUsed: { input: 0, output: 0, cacheCreation: 0, cacheRead: 0 },
571
- cost: 0,
572
- error: `Directory not found: ${projectPath}\nPlease provide a valid directory using --directory=<path>\nExample: kosuke tickets --directory=./my-project`,
573
- },
574
- };
575
- return;
576
- }
577
- const stats = statSync(projectPath);
578
- if (!stats.isDirectory()) {
579
- yield {
580
- type: 'done',
581
- data: {
582
- status: 'error',
583
- ticketsFile: null,
584
- totalTickets: 0,
585
- tokensUsed: { input: 0, output: 0, cacheCreation: 0, cacheRead: 0 },
586
- cost: 0,
587
- error: `Path is not a directory: ${projectPath}\nPlease provide a valid directory path.`,
588
- },
589
- };
590
- return;
591
- }
592
- // 2. Get requirements content from file
593
- let requirementsContent;
594
- if (options.path) {
595
- const requirementsPath = join(projectPath, options.path);
596
- if (!existsSync(requirementsPath)) {
597
- yield {
598
- type: 'done',
599
- data: {
600
- status: 'error',
601
- ticketsFile: null,
602
- totalTickets: 0,
603
- tokensUsed: { input: 0, output: 0, cacheCreation: 0, cacheRead: 0 },
604
- cost: 0,
605
- error: `Requirements document not found: ${options.path}\nPlease provide a valid path using --path=<file>\nExample: kosuke tickets --path=requirements.md`,
606
- },
607
- };
608
- return;
609
- }
610
- requirementsContent = readFileSync(requirementsPath, 'utf-8');
611
- }
612
- else {
613
- // Default to docs.md if path not provided
614
- const defaultPath = 'docs.md';
615
- const requirementsPath = join(projectPath, defaultPath);
616
- if (!existsSync(requirementsPath)) {
617
- yield {
618
- type: 'done',
619
- data: {
620
- status: 'error',
621
- ticketsFile: null,
622
- totalTickets: 0,
623
- tokensUsed: { input: 0, output: 0, cacheCreation: 0, cacheRead: 0 },
624
- cost: 0,
625
- error: 'Requirements document not found. Use either:\n --path=requirements.md (custom file)\n Or create a docs.md file in the project directory\n\nFor interactive ticket creation with questions, use:\n kosuke plan --prompt="Your feature description"',
626
- },
627
- };
628
- return;
629
- }
630
- requirementsContent = readFileSync(requirementsPath, 'utf-8');
631
- }
632
- // 3. Determine output path
633
- const outputFilename = options.output || 'tickets.json';
634
- const outputPath = join(projectPath, outputFilename);
635
- // 4. Generate ALL tickets in a single comprehensive agent call
636
- const systemPrompt = buildTicketPrompt(requirementsContent, projectPath, isScaffoldMode, options.noTest ?? false);
637
- const stream = runAgentStream('Generate all tickets from requirements', {
638
- systemPrompt,
639
- cwd: projectPath,
640
- maxTurns: 40,
641
- verbosity: 'normal',
642
- captureConversation: true,
643
- });
644
- let fullResponse = '';
645
- let tokensUsed = { input: 0, output: 0, cacheCreation: 0, cacheRead: 0 };
646
- let cost = 0;
647
- // Yield events from stream
648
- for await (const event of stream) {
649
- if (event.type === 'message') {
650
- yield { type: 'message', data: event.data };
651
- // Accumulate response text
652
- const claudeMessage = event.data;
653
- if (claudeMessage.type === 'assistant' && claudeMessage.message) {
654
- const msg = claudeMessage.message;
655
- if (msg.content && Array.isArray(msg.content)) {
656
- for (const block of msg.content) {
657
- if (block.type === 'text' && block.text) {
658
- fullResponse += block.text;
659
- }
660
- else if (block.type === 'tool_use' && block.name) {
661
- yield {
662
- type: 'tool_call',
663
- data: { name: block.name, input: block.input || {} },
664
- };
665
- }
666
- }
667
- }
668
- }
669
- }
670
- else if (event.type === 'agent_result') {
671
- tokensUsed = event.data.tokensUsed;
672
- cost = event.data.cost;
673
- }
674
- }
675
- // 5. Extract JSON from response (simple extraction)
676
- let tickets = extractTicketsJSON(fullResponse);
677
- // 6. If extraction failed, try to fix via Claude using fix stream
678
- if (!tickets) {
679
- // Write raw response to temporary file for fixing
680
- const tempRawPath = outputPath.replace('.json', '.raw.txt');
681
- writeFileSync(tempRawPath, fullResponse, 'utf-8');
682
- try {
683
- const fixStream = fixCoreStream({
684
- format: 'json',
685
- file: tempRawPath,
686
- output: outputPath,
687
- directory: projectPath,
688
- noLogs: true,
689
- });
690
- let fixResult = null;
691
- for await (const event of fixStream) {
692
- if (event.type === 'done') {
693
- fixResult = event.data;
694
- }
695
- }
696
- if (!fixResult || fixResult.status === 'error') {
697
- yield {
698
- type: 'done',
699
- data: {
700
- status: 'error',
701
- ticketsFile: null,
702
- totalTickets: 0,
703
- tokensUsed,
704
- cost,
705
- error: fixResult?.error || 'Failed to fix JSON extraction',
706
- },
707
- };
708
- return;
709
- }
710
- // Load tickets from file (fix wrote them)
711
- const fixedData = loadTicketsFile(outputPath);
712
- tickets = fixedData.tickets;
713
- }
714
- finally {
715
- // Clean up temporary file
716
- const { unlinkSync } = await import('fs');
717
- if (existsSync(tempRawPath)) {
718
- unlinkSync(tempRawPath);
719
- }
720
- }
721
- }
722
- else {
723
- // 7. Write raw tickets to file (before validation)
724
- writeTicketsFile(outputPath, tickets);
725
- }
726
- // 8. Validate tickets file using validate-tickets stream
727
- const validateStream = validateTicketsCoreStream({
728
- tickets: outputPath,
729
- directory: projectPath,
730
- strict: false,
731
- noLogs: false,
732
- });
733
- let validateResult = null;
734
- for await (const event of validateStream) {
735
- if (event.type === 'done') {
736
- validateResult = event.data;
737
- }
738
- }
739
- if (!validateResult || validateResult.status === 'error') {
740
- yield {
741
- type: 'done',
742
- data: {
743
- status: 'error',
744
- ticketsFile: outputPath,
745
- totalTickets: tickets?.length || 0,
746
- tokensUsed,
747
- cost,
748
- error: validateResult?.error || 'Validation failed',
749
- },
750
- };
751
- return;
752
- }
753
- // 9. Load validated tickets
754
- const ticketsData = loadTicketsFile(outputPath);
755
- const allTickets = ticketsData.tickets;
756
- yield {
757
- type: 'done',
758
- data: {
759
- status: 'success',
760
- ticketsFile: outputPath,
761
- totalTickets: allTickets.length,
762
- tokensUsed,
763
- cost,
764
- },
765
- };
766
- }
767
- catch (error) {
768
- yield {
769
- type: 'done',
770
- data: {
771
- status: 'error',
772
- ticketsFile: null,
773
- totalTickets: 0,
774
- tokensUsed: { input: 0, output: 0, cacheCreation: 0, cacheRead: 0 },
775
- cost: 0,
776
- error: error instanceof Error ? error.message : String(error),
777
- },
778
- };
779
- }
780
- }
781
- /**
782
- * Main tickets command
783
- */
784
- export async function ticketsCommand(options) {
785
- const { noLogs = false, directory, scaffold = false } = options;
786
- console.log('๐ŸŽซ Starting Ticket Generation...\n');
787
- // Initialize logging context
788
- const logContext = logger.createContext('tickets', { noLogs });
789
- const cleanupHandler = setupCancellationHandler(logContext);
790
- try {
791
- // Validate environment
792
- if (!process.env.ANTHROPIC_API_KEY) {
793
- throw new Error('ANTHROPIC_API_KEY environment variable is required');
794
- }
795
- // Resolve paths for display
796
- const projectPath = directory ? resolve(directory) : process.cwd();
797
- const isScaffoldMode = scaffold;
798
- console.log(`๐Ÿ“ Using project directory: ${projectPath}`);
799
- console.log(`๐Ÿ—๏ธ Mode: ${isScaffoldMode ? 'Scaffold (template adaptation + business logic)' : 'Logic-only (business features)'}\n`);
800
- // Get requirements path for display
801
- const requirementsPath = options.path
802
- ? join(projectPath, options.path)
803
- : join(projectPath, 'docs.md');
804
- if (existsSync(requirementsPath)) {
805
- const requirementsContent = readFileSync(requirementsPath, 'utf-8');
806
- console.log(`๐Ÿ“„ Loaded ${options.path || 'docs.md'} (${requirementsContent.length} characters)\n`);
807
- }
808
- console.log(`\n${'='.repeat(80)}`);
809
- console.log('๐ŸŽฏ Generating Tickets with Claude Code Agent');
810
- console.log(`${'='.repeat(80)}\n`);
811
- // Consume stream
812
- const stream = ticketsCoreStream(options);
813
- let finalResult = null;
814
- for await (const event of stream) {
815
- if (event.type === 'done') {
816
- finalResult = event.data;
817
- }
818
- // Messages are already logged by runAgentStream with verbosity
819
- }
820
- if (!finalResult || finalResult.status === 'error') {
821
- throw new Error(finalResult?.error || 'Unknown error during ticket generation');
822
- }
823
- // Now TypeScript knows finalResult.status === 'success'
824
- const { ticketsFile, totalTickets, tokensUsed, cost } = finalResult;
825
- // Track metrics
826
- logger.trackTokens(logContext, tokensUsed);
827
- // Load and display tickets summary
828
- const ticketsData = loadTicketsFile(ticketsFile);
829
- const allTickets = ticketsData.tickets;
830
- displayTicketsSummary(allTickets);
831
- // Get all tickets by batch (scaffold vs logic)
832
- const scaffoldTickets = allTickets.filter((t) => t.id.toUpperCase().startsWith('SCAFFOLD-'));
833
- const logicTickets = allTickets.filter((t) => t.id.toUpperCase().startsWith('LOGIC-'));
834
- // Display summary
835
- console.log(`\n${'='.repeat(80)}`);
836
- console.log('๐Ÿ“Š Ticket Generation Summary');
837
- console.log(`${'='.repeat(80)}`);
838
- if (scaffoldTickets.length > 0) {
839
- console.log(`\n๐Ÿ—๏ธ Scaffold Tickets (Template Adaptation): ${scaffoldTickets.length}`);
840
- console.log(` ๐Ÿ—„๏ธ Schema: ${scaffoldTickets.filter((t) => t.type === 'schema').length} (auto-validated)`);
841
- console.log(` ๐Ÿ”„ Refactor: ${scaffoldTickets.filter((t) => t.type === 'refactor').length} (backend + frontend)`);
842
- console.log(` ๐Ÿงช Tests: ${scaffoldTickets.filter((t) => t.type === 'test').length}`);
843
- }
844
- console.log(`\n๐Ÿ’ก Logic Tickets (Business Functionality): ${logicTickets.length}`);
845
- console.log(` ๐Ÿ—„๏ธ Schema: ${logicTickets.filter((t) => t.type === 'schema').length} (auto-validated)`);
846
- console.log(` ๐Ÿ Engine: ${logicTickets.filter((t) => t.type === 'engine').length}`);
847
- console.log(` โš™๏ธ Backend: ${logicTickets.filter((t) => t.type === 'backend').length}`);
848
- console.log(` ๐ŸŽจ Frontend: ${logicTickets.filter((t) => t.type === 'frontend').length}`);
849
- console.log(` ๐Ÿงช Tests: ${logicTickets.filter((t) => t.type === 'test').length}`);
850
- console.log(`\n๐Ÿ“ Total Tickets: ${totalTickets}`);
851
- console.log(`${'='.repeat(80)}\n`);
852
- // Display cost breakdown
853
- const costBreakdown = formatCostBreakdown({
854
- cost,
855
- tokensUsed,
856
- fixCount: 0,
857
- response: '',
858
- filesReferenced: new Set(),
859
- });
860
- console.log(`๐Ÿ’ฐ Total Cost: ${costBreakdown}\n`);
861
- // Final confirmation
862
- console.log(`โœ… All tickets saved to: ${ticketsFile}\n`);
863
- console.log('โœ… Ticket generation completed successfully!');
864
- // Log successful execution
865
- await logger.complete(logContext, 'success');
866
- cleanupHandler();
867
- }
868
- catch (error) {
869
- console.error('\nโŒ Ticket generation failed:', error);
870
- // Log failed execution
871
- await logger.complete(logContext, 'error', error);
872
- cleanupHandler();
873
- throw error;
874
- }
875
- }
876
- //# sourceMappingURL=tickets.js.map