@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.
- package/.claude/agents/code-reviewer.md +170 -0
- package/.claude/agents/docs-generator.md +80 -0
- package/.claude/agents/implementation-reviewer.md +119 -0
- package/.claude/agents/parallel-researcher.md +52 -0
- package/.claude/agents/research-validator.md +116 -0
- package/.claude/agents/schema-generator.md +70 -0
- package/.claude/agents/test-writer.md +104 -0
- package/.claude/api-dev-state.json +305 -56
- package/.claude/commands/README.md +21 -10
- package/.claude/commands/add-command.md +8 -5
- package/.claude/commands/api-create.md +36 -25
- package/.claude/commands/api-env.md +1 -0
- package/.claude/commands/api-interview.md +32 -19
- package/.claude/commands/api-research.md +47 -21
- package/.claude/commands/api-status.md +21 -1
- package/.claude/commands/api-verify.md +14 -13
- package/.claude/commands/beepboop.md +4 -5
- package/.claude/commands/busycommit.md +2 -3
- package/.claude/commands/commit.md +2 -3
- package/.claude/commands/cycle.md +2 -7
- package/.claude/commands/gap.md +2 -3
- package/.claude/commands/green.md +2 -7
- package/.claude/commands/issue.md +3 -8
- package/.claude/commands/ntfy-setup.md +91 -0
- package/.claude/commands/ntfy-test.md +74 -0
- package/.claude/commands/plan.md +2 -3
- package/.claude/commands/pr.md +2 -3
- package/.claude/commands/publish.md +40 -0
- package/.claude/commands/red.md +2 -7
- package/.claude/commands/refactor.md +2 -7
- package/.claude/commands/spike.md +2 -7
- package/.claude/commands/summarize.md +2 -3
- package/.claude/commands/tdd.md +2 -7
- package/.claude/commands/worktree-add.md +208 -216
- package/.claude/commands/worktree-cleanup.md +172 -178
- package/.claude/settings.json +63 -12
- package/.claude/settings.local.json +2 -1
- package/.claude-plugin/marketplace.json +2 -11
- package/.skills/README.md +55 -53
- package/.skills/_shared/settings.json +1 -1
- package/.skills/add-command/SKILL.md +10 -5
- package/.skills/api-create/SKILL.md +146 -35
- package/.skills/api-env/SKILL.md +1 -0
- package/.skills/api-interview/SKILL.md +32 -19
- package/.skills/api-research/SKILL.md +47 -21
- package/.skills/api-status/SKILL.md +21 -1
- package/.skills/api-verify/SKILL.md +14 -13
- package/.skills/beepboop/SKILL.md +6 -5
- package/.skills/busycommit/SKILL.md +4 -3
- package/.skills/commit/SKILL.md +4 -3
- package/.skills/cycle/SKILL.md +4 -7
- package/.skills/gap/SKILL.md +4 -3
- package/.skills/green/SKILL.md +4 -7
- package/.skills/issue/SKILL.md +5 -8
- package/.skills/plan/SKILL.md +4 -3
- package/.skills/pr/SKILL.md +4 -3
- package/.skills/publish/SKILL.md +160 -0
- package/.skills/red/SKILL.md +4 -7
- package/.skills/refactor/SKILL.md +4 -7
- package/.skills/spike/SKILL.md +4 -7
- package/.skills/summarize/SKILL.md +4 -3
- package/.skills/tdd/SKILL.md +4 -7
- package/.skills/update-todos/SKILL.md +22 -0
- package/.skills/worktree-add/SKILL.md +210 -216
- package/.skills/worktree-cleanup/SKILL.md +183 -187
- package/CHANGELOG.md +97 -79
- package/README.md +161 -7142
- package/bin/cli.js +448 -805
- package/commands/README.md +66 -31
- package/commands/add-command.md +8 -5
- package/commands/beepboop.md +4 -5
- package/commands/busycommit.md +2 -3
- package/commands/commit.md +2 -3
- package/commands/cycle.md +2 -7
- package/commands/gap.md +2 -3
- package/commands/green.md +2 -7
- package/commands/hustle-api-continue.md +8 -5
- package/commands/hustle-api-create.md +70 -29
- package/commands/hustle-api-env.md +1 -0
- package/commands/hustle-api-interview.md +32 -19
- package/commands/hustle-api-research.md +47 -21
- package/commands/hustle-api-sessions.md +8 -7
- package/commands/hustle-api-status.md +21 -1
- package/commands/hustle-api-verify.md +14 -13
- package/commands/hustle-combine.md +488 -241
- package/commands/hustle-ui-create-page.md +113 -50
- package/commands/hustle-ui-create.md +179 -26
- package/commands/issue.md +3 -8
- package/commands/plan.md +2 -3
- package/commands/pr.md +2 -3
- package/commands/red.md +2 -7
- package/commands/refactor.md +2 -7
- package/commands/spike.md +2 -7
- package/commands/summarize.md +2 -3
- package/commands/tdd.md +2 -7
- package/commands/worktree-add.md +208 -216
- package/commands/worktree-cleanup.md +172 -178
- package/hooks/api-workflow-check.py +5 -3
- package/hooks/enforce-component-type-confirm.py +97 -0
- package/hooks/lib/__init__.py +1 -0
- package/hooks/lib/greptile.py +355 -0
- package/hooks/lib/ntfy.py +209 -0
- package/hooks/notify-input-needed.py +73 -0
- package/hooks/notify-phase-complete.py +90 -0
- package/hooks/run-code-review.py +246 -0
- package/hooks/track-token-usage.py +121 -0
- package/package.json +13 -3
- package/scripts/collect-test-results.ts +102 -77
- package/scripts/extract-parameters.ts +112 -70
- package/scripts/generate-test-manifest.ts +118 -77
- package/templates/.env.example +57 -0
- package/templates/BRAND_GUIDE.md +92 -52
- package/templates/CLAUDE-SECTION.md +40 -37
- package/templates/SPEC.json +186 -38
- package/templates/api-dev-state.json +33 -4
- package/templates/api-showcase/_components/APICard.tsx +22 -18
- package/templates/api-showcase/_components/APIModal.tsx +110 -64
- package/templates/api-showcase/_components/APIShowcase.tsx +53 -35
- package/templates/api-showcase/_components/APITester.tsx +128 -67
- package/templates/api-showcase/page.tsx +4 -4
- package/templates/api-test/page.tsx +51 -30
- package/templates/api-test/test-structure/route.ts +43 -34
- package/templates/component/Component.stories.tsx +41 -39
- package/templates/component/Component.test.tsx +96 -78
- package/templates/component/Component.tsx +63 -52
- package/templates/component/Component.types.ts +10 -6
- package/templates/component/Component.visual.spec.ts +170 -0
- package/templates/component/index.ts +2 -2
- package/templates/dev-tools/_components/DevToolsLanding.tsx +8 -8
- package/templates/dev-tools/page.tsx +4 -3
- package/templates/mcp-servers.json +30 -2
- package/templates/page/page.e2e.test.ts +56 -48
- package/templates/page/page.tsx +3 -3
- package/templates/shared/HeroHeader.tsx +16 -15
- package/templates/shared/index.ts +1 -1
- package/templates/ui-showcase/_components/PreviewCard.tsx +20 -20
- package/templates/ui-showcase/_components/PreviewModal.tsx +149 -108
- package/templates/ui-showcase/_components/UIShowcase.tsx +43 -35
- package/templates/ui-showcase/page.tsx +4 -4
|
@@ -24,191 +24,186 @@ Current worktrees: !git worktree list`
|
|
|
24
24
|
|
|
25
25
|
<execution_steps>
|
|
26
26
|
<step_0>
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
If MCP validation fails:
|
|
39
|
-
- Show clear error message
|
|
40
|
-
- Provide setup instructions
|
|
41
|
-
- Fallback to CLI if possible
|
|
42
|
-
</error_handling>
|
|
43
|
-
<purpose>Ensure required MCP dependencies are available before proceeding</purpose>
|
|
27
|
+
<description>Validate MCP dependencies</description>
|
|
28
|
+
<check_github_mcp>
|
|
29
|
+
<requirement>GitHub MCP server must be configured</requirement>
|
|
30
|
+
<fallback>If unavailable, use `gh` CLI commands</fallback>
|
|
31
|
+
<validation> - Try listing available MCP resources - If GitHub MCP not found, switch to CLI fallback - Inform user about MCP configuration if needed
|
|
32
|
+
</validation>
|
|
33
|
+
</check_github_mcp>
|
|
34
|
+
<error_handling>
|
|
35
|
+
If MCP validation fails: - Show clear error message - Provide setup instructions - Fallback to CLI if possible
|
|
36
|
+
</error_handling>
|
|
37
|
+
<purpose>Ensure required MCP dependencies are available before proceeding</purpose>
|
|
44
38
|
</step_0>
|
|
45
39
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
40
|
+
<step_1>
|
|
41
|
+
<description>Verify we're in main branch</description>
|
|
42
|
+
<check_command>git branch --show-current</check_command>
|
|
43
|
+
<required_branch>main</required_branch>
|
|
44
|
+
<error_if_not_main>Exit with error message: "This command must be run from the main branch"</error_if_not_main>
|
|
45
|
+
<purpose>Ensure we're consolidating to the main worktree</purpose>
|
|
46
|
+
</step_1>
|
|
53
47
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
48
|
+
<step_2>
|
|
49
|
+
<description>Get list of all worktrees</description>
|
|
50
|
+
<command>git worktree list --porcelain</command>
|
|
51
|
+
<parse_output>Extract worktree paths and branch names</parse_output>
|
|
52
|
+
<exclude_main>Filter out the main worktree from cleanup candidates</exclude_main>
|
|
53
|
+
<purpose>Identify all worktrees that could potentially be cleaned up</purpose>
|
|
54
|
+
</step_2>
|
|
61
55
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
56
|
+
<step_3>
|
|
57
|
+
<description>Find oldest worktree by directory age</description>
|
|
58
|
+
<get_worktree_ages>
|
|
59
|
+
<command_macos>git worktree list | grep -v "main" | awk '{print $1}' | while read path; do /usr/bin/stat -f "%Sm|%N" -t "%Y-%m-%d %H:%M:%S" "$path" 2>/dev/null; done | sort</command_macos>
|
|
60
|
+
<command_linux>git worktree list | grep -v "main" | awk '{print $1}' | xargs stat -c "%y|%n" | sort</command_linux>
|
|
61
|
+
<purpose>List all worktrees sorted by directory modification time (oldest first)</purpose>
|
|
62
|
+
<note>Use full path /usr/bin/stat on macOS, regular stat on Linux.</note>
|
|
63
|
+
</get_worktree_ages>
|
|
64
|
+
<filter_recent>
|
|
65
|
+
<exclude_new>For worktrees created within the last 24 hours, let user know that this worktree might not be worth cleaning</exclude_new>
|
|
66
|
+
<get_current_time>date +"%Y-%m-%d %H:%M"</get_current_time>
|
|
67
|
+
</filter_recent>
|
|
68
|
+
<select_oldest>
|
|
69
|
+
<extract_branch_name>Parse branch name from oldest worktree path</extract_branch_name>
|
|
70
|
+
<important_note>DO NOT use "git branch --merged" to check merge status - it's unreliable</important_note>
|
|
71
|
+
<proceed_to_pr_check>Move directly to step 4 to verify PR merge status instead</proceed_to_pr_check>
|
|
72
|
+
</select_oldest>
|
|
73
|
+
<purpose>Identify oldest worktree candidate - actual merge verification happens via GitHub PR in next step</purpose>
|
|
74
|
+
</step_3>
|
|
81
75
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
76
|
+
<step_4>
|
|
77
|
+
<description>Verify GitHub PR merge status (primary merge verification)</description>
|
|
78
|
+
<determine_repo>
|
|
79
|
+
<check_remote>git remote get-url origin</check_remote>
|
|
80
|
+
<parse_repo>Extract owner/repo from GitHub URL</parse_repo>
|
|
81
|
+
<fallback>Use project repository from git remote (owner/repo format)</fallback>
|
|
82
|
+
</determine_repo>
|
|
83
|
+
<search_pr>
|
|
84
|
+
<tool>mcp**github**search_pull_requests</tool>
|
|
85
|
+
<query>repo:owner/repo head:{branch_name} base:main</query>
|
|
86
|
+
<purpose>Find PR for this branch targeting main</purpose>
|
|
87
|
+
<important>This is the PRIMARY way to verify if a branch was merged - NOT git commands</important>
|
|
88
|
+
</search_pr>
|
|
89
|
+
<verify_pr_merged>
|
|
90
|
+
<if_pr_found>
|
|
91
|
+
<get_pr_details>Use mcp**github**pull_request_read to get full PR info</get_pr_details>
|
|
92
|
+
<confirm_merged>Verify PR state is "closed" AND merged_at is not null AND base is "main"</confirm_merged>
|
|
93
|
+
<extract_issue_number>Look for issue references in PR title/body (e.g., #14533, owner/repo#14533)</extract_issue_number>
|
|
94
|
+
<if_merged>Proceed with cleanup - this branch was definitively merged to main</if_merged>
|
|
95
|
+
<if_not_merged>
|
|
96
|
+
<skip_worktree>This worktree is NOT merged - continue to next oldest worktree</skip_worktree>
|
|
97
|
+
<repeat_from_step_3>Go back and find the next oldest worktree to check</repeat_from_step_3>
|
|
98
|
+
</if_not_merged>
|
|
99
|
+
</if_pr_found>
|
|
100
|
+
<if_no_pr>
|
|
101
|
+
<skip_worktree>No PR found - this branch was likely never submitted for review</skip_worktree>
|
|
102
|
+
<continue_to_next>Continue checking next oldest worktree</continue_to_next>
|
|
103
|
+
</if_no_pr>
|
|
104
|
+
</verify_pr_merged>
|
|
105
|
+
<purpose>Use GitHub PR status as the authoritative source for merge verification instead of unreliable git commands</purpose>
|
|
106
|
+
</step_4>
|
|
113
107
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
108
|
+
<step_4_5>
|
|
109
|
+
<description>Check and close related GitHub issue</description>
|
|
110
|
+
<if_issue_found>
|
|
111
|
+
<get_issue_details>
|
|
112
|
+
<tool>mcp**github**issue_read</tool>
|
|
113
|
+
<method>get</method>
|
|
114
|
+
<extract_repo>From issue reference (main-repo vs cross-repo)</extract_repo>
|
|
115
|
+
</get_issue_details>
|
|
116
|
+
<check_issue_state>
|
|
117
|
+
<if_open>
|
|
118
|
+
<ask_close>Ask user: "Related issue #{number} is still open. Should I close it? (y/N)"</ask_close>
|
|
119
|
+
<if_yes_close>
|
|
120
|
+
<add_closing_comment>
|
|
121
|
+
<tool>mcp**github**add_issue_comment</tool>
|
|
122
|
+
<body_template>Closing this issue as branch {branch_name} was merged to main on {merge_date} via PR #{pr_number}.</body_template>
|
|
123
|
+
<get_merge_date>Extract merge date from PR details</get_merge_date>
|
|
124
|
+
<get_pr_number>Use PR number from search results</get_pr_number>
|
|
125
|
+
</add_closing_comment>
|
|
126
|
+
<close_issue>
|
|
127
|
+
<tool>mcp**github**issue_write</tool>
|
|
128
|
+
<method>update</method>
|
|
129
|
+
<state>closed</state>
|
|
130
|
+
<state_reason>completed</state_reason>
|
|
131
|
+
</close_issue>
|
|
132
|
+
</if_yes_close>
|
|
133
|
+
</if_open>
|
|
134
|
+
<if_closed>Inform user issue is already closed</if_closed>
|
|
135
|
+
</check_issue_state>
|
|
136
|
+
</if_issue_found>
|
|
137
|
+
<if_no_issue>Continue without issue management</if_no_issue>
|
|
138
|
+
<purpose>Ensure proper issue lifecycle management</purpose>
|
|
139
|
+
</step_4_5>
|
|
146
140
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
141
|
+
<step_5>
|
|
142
|
+
<description>Check if worktree is locked</description>
|
|
143
|
+
<check_command>git worktree list --porcelain | grep -A5 "worktree {path}" | grep "locked"</check_command>
|
|
144
|
+
<if_locked>
|
|
145
|
+
<unlock_command>git worktree unlock {path}</unlock_command>
|
|
146
|
+
<notify_user>Inform user that worktree was unlocked</notify_user>
|
|
147
|
+
</if_locked>
|
|
148
|
+
<purpose>Unlock worktree if it was locked for tracking purposes</purpose>
|
|
149
|
+
</step_5>
|
|
156
150
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
151
|
+
<step_6>
|
|
152
|
+
<description>Analyze Claude settings differences</description>
|
|
153
|
+
<read_main_settings>.claude/settings.local.json</read_main_settings>
|
|
154
|
+
<read_worktree_settings>{worktree_path}/.claude/settings.local.json</read_worktree_settings>
|
|
155
|
+
<compare_allow_lists>
|
|
156
|
+
<extract_main_allows>Extract "allow" array from main settings</extract_main_allows>
|
|
157
|
+
<extract_worktree_allows>Extract "allow" array from worktree settings</extract_worktree_allows>
|
|
158
|
+
<find_differences>Identify entries in worktree that are not in main</find_differences>
|
|
159
|
+
</compare_allow_lists>
|
|
160
|
+
<filter_suggestions>
|
|
161
|
+
<include_filesystem>Read permissions for filesystem paths</include_filesystem>
|
|
162
|
+
<exclude_intrusive>Exclude bash commands, write permissions, etc.</exclude_intrusive>
|
|
163
|
+
<focus_user_specific>Include only user-specific, non-disruptive entries</focus_user_specific>
|
|
164
|
+
</filter_suggestions>
|
|
165
|
+
<purpose>Identify useful settings to consolidate before cleanup</purpose>
|
|
166
|
+
</step_6>
|
|
173
167
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
168
|
+
<step_7>
|
|
169
|
+
<description>Suggest settings consolidation</description>
|
|
170
|
+
<if_differences_found>
|
|
171
|
+
<display_suggestions>Show filtered differences to user</display_suggestions>
|
|
172
|
+
<ask_confirmation>Ask user which entries to add to main settings</ask_confirmation>
|
|
173
|
+
<apply_changes>Update main .claude/settings.local.json with selected entries</apply_changes>
|
|
174
|
+
</if_differences_found>
|
|
175
|
+
<if_no_differences>Inform user no settings need consolidation</if_no_differences>
|
|
176
|
+
<purpose>Preserve useful development settings before removing worktree</purpose>
|
|
177
|
+
</step_7>
|
|
184
178
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
<summary>
|
|
188
|
-
<display_worktree>Show worktree path and branch name</display_worktree>
|
|
189
|
-
<show_pr_status>Show merged PR details if found</show_pr_status>
|
|
190
|
-
<show_issue_status>Show related issue status if found</show_issue_status>
|
|
191
|
-
<show_last_activity>Display directory creation/modification date</show_last_activity>
|
|
192
|
-
</summary>
|
|
193
|
-
<safety_checks>
|
|
194
|
-
<check_uncommitted>git status --porcelain in worktree directory</check_uncommitted>
|
|
195
|
-
<warn_if_dirty>Alert user if uncommitted changes exist</warn_if_dirty>
|
|
196
|
-
</safety_checks>
|
|
197
|
-
<ask_deletion>Ask user confirmation: "Delete this worktree? (y/N)"</ask_deletion>
|
|
198
|
-
<purpose>Final safety check before irreversible deletion</purpose>
|
|
199
|
-
</step_8>
|
|
179
|
+
<step_8>
|
|
180
|
+
<description>Final cleanup confirmation</description>
|
|
200
181
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
182
|
+
<summary>
|
|
183
|
+
<display_worktree>Show worktree path and branch name</display_worktree>
|
|
184
|
+
<show_pr_status>Show merged PR details if found</show_pr_status>
|
|
185
|
+
<show_issue_status>Show related issue status if found</show_issue_status>
|
|
186
|
+
<show_last_activity>Display directory creation/modification date</show_last_activity>
|
|
187
|
+
</summary>
|
|
188
|
+
<safety_checks>
|
|
189
|
+
<check_uncommitted>git status --porcelain in worktree directory</check_uncommitted>
|
|
190
|
+
<warn_if_dirty>Alert user if uncommitted changes exist</warn_if_dirty>
|
|
191
|
+
</safety_checks>
|
|
192
|
+
<ask_deletion>Ask user confirmation: "Delete this worktree? (y/N)"</ask_deletion>
|
|
193
|
+
<purpose>Final safety check before irreversible deletion</purpose>
|
|
194
|
+
</step_8>
|
|
195
|
+
|
|
196
|
+
<step_9>
|
|
197
|
+
<description>Delete worktree</description>
|
|
198
|
+
<if_confirmed>
|
|
199
|
+
<remove_worktree>git worktree remove {path} --force</remove_worktree>
|
|
200
|
+
<cleanup_branch>git branch -d {branch_name}</cleanup_branch>
|
|
201
|
+
<success_message>Inform user worktree was successfully removed</success_message>
|
|
202
|
+
<next_steps>Suggest running command again to find next candidate</next_steps>
|
|
203
|
+
</if_confirmed>
|
|
204
|
+
<if_declined>Exit gracefully with no changes</if_declined>
|
|
205
|
+
<purpose>Perform the actual cleanup and guide user for next iteration</purpose>
|
|
206
|
+
</step_9>
|
|
212
207
|
</execution_steps>
|
|
213
208
|
|
|
214
209
|
<important_notes>
|
|
@@ -226,8 +221,7 @@ Current worktrees: !git worktree list`
|
|
|
226
221
|
- Processes one worktree at a time to maintain control
|
|
227
222
|
- Must be run from main branch for safety
|
|
228
223
|
- Works with standard GitHub repository URLs (owner/repo format)
|
|
229
|
-
</important_notes>
|
|
230
|
-
|
|
224
|
+
</important_notes>
|
|
231
225
|
|
|
232
226
|
## 🛡 Project Rules (Injected into every command)
|
|
233
227
|
|
|
@@ -253,7 +247,7 @@ Current worktrees: !git worktree list`
|
|
|
253
247
|
4. **API KEY MANAGEMENT:**
|
|
254
248
|
- Support three loading methods:
|
|
255
249
|
- Server environment variables
|
|
256
|
-
-
|
|
250
|
+
- NEXT*PUBLIC* variables (client-side)
|
|
257
251
|
- Custom headers (X-OpenAI-Key, X-Anthropic-Key, etc.)
|
|
258
252
|
- Never hardcode API keys
|
|
259
253
|
- Always validate key availability before use
|
|
@@ -278,4 +272,4 @@ Current worktrees: !git worktree list`
|
|
|
278
272
|
- Code examples
|
|
279
273
|
- Testing notes
|
|
280
274
|
- Document expected behavior and edge cases
|
|
281
|
-
- Include real-world output examples
|
|
275
|
+
- Include real-world output examples
|
|
@@ -615,9 +615,11 @@ def main():
|
|
|
615
615
|
design_research = phases.get("design_research", {}) # For UI workflows
|
|
616
616
|
selection = phases.get("selection", {}) # For combine workflows
|
|
617
617
|
|
|
618
|
-
if (
|
|
619
|
-
|
|
620
|
-
|
|
618
|
+
# Check if workflow was NOT started (status is None or "not_started")
|
|
619
|
+
not_started_statuses = [None, "not_started"]
|
|
620
|
+
if (research.get("status") in not_started_statuses and
|
|
621
|
+
design_research.get("status") in not_started_statuses and
|
|
622
|
+
selection.get("status") in not_started_statuses):
|
|
621
623
|
# Workflow not started, allow stop
|
|
622
624
|
print(json.dumps({"decision": "approve"}))
|
|
623
625
|
sys.exit(0)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Hook: PreToolUse for Write/Edit
|
|
4
|
+
Purpose: Ensure user has confirmed component type before proceeding
|
|
5
|
+
|
|
6
|
+
This hook checks that:
|
|
7
|
+
1. AI has suggested a component type (basic/complex)
|
|
8
|
+
2. User has explicitly confirmed the type
|
|
9
|
+
3. The confirmation is recorded in state
|
|
10
|
+
|
|
11
|
+
If not confirmed, blocks the write and reminds to get user confirmation.
|
|
12
|
+
|
|
13
|
+
Version: 3.10.0
|
|
14
|
+
"""
|
|
15
|
+
import json
|
|
16
|
+
import sys
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def main():
|
|
21
|
+
# Read hook input from stdin
|
|
22
|
+
try:
|
|
23
|
+
input_data = json.load(sys.stdin)
|
|
24
|
+
except json.JSONDecodeError:
|
|
25
|
+
print(json.dumps({"continue": True}))
|
|
26
|
+
sys.exit(0)
|
|
27
|
+
|
|
28
|
+
tool_name = input_data.get("tool_name", "")
|
|
29
|
+
tool_input = input_data.get("tool_input", {})
|
|
30
|
+
|
|
31
|
+
# Only check Write/Edit operations
|
|
32
|
+
if tool_name not in ["Write", "Edit"]:
|
|
33
|
+
print(json.dumps({"continue": True}))
|
|
34
|
+
sys.exit(0)
|
|
35
|
+
|
|
36
|
+
# Check if writing to a component file
|
|
37
|
+
file_path = tool_input.get("file_path", "")
|
|
38
|
+
if "/components/" not in file_path:
|
|
39
|
+
print(json.dumps({"continue": True}))
|
|
40
|
+
sys.exit(0)
|
|
41
|
+
|
|
42
|
+
# Check for state file
|
|
43
|
+
cwd = Path.cwd()
|
|
44
|
+
state_file = cwd / ".claude" / "api-dev-state.json"
|
|
45
|
+
|
|
46
|
+
if not state_file.exists():
|
|
47
|
+
print(json.dumps({"continue": True}))
|
|
48
|
+
sys.exit(0)
|
|
49
|
+
|
|
50
|
+
try:
|
|
51
|
+
state = json.loads(state_file.read_text())
|
|
52
|
+
except (json.JSONDecodeError, IOError):
|
|
53
|
+
print(json.dumps({"continue": True}))
|
|
54
|
+
sys.exit(0)
|
|
55
|
+
|
|
56
|
+
# Check if this is a UI workflow
|
|
57
|
+
workflow = state.get("workflow", "")
|
|
58
|
+
if "ui-create" not in workflow:
|
|
59
|
+
print(json.dumps({"continue": True}))
|
|
60
|
+
sys.exit(0)
|
|
61
|
+
|
|
62
|
+
# Check for component type confirmation
|
|
63
|
+
ui_config = state.get("ui_config", {})
|
|
64
|
+
user_confirmed = ui_config.get("user_confirmed", False)
|
|
65
|
+
component_type = ui_config.get("component_type", "")
|
|
66
|
+
ai_suggested = ui_config.get("ai_suggested", "")
|
|
67
|
+
|
|
68
|
+
if not user_confirmed:
|
|
69
|
+
print(json.dumps({
|
|
70
|
+
"continue": False,
|
|
71
|
+
"reason": (
|
|
72
|
+
"⚠️ Component type not confirmed by user.\n\n"
|
|
73
|
+
"Before writing component files, you must:\n\n"
|
|
74
|
+
"1. Analyze the component and suggest a type (Basic or Complex)\n"
|
|
75
|
+
"2. Present your suggestion to the user\n"
|
|
76
|
+
"3. Get explicit confirmation\n"
|
|
77
|
+
"4. Update state with user_confirmed: true\n\n"
|
|
78
|
+
"Example state update:\n"
|
|
79
|
+
"{\n"
|
|
80
|
+
' "ui_config": {\n'
|
|
81
|
+
f' "component_type": "{component_type or "basic"}",\n'
|
|
82
|
+
f' "ai_suggested": "{ai_suggested or "basic"}",\n'
|
|
83
|
+
' "user_confirmed": true\n'
|
|
84
|
+
" }\n"
|
|
85
|
+
"}\n\n"
|
|
86
|
+
"Use AskUserQuestion to get confirmation."
|
|
87
|
+
)
|
|
88
|
+
}))
|
|
89
|
+
sys.exit(0)
|
|
90
|
+
|
|
91
|
+
# All checks passed
|
|
92
|
+
print(json.dumps({"continue": True}))
|
|
93
|
+
sys.exit(0)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
if __name__ == "__main__":
|
|
97
|
+
main()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Hook library modules
|