@hustle-together/api-dev-tools 3.6.5 → 3.10.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 (72) hide show
  1. package/README.md +5599 -258
  2. package/bin/cli.js +395 -20
  3. package/commands/README.md +459 -71
  4. package/commands/hustle-api-continue.md +158 -0
  5. package/commands/{api-create.md → hustle-api-create.md} +35 -15
  6. package/commands/{api-env.md → hustle-api-env.md} +4 -4
  7. package/commands/{api-interview.md → hustle-api-interview.md} +1 -1
  8. package/commands/{api-research.md → hustle-api-research.md} +3 -3
  9. package/commands/hustle-api-sessions.md +149 -0
  10. package/commands/{api-status.md → hustle-api-status.md} +16 -16
  11. package/commands/{api-verify.md → hustle-api-verify.md} +2 -2
  12. package/commands/hustle-combine.md +763 -0
  13. package/commands/hustle-ui-create-page.md +933 -0
  14. package/commands/hustle-ui-create.md +825 -0
  15. package/hooks/api-workflow-check.py +545 -21
  16. package/hooks/cache-research.py +337 -0
  17. package/hooks/check-api-routes.py +168 -0
  18. package/hooks/check-playwright-setup.py +103 -0
  19. package/hooks/check-storybook-setup.py +81 -0
  20. package/hooks/detect-interruption.py +165 -0
  21. package/hooks/enforce-a11y-audit.py +202 -0
  22. package/hooks/enforce-brand-guide.py +241 -0
  23. package/hooks/enforce-documentation.py +60 -8
  24. package/hooks/enforce-freshness.py +184 -0
  25. package/hooks/enforce-page-components.py +186 -0
  26. package/hooks/enforce-page-data-schema.py +155 -0
  27. package/hooks/enforce-questions-sourced.py +146 -0
  28. package/hooks/enforce-schema-from-interview.py +248 -0
  29. package/hooks/enforce-ui-disambiguation.py +108 -0
  30. package/hooks/enforce-ui-interview.py +130 -0
  31. package/hooks/generate-manifest-entry.py +1161 -0
  32. package/hooks/session-logger.py +297 -0
  33. package/hooks/session-startup.py +160 -15
  34. package/hooks/track-scope-coverage.py +220 -0
  35. package/hooks/track-tool-use.py +81 -1
  36. package/hooks/update-api-showcase.py +149 -0
  37. package/hooks/update-registry.py +352 -0
  38. package/hooks/update-ui-showcase.py +212 -0
  39. package/package.json +8 -3
  40. package/templates/BRAND_GUIDE.md +299 -0
  41. package/templates/CLAUDE-SECTION.md +56 -24
  42. package/templates/SPEC.json +640 -0
  43. package/templates/api-dev-state.json +217 -161
  44. package/templates/api-showcase/_components/APICard.tsx +153 -0
  45. package/templates/api-showcase/_components/APIModal.tsx +375 -0
  46. package/templates/api-showcase/_components/APIShowcase.tsx +231 -0
  47. package/templates/api-showcase/_components/APITester.tsx +522 -0
  48. package/templates/api-showcase/page.tsx +41 -0
  49. package/templates/component/Component.stories.tsx +172 -0
  50. package/templates/component/Component.test.tsx +237 -0
  51. package/templates/component/Component.tsx +86 -0
  52. package/templates/component/Component.types.ts +55 -0
  53. package/templates/component/index.ts +15 -0
  54. package/templates/dev-tools/_components/DevToolsLanding.tsx +320 -0
  55. package/templates/dev-tools/page.tsx +10 -0
  56. package/templates/page/page.e2e.test.ts +218 -0
  57. package/templates/page/page.tsx +42 -0
  58. package/templates/performance-budgets.json +58 -0
  59. package/templates/registry.json +13 -0
  60. package/templates/settings.json +90 -0
  61. package/templates/shared/HeroHeader.tsx +261 -0
  62. package/templates/shared/index.ts +1 -0
  63. package/templates/ui-showcase/_components/PreviewCard.tsx +315 -0
  64. package/templates/ui-showcase/_components/PreviewModal.tsx +676 -0
  65. package/templates/ui-showcase/_components/UIShowcase.tsx +262 -0
  66. package/templates/ui-showcase/page.tsx +26 -0
  67. package/demo/hustle-together/blog/gemini-vs-claude-widgets.html +0 -959
  68. package/demo/hustle-together/blog/interview-driven-api-development.html +0 -1146
  69. package/demo/hustle-together/blog/tdd-for-ai.html +0 -982
  70. package/demo/hustle-together/index.html +0 -1312
  71. package/demo/workflow-demo-v3.5-backup.html +0 -5008
  72. package/demo/workflow-demo.html +0 -6202
@@ -0,0 +1,763 @@
1
+ # Hustle Combine - API and UI Orchestration Workflow v3.8.0
2
+
3
+ **Usage:** `/hustle-combine [api|ui]`
4
+
5
+ **Purpose:** Combines existing APIs or UI elements from the registry into new orchestration endpoints or composed components.
6
+
7
+ ## Overview
8
+
9
+ This command reads from `.claude/registry.json` to present available elements for combination. It creates NEW orchestration layers using EXISTING, tested components.
10
+
11
+ **Key Principle:** We're not creating new APIs from scratch - we're combining existing, working APIs into orchestration endpoints.
12
+
13
+ ---
14
+
15
+ ## CRITICAL: MANDATORY USER INTERACTION
16
+
17
+ **YOU MUST USE THE `AskUserQuestion` TOOL AT EVERY CHECKPOINT.**
18
+
19
+ This workflow requires REAL user input at each phase. You are **FORBIDDEN** from:
20
+ - Self-answering questions
21
+ - Assuming user responses
22
+ - Proceeding without explicit user confirmation
23
+ - Making decisions on behalf of the user
24
+
25
+ ### How to Ask Questions Correctly
26
+
27
+ At every prompt in this workflow, you MUST call the `AskUserQuestion` tool with this EXACT schema:
28
+
29
+ ```json
30
+ {
31
+ "questions": [
32
+ {
33
+ "question": "Your question here? (must end with ?)",
34
+ "header": "Phase",
35
+ "multiSelect": false,
36
+ "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"}
40
+ ]
41
+ }
42
+ ]
43
+ }
44
+ ```
45
+
46
+ **CRITICAL REQUIREMENTS:**
47
+ - `header`: Max 12 characters (e.g., "Mode", "Select", "Order")
48
+ - `options`: 2-4 options, each with `label` (1-5 words) and `description`
49
+ - `multiSelect`: Required boolean (true for checkboxes, false for radio)
50
+ - `question`: Must end with a question mark
51
+
52
+ **WAIT for the user's response before proceeding.** Do NOT continue until you receive the response.
53
+
54
+ ### Phase Exit Confirmation
55
+
56
+ **Every phase requires an EXIT CONFIRMATION question** before proceeding to the next phase.
57
+
58
+ Example:
59
+ ```json
60
+ {
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
+ }]
70
+ }
71
+ ```
72
+
73
+ ---
74
+
75
+ ## Mode Selection
76
+
77
+ When running `/hustle-combine`, first determine the mode:
78
+
79
+ Use AskUserQuestion:
80
+ ```json
81
+ {
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
+ }
92
+ ```
93
+
94
+ ---
95
+
96
+ ## Mode A: Combine APIs
97
+
98
+ ### 13 Phases for API Combination
99
+
100
+ ```
101
+ Phase 1: SELECTION - Present checkboxes from registry, user selects 2+ APIs
102
+ Phase 2: SCOPE - "What should this combined endpoint do?"
103
+ Phase 3: INITIAL RESEARCH - Orchestration patterns (lighter - APIs already researched)
104
+ Phase 4: INTERVIEW - Flow order, error handling, caching, naming
105
+ Phase 5: DEEP RESEARCH - Edge cases between APIs (optional/lighter)
106
+ Phase 6: COMBINED SCHEMA - Zod types composing existing schemas
107
+ Phase 7: ENVIRONMENT - Verify all required API keys exist
108
+ Phase 8: TDD RED - Integration tests for combined flow
109
+ Phase 9: TDD GREEN - Orchestration route implementation
110
+ 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
114
+ ```
115
+
116
+ ---
117
+
118
+ ### Phase 1: SELECTION (Programmatic from Registry)
119
+
120
+ Read `.claude/registry.json` and present available APIs.
121
+
122
+ **IMPORTANT:** Options are dynamically generated from registry.json. Only show APIs with `status: "complete"`.
123
+
124
+ Use AskUserQuestion with multiSelect:
125
+ ```json
126
+ {
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
+ }]
135
+ }
136
+ ```
137
+
138
+ **After selection, store in state:**
139
+ ```json
140
+ {
141
+ "workflow": "combine-api",
142
+ "combine_config": {
143
+ "mode": "api",
144
+ "source_elements": [
145
+ { "type": "api", "name": "api1" },
146
+ { "type": "api", "name": "api2" }
147
+ ]
148
+ }
149
+ }
150
+ ```
151
+
152
+ **Phase Exit:**
153
+ ```json
154
+ {
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
+ }]
164
+ }
165
+ ```
166
+
167
+ ---
168
+
169
+ ### Phase 2: SCOPE
170
+
171
+ Ask what the combined endpoint should do:
172
+
173
+ ```json
174
+ {
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
+ }]
183
+ }
184
+ ```
185
+
186
+ Store the purpose in state for later use in schema and tests.
187
+
188
+ **Phase Exit:**
189
+ ```json
190
+ {
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
+ }]
200
+ }
201
+ ```
202
+
203
+ ---
204
+
205
+ ### Phase 3: INITIAL RESEARCH (Lighter)
206
+
207
+ Since APIs already exist, focus ONLY on orchestration patterns:
208
+ - Gateway aggregation patterns
209
+ - Error propagation between services
210
+ - Response composition strategies
211
+
212
+ ```json
213
+ {
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
+ }]
223
+ }
224
+ ```
225
+
226
+ If user chooses to research, use WebSearch and Context7 for:
227
+ - "API gateway aggregation patterns"
228
+ - "Service composition error handling"
229
+ - "Response aggregation TypeScript patterns"
230
+
231
+ **Phase Exit:**
232
+ ```json
233
+ {
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
+ }]
243
+ }
244
+ ```
245
+
246
+ ---
247
+
248
+ ### Phase 4: INTERVIEW
249
+
250
+ Key questions for API combination (ask one at a time):
251
+
252
+ **Q1: Endpoint Name**
253
+ ```json
254
+ {
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
+ }]
264
+ }
265
+ ```
266
+
267
+ **Q2: Execution Order**
268
+ ```json
269
+ {
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
+ }]
280
+ }
281
+ ```
282
+
283
+ **Q3: Error Handling**
284
+ ```json
285
+ {
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
+ }]
296
+ }
297
+ ```
298
+
299
+ **Q4: Data Transformation**
300
+ ```json
301
+ {
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
+ }]
311
+ }
312
+ ```
313
+
314
+ **Q5: Caching**
315
+ ```json
316
+ {
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
+ }]
327
+ }
328
+ ```
329
+
330
+ **Store all decisions in state:**
331
+ ```json
332
+ {
333
+ "phases": {
334
+ "interview": {
335
+ "status": "complete",
336
+ "decisions": {
337
+ "endpoint_name": "brand-voice",
338
+ "execution_order": "sequential",
339
+ "error_strategy": "fail-fast",
340
+ "data_transformation": false,
341
+ "caching_strategy": "none"
342
+ }
343
+ }
344
+ }
345
+ }
346
+ ```
347
+
348
+ **Phase Exit:**
349
+ ```json
350
+ {
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
+ }]
360
+ }
361
+ ```
362
+
363
+ ---
364
+
365
+ ### Phase 5: DEEP RESEARCH (Optional)
366
+
367
+ Based on interview answers, propose targeted research:
368
+
369
+ ```json
370
+ {
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
+ }]
381
+ }
382
+ ```
383
+
384
+ Topics to propose based on interview:
385
+ - If sequential: "data passing between API calls"
386
+ - If parallel: "Promise.all error handling patterns"
387
+ - If retry: "exponential backoff strategies"
388
+ - If caching: "response caching with invalidation"
389
+
390
+ ---
391
+
392
+ ### Phase 6: COMBINED SCHEMA
393
+
394
+ Create Zod schema that COMPOSES existing schemas:
395
+
396
+ ```typescript
397
+ // 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';
401
+
402
+ // Combined request schema
403
+ export const CombinedRequestSchema = z.object({
404
+ // Fields needed by both APIs
405
+ });
406
+
407
+ // Combined response schema
408
+ export const CombinedResponseSchema = z.object({
409
+ api1: Api1ResponseSchema,
410
+ api2: Api2ResponseSchema,
411
+ combined_at: z.string(),
412
+ });
413
+
414
+ export type CombinedRequest = z.infer<typeof CombinedRequestSchema>;
415
+ export type CombinedResponse = z.infer<typeof CombinedResponseSchema>;
416
+ ```
417
+
418
+ **Ask for approval:**
419
+ ```json
420
+ {
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
+ }]
430
+ }
431
+ ```
432
+
433
+ ---
434
+
435
+ ### Phase 7: ENVIRONMENT CHECK
436
+
437
+ Verify all API keys from combined APIs are available.
438
+
439
+ Read the source API entries in registry.json to determine required environment variables.
440
+
441
+ Report:
442
+ ```
443
+ Environment Check:
444
+ [checkmark] API1_KEY - Found
445
+ [checkmark] API2_KEY - Found
446
+
447
+ All required keys available.
448
+ ```
449
+
450
+ ```json
451
+ {
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
+ }]
461
+ }
462
+ ```
463
+
464
+ ---
465
+
466
+ ### Phase 8: TDD RED (Integration Tests)
467
+
468
+ Write tests for the combined flow:
469
+
470
+ ```typescript
471
+ // src/app/api/v2/[combined-name]/__tests__/[combined-name].api.test.ts
472
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
473
+
474
+ describe('[Combined Name] API', () => {
475
+ describe('POST /api/v2/[combined-name]', () => {
476
+ it('should call both APIs and combine results', async () => {
477
+ // Test combined flow
478
+ });
479
+
480
+ it('should handle first API failure correctly', async () => {
481
+ // Test error handling based on interview decisions
482
+ });
483
+
484
+ // More tests based on interview decisions...
485
+ });
486
+ });
487
+ ```
488
+
489
+ Run tests - they should FAIL (Red phase).
490
+
491
+ **Phase Exit:**
492
+ ```json
493
+ {
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
+ }]
503
+ }
504
+ ```
505
+
506
+ ---
507
+
508
+ ### Phase 9: TDD GREEN (Orchestration Route)
509
+
510
+ Implement the orchestration logic:
511
+
512
+ ```typescript
513
+ // src/app/api/v2/[combined-name]/route.ts
514
+ import { NextRequest, NextResponse } from 'next/server';
515
+ import { CombinedRequestSchema } from './schemas';
516
+
517
+ export async function POST(request: NextRequest) {
518
+ try {
519
+ const body = await request.json();
520
+ const validated = CombinedRequestSchema.parse(body);
521
+
522
+ // Implementation based on interview decisions:
523
+ // - Sequential/Parallel/Conditional execution
524
+ // - Error handling strategy
525
+ // - Data transformation
526
+ // - Caching
527
+
528
+ return NextResponse.json({
529
+ // Combined response
530
+ combined_at: new Date().toISOString(),
531
+ });
532
+ } catch (error) {
533
+ return NextResponse.json(
534
+ { error: error.message },
535
+ { status: 500 }
536
+ );
537
+ }
538
+ }
539
+ ```
540
+
541
+ Run tests - all must pass (Green phase).
542
+
543
+ ---
544
+
545
+ ### Phase 10: VERIFY
546
+
547
+ Test the full flow end-to-end:
548
+
549
+ ```json
550
+ {
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
+ }]
560
+ }
561
+ ```
562
+
563
+ If verifying, make actual requests and report results.
564
+
565
+ ---
566
+
567
+ ### Phase 11: REFACTOR
568
+
569
+ Clean up the orchestration code:
570
+ - Extract reusable patterns
571
+ - Add error logging
572
+ - Optimize parallel calls if applicable
573
+ - Add JSDoc comments
574
+
575
+ Run tests after each change to ensure they still pass.
576
+
577
+ **Phase Exit:**
578
+ ```json
579
+ {
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
+ }]
589
+ }
590
+ ```
591
+
592
+ ---
593
+
594
+ ### Phase 12: DOCUMENTATION
595
+
596
+ Update:
597
+ 1. `api-tests-manifest.json` - Add new combined endpoint
598
+ 2. `registry.json` - Add to `combined` section
599
+ 3. Any project docs as needed
600
+
601
+ ```json
602
+ {
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
+ }]
612
+ }
613
+ ```
614
+
615
+ ---
616
+
617
+ ### Phase 13: COMPLETION
618
+
619
+ Update registry.json with the new combined API:
620
+
621
+ ```json
622
+ {
623
+ "combined": {
624
+ "[combined-name]": {
625
+ "name": "[Display Name]",
626
+ "type": "api",
627
+ "description": "[Purpose from interview]",
628
+ "combines": ["api1", "api2"],
629
+ "route": "src/app/api/v2/[combined-name]/route.ts",
630
+ "schemas": "src/app/api/v2/[combined-name]/schemas.ts",
631
+ "tests": "src/app/api/v2/[combined-name]/__tests__/",
632
+ "flow_type": "[sequential|parallel|conditional]",
633
+ "created_at": "[date]",
634
+ "status": "complete"
635
+ }
636
+ }
637
+ }
638
+ ```
639
+
640
+ **Final confirmation:**
641
+ ```json
642
+ {
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
+ }]
652
+ }
653
+ ```
654
+
655
+ ---
656
+
657
+ ## Mode B: Combine UI (Coming Soon)
658
+
659
+ UI combination requires `/hustle-ui-create` to be implemented first.
660
+
661
+ Three sub-modes planned:
662
+ - **A) Composed Component** - Combine existing components
663
+ - **B) Page with Components** - Create page using components
664
+ - **C) Page with Components + API** - Create page with data fetching
665
+
666
+ ---
667
+
668
+ ## State File Structure
669
+
670
+ ```json
671
+ {
672
+ "version": "3.8.0",
673
+ "workflow": "combine-api",
674
+ "element_name": "brand-voice",
675
+ "element_type": "combined",
676
+
677
+ "combine_config": {
678
+ "mode": "api",
679
+ "source_elements": [
680
+ { "type": "api", "name": "brandfetch" },
681
+ { "type": "api", "name": "elevenlabs" }
682
+ ],
683
+ "flow_type": "sequential",
684
+ "error_strategy": "fail-fast"
685
+ },
686
+
687
+ "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 }
701
+ }
702
+ }
703
+ ```
704
+
705
+ ---
706
+
707
+ ## Output Artifacts
708
+
709
+ 1. **Route Handler**: `/src/app/api/v2/[combined-name]/route.ts`
710
+ 2. **Schema File**: `/src/app/api/v2/[combined-name]/schemas.ts`
711
+ 3. **Test Suite**: `/src/app/api/v2/[combined-name]/__tests__/`
712
+ 4. **Updated Registry**: `.claude/registry.json` (combined section)
713
+ 5. **Updated Manifest**: `api-tests-manifest.json`
714
+
715
+ ---
716
+
717
+ ## Example: WordPress + Elementor
718
+
719
+ ```
720
+ /hustle-combine api
721
+
722
+ Available APIs:
723
+ [checkbox] wordpress - WordPress REST API
724
+ [checkbox] elementor - Elementor widget API
725
+ [checkbox] brandfetch - Brand data extraction
726
+
727
+ > wordpress, elementor
728
+
729
+ Purpose: "Log into WordPress, then create Elementor template"
730
+
731
+ Interview:
732
+ - Order: Sequential (WordPress auth first)
733
+ - Errors: Fail if WordPress auth fails
734
+ - Name: wp-elementor-sync
735
+
736
+ Creates:
737
+ src/app/api/v2/wp-elementor-sync/
738
+ ├── route.ts
739
+ ├── schemas.ts
740
+ └── __tests__/
741
+ ```
742
+
743
+ <claude-commands-template>
744
+ ## Project Rules
745
+
746
+ 1. **Registry Required**: Only combine APIs that exist in registry.json with `status: "complete"`
747
+ 2. **No Skipping Selection**: User MUST select from available APIs
748
+ 3. **Interview Required**: All decisions must come from user, not assumptions
749
+ 4. **Lighter Research**: Since APIs exist, research focuses on orchestration patterns only
750
+ 5. **Test Integration**: Tests verify APIs work together, not individual API behavior
751
+ 6. **Update Registry**: Always update registry.json on completion
752
+
753
+ ## Never Skip
754
+
755
+ - Phase 1 (Selection) - Must read from registry
756
+ - Phase 4 (Interview) - All orchestration decisions from user
757
+ - Phase 8 (TDD Red) - Integration tests first
758
+ - Phase 13 (Complete) - Registry update required
759
+
760
+ ## User Interaction Required
761
+
762
+ Every phase MUST use `AskUserQuestion` tool. Self-answering is FORBIDDEN.
763
+ </claude-commands-template>