@hustle-together/api-dev-tools 3.10.1 → 3.12.1

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 (178) 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 +331 -0
  9. package/.claude/commands/README.md +196 -0
  10. package/.claude/commands/add-command.md +212 -0
  11. package/.claude/commands/api-create.md +510 -0
  12. package/.claude/commands/api-env.md +51 -0
  13. package/.claude/commands/api-interview.md +344 -0
  14. package/.claude/commands/api-research.md +357 -0
  15. package/.claude/commands/api-status.md +279 -0
  16. package/.claude/commands/api-verify.md +232 -0
  17. package/.claude/commands/beepboop.md +96 -0
  18. package/.claude/commands/busycommit.md +111 -0
  19. package/.claude/commands/commit.md +82 -0
  20. package/.claude/commands/cycle.md +137 -0
  21. package/.claude/commands/gap.md +85 -0
  22. package/.claude/commands/green.md +137 -0
  23. package/.claude/commands/issue.md +187 -0
  24. package/.claude/commands/ntfy-setup.md +91 -0
  25. package/.claude/commands/ntfy-test.md +74 -0
  26. package/.claude/commands/plan.md +167 -0
  27. package/.claude/commands/pr.md +121 -0
  28. package/.claude/commands/publish.md +40 -0
  29. package/.claude/commands/red.md +137 -0
  30. package/.claude/commands/refactor.md +137 -0
  31. package/.claude/commands/spike.md +137 -0
  32. package/.claude/commands/summarize.md +93 -0
  33. package/.claude/commands/tdd.md +139 -0
  34. package/.claude/commands/worktree-add.md +307 -0
  35. package/.claude/commands/worktree-cleanup.md +275 -0
  36. package/.claude/hooks/api-workflow-check.py +227 -0
  37. package/.claude/hooks/enforce-deep-research.py +185 -0
  38. package/.claude/hooks/enforce-disambiguation.py +155 -0
  39. package/.claude/hooks/enforce-documentation.py +192 -0
  40. package/.claude/hooks/enforce-environment.py +253 -0
  41. package/.claude/hooks/enforce-external-research.py +328 -0
  42. package/.claude/hooks/enforce-interview.py +421 -0
  43. package/.claude/hooks/enforce-refactor.py +189 -0
  44. package/.claude/hooks/enforce-research.py +159 -0
  45. package/.claude/hooks/enforce-schema.py +186 -0
  46. package/.claude/hooks/enforce-scope.py +160 -0
  47. package/.claude/hooks/enforce-tdd-red.py +250 -0
  48. package/.claude/hooks/enforce-verify.py +186 -0
  49. package/.claude/hooks/periodic-reground.py +154 -0
  50. package/.claude/hooks/session-startup.py +151 -0
  51. package/.claude/hooks/track-tool-use.py +626 -0
  52. package/.claude/hooks/verify-after-green.py +282 -0
  53. package/.claude/hooks/verify-implementation.py +225 -0
  54. package/.claude/research/index.json +6 -0
  55. package/.claude/settings.json +144 -0
  56. package/.claude/settings.local.json +12 -0
  57. package/.claude-plugin/marketplace.json +103 -0
  58. package/.skills/README.md +293 -0
  59. package/.skills/_shared/convert-commands.py +192 -0
  60. package/.skills/_shared/hooks/api-workflow-check.py +227 -0
  61. package/.skills/_shared/hooks/enforce-deep-research.py +185 -0
  62. package/.skills/_shared/hooks/enforce-disambiguation.py +155 -0
  63. package/.skills/_shared/hooks/enforce-documentation.py +192 -0
  64. package/.skills/_shared/hooks/enforce-environment.py +253 -0
  65. package/.skills/_shared/hooks/enforce-external-research.py +328 -0
  66. package/.skills/_shared/hooks/enforce-interview.py +421 -0
  67. package/.skills/_shared/hooks/enforce-refactor.py +189 -0
  68. package/.skills/_shared/hooks/enforce-research.py +159 -0
  69. package/.skills/_shared/hooks/enforce-schema.py +186 -0
  70. package/.skills/_shared/hooks/enforce-scope.py +160 -0
  71. package/.skills/_shared/hooks/enforce-tdd-red.py +250 -0
  72. package/.skills/_shared/hooks/enforce-verify.py +186 -0
  73. package/.skills/_shared/hooks/periodic-reground.py +154 -0
  74. package/.skills/_shared/hooks/session-startup.py +151 -0
  75. package/.skills/_shared/hooks/track-tool-use.py +626 -0
  76. package/.skills/_shared/hooks/verify-after-green.py +282 -0
  77. package/.skills/_shared/hooks/verify-implementation.py +225 -0
  78. package/.skills/_shared/install.sh +114 -0
  79. package/.skills/_shared/settings.json +93 -0
  80. package/.skills/add-command/SKILL.md +227 -0
  81. package/.skills/api-create/SKILL.md +623 -0
  82. package/.skills/api-env/SKILL.md +64 -0
  83. package/.skills/api-interview/SKILL.md +357 -0
  84. package/.skills/api-research/SKILL.md +370 -0
  85. package/.skills/api-status/SKILL.md +292 -0
  86. package/.skills/api-verify/SKILL.md +245 -0
  87. package/.skills/beepboop/SKILL.md +111 -0
  88. package/.skills/busycommit/SKILL.md +126 -0
  89. package/.skills/commit/SKILL.md +97 -0
  90. package/.skills/cycle/SKILL.md +152 -0
  91. package/.skills/gap/SKILL.md +100 -0
  92. package/.skills/green/SKILL.md +152 -0
  93. package/.skills/issue/SKILL.md +202 -0
  94. package/.skills/plan/SKILL.md +182 -0
  95. package/.skills/pr/SKILL.md +136 -0
  96. package/.skills/publish/SKILL.md +160 -0
  97. package/.skills/red/SKILL.md +152 -0
  98. package/.skills/refactor/SKILL.md +152 -0
  99. package/.skills/spike/SKILL.md +152 -0
  100. package/.skills/summarize/SKILL.md +108 -0
  101. package/.skills/tdd/SKILL.md +154 -0
  102. package/.skills/update-todos/SKILL.md +250 -0
  103. package/.skills/worktree-add/SKILL.md +322 -0
  104. package/.skills/worktree-cleanup/SKILL.md +290 -0
  105. package/CHANGELOG.md +115 -0
  106. package/README.md +161 -7101
  107. package/bin/cli.js +448 -805
  108. package/commands/README.md +66 -31
  109. package/commands/add-command.md +8 -5
  110. package/commands/beepboop.md +4 -5
  111. package/commands/busycommit.md +2 -3
  112. package/commands/commit.md +2 -3
  113. package/commands/cycle.md +2 -7
  114. package/commands/gap.md +2 -3
  115. package/commands/green.md +2 -7
  116. package/commands/hustle-api-continue.md +8 -5
  117. package/commands/hustle-api-create.md +70 -29
  118. package/commands/hustle-api-env.md +1 -0
  119. package/commands/hustle-api-interview.md +32 -19
  120. package/commands/hustle-api-research.md +47 -21
  121. package/commands/hustle-api-sessions.md +8 -7
  122. package/commands/hustle-api-status.md +21 -1
  123. package/commands/hustle-api-verify.md +14 -13
  124. package/commands/hustle-combine.md +488 -241
  125. package/commands/hustle-ui-create-page.md +113 -50
  126. package/commands/hustle-ui-create.md +179 -26
  127. package/commands/issue.md +3 -8
  128. package/commands/plan.md +2 -3
  129. package/commands/pr.md +2 -3
  130. package/commands/red.md +2 -7
  131. package/commands/refactor.md +2 -7
  132. package/commands/spike.md +2 -7
  133. package/commands/summarize.md +2 -3
  134. package/commands/tdd.md +2 -7
  135. package/commands/worktree-add.md +208 -216
  136. package/commands/worktree-cleanup.md +172 -178
  137. package/hooks/api-workflow-check.py +5 -3
  138. package/hooks/enforce-component-type-confirm.py +97 -0
  139. package/hooks/lib/__init__.py +1 -0
  140. package/hooks/lib/greptile.py +355 -0
  141. package/hooks/lib/ntfy.py +209 -0
  142. package/hooks/notify-input-needed.py +73 -0
  143. package/hooks/notify-phase-complete.py +90 -0
  144. package/hooks/run-code-review.py +246 -0
  145. package/hooks/track-token-usage.py +121 -0
  146. package/package.json +33 -12
  147. package/scripts/collect-test-results.ts +102 -77
  148. package/scripts/extract-parameters.ts +112 -70
  149. package/scripts/generate-test-manifest.ts +118 -77
  150. package/templates/.env.example +57 -0
  151. package/templates/BRAND_GUIDE.md +92 -52
  152. package/templates/CLAUDE-SECTION.md +40 -37
  153. package/templates/SPEC.json +186 -38
  154. package/templates/api-dev-state.json +33 -4
  155. package/templates/api-showcase/_components/APICard.tsx +22 -18
  156. package/templates/api-showcase/_components/APIModal.tsx +110 -64
  157. package/templates/api-showcase/_components/APIShowcase.tsx +53 -35
  158. package/templates/api-showcase/_components/APITester.tsx +128 -67
  159. package/templates/api-showcase/page.tsx +4 -4
  160. package/templates/api-test/page.tsx +51 -30
  161. package/templates/api-test/test-structure/route.ts +43 -34
  162. package/templates/component/Component.stories.tsx +41 -39
  163. package/templates/component/Component.test.tsx +96 -78
  164. package/templates/component/Component.tsx +63 -52
  165. package/templates/component/Component.types.ts +10 -6
  166. package/templates/component/Component.visual.spec.ts +170 -0
  167. package/templates/component/index.ts +2 -2
  168. package/templates/dev-tools/_components/DevToolsLanding.tsx +8 -8
  169. package/templates/dev-tools/page.tsx +4 -3
  170. package/templates/mcp-servers.json +30 -2
  171. package/templates/page/page.e2e.test.ts +56 -48
  172. package/templates/page/page.tsx +3 -3
  173. package/templates/shared/HeroHeader.tsx +16 -15
  174. package/templates/shared/index.ts +1 -1
  175. package/templates/ui-showcase/_components/PreviewCard.tsx +20 -20
  176. package/templates/ui-showcase/_components/PreviewModal.tsx +149 -108
  177. package/templates/ui-showcase/_components/UIShowcase.tsx +43 -35
  178. package/templates/ui-showcase/page.tsx +4 -4
@@ -1,15 +1,15 @@
1
- 'use client';
1
+ "use client";
2
2
 
3
- import { useState, useMemo } from 'react';
4
- import { HeroHeader } from '../shared/HeroHeader';
5
- import { PreviewCard } from './PreviewCard';
6
- import { PreviewModal } from './PreviewModal';
3
+ import { useState, useMemo } from "react";
4
+ import { HeroHeader } from "../shared/HeroHeader";
5
+ import { PreviewCard } from "./PreviewCard";
6
+ import { PreviewModal } from "./PreviewModal";
7
7
 
8
8
  // Import registry - this will be updated by the CLI when components are created
9
9
  // Note: In production, this could be fetched from an API route
10
- import registry from '@/../.claude/registry.json';
10
+ import registry from "@/../.claude/registry.json";
11
11
 
12
- type FilterType = 'all' | 'components' | 'pages';
12
+ type FilterType = "all" | "components" | "pages";
13
13
 
14
14
  interface RegistryItem {
15
15
  name: string;
@@ -48,11 +48,11 @@ interface Registry {
48
48
  * Created with Hustle API Dev Tools (v3.9.2)
49
49
  */
50
50
  export function UIShowcase() {
51
- const [filter, setFilter] = useState<FilterType>('all');
52
- const [searchQuery, setSearchQuery] = useState('');
51
+ const [filter, setFilter] = useState<FilterType>("all");
52
+ const [searchQuery, setSearchQuery] = useState("");
53
53
  const [selectedItem, setSelectedItem] = useState<{
54
54
  id: string;
55
- type: 'component' | 'page';
55
+ type: "component" | "page";
56
56
  data: RegistryItem;
57
57
  } | null>(null);
58
58
 
@@ -63,18 +63,18 @@ export function UIShowcase() {
63
63
  const allItems = useMemo(() => {
64
64
  const items: Array<{
65
65
  id: string;
66
- type: 'component' | 'page';
66
+ type: "component" | "page";
67
67
  data: RegistryItem;
68
68
  }> = [];
69
69
 
70
70
  // Add components
71
71
  Object.entries(typedRegistry.components || {}).forEach(([id, data]) => {
72
- items.push({ id, type: 'component', data });
72
+ items.push({ id, type: "component", data });
73
73
  });
74
74
 
75
75
  // Add pages
76
76
  Object.entries(typedRegistry.pages || {}).forEach(([id, data]) => {
77
- items.push({ id, type: 'page', data });
77
+ items.push({ id, type: "page", data });
78
78
  });
79
79
 
80
80
  return items;
@@ -84,7 +84,7 @@ export function UIShowcase() {
84
84
  const filteredItems = useMemo(() => {
85
85
  return allItems.filter((item) => {
86
86
  // Type filter
87
- if (filter !== 'all' && filter !== `${item.type}s`) {
87
+ if (filter !== "all" && filter !== `${item.type}s`) {
88
88
  return false;
89
89
  }
90
90
 
@@ -92,7 +92,9 @@ export function UIShowcase() {
92
92
  if (searchQuery) {
93
93
  const query = searchQuery.toLowerCase();
94
94
  const matchesName = item.data.name?.toLowerCase().includes(query);
95
- const matchesDescription = item.data.description?.toLowerCase().includes(query);
95
+ const matchesDescription = item.data.description
96
+ ?.toLowerCase()
97
+ .includes(query);
96
98
  return matchesName || matchesDescription;
97
99
  }
98
100
 
@@ -112,8 +114,8 @@ export function UIShowcase() {
112
114
  badge="Component Library"
113
115
  description={
114
116
  <>
115
- Live preview and testing for all{' '}
116
- <strong>Hustle</strong> components and pages.
117
+ Live preview and testing for all <strong>Hustle</strong> components
118
+ and pages.
117
119
  </>
118
120
  }
119
121
  />
@@ -125,11 +127,17 @@ export function UIShowcase() {
125
127
  {/* Stats */}
126
128
  <div className="flex items-center gap-4">
127
129
  <span className="text-sm text-gray-600 dark:text-gray-400">
128
- <strong className="text-black dark:text-white">{componentCount}</strong> components
130
+ <strong className="text-black dark:text-white">
131
+ {componentCount}
132
+ </strong>{" "}
133
+ components
129
134
  </span>
130
135
  <span className="h-4 w-px bg-black dark:bg-gray-600" />
131
136
  <span className="text-sm text-gray-600 dark:text-gray-400">
132
- <strong className="text-black dark:text-white">{pageCount}</strong> pages
137
+ <strong className="text-black dark:text-white">
138
+ {pageCount}
139
+ </strong>{" "}
140
+ pages
133
141
  </span>
134
142
  </div>
135
143
 
@@ -148,31 +156,31 @@ export function UIShowcase() {
148
156
  {/* Filter Tabs */}
149
157
  <div className="mt-4 flex gap-2">
150
158
  <button
151
- onClick={() => setFilter('all')}
159
+ onClick={() => setFilter("all")}
152
160
  className={`border-2 px-3 py-1.5 text-sm font-bold transition-colors ${
153
- filter === 'all'
154
- ? 'border-[#BA0C2F] bg-[#BA0C2F] text-white'
155
- : 'border-black bg-white text-black hover:border-[#BA0C2F] dark:border-gray-600 dark:bg-gray-800 dark:text-white'
161
+ filter === "all"
162
+ ? "border-[#BA0C2F] bg-[#BA0C2F] text-white"
163
+ : "border-black bg-white text-black hover:border-[#BA0C2F] dark:border-gray-600 dark:bg-gray-800 dark:text-white"
156
164
  }`}
157
165
  >
158
166
  All ({allItems.length})
159
167
  </button>
160
168
  <button
161
- onClick={() => setFilter('components')}
169
+ onClick={() => setFilter("components")}
162
170
  className={`border-2 px-3 py-1.5 text-sm font-bold transition-colors ${
163
- filter === 'components'
164
- ? 'border-[#BA0C2F] bg-[#BA0C2F] text-white'
165
- : 'border-black bg-white text-black hover:border-[#BA0C2F] dark:border-gray-600 dark:bg-gray-800 dark:text-white'
171
+ filter === "components"
172
+ ? "border-[#BA0C2F] bg-[#BA0C2F] text-white"
173
+ : "border-black bg-white text-black hover:border-[#BA0C2F] dark:border-gray-600 dark:bg-gray-800 dark:text-white"
166
174
  }`}
167
175
  >
168
176
  Components ({componentCount})
169
177
  </button>
170
178
  <button
171
- onClick={() => setFilter('pages')}
179
+ onClick={() => setFilter("pages")}
172
180
  className={`border-2 px-3 py-1.5 text-sm font-bold transition-colors ${
173
- filter === 'pages'
174
- ? 'border-[#BA0C2F] bg-[#BA0C2F] text-white'
175
- : 'border-black bg-white text-black hover:border-[#BA0C2F] dark:border-gray-600 dark:bg-gray-800 dark:text-white'
181
+ filter === "pages"
182
+ ? "border-[#BA0C2F] bg-[#BA0C2F] text-white"
183
+ : "border-black bg-white text-black hover:border-[#BA0C2F] dark:border-gray-600 dark:bg-gray-800 dark:text-white"
176
184
  }`}
177
185
  >
178
186
  Pages ({pageCount})
@@ -204,12 +212,12 @@ export function UIShowcase() {
204
212
  </svg>
205
213
  </div>
206
214
  <h2 className="text-xl font-bold text-black dark:text-white">
207
- {searchQuery ? 'No results found' : 'No items yet'}
215
+ {searchQuery ? "No results found" : "No items yet"}
208
216
  </h2>
209
217
  <p className="mt-2 text-sm text-gray-600 dark:text-gray-400">
210
218
  {searchQuery
211
219
  ? `No components or pages match "${searchQuery}"`
212
- : 'Run /ui-create to add components and pages'}
220
+ : "Run /ui-create to add components and pages"}
213
221
  </p>
214
222
  </div>
215
223
  ) : (
@@ -245,7 +253,7 @@ export function UIShowcase() {
245
253
  {/* Footer */}
246
254
  <footer className="border-t-2 border-black py-6 text-center text-sm text-gray-600 dark:border-gray-600 dark:text-gray-400">
247
255
  <p>
248
- Created with{' '}
256
+ Created with{" "}
249
257
  <a
250
258
  href="https://github.com/hustle-together/api-dev-tools"
251
259
  target="_blank"
@@ -253,7 +261,7 @@ export function UIShowcase() {
253
261
  className="font-bold text-black hover:text-[#BA0C2F] dark:text-white"
254
262
  >
255
263
  Hustle API Dev Tools
256
- </a>{' '}
264
+ </a>{" "}
257
265
  v3.9.2
258
266
  </p>
259
267
  </footer>
@@ -1,9 +1,9 @@
1
- import type { Metadata } from 'next';
2
- import { UIShowcase } from './UIShowcase';
1
+ import type { Metadata } from "next";
2
+ import { UIShowcase } from "./UIShowcase";
3
3
 
4
4
  export const metadata: Metadata = {
5
- title: 'UI Showcase',
6
- description: 'Preview all components and pages created with Hustle UI Create',
5
+ title: "UI Showcase",
6
+ description: "Preview all components and pages created with Hustle UI Create",
7
7
  };
8
8
 
9
9
  /**