@hustle-together/api-dev-tools 3.12.16 → 4.5.3

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 (180) hide show
  1. package/.claude/adr-requests/.gitkeep +10 -0
  2. package/.claude/agents/adr-researcher.md +109 -0
  3. package/.claude/agents/visual-analyzer.md +183 -0
  4. package/.claude/api-dev-state.json +10 -0
  5. package/.claude/documentation-audit.json +114 -0
  6. package/.claude/registry.json +289 -0
  7. package/.claude/settings.json +45 -1
  8. package/.claude/settings.local.json +1 -7
  9. package/.claude/workflow-logs/None.json +49 -0
  10. package/.claude/workflow-logs/session-20251230-143727.json +106 -0
  11. package/.skills/adr-deep-research/SKILL.md +351 -0
  12. package/.skills/api-create/SKILL.md +34 -20
  13. package/.skills/api-research/SKILL.md +130 -0
  14. package/.skills/docs-update/SKILL.md +205 -0
  15. package/.skills/hustle-brand/SKILL.md +368 -0
  16. package/.skills/hustle-build/SKILL.md +365 -38
  17. package/.skills/parallel-spawn/SKILL.md +212 -0
  18. package/.skills/ralph-continue/SKILL.md +151 -0
  19. package/.skills/ralph-loop/SKILL.md +341 -0
  20. package/.skills/ralph-status/SKILL.md +87 -0
  21. package/.skills/refactor/SKILL.md +59 -0
  22. package/.skills/shadcn/SKILL.md +522 -0
  23. package/.skills/test-all/SKILL.md +210 -0
  24. package/.skills/test-builds/SKILL.md +208 -0
  25. package/.skills/test-debug/SKILL.md +212 -0
  26. package/.skills/test-e2e/SKILL.md +168 -0
  27. package/.skills/test-review/SKILL.md +707 -0
  28. package/.skills/test-unit/SKILL.md +143 -0
  29. package/.skills/test-visual/SKILL.md +301 -0
  30. package/.skills/token-report/SKILL.md +132 -0
  31. package/CHANGELOG.md +488 -0
  32. package/README.md +346 -53
  33. package/bin/cli.js +359 -123
  34. package/hooks/__pycache__/api-workflow-check.cpython-314.pyc +0 -0
  35. package/hooks/__pycache__/auto-answer.cpython-314.pyc +0 -0
  36. package/hooks/__pycache__/cache-research.cpython-314.pyc +0 -0
  37. package/hooks/__pycache__/check-api-routes.cpython-314.pyc +0 -0
  38. package/hooks/__pycache__/check-playwright-setup.cpython-314.pyc +0 -0
  39. package/hooks/__pycache__/check-storybook-setup.cpython-314.pyc +0 -0
  40. package/hooks/__pycache__/check-update.cpython-314.pyc +0 -0
  41. package/hooks/__pycache__/completion-promise-detector.cpython-314.pyc +0 -0
  42. package/hooks/__pycache__/context-capacity-warning.cpython-314.pyc +0 -0
  43. package/hooks/__pycache__/detect-interruption.cpython-314.pyc +0 -0
  44. package/hooks/__pycache__/docs-update-check.cpython-314.pyc +0 -0
  45. package/hooks/__pycache__/enforce-a11y-audit.cpython-314.pyc +0 -0
  46. package/hooks/__pycache__/enforce-brand-guide.cpython-314.pyc +0 -0
  47. package/hooks/__pycache__/enforce-component-type-confirm.cpython-314.pyc +0 -0
  48. package/hooks/__pycache__/enforce-deep-research.cpython-314.pyc +0 -0
  49. package/hooks/__pycache__/enforce-disambiguation.cpython-314.pyc +0 -0
  50. package/hooks/__pycache__/enforce-documentation.cpython-314.pyc +0 -0
  51. package/hooks/__pycache__/enforce-dry-run.cpython-314.pyc +0 -0
  52. package/hooks/__pycache__/enforce-environment.cpython-314.pyc +0 -0
  53. package/hooks/__pycache__/enforce-external-research.cpython-314.pyc +0 -0
  54. package/hooks/__pycache__/enforce-freshness.cpython-314.pyc +0 -0
  55. package/hooks/__pycache__/enforce-interview.cpython-314.pyc +0 -0
  56. package/hooks/__pycache__/enforce-page-components.cpython-314.pyc +0 -0
  57. package/hooks/__pycache__/enforce-page-data-schema.cpython-314.pyc +0 -0
  58. package/hooks/__pycache__/enforce-questions-sourced.cpython-314.pyc +0 -0
  59. package/hooks/__pycache__/enforce-refactor.cpython-314.pyc +0 -0
  60. package/hooks/__pycache__/enforce-research.cpython-314.pyc +0 -0
  61. package/hooks/__pycache__/enforce-schema-from-interview.cpython-314.pyc +0 -0
  62. package/hooks/__pycache__/enforce-schema.cpython-314.pyc +0 -0
  63. package/hooks/__pycache__/enforce-scope.cpython-314.pyc +0 -0
  64. package/hooks/__pycache__/enforce-tdd-red.cpython-314.pyc +0 -0
  65. package/hooks/__pycache__/enforce-ui-disambiguation.cpython-314.pyc +0 -0
  66. package/hooks/__pycache__/enforce-ui-interview.cpython-314.pyc +0 -0
  67. package/hooks/__pycache__/enforce-verify.cpython-314.pyc +0 -0
  68. package/hooks/__pycache__/generate-adr-options.cpython-314.pyc +0 -0
  69. package/hooks/__pycache__/generate-manifest-entry.cpython-314.pyc +0 -0
  70. package/hooks/__pycache__/hook_utils.cpython-314.pyc +0 -0
  71. package/hooks/__pycache__/notify-input-needed.cpython-314.pyc +0 -0
  72. package/hooks/__pycache__/notify-phase-complete.cpython-314.pyc +0 -0
  73. package/hooks/__pycache__/ntfy-on-question.cpython-314.pyc +0 -0
  74. package/hooks/__pycache__/orchestrator-completion.cpython-314.pyc +0 -0
  75. package/hooks/__pycache__/orchestrator-handoff.cpython-314.pyc +0 -0
  76. package/hooks/__pycache__/orchestrator-session-startup.cpython-314.pyc +0 -0
  77. package/hooks/__pycache__/parallel-orchestrator.cpython-314.pyc +0 -0
  78. package/hooks/__pycache__/periodic-reground.cpython-314.pyc +0 -0
  79. package/hooks/__pycache__/project-document-prompt.cpython-314.pyc +0 -0
  80. package/hooks/__pycache__/remote-question-proxy.cpython-314.pyc +0 -0
  81. package/hooks/__pycache__/remote-question-server.cpython-314.pyc +0 -0
  82. package/hooks/__pycache__/run-code-review.cpython-314.pyc +0 -0
  83. package/hooks/__pycache__/run-visual-qa.cpython-314.pyc +0 -0
  84. package/hooks/__pycache__/session-logger.cpython-314.pyc +0 -0
  85. package/hooks/__pycache__/session-startup.cpython-314.pyc +0 -0
  86. package/hooks/__pycache__/track-scope-coverage.cpython-314.pyc +0 -0
  87. package/hooks/__pycache__/track-token-usage.cpython-314.pyc +0 -0
  88. package/hooks/__pycache__/track-tool-use.cpython-314.pyc +0 -0
  89. package/hooks/__pycache__/update-adr-decision.cpython-314.pyc +0 -0
  90. package/hooks/__pycache__/update-api-showcase.cpython-314.pyc +0 -0
  91. package/hooks/__pycache__/update-registry.cpython-314.pyc +0 -0
  92. package/hooks/__pycache__/update-ui-showcase.cpython-314.pyc +0 -0
  93. package/hooks/__pycache__/verify-after-green.cpython-314.pyc +0 -0
  94. package/hooks/__pycache__/verify-implementation.cpython-314.pyc +0 -0
  95. package/hooks/api-workflow-check.py +34 -0
  96. package/hooks/auto-answer.py +97 -20
  97. package/{.claude/hooks → hooks}/completion-promise-detector.py +0 -0
  98. package/{.claude/hooks → hooks}/context-capacity-warning.py +0 -0
  99. package/{.claude/hooks → hooks}/docs-update-check.py +0 -0
  100. package/{.claude/hooks → hooks}/enforce-dry-run.py +0 -0
  101. package/hooks/enforce-external-research.py +25 -0
  102. package/hooks/enforce-interview.py +20 -0
  103. package/{.claude/hooks → hooks}/generate-adr-options.py +0 -0
  104. package/{.claude/hooks → hooks}/hook_utils.py +0 -0
  105. package/hooks/ntfy-on-question.py +15 -2
  106. package/hooks/orchestrator-handoff.py +81 -3
  107. package/{.claude/hooks → hooks}/parallel-orchestrator.py +0 -0
  108. package/hooks/periodic-reground.py +40 -0
  109. package/{.claude/hooks → hooks}/remote-question-server.py +0 -0
  110. package/hooks/run-code-review.py +176 -29
  111. package/{.claude/hooks → hooks}/run-visual-qa.py +0 -0
  112. package/hooks/session-logger.py +27 -1
  113. package/hooks/session-startup.py +113 -0
  114. package/{.claude/hooks → hooks}/update-adr-decision.py +0 -0
  115. package/package.json +1 -1
  116. package/templates/.skills/hustle-interview/SKILL.md +174 -0
  117. package/templates/adr-viewer/_components/ADRViewer.tsx +326 -0
  118. package/templates/api-dev-state.json +33 -1
  119. package/templates/brand-page/page.tsx +645 -0
  120. package/templates/component/Component.visual.spec.ts +30 -24
  121. package/templates/eslint-plugin-zod-schema/index.js +446 -0
  122. package/templates/eslint-plugin-zod-schema/package.json +26 -0
  123. package/templates/github-workflows/security.yml +274 -0
  124. package/templates/hustle-build-defaults.json +53 -1
  125. package/templates/page/page.e2e.test.ts +30 -26
  126. package/templates/performance-budgets.json +63 -5
  127. package/templates/registry.json +279 -3
  128. package/templates/review-dashboard/page.tsx +510 -0
  129. package/templates/settings.json +74 -7
  130. package/templates/ui-showcase/_components/UIShowcase.tsx +47 -0
  131. package/templates/ui-showcase/_components/VisualTestingDashboard.tsx +579 -0
  132. package/.claude/commands/hustle-combine.md +0 -1089
  133. package/.claude/commands/hustle-ui-create-page.md +0 -1078
  134. package/.claude/commands/hustle-ui-create.md +0 -1058
  135. package/.claude/hooks/auto-answer.py +0 -305
  136. package/.claude/hooks/cache-research.py +0 -337
  137. package/.claude/hooks/check-api-routes.py +0 -168
  138. package/.claude/hooks/check-playwright-setup.py +0 -103
  139. package/.claude/hooks/check-storybook-setup.py +0 -81
  140. package/.claude/hooks/check-update.py +0 -132
  141. package/.claude/hooks/detect-interruption.py +0 -165
  142. package/.claude/hooks/enforce-a11y-audit.py +0 -202
  143. package/.claude/hooks/enforce-brand-guide.py +0 -241
  144. package/.claude/hooks/enforce-component-type-confirm.py +0 -97
  145. package/.claude/hooks/enforce-freshness.py +0 -184
  146. package/.claude/hooks/enforce-page-components.py +0 -186
  147. package/.claude/hooks/enforce-page-data-schema.py +0 -155
  148. package/.claude/hooks/enforce-questions-sourced.py +0 -146
  149. package/.claude/hooks/enforce-schema-from-interview.py +0 -248
  150. package/.claude/hooks/enforce-ui-disambiguation.py +0 -108
  151. package/.claude/hooks/enforce-ui-interview.py +0 -130
  152. package/.claude/hooks/generate-manifest-entry.py +0 -1161
  153. package/.claude/hooks/lib/__init__.py +0 -1
  154. package/.claude/hooks/lib/greptile.py +0 -355
  155. package/.claude/hooks/lib/ntfy.py +0 -209
  156. package/.claude/hooks/notify-input-needed.py +0 -73
  157. package/.claude/hooks/notify-phase-complete.py +0 -90
  158. package/.claude/hooks/ntfy-on-question.py +0 -240
  159. package/.claude/hooks/orchestrator-completion.py +0 -313
  160. package/.claude/hooks/orchestrator-handoff.py +0 -267
  161. package/.claude/hooks/orchestrator-session-startup.py +0 -146
  162. package/.claude/hooks/run-code-review.py +0 -393
  163. package/.claude/hooks/session-logger.py +0 -323
  164. package/.claude/hooks/test-orchestrator-reground.py +0 -248
  165. package/.claude/hooks/track-scope-coverage.py +0 -220
  166. package/.claude/hooks/track-token-usage.py +0 -121
  167. package/.claude/hooks/update-api-showcase.py +0 -161
  168. package/.claude/hooks/update-registry.py +0 -352
  169. package/.claude/hooks/update-ui-showcase.py +0 -224
  170. package/.claude/test-auto-answer-bot.py +0 -183
  171. package/.claude/test-completion-detector.py +0 -263
  172. package/.claude/test-orchestrator-state.json +0 -20
  173. package/.claude/test-orchestrator.sh +0 -271
  174. /package/{.claude/commands → commands}/hustle-build.md +0 -0
  175. /package/{.claude/hooks → hooks}/lib/__pycache__/__init__.cpython-314.pyc +0 -0
  176. /package/{.claude/hooks → hooks}/lib/__pycache__/greptile.cpython-314.pyc +0 -0
  177. /package/{.claude/hooks → hooks}/lib/__pycache__/ntfy.cpython-314.pyc +0 -0
  178. /package/{.claude/hooks → hooks}/project-document-prompt.py +0 -0
  179. /package/{.claude/hooks → hooks}/remote-question-proxy.py +0 -0
  180. /package/{.claude/hooks → hooks}/update-testing-checklist.py +0 -0
@@ -1,1089 +0,0 @@
1
- # Hustle Combine - API and UI Orchestration Workflow v4.0.0
2
-
3
- **Usage:** `/hustle-combine [api|ui] [--auto] [--resume [workflow-id]]`
4
-
5
- **Purpose:** Combines existing APIs or UI elements from the registry into new orchestration endpoints or composed components.
6
-
7
- ## Arguments
8
-
9
- - `[api|ui]` - Mode: combine APIs or UI elements
10
- - `--auto` - Fully autonomous mode, auto-answers all questions with comprehensive defaults
11
- - `--resume [workflow-id]` - Resume an interrupted workflow from its last phase
12
-
13
- ---
14
-
15
- ## Auto Mode (`--auto`)
16
-
17
- When `--auto` flag is used:
18
-
19
- 1. **No Interactive Questions:**
20
- - All questions auto-answered with comprehensive defaults
21
- - Uses `.claude/hustle-build-defaults.json` for configured answers
22
- - Falls back to "most comprehensive" option when no default exists
23
-
24
- 2. **Comprehensive Selection Logic:**
25
- - Selects parallel execution (when APIs are independent)
26
- - Uses partial-success error handling
27
- - Enables unified caching strategy
28
- - Uses exponential retry with 30s timeout
29
-
30
- 3. **API Selection in Orchestrated Mode:**
31
- - When `orchestrated: true`, APIs are pre-selected by orchestrator
32
- - Selection phase is skipped, proceeds directly to Scope
33
-
34
- 4. **Logging:**
35
- - All decisions logged to `.claude/workflow-logs/hustle-combine/[workflow-id].json`
36
- - Review with `/hustle-combine-review [workflow-id]`
37
-
38
- ---
39
-
40
- ## Resume Mode (`--resume`)
41
-
42
- When `--resume [workflow-id]` is used:
43
-
44
- 1. Load state from `.claude/api-dev-state.json`
45
- 2. Find the last incomplete phase
46
- 3. Continue from that point
47
- 4. Preserve all previous decisions and API selections
48
-
49
- ---
50
-
51
- ## Orchestrated Mode
52
-
53
- When running as part of `/hustle-build`:
54
-
55
- 1. `orchestrated: true` flag is set in state
56
- 2. `shared_decisions` are pre-filled from orchestrator interview
57
- 3. Source APIs are pre-selected based on orchestrator decomposition
58
- 4. Questions covered by shared_decisions are SKIPPED
59
- 5. Only combination-specific questions are asked (execution order, caching)
60
-
61
- ---
62
-
63
- ## Overview
64
-
65
- This command reads from `.claude/registry.json` to present available elements for combination. It creates NEW orchestration layers using EXISTING, tested components.
66
-
67
- **Key Principle:** We're not creating new APIs from scratch - we're combining existing, working APIs into orchestration endpoints.
68
-
69
- ---
70
-
71
- ## CRITICAL: MANDATORY USER INTERACTION
72
-
73
- **YOU MUST USE THE `AskUserQuestion` TOOL AT EVERY CHECKPOINT.**
74
-
75
- This workflow requires REAL user input at each phase. You are **FORBIDDEN** from:
76
-
77
- - Self-answering questions
78
- - Assuming user responses
79
- - Proceeding without explicit user confirmation
80
- - Making decisions on behalf of the user
81
-
82
- ### How to Ask Questions Correctly
83
-
84
- At every prompt in this workflow, you MUST call the `AskUserQuestion` tool with this EXACT schema:
85
-
86
- ```json
87
- {
88
- "questions": [
89
- {
90
- "question": "Your question here? (must end with ?)",
91
- "header": "Phase",
92
- "multiSelect": false,
93
- "options": [
94
- { "label": "Option A", "description": "What this option means" },
95
- { "label": "Option B", "description": "What this option means" },
96
- { "label": "Other", "description": "I'll type my own answer" }
97
- ]
98
- }
99
- ]
100
- }
101
- ```
102
-
103
- **CRITICAL REQUIREMENTS:**
104
-
105
- - `header`: Max 12 characters (e.g., "Mode", "Select", "Order")
106
- - `options`: 2-4 options, each with `label` (1-5 words) and `description`
107
- - `multiSelect`: Required boolean (true for checkboxes, false for radio)
108
- - `question`: Must end with a question mark
109
-
110
- **WAIT for the user's response before proceeding.** Do NOT continue until you receive the response.
111
-
112
- ### Phase Exit Confirmation
113
-
114
- **Every phase requires an EXIT CONFIRMATION question** before proceeding to the next phase.
115
-
116
- Example:
117
-
118
- ```json
119
- {
120
- "questions": [
121
- {
122
- "question": "Phase complete. Ready to proceed to next phase?",
123
- "header": "Proceed",
124
- "multiSelect": false,
125
- "options": [
126
- { "label": "Yes, proceed", "description": "Move to next phase" },
127
- {
128
- "label": "No, make changes",
129
- "description": "I need to modify something"
130
- }
131
- ]
132
- }
133
- ]
134
- }
135
- ```
136
-
137
- ---
138
-
139
- ## Mode Selection
140
-
141
- When running `/hustle-combine`, first determine the mode:
142
-
143
- Use AskUserQuestion:
144
-
145
- ```json
146
- {
147
- "questions": [
148
- {
149
- "question": "What would you like to combine?",
150
- "header": "Mode",
151
- "multiSelect": false,
152
- "options": [
153
- {
154
- "label": "APIs",
155
- "description": "Combine existing API endpoints into orchestration layer"
156
- },
157
- {
158
- "label": "UI",
159
- "description": "Combine existing components/pages (coming soon)"
160
- }
161
- ]
162
- }
163
- ]
164
- }
165
- ```
166
-
167
- ---
168
-
169
- ## Mode A: Combine APIs
170
-
171
- ### 14 Phases for API Combination
172
-
173
- ```
174
- Phase 1: SELECTION - Present checkboxes from registry, user selects 2+ APIs
175
- Phase 2: SCOPE - "What should this combined endpoint do?"
176
- Phase 3: INITIAL RESEARCH - Orchestration patterns (lighter - APIs already researched)
177
- Phase 4: INTERVIEW - Flow order, error handling, caching, naming
178
- Phase 5: DEEP RESEARCH - Edge cases between APIs (optional/lighter)
179
- Phase 6: COMBINED SCHEMA - Zod types composing existing schemas
180
- Phase 7: ENVIRONMENT - Verify all required API keys exist
181
- Phase 8: TDD RED - Integration tests for combined flow
182
- Phase 9: TDD GREEN - Orchestration route implementation
183
- Phase 10: VERIFY - Full flow works end-to-end
184
- Phase 11: CODE REVIEW - Greptile AI review for bugs, security, performance
185
- Phase 12: REFACTOR - Fix review issues + clean up, optimize
186
- Phase 13: DOCUMENTATION - Update manifest, document combined endpoint
187
- Phase 14: COMPLETE - Update registry with new combined API
188
- ```
189
-
190
- ---
191
-
192
- ### Phase 1: SELECTION (Programmatic from Registry)
193
-
194
- Read `.claude/registry.json` and present available APIs.
195
-
196
- **IMPORTANT:** Options are dynamically generated from registry.json. Only show APIs with `status: "complete"`.
197
-
198
- Use AskUserQuestion with multiSelect:
199
-
200
- ```json
201
- {
202
- "questions": [
203
- {
204
- "question": "Select APIs to combine (choose 2 or more):",
205
- "header": "Select",
206
- "multiSelect": true,
207
- "options": [
208
- {
209
- "label": "[api-name]",
210
- "description": "[api-description from registry]"
211
- }
212
- ]
213
- }
214
- ]
215
- }
216
- ```
217
-
218
- **After selection, store in state:**
219
-
220
- ```json
221
- {
222
- "workflow": "combine-api",
223
- "combine_config": {
224
- "mode": "api",
225
- "source_elements": [
226
- { "type": "api", "name": "api1" },
227
- { "type": "api", "name": "api2" }
228
- ]
229
- }
230
- }
231
- ```
232
-
233
- **Phase Exit:**
234
-
235
- ```json
236
- {
237
- "questions": [
238
- {
239
- "question": "Selected [N] APIs. Ready to define the purpose?",
240
- "header": "Proceed",
241
- "multiSelect": false,
242
- "options": [
243
- { "label": "Yes, proceed", "description": "Move to Scope phase" },
244
- {
245
- "label": "Change selection",
246
- "description": "I want to select different APIs"
247
- }
248
- ]
249
- }
250
- ]
251
- }
252
- ```
253
-
254
- ---
255
-
256
- ### Phase 2: SCOPE
257
-
258
- Ask what the combined endpoint should do:
259
-
260
- ```json
261
- {
262
- "questions": [
263
- {
264
- "question": "What should this combined endpoint do? Describe the purpose:",
265
- "header": "Purpose",
266
- "multiSelect": false,
267
- "options": [
268
- { "label": "Describe it", "description": "I'll type the purpose" }
269
- ]
270
- }
271
- ]
272
- }
273
- ```
274
-
275
- Store the purpose in state for later use in schema and tests.
276
-
277
- **Phase Exit:**
278
-
279
- ```json
280
- {
281
- "questions": [
282
- {
283
- "question": "Purpose defined. Ready to research orchestration patterns?",
284
- "header": "Proceed",
285
- "multiSelect": false,
286
- "options": [
287
- { "label": "Yes, proceed", "description": "Move to Research phase" },
288
- {
289
- "label": "Refine purpose",
290
- "description": "I want to clarify the purpose"
291
- }
292
- ]
293
- }
294
- ]
295
- }
296
- ```
297
-
298
- ---
299
-
300
- ### Phase 3: INITIAL RESEARCH (Lighter)
301
-
302
- Since APIs already exist, focus ONLY on orchestration patterns:
303
-
304
- - Gateway aggregation patterns
305
- - Error propagation between services
306
- - Response composition strategies
307
-
308
- ```json
309
- {
310
- "questions": [
311
- {
312
- "question": "Research focus: I'll look up orchestration patterns for combining [API1] + [API2]. Proceed?",
313
- "header": "Research",
314
- "multiSelect": false,
315
- "options": [
316
- {
317
- "label": "Yes, proceed",
318
- "description": "Research orchestration patterns"
319
- },
320
- {
321
- "label": "Skip research",
322
- "description": "I know how I want to combine them"
323
- }
324
- ]
325
- }
326
- ]
327
- }
328
- ```
329
-
330
- If user chooses to research, use WebSearch and Context7 for:
331
-
332
- - "API gateway aggregation patterns"
333
- - "Service composition error handling"
334
- - "Response aggregation TypeScript patterns"
335
-
336
- **Phase Exit:**
337
-
338
- ```json
339
- {
340
- "questions": [
341
- {
342
- "question": "Research complete. Ready for interview questions?",
343
- "header": "Proceed",
344
- "multiSelect": false,
345
- "options": [
346
- { "label": "Yes, interview", "description": "Move to Interview phase" },
347
- {
348
- "label": "More research",
349
- "description": "I need to research [topic]"
350
- }
351
- ]
352
- }
353
- ]
354
- }
355
- ```
356
-
357
- ---
358
-
359
- ### Phase 4: INTERVIEW
360
-
361
- Key questions for API combination (ask one at a time):
362
-
363
- **Q1: Endpoint Name**
364
-
365
- ```json
366
- {
367
- "questions": [
368
- {
369
- "question": "What should the combined endpoint be called?",
370
- "header": "Name",
371
- "multiSelect": false,
372
- "options": [
373
- {
374
- "label": "[suggested-name]",
375
- "description": "Suggested: /api/v2/[suggested-name]"
376
- },
377
- { "label": "Custom name", "description": "I'll type my own" }
378
- ]
379
- }
380
- ]
381
- }
382
- ```
383
-
384
- **Q2: Execution Order**
385
-
386
- ```json
387
- {
388
- "questions": [
389
- {
390
- "question": "How should the APIs execute?",
391
- "header": "Order",
392
- "multiSelect": false,
393
- "options": [
394
- { "label": "Parallel", "description": "All at once, combine results" },
395
- {
396
- "label": "Sequential",
397
- "description": "One after another, pass data between"
398
- },
399
- {
400
- "label": "Conditional",
401
- "description": "Second API depends on first result"
402
- }
403
- ]
404
- }
405
- ]
406
- }
407
- ```
408
-
409
- **Q3: Error Handling**
410
-
411
- ```json
412
- {
413
- "questions": [
414
- {
415
- "question": "If the first API fails, what should happen?",
416
- "header": "Errors",
417
- "multiSelect": false,
418
- "options": [
419
- {
420
- "label": "Fail entire request",
421
- "description": "Return error, don't call other APIs"
422
- },
423
- {
424
- "label": "Continue with partial",
425
- "description": "Return what succeeded"
426
- },
427
- {
428
- "label": "Retry once",
429
- "description": "Retry failed API, then fail if still failing"
430
- }
431
- ]
432
- }
433
- ]
434
- }
435
- ```
436
-
437
- **Q4: Data Transformation**
438
-
439
- ```json
440
- {
441
- "questions": [
442
- {
443
- "question": "Do you need to transform data between APIs?",
444
- "header": "Transform",
445
- "multiSelect": false,
446
- "options": [
447
- { "label": "No", "description": "Use responses as-is" },
448
- { "label": "Yes", "description": "I'll describe the transformation" }
449
- ]
450
- }
451
- ]
452
- }
453
- ```
454
-
455
- **Q5: Caching**
456
-
457
- ```json
458
- {
459
- "questions": [
460
- {
461
- "question": "Caching strategy?",
462
- "header": "Cache",
463
- "multiSelect": false,
464
- "options": [
465
- { "label": "No caching", "description": "Always fetch fresh" },
466
- {
467
- "label": "Cache combined result",
468
- "description": "Cache the final response"
469
- },
470
- {
471
- "label": "Cache individual APIs",
472
- "description": "Cache each API's response separately"
473
- }
474
- ]
475
- }
476
- ]
477
- }
478
- ```
479
-
480
- **Store all decisions in state:**
481
-
482
- ```json
483
- {
484
- "phases": {
485
- "interview": {
486
- "status": "complete",
487
- "decisions": {
488
- "endpoint_name": "brand-voice",
489
- "execution_order": "sequential",
490
- "error_strategy": "fail-fast",
491
- "data_transformation": false,
492
- "caching_strategy": "none"
493
- }
494
- }
495
- }
496
- }
497
- ```
498
-
499
- **Phase Exit:**
500
-
501
- ```json
502
- {
503
- "questions": [
504
- {
505
- "question": "Interview complete. Ready for deep research?",
506
- "header": "Proceed",
507
- "multiSelect": false,
508
- "options": [
509
- {
510
- "label": "Yes, proceed",
511
- "description": "Move to Deep Research phase"
512
- },
513
- {
514
- "label": "Change answers",
515
- "description": "I want to modify my answers"
516
- }
517
- ]
518
- }
519
- ]
520
- }
521
- ```
522
-
523
- ---
524
-
525
- ### Phase 5: DEEP RESEARCH (Optional)
526
-
527
- Based on interview answers, propose targeted research:
528
-
529
- ```json
530
- {
531
- "questions": [
532
- {
533
- "question": "Based on your answers, should I research: [specific topics based on interview]?",
534
- "header": "Deep",
535
- "multiSelect": false,
536
- "options": [
537
- { "label": "Yes, research these", "description": "Run the searches" },
538
- {
539
- "label": "Add more topics",
540
- "description": "I need [something specific]"
541
- },
542
- { "label": "Skip to schema", "description": "I have enough info" }
543
- ]
544
- }
545
- ]
546
- }
547
- ```
548
-
549
- Topics to propose based on interview:
550
-
551
- - If sequential: "data passing between API calls"
552
- - If parallel: "Promise.all error handling patterns"
553
- - If retry: "exponential backoff strategies"
554
- - If caching: "response caching with invalidation"
555
-
556
- ---
557
-
558
- ### Phase 6: COMBINED SCHEMA
559
-
560
- Create Zod schema that COMPOSES existing schemas:
561
-
562
- ```typescript
563
- // src/app/api/v2/[combined-name]/schemas.ts
564
- import { z } from "zod";
565
- import { Api1ResponseSchema } from "../api1/schemas";
566
- import { Api2ResponseSchema } from "../api2/schemas";
567
-
568
- // Combined request schema
569
- export const CombinedRequestSchema = z.object({
570
- // Fields needed by both APIs
571
- });
572
-
573
- // Combined response schema
574
- export const CombinedResponseSchema = z.object({
575
- api1: Api1ResponseSchema,
576
- api2: Api2ResponseSchema,
577
- combined_at: z.string(),
578
- });
579
-
580
- export type CombinedRequest = z.infer<typeof CombinedRequestSchema>;
581
- export type CombinedResponse = z.infer<typeof CombinedResponseSchema>;
582
- ```
583
-
584
- **Ask for approval:**
585
-
586
- ```json
587
- {
588
- "questions": [
589
- {
590
- "question": "Combined schema created. It imports from [API1] and [API2] schemas. Approve?",
591
- "header": "Schema",
592
- "multiSelect": false,
593
- "options": [
594
- { "label": "Yes, approved", "description": "Schema looks correct" },
595
- { "label": "Make changes", "description": "I need to modify something" }
596
- ]
597
- }
598
- ]
599
- }
600
- ```
601
-
602
- ---
603
-
604
- ### Phase 7: ENVIRONMENT CHECK
605
-
606
- Verify all API keys from combined APIs are available.
607
-
608
- Read the source API entries in registry.json to determine required environment variables.
609
-
610
- Report:
611
-
612
- ```
613
- Environment Check:
614
- [checkmark] API1_KEY - Found
615
- [checkmark] API2_KEY - Found
616
-
617
- All required keys available.
618
- ```
619
-
620
- ```json
621
- {
622
- "questions": [
623
- {
624
- "question": "Environment check passed. All [N] API keys found. Ready for TDD?",
625
- "header": "Env",
626
- "multiSelect": false,
627
- "options": [
628
- { "label": "Yes, write tests", "description": "Proceed to TDD Red" },
629
- {
630
- "label": "No, need setup",
631
- "description": "I need to configure something"
632
- }
633
- ]
634
- }
635
- ]
636
- }
637
- ```
638
-
639
- ---
640
-
641
- ### Phase 8: TDD RED (Integration Tests)
642
-
643
- Write tests for the combined flow:
644
-
645
- ```typescript
646
- // src/app/api/v2/[combined-name]/__tests__/[combined-name].api.test.ts
647
- import { describe, it, expect, vi, beforeEach } from "vitest";
648
-
649
- describe("[Combined Name] API", () => {
650
- describe("POST /api/v2/[combined-name]", () => {
651
- it("should call both APIs and combine results", async () => {
652
- // Test combined flow
653
- });
654
-
655
- it("should handle first API failure correctly", async () => {
656
- // Test error handling based on interview decisions
657
- });
658
-
659
- // More tests based on interview decisions...
660
- });
661
- });
662
- ```
663
-
664
- Run tests - they should FAIL (Red phase).
665
-
666
- **Phase Exit:**
667
-
668
- ```json
669
- {
670
- "questions": [
671
- {
672
- "question": "Failing tests written. Ready to implement?",
673
- "header": "Proceed",
674
- "multiSelect": false,
675
- "options": [
676
- { "label": "Yes, implement", "description": "Move to TDD Green phase" },
677
- {
678
- "label": "Add more tests",
679
- "description": "I need to test more scenarios"
680
- }
681
- ]
682
- }
683
- ]
684
- }
685
- ```
686
-
687
- ---
688
-
689
- ### Phase 9: TDD GREEN (Orchestration Route)
690
-
691
- Implement the orchestration logic:
692
-
693
- ```typescript
694
- // src/app/api/v2/[combined-name]/route.ts
695
- import { NextRequest, NextResponse } from "next/server";
696
- import { CombinedRequestSchema } from "./schemas";
697
-
698
- export async function POST(request: NextRequest) {
699
- try {
700
- const body = await request.json();
701
- const validated = CombinedRequestSchema.parse(body);
702
-
703
- // Implementation based on interview decisions:
704
- // - Sequential/Parallel/Conditional execution
705
- // - Error handling strategy
706
- // - Data transformation
707
- // - Caching
708
-
709
- return NextResponse.json({
710
- // Combined response
711
- combined_at: new Date().toISOString(),
712
- });
713
- } catch (error) {
714
- return NextResponse.json({ error: error.message }, { status: 500 });
715
- }
716
- }
717
- ```
718
-
719
- Run tests - all must pass (Green phase).
720
-
721
- ---
722
-
723
- ### Phase 10: VERIFY
724
-
725
- Test the full flow end-to-end:
726
-
727
- ```json
728
- {
729
- "questions": [
730
- {
731
- "question": "Integration tests pass. Should I verify the full flow manually with real API calls?",
732
- "header": "Verify",
733
- "multiSelect": false,
734
- "options": [
735
- {
736
- "label": "Yes, test real flow",
737
- "description": "Make actual API calls"
738
- },
739
- {
740
- "label": "Skip, tests sufficient",
741
- "description": "Proceed to refactor"
742
- }
743
- ]
744
- }
745
- ]
746
- }
747
- ```
748
-
749
- If verifying, make actual requests and report results.
750
-
751
- ---
752
-
753
- ### Phase 11: CODE REVIEW (Greptile)
754
-
755
- Run Greptile AI code review before refactoring:
756
-
757
- - Bug detection with full codebase context
758
- - Security vulnerability scanning (OWASP top 10)
759
- - Performance issue identification
760
-
761
- **Requires:** GREPTILE_API_KEY + GITHUB_TOKEN
762
-
763
- ```json
764
- {
765
- "questions": [
766
- {
767
- "question": "Code review found [N] issue(s). How should I proceed?",
768
- "header": "Review",
769
- "multiSelect": false,
770
- "options": [
771
- { "label": "Fix all", "description": "Address all issues in refactor" },
772
- {
773
- "label": "Critical only",
774
- "description": "Fix critical, defer others"
775
- },
776
- { "label": "Skip", "description": "No issues to fix" }
777
- ]
778
- }
779
- ]
780
- }
781
- ```
782
-
783
- ---
784
-
785
- ### Phase 12: REFACTOR
786
-
787
- Fix review issues + clean up the orchestration code:
788
-
789
- - Address Greptile issues (bugs, security, performance)
790
- - Extract reusable patterns
791
- - Add error logging
792
- - Optimize parallel calls if applicable
793
- - Add JSDoc comments
794
-
795
- Run tests after each change to ensure they still pass.
796
-
797
- **Phase Exit:**
798
-
799
- ```json
800
- {
801
- "questions": [
802
- {
803
- "question": "Refactoring complete. Tests still pass. Ready to document?",
804
- "header": "Proceed",
805
- "multiSelect": false,
806
- "options": [
807
- {
808
- "label": "Yes, document",
809
- "description": "Move to Documentation phase"
810
- },
811
- {
812
- "label": "More refactoring",
813
- "description": "I want to clean up more"
814
- }
815
- ]
816
- }
817
- ]
818
- }
819
- ```
820
-
821
- ---
822
-
823
- ### Phase 13: DOCUMENTATION
824
-
825
- Update:
826
-
827
- 1. `api-tests-manifest.json` - Add new combined endpoint
828
- 2. `registry.json` - Add to `combined` section
829
- 3. Any project docs as needed
830
-
831
- ```json
832
- {
833
- "questions": [
834
- {
835
- "question": "Documentation updated. Ready to complete?",
836
- "header": "Docs",
837
- "multiSelect": false,
838
- "options": [
839
- {
840
- "label": "Yes, complete",
841
- "description": "Finalize and update registry"
842
- },
843
- { "label": "Need more docs", "description": "I want to add something" }
844
- ]
845
- }
846
- ]
847
- }
848
- ```
849
-
850
- ---
851
-
852
- ### Phase 14: COMPLETION
853
-
854
- Update registry.json with the new combined API:
855
-
856
- ```json
857
- {
858
- "combined": {
859
- "[combined-name]": {
860
- "name": "[Display Name]",
861
- "type": "api",
862
- "description": "[Purpose from interview]",
863
- "combines": ["api1", "api2"],
864
- "route": "src/app/api/v2/[combined-name]/route.ts",
865
- "schemas": "src/app/api/v2/[combined-name]/schemas.ts",
866
- "tests": "src/app/api/v2/[combined-name]/__tests__/",
867
- "flow_type": "[sequential|parallel|conditional]",
868
- "created_at": "[date]",
869
- "status": "complete"
870
- }
871
- }
872
- }
873
- ```
874
-
875
- **Final confirmation:**
876
-
877
- ```json
878
- {
879
- "questions": [
880
- {
881
- "question": "Combined API complete. Registry updated. Anything else?",
882
- "header": "Complete",
883
- "multiSelect": false,
884
- "options": [
885
- { "label": "Done", "description": "Workflow complete" },
886
- {
887
- "label": "Create another",
888
- "description": "Start new combine workflow"
889
- }
890
- ]
891
- }
892
- ]
893
- }
894
- ```
895
-
896
- ### End-of-Workflow Summary
897
-
898
- After successful combination, display:
899
-
900
- ```
901
- ═══════════════════════════════════════════════════════════════
902
- ✅ COMBINED API CREATED: [combined-name]
903
-
904
- 📍 Quick Links:
905
- • Test it: /api-showcase
906
- • API Docs: /docs/api/[combined-name]
907
- • Run tests: pnpm test src/app/api/v2/[combined-name]
908
- • TypeDoc: pnpm typedoc
909
-
910
- 📦 Combined: [api1] + [api2]
911
- 📊 Dashboard: /hustle-dev-dashboard
912
-
913
- Next Steps:
914
- • /commit - Commit your changes
915
- • /hustle-api-create - Create another API
916
- ═══════════════════════════════════════════════════════════════
917
- ```
918
-
919
- ---
920
-
921
- ## Mode B: Combine UI (Coming Soon)
922
-
923
- UI combination requires `/hustle-ui-create` to be implemented first.
924
-
925
- Three sub-modes planned:
926
-
927
- - **A) Composed Component** - Combine existing components
928
- - **B) Page with Components** - Create page using components
929
- - **C) Page with Components + API** - Create page with data fetching
930
-
931
- ---
932
-
933
- ## State File Structure
934
-
935
- ```json
936
- {
937
- "version": "3.11.0",
938
- "workflow": "combine-api",
939
- "element_name": "brand-voice",
940
- "element_type": "combined",
941
-
942
- "combine_config": {
943
- "mode": "api",
944
- "source_elements": [
945
- { "type": "api", "name": "brandfetch" },
946
- { "type": "api", "name": "elevenlabs" }
947
- ],
948
- "flow_type": "sequential",
949
- "error_strategy": "fail-fast"
950
- },
951
-
952
- "phases": {
953
- "selection": {
954
- "status": "complete",
955
- "apis_selected": 2,
956
- "user_question_asked": true,
957
- "phase_exit_confirmed": true
958
- },
959
- "scope": {
960
- "status": "complete",
961
- "purpose": "...",
962
- "user_question_asked": true,
963
- "phase_exit_confirmed": true
964
- },
965
- "research_initial": {
966
- "status": "complete",
967
- "user_question_asked": true,
968
- "phase_exit_confirmed": true
969
- },
970
- "interview": {
971
- "status": "complete",
972
- "decisions": {},
973
- "user_question_asked": true,
974
- "phase_exit_confirmed": true
975
- },
976
- "research_deep": {
977
- "status": "skipped",
978
- "user_question_asked": true,
979
- "phase_exit_confirmed": true
980
- },
981
- "schema_creation": {
982
- "status": "complete",
983
- "user_question_asked": true,
984
- "phase_exit_confirmed": true
985
- },
986
- "environment_check": {
987
- "status": "complete",
988
- "user_question_asked": true,
989
- "phase_exit_confirmed": true
990
- },
991
- "tdd_red": {
992
- "status": "complete",
993
- "user_question_asked": true,
994
- "phase_exit_confirmed": true
995
- },
996
- "tdd_green": {
997
- "status": "complete",
998
- "user_question_asked": true,
999
- "phase_exit_confirmed": true
1000
- },
1001
- "verify": {
1002
- "status": "complete",
1003
- "user_question_asked": true,
1004
- "phase_exit_confirmed": true
1005
- },
1006
- "code_review": {
1007
- "status": "complete",
1008
- "user_question_asked": true,
1009
- "phase_exit_confirmed": true
1010
- },
1011
- "tdd_refactor": {
1012
- "status": "complete",
1013
- "user_question_asked": true,
1014
- "phase_exit_confirmed": true
1015
- },
1016
- "documentation": {
1017
- "status": "complete",
1018
- "user_question_asked": true,
1019
- "phase_exit_confirmed": true
1020
- },
1021
- "completion": {
1022
- "status": "complete",
1023
- "user_question_asked": true,
1024
- "phase_exit_confirmed": true
1025
- }
1026
- }
1027
- }
1028
- ```
1029
-
1030
- ---
1031
-
1032
- ## Output Artifacts
1033
-
1034
- 1. **Route Handler**: `/src/app/api/v2/[combined-name]/route.ts`
1035
- 2. **Schema File**: `/src/app/api/v2/[combined-name]/schemas.ts`
1036
- 3. **Test Suite**: `/src/app/api/v2/[combined-name]/__tests__/`
1037
- 4. **Updated Registry**: `.claude/registry.json` (combined section)
1038
- 5. **Updated Manifest**: `api-tests-manifest.json`
1039
-
1040
- ---
1041
-
1042
- ## Example: WordPress + Elementor
1043
-
1044
- ```
1045
- /hustle-combine api
1046
-
1047
- Available APIs:
1048
- [checkbox] wordpress - WordPress REST API
1049
- [checkbox] elementor - Elementor widget API
1050
- [checkbox] brandfetch - Brand data extraction
1051
-
1052
- > wordpress, elementor
1053
-
1054
- Purpose: "Log into WordPress, then create Elementor template"
1055
-
1056
- Interview:
1057
- - Order: Sequential (WordPress auth first)
1058
- - Errors: Fail if WordPress auth fails
1059
- - Name: wp-elementor-sync
1060
-
1061
- Creates:
1062
- src/app/api/v2/wp-elementor-sync/
1063
- ├── route.ts
1064
- ├── schemas.ts
1065
- └── __tests__/
1066
- ```
1067
-
1068
- <claude-commands-template>
1069
- ## Project Rules
1070
-
1071
- 1. **Registry Required**: Only combine APIs that exist in registry.json with `status: "complete"`
1072
- 2. **No Skipping Selection**: User MUST select from available APIs
1073
- 3. **Interview Required**: All decisions must come from user, not assumptions
1074
- 4. **Lighter Research**: Since APIs exist, research focuses on orchestration patterns only
1075
- 5. **Test Integration**: Tests verify APIs work together, not individual API behavior
1076
- 6. **Update Registry**: Always update registry.json on completion
1077
-
1078
- ## Never Skip
1079
-
1080
- - Phase 1 (Selection) - Must read from registry
1081
- - Phase 4 (Interview) - All orchestration decisions from user
1082
- - Phase 8 (TDD Red) - Integration tests first
1083
- - Phase 11 (Code Review) - Greptile review before refactoring
1084
- - Phase 14 (Complete) - Registry update required
1085
-
1086
- ## User Interaction Required
1087
-
1088
- Every phase MUST use `AskUserQuestion` tool. Self-answering is FORBIDDEN.
1089
- </claude-commands-template>