@hustle-together/api-dev-tools 3.11.1 → 3.12.2

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 (139) hide show
  1. package/.claude/agents/code-reviewer.md +170 -0
  2. package/.claude/agents/docs-generator.md +80 -0
  3. package/.claude/agents/implementation-reviewer.md +119 -0
  4. package/.claude/agents/parallel-researcher.md +52 -0
  5. package/.claude/agents/research-validator.md +116 -0
  6. package/.claude/agents/schema-generator.md +70 -0
  7. package/.claude/agents/test-writer.md +104 -0
  8. package/.claude/api-dev-state.json +305 -56
  9. package/.claude/commands/README.md +21 -10
  10. package/.claude/commands/add-command.md +8 -5
  11. package/.claude/commands/api-create.md +36 -25
  12. package/.claude/commands/api-env.md +1 -0
  13. package/.claude/commands/api-interview.md +32 -19
  14. package/.claude/commands/api-research.md +47 -21
  15. package/.claude/commands/api-status.md +21 -1
  16. package/.claude/commands/api-verify.md +14 -13
  17. package/.claude/commands/beepboop.md +4 -5
  18. package/.claude/commands/busycommit.md +2 -3
  19. package/.claude/commands/commit.md +2 -3
  20. package/.claude/commands/cycle.md +2 -7
  21. package/.claude/commands/gap.md +2 -3
  22. package/.claude/commands/green.md +2 -7
  23. package/.claude/commands/issue.md +3 -8
  24. package/.claude/commands/ntfy-setup.md +91 -0
  25. package/.claude/commands/ntfy-test.md +74 -0
  26. package/.claude/commands/plan.md +2 -3
  27. package/.claude/commands/pr.md +2 -3
  28. package/.claude/commands/publish.md +40 -0
  29. package/.claude/commands/red.md +2 -7
  30. package/.claude/commands/refactor.md +2 -7
  31. package/.claude/commands/spike.md +2 -7
  32. package/.claude/commands/summarize.md +2 -3
  33. package/.claude/commands/tdd.md +2 -7
  34. package/.claude/commands/worktree-add.md +208 -216
  35. package/.claude/commands/worktree-cleanup.md +172 -178
  36. package/.claude/settings.json +63 -12
  37. package/.claude/settings.local.json +2 -1
  38. package/.claude-plugin/marketplace.json +2 -11
  39. package/.skills/README.md +55 -53
  40. package/.skills/_shared/settings.json +1 -1
  41. package/.skills/add-command/SKILL.md +10 -5
  42. package/.skills/api-create/SKILL.md +146 -35
  43. package/.skills/api-env/SKILL.md +1 -0
  44. package/.skills/api-interview/SKILL.md +32 -19
  45. package/.skills/api-research/SKILL.md +47 -21
  46. package/.skills/api-status/SKILL.md +21 -1
  47. package/.skills/api-verify/SKILL.md +14 -13
  48. package/.skills/beepboop/SKILL.md +6 -5
  49. package/.skills/busycommit/SKILL.md +4 -3
  50. package/.skills/commit/SKILL.md +4 -3
  51. package/.skills/cycle/SKILL.md +4 -7
  52. package/.skills/gap/SKILL.md +4 -3
  53. package/.skills/green/SKILL.md +4 -7
  54. package/.skills/issue/SKILL.md +5 -8
  55. package/.skills/plan/SKILL.md +4 -3
  56. package/.skills/pr/SKILL.md +4 -3
  57. package/.skills/publish/SKILL.md +160 -0
  58. package/.skills/red/SKILL.md +4 -7
  59. package/.skills/refactor/SKILL.md +4 -7
  60. package/.skills/spike/SKILL.md +4 -7
  61. package/.skills/summarize/SKILL.md +4 -3
  62. package/.skills/tdd/SKILL.md +4 -7
  63. package/.skills/update-todos/SKILL.md +22 -0
  64. package/.skills/worktree-add/SKILL.md +210 -216
  65. package/.skills/worktree-cleanup/SKILL.md +183 -187
  66. package/CHANGELOG.md +97 -79
  67. package/README.md +161 -7142
  68. package/bin/cli.js +448 -805
  69. package/commands/README.md +66 -31
  70. package/commands/add-command.md +8 -5
  71. package/commands/beepboop.md +4 -5
  72. package/commands/busycommit.md +2 -3
  73. package/commands/commit.md +2 -3
  74. package/commands/cycle.md +2 -7
  75. package/commands/gap.md +2 -3
  76. package/commands/green.md +2 -7
  77. package/commands/hustle-api-continue.md +8 -5
  78. package/commands/hustle-api-create.md +70 -29
  79. package/commands/hustle-api-env.md +1 -0
  80. package/commands/hustle-api-interview.md +32 -19
  81. package/commands/hustle-api-research.md +47 -21
  82. package/commands/hustle-api-sessions.md +8 -7
  83. package/commands/hustle-api-status.md +21 -1
  84. package/commands/hustle-api-verify.md +14 -13
  85. package/commands/hustle-combine.md +488 -241
  86. package/commands/hustle-ui-create-page.md +113 -50
  87. package/commands/hustle-ui-create.md +179 -26
  88. package/commands/issue.md +3 -8
  89. package/commands/plan.md +2 -3
  90. package/commands/pr.md +2 -3
  91. package/commands/red.md +2 -7
  92. package/commands/refactor.md +2 -7
  93. package/commands/spike.md +2 -7
  94. package/commands/summarize.md +2 -3
  95. package/commands/tdd.md +2 -7
  96. package/commands/worktree-add.md +208 -216
  97. package/commands/worktree-cleanup.md +172 -178
  98. package/hooks/api-workflow-check.py +5 -3
  99. package/hooks/enforce-component-type-confirm.py +97 -0
  100. package/hooks/lib/__init__.py +1 -0
  101. package/hooks/lib/greptile.py +355 -0
  102. package/hooks/lib/ntfy.py +209 -0
  103. package/hooks/notify-input-needed.py +73 -0
  104. package/hooks/notify-phase-complete.py +90 -0
  105. package/hooks/run-code-review.py +246 -0
  106. package/hooks/track-token-usage.py +121 -0
  107. package/package.json +13 -3
  108. package/scripts/collect-test-results.ts +102 -77
  109. package/scripts/extract-parameters.ts +112 -70
  110. package/scripts/generate-test-manifest.ts +118 -77
  111. package/templates/.env.example +57 -0
  112. package/templates/BRAND_GUIDE.md +92 -52
  113. package/templates/CLAUDE-SECTION.md +40 -37
  114. package/templates/SPEC.json +186 -38
  115. package/templates/api-dev-state.json +33 -4
  116. package/templates/api-showcase/_components/APICard.tsx +22 -18
  117. package/templates/api-showcase/_components/APIModal.tsx +110 -64
  118. package/templates/api-showcase/_components/APIShowcase.tsx +53 -35
  119. package/templates/api-showcase/_components/APITester.tsx +128 -67
  120. package/templates/api-showcase/page.tsx +4 -4
  121. package/templates/api-test/page.tsx +51 -30
  122. package/templates/api-test/test-structure/route.ts +43 -34
  123. package/templates/component/Component.stories.tsx +41 -39
  124. package/templates/component/Component.test.tsx +96 -78
  125. package/templates/component/Component.tsx +63 -52
  126. package/templates/component/Component.types.ts +10 -6
  127. package/templates/component/Component.visual.spec.ts +170 -0
  128. package/templates/component/index.ts +2 -2
  129. package/templates/dev-tools/_components/DevToolsLanding.tsx +8 -8
  130. package/templates/dev-tools/page.tsx +4 -3
  131. package/templates/mcp-servers.json +30 -2
  132. package/templates/page/page.e2e.test.ts +56 -48
  133. package/templates/page/page.tsx +3 -3
  134. package/templates/shared/HeroHeader.tsx +16 -15
  135. package/templates/shared/index.ts +1 -1
  136. package/templates/ui-showcase/_components/PreviewCard.tsx +20 -20
  137. package/templates/ui-showcase/_components/PreviewModal.tsx +149 -108
  138. package/templates/ui-showcase/_components/UIShowcase.tsx +43 -35
  139. package/templates/ui-showcase/page.tsx +4 -4
@@ -1,4 +1,4 @@
1
- # Hustle Combine - API and UI Orchestration Workflow v3.8.0
1
+ # Hustle Combine - API and UI Orchestration Workflow v3.11.0
2
2
 
3
3
  **Usage:** `/hustle-combine [api|ui]`
4
4
 
@@ -17,6 +17,7 @@ This command reads from `.claude/registry.json` to present available elements fo
17
17
  **YOU MUST USE THE `AskUserQuestion` TOOL AT EVERY CHECKPOINT.**
18
18
 
19
19
  This workflow requires REAL user input at each phase. You are **FORBIDDEN** from:
20
+
20
21
  - Self-answering questions
21
22
  - Assuming user responses
22
23
  - Proceeding without explicit user confirmation
@@ -34,9 +35,9 @@ At every prompt in this workflow, you MUST call the `AskUserQuestion` tool with
34
35
  "header": "Phase",
35
36
  "multiSelect": false,
36
37
  "options": [
37
- {"label": "Option A", "description": "What this option means"},
38
- {"label": "Option B", "description": "What this option means"},
39
- {"label": "Other", "description": "I'll type my own answer"}
38
+ { "label": "Option A", "description": "What this option means" },
39
+ { "label": "Option B", "description": "What this option means" },
40
+ { "label": "Other", "description": "I'll type my own answer" }
40
41
  ]
41
42
  }
42
43
  ]
@@ -44,6 +45,7 @@ At every prompt in this workflow, you MUST call the `AskUserQuestion` tool with
44
45
  ```
45
46
 
46
47
  **CRITICAL REQUIREMENTS:**
48
+
47
49
  - `header`: Max 12 characters (e.g., "Mode", "Select", "Order")
48
50
  - `options`: 2-4 options, each with `label` (1-5 words) and `description`
49
51
  - `multiSelect`: Required boolean (true for checkboxes, false for radio)
@@ -56,17 +58,23 @@ At every prompt in this workflow, you MUST call the `AskUserQuestion` tool with
56
58
  **Every phase requires an EXIT CONFIRMATION question** before proceeding to the next phase.
57
59
 
58
60
  Example:
61
+
59
62
  ```json
60
63
  {
61
- "questions": [{
62
- "question": "Phase complete. Ready to proceed to next phase?",
63
- "header": "Proceed",
64
- "multiSelect": false,
65
- "options": [
66
- {"label": "Yes, proceed", "description": "Move to next phase"},
67
- {"label": "No, make changes", "description": "I need to modify something"}
68
- ]
69
- }]
64
+ "questions": [
65
+ {
66
+ "question": "Phase complete. Ready to proceed to next phase?",
67
+ "header": "Proceed",
68
+ "multiSelect": false,
69
+ "options": [
70
+ { "label": "Yes, proceed", "description": "Move to next phase" },
71
+ {
72
+ "label": "No, make changes",
73
+ "description": "I need to modify something"
74
+ }
75
+ ]
76
+ }
77
+ ]
70
78
  }
71
79
  ```
72
80
 
@@ -77,17 +85,26 @@ Example:
77
85
  When running `/hustle-combine`, first determine the mode:
78
86
 
79
87
  Use AskUserQuestion:
88
+
80
89
  ```json
81
90
  {
82
- "questions": [{
83
- "question": "What would you like to combine?",
84
- "header": "Mode",
85
- "multiSelect": false,
86
- "options": [
87
- {"label": "APIs", "description": "Combine existing API endpoints into orchestration layer"},
88
- {"label": "UI", "description": "Combine existing components/pages (coming soon)"}
89
- ]
90
- }]
91
+ "questions": [
92
+ {
93
+ "question": "What would you like to combine?",
94
+ "header": "Mode",
95
+ "multiSelect": false,
96
+ "options": [
97
+ {
98
+ "label": "APIs",
99
+ "description": "Combine existing API endpoints into orchestration layer"
100
+ },
101
+ {
102
+ "label": "UI",
103
+ "description": "Combine existing components/pages (coming soon)"
104
+ }
105
+ ]
106
+ }
107
+ ]
91
108
  }
92
109
  ```
93
110
 
@@ -95,7 +112,7 @@ Use AskUserQuestion:
95
112
 
96
113
  ## Mode A: Combine APIs
97
114
 
98
- ### 13 Phases for API Combination
115
+ ### 14 Phases for API Combination
99
116
 
100
117
  ```
101
118
  Phase 1: SELECTION - Present checkboxes from registry, user selects 2+ APIs
@@ -108,9 +125,10 @@ Phase 7: ENVIRONMENT - Verify all required API keys exist
108
125
  Phase 8: TDD RED - Integration tests for combined flow
109
126
  Phase 9: TDD GREEN - Orchestration route implementation
110
127
  Phase 10: VERIFY - Full flow works end-to-end
111
- Phase 11: REFACTOR - Clean up, optimize
112
- Phase 12: DOCUMENTATION - Update manifest, document combined endpoint
113
- Phase 13: COMPLETE - Update registry with new combined API
128
+ Phase 11: CODE REVIEW - Greptile AI review for bugs, security, performance
129
+ Phase 12: REFACTOR - Fix review issues + clean up, optimize
130
+ Phase 13: DOCUMENTATION - Update manifest, document combined endpoint
131
+ Phase 14: COMPLETE - Update registry with new combined API
114
132
  ```
115
133
 
116
134
  ---
@@ -122,20 +140,27 @@ Read `.claude/registry.json` and present available APIs.
122
140
  **IMPORTANT:** Options are dynamically generated from registry.json. Only show APIs with `status: "complete"`.
123
141
 
124
142
  Use AskUserQuestion with multiSelect:
143
+
125
144
  ```json
126
145
  {
127
- "questions": [{
128
- "question": "Select APIs to combine (choose 2 or more):",
129
- "header": "Select",
130
- "multiSelect": true,
131
- "options": [
132
- {"label": "[api-name]", "description": "[api-description from registry]"}
133
- ]
134
- }]
146
+ "questions": [
147
+ {
148
+ "question": "Select APIs to combine (choose 2 or more):",
149
+ "header": "Select",
150
+ "multiSelect": true,
151
+ "options": [
152
+ {
153
+ "label": "[api-name]",
154
+ "description": "[api-description from registry]"
155
+ }
156
+ ]
157
+ }
158
+ ]
135
159
  }
136
160
  ```
137
161
 
138
162
  **After selection, store in state:**
163
+
139
164
  ```json
140
165
  {
141
166
  "workflow": "combine-api",
@@ -150,17 +175,23 @@ Use AskUserQuestion with multiSelect:
150
175
  ```
151
176
 
152
177
  **Phase Exit:**
178
+
153
179
  ```json
154
180
  {
155
- "questions": [{
156
- "question": "Selected [N] APIs. Ready to define the purpose?",
157
- "header": "Proceed",
158
- "multiSelect": false,
159
- "options": [
160
- {"label": "Yes, proceed", "description": "Move to Scope phase"},
161
- {"label": "Change selection", "description": "I want to select different APIs"}
162
- ]
163
- }]
181
+ "questions": [
182
+ {
183
+ "question": "Selected [N] APIs. Ready to define the purpose?",
184
+ "header": "Proceed",
185
+ "multiSelect": false,
186
+ "options": [
187
+ { "label": "Yes, proceed", "description": "Move to Scope phase" },
188
+ {
189
+ "label": "Change selection",
190
+ "description": "I want to select different APIs"
191
+ }
192
+ ]
193
+ }
194
+ ]
164
195
  }
165
196
  ```
166
197
 
@@ -172,31 +203,39 @@ Ask what the combined endpoint should do:
172
203
 
173
204
  ```json
174
205
  {
175
- "questions": [{
176
- "question": "What should this combined endpoint do? Describe the purpose:",
177
- "header": "Purpose",
178
- "multiSelect": false,
179
- "options": [
180
- {"label": "Describe it", "description": "I'll type the purpose"}
181
- ]
182
- }]
206
+ "questions": [
207
+ {
208
+ "question": "What should this combined endpoint do? Describe the purpose:",
209
+ "header": "Purpose",
210
+ "multiSelect": false,
211
+ "options": [
212
+ { "label": "Describe it", "description": "I'll type the purpose" }
213
+ ]
214
+ }
215
+ ]
183
216
  }
184
217
  ```
185
218
 
186
219
  Store the purpose in state for later use in schema and tests.
187
220
 
188
221
  **Phase Exit:**
222
+
189
223
  ```json
190
224
  {
191
- "questions": [{
192
- "question": "Purpose defined. Ready to research orchestration patterns?",
193
- "header": "Proceed",
194
- "multiSelect": false,
195
- "options": [
196
- {"label": "Yes, proceed", "description": "Move to Research phase"},
197
- {"label": "Refine purpose", "description": "I want to clarify the purpose"}
198
- ]
199
- }]
225
+ "questions": [
226
+ {
227
+ "question": "Purpose defined. Ready to research orchestration patterns?",
228
+ "header": "Proceed",
229
+ "multiSelect": false,
230
+ "options": [
231
+ { "label": "Yes, proceed", "description": "Move to Research phase" },
232
+ {
233
+ "label": "Refine purpose",
234
+ "description": "I want to clarify the purpose"
235
+ }
236
+ ]
237
+ }
238
+ ]
200
239
  }
201
240
  ```
202
241
 
@@ -205,41 +244,57 @@ Store the purpose in state for later use in schema and tests.
205
244
  ### Phase 3: INITIAL RESEARCH (Lighter)
206
245
 
207
246
  Since APIs already exist, focus ONLY on orchestration patterns:
247
+
208
248
  - Gateway aggregation patterns
209
249
  - Error propagation between services
210
250
  - Response composition strategies
211
251
 
212
252
  ```json
213
253
  {
214
- "questions": [{
215
- "question": "Research focus: I'll look up orchestration patterns for combining [API1] + [API2]. Proceed?",
216
- "header": "Research",
217
- "multiSelect": false,
218
- "options": [
219
- {"label": "Yes, proceed", "description": "Research orchestration patterns"},
220
- {"label": "Skip research", "description": "I know how I want to combine them"}
221
- ]
222
- }]
254
+ "questions": [
255
+ {
256
+ "question": "Research focus: I'll look up orchestration patterns for combining [API1] + [API2]. Proceed?",
257
+ "header": "Research",
258
+ "multiSelect": false,
259
+ "options": [
260
+ {
261
+ "label": "Yes, proceed",
262
+ "description": "Research orchestration patterns"
263
+ },
264
+ {
265
+ "label": "Skip research",
266
+ "description": "I know how I want to combine them"
267
+ }
268
+ ]
269
+ }
270
+ ]
223
271
  }
224
272
  ```
225
273
 
226
274
  If user chooses to research, use WebSearch and Context7 for:
275
+
227
276
  - "API gateway aggregation patterns"
228
277
  - "Service composition error handling"
229
278
  - "Response aggregation TypeScript patterns"
230
279
 
231
280
  **Phase Exit:**
281
+
232
282
  ```json
233
283
  {
234
- "questions": [{
235
- "question": "Research complete. Ready for interview questions?",
236
- "header": "Proceed",
237
- "multiSelect": false,
238
- "options": [
239
- {"label": "Yes, interview", "description": "Move to Interview phase"},
240
- {"label": "More research", "description": "I need to research [topic]"}
241
- ]
242
- }]
284
+ "questions": [
285
+ {
286
+ "question": "Research complete. Ready for interview questions?",
287
+ "header": "Proceed",
288
+ "multiSelect": false,
289
+ "options": [
290
+ { "label": "Yes, interview", "description": "Move to Interview phase" },
291
+ {
292
+ "label": "More research",
293
+ "description": "I need to research [topic]"
294
+ }
295
+ ]
296
+ }
297
+ ]
243
298
  }
244
299
  ```
245
300
 
@@ -250,84 +305,124 @@ If user chooses to research, use WebSearch and Context7 for:
250
305
  Key questions for API combination (ask one at a time):
251
306
 
252
307
  **Q1: Endpoint Name**
308
+
253
309
  ```json
254
310
  {
255
- "questions": [{
256
- "question": "What should the combined endpoint be called?",
257
- "header": "Name",
258
- "multiSelect": false,
259
- "options": [
260
- {"label": "[suggested-name]", "description": "Suggested: /api/v2/[suggested-name]"},
261
- {"label": "Custom name", "description": "I'll type my own"}
262
- ]
263
- }]
311
+ "questions": [
312
+ {
313
+ "question": "What should the combined endpoint be called?",
314
+ "header": "Name",
315
+ "multiSelect": false,
316
+ "options": [
317
+ {
318
+ "label": "[suggested-name]",
319
+ "description": "Suggested: /api/v2/[suggested-name]"
320
+ },
321
+ { "label": "Custom name", "description": "I'll type my own" }
322
+ ]
323
+ }
324
+ ]
264
325
  }
265
326
  ```
266
327
 
267
328
  **Q2: Execution Order**
329
+
268
330
  ```json
269
331
  {
270
- "questions": [{
271
- "question": "How should the APIs execute?",
272
- "header": "Order",
273
- "multiSelect": false,
274
- "options": [
275
- {"label": "Parallel", "description": "All at once, combine results"},
276
- {"label": "Sequential", "description": "One after another, pass data between"},
277
- {"label": "Conditional", "description": "Second API depends on first result"}
278
- ]
279
- }]
332
+ "questions": [
333
+ {
334
+ "question": "How should the APIs execute?",
335
+ "header": "Order",
336
+ "multiSelect": false,
337
+ "options": [
338
+ { "label": "Parallel", "description": "All at once, combine results" },
339
+ {
340
+ "label": "Sequential",
341
+ "description": "One after another, pass data between"
342
+ },
343
+ {
344
+ "label": "Conditional",
345
+ "description": "Second API depends on first result"
346
+ }
347
+ ]
348
+ }
349
+ ]
280
350
  }
281
351
  ```
282
352
 
283
353
  **Q3: Error Handling**
354
+
284
355
  ```json
285
356
  {
286
- "questions": [{
287
- "question": "If the first API fails, what should happen?",
288
- "header": "Errors",
289
- "multiSelect": false,
290
- "options": [
291
- {"label": "Fail entire request", "description": "Return error, don't call other APIs"},
292
- {"label": "Continue with partial", "description": "Return what succeeded"},
293
- {"label": "Retry once", "description": "Retry failed API, then fail if still failing"}
294
- ]
295
- }]
357
+ "questions": [
358
+ {
359
+ "question": "If the first API fails, what should happen?",
360
+ "header": "Errors",
361
+ "multiSelect": false,
362
+ "options": [
363
+ {
364
+ "label": "Fail entire request",
365
+ "description": "Return error, don't call other APIs"
366
+ },
367
+ {
368
+ "label": "Continue with partial",
369
+ "description": "Return what succeeded"
370
+ },
371
+ {
372
+ "label": "Retry once",
373
+ "description": "Retry failed API, then fail if still failing"
374
+ }
375
+ ]
376
+ }
377
+ ]
296
378
  }
297
379
  ```
298
380
 
299
381
  **Q4: Data Transformation**
382
+
300
383
  ```json
301
384
  {
302
- "questions": [{
303
- "question": "Do you need to transform data between APIs?",
304
- "header": "Transform",
305
- "multiSelect": false,
306
- "options": [
307
- {"label": "No", "description": "Use responses as-is"},
308
- {"label": "Yes", "description": "I'll describe the transformation"}
309
- ]
310
- }]
385
+ "questions": [
386
+ {
387
+ "question": "Do you need to transform data between APIs?",
388
+ "header": "Transform",
389
+ "multiSelect": false,
390
+ "options": [
391
+ { "label": "No", "description": "Use responses as-is" },
392
+ { "label": "Yes", "description": "I'll describe the transformation" }
393
+ ]
394
+ }
395
+ ]
311
396
  }
312
397
  ```
313
398
 
314
399
  **Q5: Caching**
400
+
315
401
  ```json
316
402
  {
317
- "questions": [{
318
- "question": "Caching strategy?",
319
- "header": "Cache",
320
- "multiSelect": false,
321
- "options": [
322
- {"label": "No caching", "description": "Always fetch fresh"},
323
- {"label": "Cache combined result", "description": "Cache the final response"},
324
- {"label": "Cache individual APIs", "description": "Cache each API's response separately"}
325
- ]
326
- }]
403
+ "questions": [
404
+ {
405
+ "question": "Caching strategy?",
406
+ "header": "Cache",
407
+ "multiSelect": false,
408
+ "options": [
409
+ { "label": "No caching", "description": "Always fetch fresh" },
410
+ {
411
+ "label": "Cache combined result",
412
+ "description": "Cache the final response"
413
+ },
414
+ {
415
+ "label": "Cache individual APIs",
416
+ "description": "Cache each API's response separately"
417
+ }
418
+ ]
419
+ }
420
+ ]
327
421
  }
328
422
  ```
329
423
 
330
424
  **Store all decisions in state:**
425
+
331
426
  ```json
332
427
  {
333
428
  "phases": {
@@ -346,17 +441,26 @@ Key questions for API combination (ask one at a time):
346
441
  ```
347
442
 
348
443
  **Phase Exit:**
444
+
349
445
  ```json
350
446
  {
351
- "questions": [{
352
- "question": "Interview complete. Ready for deep research?",
353
- "header": "Proceed",
354
- "multiSelect": false,
355
- "options": [
356
- {"label": "Yes, proceed", "description": "Move to Deep Research phase"},
357
- {"label": "Change answers", "description": "I want to modify my answers"}
358
- ]
359
- }]
447
+ "questions": [
448
+ {
449
+ "question": "Interview complete. Ready for deep research?",
450
+ "header": "Proceed",
451
+ "multiSelect": false,
452
+ "options": [
453
+ {
454
+ "label": "Yes, proceed",
455
+ "description": "Move to Deep Research phase"
456
+ },
457
+ {
458
+ "label": "Change answers",
459
+ "description": "I want to modify my answers"
460
+ }
461
+ ]
462
+ }
463
+ ]
360
464
  }
361
465
  ```
362
466
 
@@ -368,20 +472,26 @@ Based on interview answers, propose targeted research:
368
472
 
369
473
  ```json
370
474
  {
371
- "questions": [{
372
- "question": "Based on your answers, should I research: [specific topics based on interview]?",
373
- "header": "Deep",
374
- "multiSelect": false,
375
- "options": [
376
- {"label": "Yes, research these", "description": "Run the searches"},
377
- {"label": "Add more topics", "description": "I need [something specific]"},
378
- {"label": "Skip to schema", "description": "I have enough info"}
379
- ]
380
- }]
475
+ "questions": [
476
+ {
477
+ "question": "Based on your answers, should I research: [specific topics based on interview]?",
478
+ "header": "Deep",
479
+ "multiSelect": false,
480
+ "options": [
481
+ { "label": "Yes, research these", "description": "Run the searches" },
482
+ {
483
+ "label": "Add more topics",
484
+ "description": "I need [something specific]"
485
+ },
486
+ { "label": "Skip to schema", "description": "I have enough info" }
487
+ ]
488
+ }
489
+ ]
381
490
  }
382
491
  ```
383
492
 
384
493
  Topics to propose based on interview:
494
+
385
495
  - If sequential: "data passing between API calls"
386
496
  - If parallel: "Promise.all error handling patterns"
387
497
  - If retry: "exponential backoff strategies"
@@ -395,9 +505,9 @@ Create Zod schema that COMPOSES existing schemas:
395
505
 
396
506
  ```typescript
397
507
  // src/app/api/v2/[combined-name]/schemas.ts
398
- import { z } from 'zod';
399
- import { Api1ResponseSchema } from '../api1/schemas';
400
- import { Api2ResponseSchema } from '../api2/schemas';
508
+ import { z } from "zod";
509
+ import { Api1ResponseSchema } from "../api1/schemas";
510
+ import { Api2ResponseSchema } from "../api2/schemas";
401
511
 
402
512
  // Combined request schema
403
513
  export const CombinedRequestSchema = z.object({
@@ -416,17 +526,20 @@ export type CombinedResponse = z.infer<typeof CombinedResponseSchema>;
416
526
  ```
417
527
 
418
528
  **Ask for approval:**
529
+
419
530
  ```json
420
531
  {
421
- "questions": [{
422
- "question": "Combined schema created. It imports from [API1] and [API2] schemas. Approve?",
423
- "header": "Schema",
424
- "multiSelect": false,
425
- "options": [
426
- {"label": "Yes, approved", "description": "Schema looks correct"},
427
- {"label": "Make changes", "description": "I need to modify something"}
428
- ]
429
- }]
532
+ "questions": [
533
+ {
534
+ "question": "Combined schema created. It imports from [API1] and [API2] schemas. Approve?",
535
+ "header": "Schema",
536
+ "multiSelect": false,
537
+ "options": [
538
+ { "label": "Yes, approved", "description": "Schema looks correct" },
539
+ { "label": "Make changes", "description": "I need to modify something" }
540
+ ]
541
+ }
542
+ ]
430
543
  }
431
544
  ```
432
545
 
@@ -439,6 +552,7 @@ Verify all API keys from combined APIs are available.
439
552
  Read the source API entries in registry.json to determine required environment variables.
440
553
 
441
554
  Report:
555
+
442
556
  ```
443
557
  Environment Check:
444
558
  [checkmark] API1_KEY - Found
@@ -449,15 +563,20 @@ All required keys available.
449
563
 
450
564
  ```json
451
565
  {
452
- "questions": [{
453
- "question": "Environment check passed. All [N] API keys found. Ready for TDD?",
454
- "header": "Env",
455
- "multiSelect": false,
456
- "options": [
457
- {"label": "Yes, write tests", "description": "Proceed to TDD Red"},
458
- {"label": "No, need setup", "description": "I need to configure something"}
459
- ]
460
- }]
566
+ "questions": [
567
+ {
568
+ "question": "Environment check passed. All [N] API keys found. Ready for TDD?",
569
+ "header": "Env",
570
+ "multiSelect": false,
571
+ "options": [
572
+ { "label": "Yes, write tests", "description": "Proceed to TDD Red" },
573
+ {
574
+ "label": "No, need setup",
575
+ "description": "I need to configure something"
576
+ }
577
+ ]
578
+ }
579
+ ]
461
580
  }
462
581
  ```
463
582
 
@@ -469,15 +588,15 @@ Write tests for the combined flow:
469
588
 
470
589
  ```typescript
471
590
  // src/app/api/v2/[combined-name]/__tests__/[combined-name].api.test.ts
472
- import { describe, it, expect, vi, beforeEach } from 'vitest';
591
+ import { describe, it, expect, vi, beforeEach } from "vitest";
473
592
 
474
- describe('[Combined Name] API', () => {
475
- describe('POST /api/v2/[combined-name]', () => {
476
- it('should call both APIs and combine results', async () => {
593
+ describe("[Combined Name] API", () => {
594
+ describe("POST /api/v2/[combined-name]", () => {
595
+ it("should call both APIs and combine results", async () => {
477
596
  // Test combined flow
478
597
  });
479
598
 
480
- it('should handle first API failure correctly', async () => {
599
+ it("should handle first API failure correctly", async () => {
481
600
  // Test error handling based on interview decisions
482
601
  });
483
602
 
@@ -489,17 +608,23 @@ describe('[Combined Name] API', () => {
489
608
  Run tests - they should FAIL (Red phase).
490
609
 
491
610
  **Phase Exit:**
611
+
492
612
  ```json
493
613
  {
494
- "questions": [{
495
- "question": "Failing tests written. Ready to implement?",
496
- "header": "Proceed",
497
- "multiSelect": false,
498
- "options": [
499
- {"label": "Yes, implement", "description": "Move to TDD Green phase"},
500
- {"label": "Add more tests", "description": "I need to test more scenarios"}
501
- ]
502
- }]
614
+ "questions": [
615
+ {
616
+ "question": "Failing tests written. Ready to implement?",
617
+ "header": "Proceed",
618
+ "multiSelect": false,
619
+ "options": [
620
+ { "label": "Yes, implement", "description": "Move to TDD Green phase" },
621
+ {
622
+ "label": "Add more tests",
623
+ "description": "I need to test more scenarios"
624
+ }
625
+ ]
626
+ }
627
+ ]
503
628
  }
504
629
  ```
505
630
 
@@ -511,8 +636,8 @@ Implement the orchestration logic:
511
636
 
512
637
  ```typescript
513
638
  // src/app/api/v2/[combined-name]/route.ts
514
- import { NextRequest, NextResponse } from 'next/server';
515
- import { CombinedRequestSchema } from './schemas';
639
+ import { NextRequest, NextResponse } from "next/server";
640
+ import { CombinedRequestSchema } from "./schemas";
516
641
 
517
642
  export async function POST(request: NextRequest) {
518
643
  try {
@@ -530,10 +655,7 @@ export async function POST(request: NextRequest) {
530
655
  combined_at: new Date().toISOString(),
531
656
  });
532
657
  } catch (error) {
533
- return NextResponse.json(
534
- { error: error.message },
535
- { status: 500 }
536
- );
658
+ return NextResponse.json({ error: error.message }, { status: 500 });
537
659
  }
538
660
  }
539
661
  ```
@@ -548,15 +670,23 @@ Test the full flow end-to-end:
548
670
 
549
671
  ```json
550
672
  {
551
- "questions": [{
552
- "question": "Integration tests pass. Should I verify the full flow manually with real API calls?",
553
- "header": "Verify",
554
- "multiSelect": false,
555
- "options": [
556
- {"label": "Yes, test real flow", "description": "Make actual API calls"},
557
- {"label": "Skip, tests sufficient", "description": "Proceed to refactor"}
558
- ]
559
- }]
673
+ "questions": [
674
+ {
675
+ "question": "Integration tests pass. Should I verify the full flow manually with real API calls?",
676
+ "header": "Verify",
677
+ "multiSelect": false,
678
+ "options": [
679
+ {
680
+ "label": "Yes, test real flow",
681
+ "description": "Make actual API calls"
682
+ },
683
+ {
684
+ "label": "Skip, tests sufficient",
685
+ "description": "Proceed to refactor"
686
+ }
687
+ ]
688
+ }
689
+ ]
560
690
  }
561
691
  ```
562
692
 
@@ -564,9 +694,43 @@ If verifying, make actual requests and report results.
564
694
 
565
695
  ---
566
696
 
567
- ### Phase 11: REFACTOR
697
+ ### Phase 11: CODE REVIEW (Greptile)
698
+
699
+ Run Greptile AI code review before refactoring:
568
700
 
569
- Clean up the orchestration code:
701
+ - Bug detection with full codebase context
702
+ - Security vulnerability scanning (OWASP top 10)
703
+ - Performance issue identification
704
+
705
+ **Requires:** GREPTILE_API_KEY + GITHUB_TOKEN
706
+
707
+ ```json
708
+ {
709
+ "questions": [
710
+ {
711
+ "question": "Code review found [N] issue(s). How should I proceed?",
712
+ "header": "Review",
713
+ "multiSelect": false,
714
+ "options": [
715
+ { "label": "Fix all", "description": "Address all issues in refactor" },
716
+ {
717
+ "label": "Critical only",
718
+ "description": "Fix critical, defer others"
719
+ },
720
+ { "label": "Skip", "description": "No issues to fix" }
721
+ ]
722
+ }
723
+ ]
724
+ }
725
+ ```
726
+
727
+ ---
728
+
729
+ ### Phase 12: REFACTOR
730
+
731
+ Fix review issues + clean up the orchestration code:
732
+
733
+ - Address Greptile issues (bugs, security, performance)
570
734
  - Extract reusable patterns
571
735
  - Add error logging
572
736
  - Optimize parallel calls if applicable
@@ -575,46 +739,61 @@ Clean up the orchestration code:
575
739
  Run tests after each change to ensure they still pass.
576
740
 
577
741
  **Phase Exit:**
742
+
578
743
  ```json
579
744
  {
580
- "questions": [{
581
- "question": "Refactoring complete. Tests still pass. Ready to document?",
582
- "header": "Proceed",
583
- "multiSelect": false,
584
- "options": [
585
- {"label": "Yes, document", "description": "Move to Documentation phase"},
586
- {"label": "More refactoring", "description": "I want to clean up more"}
587
- ]
588
- }]
745
+ "questions": [
746
+ {
747
+ "question": "Refactoring complete. Tests still pass. Ready to document?",
748
+ "header": "Proceed",
749
+ "multiSelect": false,
750
+ "options": [
751
+ {
752
+ "label": "Yes, document",
753
+ "description": "Move to Documentation phase"
754
+ },
755
+ {
756
+ "label": "More refactoring",
757
+ "description": "I want to clean up more"
758
+ }
759
+ ]
760
+ }
761
+ ]
589
762
  }
590
763
  ```
591
764
 
592
765
  ---
593
766
 
594
- ### Phase 12: DOCUMENTATION
767
+ ### Phase 13: DOCUMENTATION
595
768
 
596
769
  Update:
770
+
597
771
  1. `api-tests-manifest.json` - Add new combined endpoint
598
772
  2. `registry.json` - Add to `combined` section
599
773
  3. Any project docs as needed
600
774
 
601
775
  ```json
602
776
  {
603
- "questions": [{
604
- "question": "Documentation updated. Ready to complete?",
605
- "header": "Docs",
606
- "multiSelect": false,
607
- "options": [
608
- {"label": "Yes, complete", "description": "Finalize and update registry"},
609
- {"label": "Need more docs", "description": "I want to add something"}
610
- ]
611
- }]
777
+ "questions": [
778
+ {
779
+ "question": "Documentation updated. Ready to complete?",
780
+ "header": "Docs",
781
+ "multiSelect": false,
782
+ "options": [
783
+ {
784
+ "label": "Yes, complete",
785
+ "description": "Finalize and update registry"
786
+ },
787
+ { "label": "Need more docs", "description": "I want to add something" }
788
+ ]
789
+ }
790
+ ]
612
791
  }
613
792
  ```
614
793
 
615
794
  ---
616
795
 
617
- ### Phase 13: COMPLETION
796
+ ### Phase 14: COMPLETION
618
797
 
619
798
  Update registry.json with the new combined API:
620
799
 
@@ -638,17 +817,23 @@ Update registry.json with the new combined API:
638
817
  ```
639
818
 
640
819
  **Final confirmation:**
820
+
641
821
  ```json
642
822
  {
643
- "questions": [{
644
- "question": "Combined API complete. Registry updated. Anything else?",
645
- "header": "Complete",
646
- "multiSelect": false,
647
- "options": [
648
- {"label": "Done", "description": "Workflow complete"},
649
- {"label": "Create another", "description": "Start new combine workflow"}
650
- ]
651
- }]
823
+ "questions": [
824
+ {
825
+ "question": "Combined API complete. Registry updated. Anything else?",
826
+ "header": "Complete",
827
+ "multiSelect": false,
828
+ "options": [
829
+ { "label": "Done", "description": "Workflow complete" },
830
+ {
831
+ "label": "Create another",
832
+ "description": "Start new combine workflow"
833
+ }
834
+ ]
835
+ }
836
+ ]
652
837
  }
653
838
  ```
654
839
 
@@ -659,6 +844,7 @@ Update registry.json with the new combined API:
659
844
  UI combination requires `/hustle-ui-create` to be implemented first.
660
845
 
661
846
  Three sub-modes planned:
847
+
662
848
  - **A) Composed Component** - Combine existing components
663
849
  - **B) Page with Components** - Create page using components
664
850
  - **C) Page with Components + API** - Create page with data fetching
@@ -669,7 +855,7 @@ Three sub-modes planned:
669
855
 
670
856
  ```json
671
857
  {
672
- "version": "3.8.0",
858
+ "version": "3.11.0",
673
859
  "workflow": "combine-api",
674
860
  "element_name": "brand-voice",
675
861
  "element_type": "combined",
@@ -685,19 +871,79 @@ Three sub-modes planned:
685
871
  },
686
872
 
687
873
  "phases": {
688
- "selection": { "status": "complete", "apis_selected": 2, "user_question_asked": true, "phase_exit_confirmed": true },
689
- "scope": { "status": "complete", "purpose": "...", "user_question_asked": true, "phase_exit_confirmed": true },
690
- "research_initial": { "status": "complete", "user_question_asked": true, "phase_exit_confirmed": true },
691
- "interview": { "status": "complete", "decisions": {}, "user_question_asked": true, "phase_exit_confirmed": true },
692
- "research_deep": { "status": "skipped", "user_question_asked": true, "phase_exit_confirmed": true },
693
- "schema_creation": { "status": "complete", "user_question_asked": true, "phase_exit_confirmed": true },
694
- "environment_check": { "status": "complete", "user_question_asked": true, "phase_exit_confirmed": true },
695
- "tdd_red": { "status": "complete", "user_question_asked": true, "phase_exit_confirmed": true },
696
- "tdd_green": { "status": "complete", "user_question_asked": true, "phase_exit_confirmed": true },
697
- "verify": { "status": "complete", "user_question_asked": true, "phase_exit_confirmed": true },
698
- "tdd_refactor": { "status": "complete", "user_question_asked": true, "phase_exit_confirmed": true },
699
- "documentation": { "status": "complete", "user_question_asked": true, "phase_exit_confirmed": true },
700
- "completion": { "status": "complete", "user_question_asked": true, "phase_exit_confirmed": true }
874
+ "selection": {
875
+ "status": "complete",
876
+ "apis_selected": 2,
877
+ "user_question_asked": true,
878
+ "phase_exit_confirmed": true
879
+ },
880
+ "scope": {
881
+ "status": "complete",
882
+ "purpose": "...",
883
+ "user_question_asked": true,
884
+ "phase_exit_confirmed": true
885
+ },
886
+ "research_initial": {
887
+ "status": "complete",
888
+ "user_question_asked": true,
889
+ "phase_exit_confirmed": true
890
+ },
891
+ "interview": {
892
+ "status": "complete",
893
+ "decisions": {},
894
+ "user_question_asked": true,
895
+ "phase_exit_confirmed": true
896
+ },
897
+ "research_deep": {
898
+ "status": "skipped",
899
+ "user_question_asked": true,
900
+ "phase_exit_confirmed": true
901
+ },
902
+ "schema_creation": {
903
+ "status": "complete",
904
+ "user_question_asked": true,
905
+ "phase_exit_confirmed": true
906
+ },
907
+ "environment_check": {
908
+ "status": "complete",
909
+ "user_question_asked": true,
910
+ "phase_exit_confirmed": true
911
+ },
912
+ "tdd_red": {
913
+ "status": "complete",
914
+ "user_question_asked": true,
915
+ "phase_exit_confirmed": true
916
+ },
917
+ "tdd_green": {
918
+ "status": "complete",
919
+ "user_question_asked": true,
920
+ "phase_exit_confirmed": true
921
+ },
922
+ "verify": {
923
+ "status": "complete",
924
+ "user_question_asked": true,
925
+ "phase_exit_confirmed": true
926
+ },
927
+ "code_review": {
928
+ "status": "complete",
929
+ "user_question_asked": true,
930
+ "phase_exit_confirmed": true
931
+ },
932
+ "tdd_refactor": {
933
+ "status": "complete",
934
+ "user_question_asked": true,
935
+ "phase_exit_confirmed": true
936
+ },
937
+ "documentation": {
938
+ "status": "complete",
939
+ "user_question_asked": true,
940
+ "phase_exit_confirmed": true
941
+ },
942
+ "completion": {
943
+ "status": "complete",
944
+ "user_question_asked": true,
945
+ "phase_exit_confirmed": true
946
+ }
701
947
  }
702
948
  }
703
949
  ```
@@ -755,7 +1001,8 @@ Creates:
755
1001
  - Phase 1 (Selection) - Must read from registry
756
1002
  - Phase 4 (Interview) - All orchestration decisions from user
757
1003
  - Phase 8 (TDD Red) - Integration tests first
758
- - Phase 13 (Complete) - Registry update required
1004
+ - Phase 11 (Code Review) - Greptile review before refactoring
1005
+ - Phase 14 (Complete) - Registry update required
759
1006
 
760
1007
  ## User Interaction Required
761
1008