qualia-framework 2.6.0 → 3.2.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 (321) hide show
  1. package/CLAUDE.md +64 -0
  2. package/README.md +103 -30
  3. package/agents/builder.md +110 -0
  4. package/agents/planner.md +134 -0
  5. package/agents/qa-browser.md +186 -0
  6. package/agents/verifier.md +221 -0
  7. package/bin/cli.js +336 -531
  8. package/bin/install.js +570 -0
  9. package/bin/qualia-ui.js +299 -0
  10. package/bin/state.js +630 -0
  11. package/bin/statusline.js +252 -0
  12. package/guide.md +63 -0
  13. package/hooks/auto-update.js +139 -0
  14. package/hooks/branch-guard.js +47 -0
  15. package/hooks/migration-guard.js +60 -0
  16. package/hooks/pre-compact.js +32 -0
  17. package/hooks/pre-deploy-gate.js +110 -0
  18. package/hooks/pre-push.js +33 -0
  19. package/hooks/session-start.js +170 -0
  20. package/package.json +29 -20
  21. package/rules/design-reference.md +179 -0
  22. package/rules/frontend.md +126 -0
  23. package/skills/qualia/SKILL.md +87 -0
  24. package/skills/qualia-build/SKILL.md +97 -0
  25. package/skills/qualia-debug/SKILL.md +87 -0
  26. package/skills/qualia-design/SKILL.md +93 -0
  27. package/skills/qualia-handoff/SKILL.md +66 -0
  28. package/skills/qualia-idk/SKILL.md +8 -0
  29. package/skills/qualia-learn/SKILL.md +88 -0
  30. package/skills/qualia-new/SKILL.md +323 -0
  31. package/{framework/skills → skills}/qualia-optimize/SKILL.md +1 -1
  32. package/skills/qualia-pause/SKILL.md +63 -0
  33. package/skills/qualia-plan/SKILL.md +101 -0
  34. package/skills/qualia-polish/SKILL.md +157 -0
  35. package/skills/qualia-quick/SKILL.md +37 -0
  36. package/skills/qualia-report/SKILL.md +105 -0
  37. package/skills/qualia-resume/SKILL.md +49 -0
  38. package/skills/qualia-review/SKILL.md +76 -0
  39. package/skills/qualia-ship/SKILL.md +90 -0
  40. package/skills/qualia-skill-new/SKILL.md +167 -0
  41. package/skills/qualia-task/SKILL.md +91 -0
  42. package/skills/qualia-verify/SKILL.md +113 -0
  43. package/templates/DESIGN.md +137 -0
  44. package/templates/plan.md +28 -0
  45. package/templates/project.md +22 -0
  46. package/templates/state.md +27 -0
  47. package/templates/tracking.json +20 -0
  48. package/tests/bin.test.sh +673 -0
  49. package/tests/hooks.test.sh +315 -0
  50. package/tests/state.test.sh +535 -0
  51. package/tests/statusline.test.sh +243 -0
  52. package/bin/collect-metrics.sh +0 -62
  53. package/framework/.claudeignore +0 -51
  54. package/framework/CLAUDE.md +0 -51
  55. package/framework/MCP_SETUP.md +0 -229
  56. package/framework/agents/architecture-strategist.md +0 -53
  57. package/framework/agents/backend-agent.md +0 -150
  58. package/framework/agents/code-simplicity-reviewer.md +0 -86
  59. package/framework/agents/frontend-agent.md +0 -111
  60. package/framework/agents/kieran-typescript-reviewer.md +0 -96
  61. package/framework/agents/performance-oracle.md +0 -111
  62. package/framework/agents/qualia-codebase-mapper.md +0 -761
  63. package/framework/agents/qualia-debugger.md +0 -1204
  64. package/framework/agents/qualia-executor.md +0 -882
  65. package/framework/agents/qualia-integration-checker.md +0 -424
  66. package/framework/agents/qualia-phase-researcher.md +0 -457
  67. package/framework/agents/qualia-plan-checker.md +0 -700
  68. package/framework/agents/qualia-planner.md +0 -1245
  69. package/framework/agents/qualia-project-researcher.md +0 -603
  70. package/framework/agents/qualia-research-synthesizer.md +0 -200
  71. package/framework/agents/qualia-roadmapper.md +0 -606
  72. package/framework/agents/qualia-verifier.md +0 -686
  73. package/framework/agents/red-team-qa.md +0 -130
  74. package/framework/agents/security-auditor.md +0 -72
  75. package/framework/agents/team-orchestrator.md +0 -229
  76. package/framework/agents/teams/framework-audit-team.md +0 -66
  77. package/framework/agents/teams/full-stack-team.md +0 -48
  78. package/framework/agents/teams/optimize-team.md +0 -53
  79. package/framework/agents/teams/review-team.md +0 -70
  80. package/framework/agents/teams/ship-team.md +0 -86
  81. package/framework/agents/test-agent.md +0 -182
  82. package/framework/hooks/auto-format.sh +0 -54
  83. package/framework/hooks/block-env-edit.sh +0 -42
  84. package/framework/hooks/branch-guard.sh +0 -43
  85. package/framework/hooks/confirm-delete.sh +0 -59
  86. package/framework/hooks/migration-validate.sh +0 -77
  87. package/framework/hooks/notification-speak.sh +0 -16
  88. package/framework/hooks/pre-commit.sh +0 -100
  89. package/framework/hooks/pre-compact.sh +0 -56
  90. package/framework/hooks/pre-deploy-gate.sh +0 -160
  91. package/framework/hooks/qualia-colors.sh +0 -32
  92. package/framework/hooks/retention-cleanup.sh +0 -62
  93. package/framework/hooks/save-session-state.sh +0 -185
  94. package/framework/hooks/session-context-loader.sh +0 -96
  95. package/framework/hooks/session-learn.sh +0 -32
  96. package/framework/hooks/skill-announce.sh +0 -123
  97. package/framework/hooks/tool-error-announce.sh +0 -27
  98. package/framework/install.ps1 +0 -323
  99. package/framework/install.sh +0 -313
  100. package/framework/qualia-framework/VERSION +0 -1
  101. package/framework/qualia-framework/assets/qualia-logo.png +0 -0
  102. package/framework/qualia-framework/bin/collect-metrics.sh +0 -67
  103. package/framework/qualia-framework/bin/generate-report-docx.py +0 -429
  104. package/framework/qualia-framework/bin/qualia-tools.js +0 -2201
  105. package/framework/qualia-framework/bin/qualia-tools.test.js +0 -1054
  106. package/framework/qualia-framework/references/checkpoints.md +0 -775
  107. package/framework/qualia-framework/references/completion-checklists.md +0 -359
  108. package/framework/qualia-framework/references/continuation-format.md +0 -249
  109. package/framework/qualia-framework/references/continuation-prompt.md +0 -97
  110. package/framework/qualia-framework/references/decimal-phase-calculation.md +0 -65
  111. package/framework/qualia-framework/references/design-quality.md +0 -56
  112. package/framework/qualia-framework/references/employee-guide.md +0 -167
  113. package/framework/qualia-framework/references/git-integration.md +0 -254
  114. package/framework/qualia-framework/references/git-planning-commit.md +0 -50
  115. package/framework/qualia-framework/references/model-profile-resolution.md +0 -32
  116. package/framework/qualia-framework/references/model-profiles.md +0 -73
  117. package/framework/qualia-framework/references/phase-argument-parsing.md +0 -61
  118. package/framework/qualia-framework/references/planning-config.md +0 -195
  119. package/framework/qualia-framework/references/questioning.md +0 -141
  120. package/framework/qualia-framework/references/tdd.md +0 -263
  121. package/framework/qualia-framework/references/ui-brand.md +0 -160
  122. package/framework/qualia-framework/references/verification-patterns.md +0 -612
  123. package/framework/qualia-framework/templates/DEBUG.md +0 -159
  124. package/framework/qualia-framework/templates/DESIGN.md +0 -81
  125. package/framework/qualia-framework/templates/UAT.md +0 -247
  126. package/framework/qualia-framework/templates/codebase/architecture.md +0 -255
  127. package/framework/qualia-framework/templates/codebase/concerns.md +0 -310
  128. package/framework/qualia-framework/templates/codebase/conventions.md +0 -307
  129. package/framework/qualia-framework/templates/codebase/integrations.md +0 -280
  130. package/framework/qualia-framework/templates/codebase/stack.md +0 -186
  131. package/framework/qualia-framework/templates/codebase/structure.md +0 -285
  132. package/framework/qualia-framework/templates/codebase/testing.md +0 -480
  133. package/framework/qualia-framework/templates/config.json +0 -35
  134. package/framework/qualia-framework/templates/context.md +0 -283
  135. package/framework/qualia-framework/templates/continue-here.md +0 -78
  136. package/framework/qualia-framework/templates/debug-subagent-prompt.md +0 -91
  137. package/framework/qualia-framework/templates/discovery.md +0 -146
  138. package/framework/qualia-framework/templates/lab-notes.md +0 -16
  139. package/framework/qualia-framework/templates/milestone-archive.md +0 -123
  140. package/framework/qualia-framework/templates/milestone.md +0 -115
  141. package/framework/qualia-framework/templates/phase-prompt.md +0 -567
  142. package/framework/qualia-framework/templates/planner-subagent-prompt.md +0 -117
  143. package/framework/qualia-framework/templates/project.md +0 -184
  144. package/framework/qualia-framework/templates/projects/ai-agent.md +0 -156
  145. package/framework/qualia-framework/templates/projects/mobile-app.md +0 -181
  146. package/framework/qualia-framework/templates/projects/voice-agent.md +0 -134
  147. package/framework/qualia-framework/templates/projects/website.md +0 -137
  148. package/framework/qualia-framework/templates/requirements.md +0 -231
  149. package/framework/qualia-framework/templates/research-project/ARCHITECTURE.md +0 -204
  150. package/framework/qualia-framework/templates/research-project/FEATURES.md +0 -147
  151. package/framework/qualia-framework/templates/research-project/PITFALLS.md +0 -200
  152. package/framework/qualia-framework/templates/research-project/STACK.md +0 -120
  153. package/framework/qualia-framework/templates/research-project/SUMMARY.md +0 -170
  154. package/framework/qualia-framework/templates/research.md +0 -552
  155. package/framework/qualia-framework/templates/roadmap.md +0 -206
  156. package/framework/qualia-framework/templates/state.md +0 -179
  157. package/framework/qualia-framework/templates/summary-complex.md +0 -59
  158. package/framework/qualia-framework/templates/summary-minimal.md +0 -41
  159. package/framework/qualia-framework/templates/summary-standard.md +0 -48
  160. package/framework/qualia-framework/templates/summary.md +0 -246
  161. package/framework/qualia-framework/templates/user-setup.md +0 -311
  162. package/framework/qualia-framework/templates/verification-report.md +0 -322
  163. package/framework/qualia-framework/workflows/add-phase.md +0 -179
  164. package/framework/qualia-framework/workflows/add-todo.md +0 -157
  165. package/framework/qualia-framework/workflows/audit-milestone.md +0 -241
  166. package/framework/qualia-framework/workflows/check-todos.md +0 -176
  167. package/framework/qualia-framework/workflows/complete-milestone.md +0 -858
  168. package/framework/qualia-framework/workflows/diagnose-issues.md +0 -219
  169. package/framework/qualia-framework/workflows/discovery-phase.md +0 -289
  170. package/framework/qualia-framework/workflows/discuss-phase.md +0 -534
  171. package/framework/qualia-framework/workflows/execute-phase.md +0 -559
  172. package/framework/qualia-framework/workflows/execute-plan.md +0 -438
  173. package/framework/qualia-framework/workflows/help.md +0 -470
  174. package/framework/qualia-framework/workflows/insert-phase.md +0 -220
  175. package/framework/qualia-framework/workflows/list-phase-assumptions.md +0 -178
  176. package/framework/qualia-framework/workflows/map-codebase.md +0 -327
  177. package/framework/qualia-framework/workflows/new-milestone.md +0 -363
  178. package/framework/qualia-framework/workflows/new-project.md +0 -982
  179. package/framework/qualia-framework/workflows/pause-work.md +0 -122
  180. package/framework/qualia-framework/workflows/plan-milestone-gaps.md +0 -256
  181. package/framework/qualia-framework/workflows/plan-phase.md +0 -422
  182. package/framework/qualia-framework/workflows/progress.md +0 -389
  183. package/framework/qualia-framework/workflows/quick.md +0 -252
  184. package/framework/qualia-framework/workflows/remove-phase.md +0 -326
  185. package/framework/qualia-framework/workflows/research-phase.md +0 -74
  186. package/framework/qualia-framework/workflows/resume-project.md +0 -306
  187. package/framework/qualia-framework/workflows/set-profile.md +0 -80
  188. package/framework/qualia-framework/workflows/settings.md +0 -145
  189. package/framework/qualia-framework/workflows/transition.md +0 -556
  190. package/framework/qualia-framework/workflows/update.md +0 -197
  191. package/framework/qualia-framework/workflows/verify-phase.md +0 -195
  192. package/framework/qualia-framework/workflows/verify-work.md +0 -625
  193. package/framework/rules/context7.md +0 -14
  194. package/framework/rules/frontend.md +0 -33
  195. package/framework/rules/speed.md +0 -23
  196. package/framework/scripts/__pycache__/say.cpython-314.pyc +0 -0
  197. package/framework/scripts/apply-retention.sh +0 -120
  198. package/framework/scripts/bootstrap-pop-os.sh +0 -354
  199. package/framework/scripts/claude-voice +0 -13
  200. package/framework/scripts/cleanup.sh +0 -131
  201. package/framework/scripts/cowork-mode.sh +0 -141
  202. package/framework/scripts/generate-project-claude-md.sh +0 -153
  203. package/framework/scripts/load-test-webhook.js +0 -172
  204. package/framework/scripts/say.py +0 -236
  205. package/framework/scripts/showcase-video-recorder/ffmpeg-builder.js +0 -167
  206. package/framework/scripts/showcase-video-recorder/playwright-helpers.js +0 -216
  207. package/framework/scripts/speak.py +0 -55
  208. package/framework/scripts/speak.sh +0 -18
  209. package/framework/scripts/status.sh +0 -138
  210. package/framework/scripts/sync-to-framework.sh +0 -65
  211. package/framework/scripts/voice-hotkey.py +0 -227
  212. package/framework/scripts/voice-input.sh +0 -51
  213. package/framework/skills/animate/SKILL.md +0 -202
  214. package/framework/skills/bolder/SKILL.md +0 -144
  215. package/framework/skills/browser-qa/SKILL.md +0 -536
  216. package/framework/skills/clarify/SKILL.md +0 -179
  217. package/framework/skills/client-handoff/SKILL.md +0 -135
  218. package/framework/skills/collab-onboard/SKILL.md +0 -111
  219. package/framework/skills/colorize/SKILL.md +0 -170
  220. package/framework/skills/critique/SKILL.md +0 -126
  221. package/framework/skills/deep-research/SKILL.md +0 -240
  222. package/framework/skills/delight/SKILL.md +0 -329
  223. package/framework/skills/deploy/SKILL.md +0 -261
  224. package/framework/skills/deploy-verify/SKILL.md +0 -377
  225. package/framework/skills/deploy-verify/scripts/canary-check.sh +0 -206
  226. package/framework/skills/deploy-verify/scripts/check-console-errors.js +0 -147
  227. package/framework/skills/deploy-verify/scripts/check-cwv.js +0 -139
  228. package/framework/skills/deploy-verify/scripts/project-detect.sh +0 -84
  229. package/framework/skills/deploy-verify/scripts/verify.sh +0 -548
  230. package/framework/skills/design-quieter/SKILL.md +0 -130
  231. package/framework/skills/distill/SKILL.md +0 -149
  232. package/framework/skills/docs-lookup/SKILL.md +0 -79
  233. package/framework/skills/fcm-notifications/SKILL.md +0 -125
  234. package/framework/skills/financial-ledger/SKILL.md +0 -1039
  235. package/framework/skills/frontend-master/NOTICE.md +0 -4
  236. package/framework/skills/frontend-master/SKILL.md +0 -127
  237. package/framework/skills/frontend-master/reference/color-and-contrast.md +0 -132
  238. package/framework/skills/frontend-master/reference/interaction-design.md +0 -123
  239. package/framework/skills/frontend-master/reference/motion-design.md +0 -99
  240. package/framework/skills/frontend-master/reference/responsive-design.md +0 -114
  241. package/framework/skills/frontend-master/reference/spatial-design.md +0 -100
  242. package/framework/skills/frontend-master/reference/typography.md +0 -131
  243. package/framework/skills/frontend-master/reference/ux-writing.md +0 -107
  244. package/framework/skills/harden/SKILL.md +0 -357
  245. package/framework/skills/i18n-rtl/SKILL.md +0 -752
  246. package/framework/skills/learn/SKILL.md +0 -95
  247. package/framework/skills/memory/SKILL.md +0 -50
  248. package/framework/skills/mobile-expo/SKILL.md +0 -977
  249. package/framework/skills/mobile-expo/references/store-checklist.md +0 -550
  250. package/framework/skills/nestjs-backend/README.md +0 -73
  251. package/framework/skills/nestjs-backend/SKILL.md +0 -446
  252. package/framework/skills/nestjs-backend/references/templates.md +0 -1173
  253. package/framework/skills/normalize/SKILL.md +0 -79
  254. package/framework/skills/onboard/SKILL.md +0 -242
  255. package/framework/skills/openrouter-agent/SKILL.md +0 -922
  256. package/framework/skills/polish/SKILL.md +0 -209
  257. package/framework/skills/pr/SKILL.md +0 -66
  258. package/framework/skills/qualia/SKILL.md +0 -199
  259. package/framework/skills/qualia-add-todo/SKILL.md +0 -68
  260. package/framework/skills/qualia-audit-milestone/SKILL.md +0 -95
  261. package/framework/skills/qualia-check-todos/SKILL.md +0 -55
  262. package/framework/skills/qualia-complete-milestone/SKILL.md +0 -134
  263. package/framework/skills/qualia-debug/SKILL.md +0 -149
  264. package/framework/skills/qualia-design/SKILL.md +0 -203
  265. package/framework/skills/qualia-discuss-phase/SKILL.md +0 -72
  266. package/framework/skills/qualia-evolve/SKILL.md +0 -200
  267. package/framework/skills/qualia-execute-phase/SKILL.md +0 -89
  268. package/framework/skills/qualia-framework-audit/SKILL.md +0 -604
  269. package/framework/skills/qualia-guide/SKILL.md +0 -32
  270. package/framework/skills/qualia-help/SKILL.md +0 -114
  271. package/framework/skills/qualia-idk/SKILL.md +0 -352
  272. package/framework/skills/qualia-list-phase-assumptions/SKILL.md +0 -67
  273. package/framework/skills/qualia-new-milestone/SKILL.md +0 -72
  274. package/framework/skills/qualia-new-project/SKILL.md +0 -232
  275. package/framework/skills/qualia-pause-work/SKILL.md +0 -96
  276. package/framework/skills/qualia-plan-milestone-gaps/SKILL.md +0 -57
  277. package/framework/skills/qualia-plan-phase/SKILL.md +0 -104
  278. package/framework/skills/qualia-production-check/SKILL.md +0 -0
  279. package/framework/skills/qualia-progress/SKILL.md +0 -53
  280. package/framework/skills/qualia-quick/SKILL.md +0 -89
  281. package/framework/skills/qualia-report/SKILL.md +0 -166
  282. package/framework/skills/qualia-research-phase/SKILL.md +0 -88
  283. package/framework/skills/qualia-resume-work/SKILL.md +0 -62
  284. package/framework/skills/qualia-review/SKILL.md +0 -263
  285. package/framework/skills/qualia-start/SKILL.md +0 -161
  286. package/framework/skills/qualia-verify-work/SKILL.md +0 -132
  287. package/framework/skills/rag/SKILL.md +0 -750
  288. package/framework/skills/responsive/SKILL.md +0 -231
  289. package/framework/skills/retro/SKILL.md +0 -284
  290. package/framework/skills/sakani-conventions/SKILL.md +0 -136
  291. package/framework/skills/sakani-conventions/evals/evals.json +0 -23
  292. package/framework/skills/sakani-conventions/references/entities.md +0 -365
  293. package/framework/skills/sakani-conventions/references/error-codes.md +0 -95
  294. package/framework/skills/seo-master/SKILL.md +0 -490
  295. package/framework/skills/seo-master/references/checklist.md +0 -199
  296. package/framework/skills/seo-master/references/structured-data.md +0 -609
  297. package/framework/skills/ship/SKILL.md +0 -239
  298. package/framework/skills/stack-researcher/SKILL.md +0 -215
  299. package/framework/skills/status/SKILL.md +0 -154
  300. package/framework/skills/status/scripts/health-check.sh +0 -562
  301. package/framework/skills/subscription-payments/SKILL.md +0 -250
  302. package/framework/skills/supabase/SKILL.md +0 -973
  303. package/framework/skills/supabase/references/templates.md +0 -159
  304. package/framework/skills/team/SKILL.md +0 -67
  305. package/framework/skills/test-runner/SKILL.md +0 -202
  306. package/framework/skills/voice-agent/SKILL.md +0 -1312
  307. package/framework/skills/zoho-workflow/SKILL.md +0 -51
  308. package/framework/statusline-command.sh +0 -117
  309. package/framework/teams/default/inboxes/plan-04.json +0 -9
  310. package/framework/teams/review-team.md +0 -75
  311. package/framework/teams/ship-team.md +0 -86
  312. package/profiles/fawzi.json +0 -16
  313. package/profiles/hasan.json +0 -16
  314. package/profiles/moayad.json +0 -16
  315. package/templates/CLAUDE-owner.md +0 -52
  316. package/templates/CLAUDE.md.hbs +0 -58
  317. package/templates/env.claude.template +0 -12
  318. package/templates/settings.json +0 -172
  319. package/uninstall.sh +0 -90
  320. /package/{framework/rules → rules}/deployment.md +0 -0
  321. /package/{framework/rules → rules}/security.md +0 -0
@@ -1,86 +0,0 @@
1
- # Ship Team
2
-
3
- > Quality gate → Deploy → Verify. Pipeline pattern — abort if any step fails.
4
-
5
- ## Agents
6
-
7
- - **quality-gate**
8
- - subagent_type: test-agent
9
- - role: Run tsc, eslint, build. Ensure no type errors, lint violations, or build failures.
10
- - commands: |
11
- npx tsc --noEmit
12
- npx next lint (or eslint .)
13
- npm run build (or next build)
14
- - abort_on_fail: true
15
-
16
- - **deploy**
17
- - subagent_type: backend-agent
18
- - role: Commit staged changes, push to remote, deploy to hosting platform
19
- - commands: |
20
- git add -A && git commit (if uncommitted changes)
21
- git push origin {branch}
22
- vercel --prod (default) OR wrangler deploy (if armenius)
23
- - abort_on_fail: true
24
-
25
- - **verify**
26
- - subagent_type: test-agent
27
- - role: Run 6-check post-deploy verification against production URL
28
- - checks: |
29
- 1. HTTP 200 — homepage loads
30
- 2. Auth flow — login/signup endpoint responds
31
- 3. Console errors — no critical JS errors
32
- 4. API latency — key endpoints < 500ms
33
- 5. SSL — valid certificate
34
- 6. Build artifacts — no source maps exposed
35
- - abort_on_fail: false (report issues but don't rollback)
36
-
37
- ## Pattern
38
-
39
- pipeline: quality-gate → deploy → verify
40
-
41
- Each step must succeed before the next begins. If quality-gate fails, deployment is blocked. If deploy fails, verification is skipped.
42
-
43
- ## Shared Context
44
-
45
- - ~/.claude/knowledge/qualia-context.md — project inventory, deploy commands, Supabase refs
46
- - .planning/STATE.md — current project state
47
- - Project's local CLAUDE.md — project-specific deploy config
48
-
49
- ## Coordination Rules
50
-
51
- - quality-gate runs ALL checks before passing — partial pass is a fail
52
- - deploy detects hosting platform from project context (Vercel default, Cloudflare for armenius)
53
- - verify uses the production URL from deploy output
54
- - If Supabase project: deploy also runs `supabase db push` if pending migrations exist
55
-
56
- ## Output
57
-
58
- SHIP-REPORT.md in current directory:
59
-
60
- ```markdown
61
- # Ship Report
62
-
63
- **Date:** {date}
64
- **Branch:** {branch}
65
- **Deploy URL:** {url}
66
-
67
- ## Quality Gate
68
- - tsc: ✓ / ✗ ({error count})
69
- - lint: ✓ / ✗ ({warning count})
70
- - build: ✓ / ✗ ({duration})
71
-
72
- ## Deployment
73
- - Platform: Vercel / Cloudflare
74
- - URL: {production url}
75
- - Commit: {sha}
76
-
77
- ## Verification
78
- | Check | Status | Details |
79
- |-------|--------|---------|
80
- | HTTP 200 | ✓/✗ | {status code} |
81
- | Auth flow | ✓/✗ | {details} |
82
- | Console errors | ✓/✗ | {count} |
83
- | API latency | ✓/✗ | {ms} |
84
- | SSL | ✓/✗ | {expiry} |
85
- | Source maps | ✓/✗ | {exposed?} |
86
- ```
@@ -1,182 +0,0 @@
1
- ---
2
- name: test-agent
3
- description: Testing and QA specialist - unit tests, integration tests, E2E with Playwright. Spawned for parallel test development.
4
- category: testing
5
- tools: Read, Write, Edit, Glob, Grep, Bash
6
- model: inherit
7
- tags: [testing, jest, vitest, playwright, qa]
8
- ---
9
-
10
- # Test Agent
11
-
12
- Specialized agent for testing and QA. Spawned for parallel test development.
13
-
14
- ## Capabilities
15
-
16
- - Write unit tests (Jest, Vitest)
17
- - Write integration tests
18
- - Create E2E tests (Playwright)
19
- - Generate test fixtures
20
- - Analyze code coverage
21
- - Find edge cases
22
-
23
- ## When to Spawn
24
-
25
- Use this agent when:
26
- - Writing tests in parallel with implementation
27
- - Need comprehensive test coverage
28
- - E2E testing for user flows
29
- - Test debugging and fixes
30
-
31
- ## Tools Available
32
-
33
- | Tool | Purpose |
34
- |------|---------|
35
- | Read | Read code to test |
36
- | Write | Create test files |
37
- | Edit | Fix existing tests |
38
- | Glob | Find test files |
39
- | Grep | Search for patterns |
40
- | Bash | Run tests |
41
-
42
- ## Example Tasks
43
-
44
- ```
45
- "Write tests for the ProfileCard component"
46
- "Create E2E test for the checkout flow"
47
- "Add integration tests for the API endpoints"
48
- "Fix the failing user registration tests"
49
- ```
50
-
51
- ## My Process
52
-
53
- 1. **Analyze code** - Understand what to test
54
- 2. **Identify test cases** - Happy paths, edge cases, errors
55
- 3. **Write tests** - Clean, descriptive tests
56
- 4. **Run tests** - Verify they work
57
- 5. **Check coverage** - Ensure adequate coverage
58
- 6. **Report back** - Return test summary
59
-
60
- ## Constraints
61
-
62
- - Focus on testing, not implementation
63
- - Use project's test framework
64
- - Follow existing test patterns
65
- - Don't modify production code (unless fixing test setup)
66
-
67
- ## Output Format
68
-
69
- When done, I return:
70
- ```markdown
71
- ## Testing Complete
72
-
73
- ### Tests Created
74
- - __tests__/ProfileCard.test.tsx (8 tests)
75
- - e2e/checkout.spec.ts (5 tests)
76
-
77
- ### Coverage Summary
78
- | File | Statements | Branches | Functions | Lines |
79
- |------|------------|----------|-----------|-------|
80
- | ProfileCard.tsx | 95% | 88% | 100% | 95% |
81
-
82
- ### Test Cases
83
- **Unit Tests:**
84
- - ✅ renders user profile
85
- - ✅ shows loading skeleton
86
- - ✅ handles edit click
87
- - ✅ displays error state
88
-
89
- **E2E Tests:**
90
- - ✅ complete checkout flow
91
- - ✅ handles payment failure
92
- - ✅ applies discount code
93
-
94
- ### Run Command
95
- \`\`\`bash
96
- npm test ProfileCard
97
- npx playwright test checkout
98
- \`\`\`
99
- ```
100
-
101
- ## Spawn Example
102
-
103
- ```typescript
104
- // From main orchestrator
105
- await Task({
106
- subagent_type: "test-agent",
107
- prompt: "Write comprehensive tests for the ProfileCard component including: render states, user interactions, loading skeleton, error handling.",
108
- run_in_background: true
109
- });
110
- ```
111
-
112
- ## Test Patterns
113
-
114
- ### Component Test Template
115
- ```typescript
116
- import { render, screen } from '@testing-library/react';
117
- import userEvent from '@testing-library/user-event';
118
- import { Component } from './Component';
119
-
120
- describe('Component', () => {
121
- it('renders correctly', () => {
122
- render(<Component />);
123
- expect(screen.getByRole('button')).toBeInTheDocument();
124
- });
125
-
126
- it('handles user interaction', async () => {
127
- const onClick = vi.fn();
128
- render(<Component onClick={onClick} />);
129
- await userEvent.click(screen.getByRole('button'));
130
- expect(onClick).toHaveBeenCalled();
131
- });
132
-
133
- it('shows loading state', () => {
134
- render(<Component loading />);
135
- expect(screen.getByTestId('skeleton')).toBeInTheDocument();
136
- });
137
-
138
- it('displays error', () => {
139
- render(<Component error="Failed" />);
140
- expect(screen.getByText('Failed')).toBeInTheDocument();
141
- });
142
- });
143
- ```
144
-
145
- ### E2E Test Template
146
- ```typescript
147
- import { test, expect } from '@playwright/test';
148
-
149
- test.describe('Feature', () => {
150
- test('completes flow', async ({ page }) => {
151
- await page.goto('/');
152
- await page.click('button:has-text("Start")');
153
- await page.fill('input[name="email"]', 'test@example.com');
154
- await page.click('button:has-text("Submit")');
155
- await expect(page.locator('.success')).toBeVisible();
156
- });
157
-
158
- test('handles error', async ({ page }) => {
159
- await page.route('**/api/**', route => route.fulfill({ status: 500 }));
160
- await page.goto('/');
161
- await page.click('button:has-text("Submit")');
162
- await expect(page.locator('.error')).toBeVisible();
163
- });
164
- });
165
- ```
166
-
167
- ### API Test Template
168
- ```typescript
169
- describe('API: /api/users', () => {
170
- it('returns user list', async () => {
171
- const response = await fetch('/api/users');
172
- const data = await response.json();
173
- expect(response.status).toBe(200);
174
- expect(data).toHaveProperty('users');
175
- });
176
-
177
- it('requires authentication', async () => {
178
- const response = await fetch('/api/users');
179
- expect(response.status).toBe(401);
180
- });
181
- });
182
- ```
@@ -1,54 +0,0 @@
1
- #!/bin/bash
2
- # Auto-format hook for PostToolUse(Write/Edit)
3
- # Runs prettier on supported file types if available in the project
4
- source "$(dirname "$0")/qualia-colors.sh"
5
-
6
- # Parse file path from stdin JSON (Claude Code hook protocol)
7
- if [ ! -t 0 ]; then
8
- INPUT=$(cat)
9
- FILE_PATH=$(echo "$INPUT" | node -e "try{const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));process.stdout.write(d.tool_input?.file_path||'')}catch(e){}" 2>/dev/null)
10
- else
11
- FILE_PATH=""
12
- fi
13
-
14
- # Skip if no file path
15
- [ -z "$FILE_PATH" ] || [ ! -f "$FILE_PATH" ] && exit 0
16
-
17
- # Get file extension
18
- EXT="${FILE_PATH##*.}"
19
-
20
- # Only format supported file types
21
- case "$EXT" in
22
- ts|tsx|js|jsx|json|css|scss|html|md|yaml|yml) ;;
23
- *) exit 0 ;;
24
- esac
25
-
26
- # Find project root (look for package.json or .git)
27
- DIR="$(dirname "$FILE_PATH")"
28
- PROJECT_ROOT=""
29
- while [ "$DIR" != "/" ]; do
30
- if [ -f "$DIR/package.json" ] || [ -d "$DIR/.git" ]; then
31
- PROJECT_ROOT="$DIR"
32
- break
33
- fi
34
- DIR="$(dirname "$DIR")"
35
- done
36
-
37
- # Try to format with prettier if available in the project
38
- if [ -n "$PROJECT_ROOT" ]; then
39
- if [ -f "$PROJECT_ROOT/node_modules/.bin/prettier" ]; then
40
- "$PROJECT_ROOT/node_modules/.bin/prettier" --write "$FILE_PATH" 2>/dev/null
41
- exit 0
42
- fi
43
- fi
44
-
45
- # No formatter found — notify once per project
46
- if [ -n "$PROJECT_ROOT" ]; then
47
- STAMP="/tmp/.no-formatter-$(echo "$PROJECT_ROOT" | md5sum | cut -c1-8)"
48
- if [ ! -f "$STAMP" ]; then
49
- touch "$STAMP"
50
- printf '{"continue":true,"systemMessage":"◆ AUTO-FORMAT: No prettier found in %s — files will not be auto-formatted."}' "$(basename "$PROJECT_ROOT")"
51
- exit 0
52
- fi
53
- fi
54
- exit 0
@@ -1,42 +0,0 @@
1
- #!/bin/bash
2
- # Block .env and credential file editing
3
- source "$(dirname "$0")/qualia-colors.sh"
4
-
5
- if [ ! -t 0 ]; then
6
- INPUT=$(cat)
7
- FILE_PATH=$(echo "$INPUT" | node -e "try{const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));process.stdout.write(d.tool_input?.file_path||d.tool_input?.filePath||'')}catch(e){}" 2>/dev/null)
8
- else
9
- FILE_PATH="${1:-}"
10
- fi
11
-
12
- if [ -z "$FILE_PATH" ]; then
13
- printf '{"continue":true}'
14
- exit 0
15
- fi
16
-
17
- BASENAME=$(basename "$FILE_PATH")
18
-
19
- if [[ "$BASENAME" == .env* ]] || [[ "$FILE_PATH" == */.env ]] || [[ "$FILE_PATH" == */.env.* ]]; then
20
- cat <<EOJSON
21
- {
22
- "continue": false,
23
- "stopReason": "◆ ENV GUARD: editing ${BASENAME} blocked",
24
- "systemMessage": "◆ BLOCKED: Cannot edit .env files through Claude Code. Tell the user EXACTLY what needs to change: which file, which variable, what value."
25
- }
26
- EOJSON
27
- exit 2
28
- fi
29
-
30
- if [[ "$FILE_PATH" == *credentials* ]] || [[ "$FILE_PATH" == *secret* ]] || [[ "$FILE_PATH" == *.pem ]] || [[ "$FILE_PATH" == *.key ]]; then
31
- cat <<EOJSON
32
- {
33
- "continue": false,
34
- "stopReason": "◆ ENV GUARD: credential file blocked",
35
- "systemMessage": "◆ BLOCKED: Cannot edit credential/secret files through Claude. Tell the user what needs changing."
36
- }
37
- EOJSON
38
- exit 2
39
- fi
40
-
41
- printf '{"continue":true}'
42
- exit 0
@@ -1,43 +0,0 @@
1
- #!/bin/bash
2
- # Branch protection — role-aware
3
- # OWNER: allowed to push to main/master
4
- # DEVELOPER/EMPLOYEE: blocked, told to use /qualia-ship
5
- source "$(dirname "$0")/qualia-colors.sh"
6
-
7
- if [ ! -t 0 ]; then
8
- INPUT=$(cat)
9
- COMMAND=$(echo "$INPUT" | node -e "try{const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));process.stdout.write(d.tool_input?.command||d.tool_input||'')}catch(e){}" 2>/dev/null)
10
- else
11
- COMMAND="${1:-}"
12
- fi
13
-
14
- case "$COMMAND" in
15
- git\ push*) ;;
16
- *) exit 0 ;;
17
- esac
18
-
19
- BRANCH=$(git branch --show-current 2>/dev/null) || true
20
- [ -z "$BRANCH" ] && exit 0
21
-
22
- # Only guard main/master
23
- if [ "$BRANCH" != "main" ] && [ "$BRANCH" != "master" ]; then
24
- exit 0
25
- fi
26
-
27
- # Check role from CLAUDE.md
28
- ROLE=$(grep -m1 "^## Role:" "$HOME/.claude/CLAUDE.md" 2>/dev/null | sed 's/^## Role: *//')
29
-
30
- # OWNER can push anywhere
31
- if [ "$ROLE" = "OWNER" ]; then
32
- exit 0
33
- fi
34
-
35
- # DEVELOPER/EMPLOYEE blocked
36
- cat <<EOJSON
37
- {
38
- "continue": false,
39
- "stopReason": "◆ BRANCH GUARD: push to ${BRANCH} blocked (${ROLE:-unknown} role)",
40
- "systemMessage": "◆ BLOCKED: As ${ROLE:-DEVELOPER}, cannot push to ${BRANCH}. Use /ship for feature branch workflow."
41
- }
42
- EOJSON
43
- exit 2
@@ -1,59 +0,0 @@
1
- #!/bin/bash
2
- # Destructive command guard — blocks dangerous operations
3
- source "$(dirname "$0")/qualia-colors.sh"
4
-
5
- if [ ! -t 0 ]; then
6
- INPUT=$(cat)
7
- COMMAND=$(echo "$INPUT" | node -e "try{const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));process.stdout.write(d.tool_input?.command||d.tool_input||'')}catch(e){}" 2>/dev/null)
8
- else
9
- COMMAND="${1:-}"
10
- fi
11
-
12
- # Early exit for safe commands
13
- case "$COMMAND" in
14
- ls*|cat*|echo*|pwd|cd*|node*|npm\ install*|npm\ run*|npm\ test*|npx*|bun*|pnpm*|grep*|find*|which*|whoami|date|head*|tail*|wc*|sort*|diff*|test*|"["*|true|false|mkdir*|touch*|cp*|mv*|chmod*|stat*|readlink*|basename*|dirname*|realpath*|tsc*|eslint*|prettier*|vitest*|jest*|python*|pip*|curl*|wget*|gh*)
15
- exit 0
16
- ;;
17
- esac
18
-
19
- block() {
20
- cat <<EOJSON
21
- {
22
- "continue": false,
23
- "stopReason": "◆ BLOCKED: That would $1 — finding a safer way",
24
- "systemMessage": "◆ BLOCKED: $1. This could cause damage. Find a safer alternative and explain to the user what was blocked and what safer approach you're using instead."
25
- }
26
- EOJSON
27
- exit 2
28
- }
29
-
30
- # Dangerous rm patterns
31
- echo "$COMMAND" | grep -qE 'rm\s+(-rf|-fr|-r)\s+(/|~/|\.\.|[A-Za-z]+/$)' && block "Dangerous recursive delete"
32
- echo "$COMMAND" | grep -qE 'rm\s.*\s(src/|app/|lib/|components/|public/|pages/|supabase/)' && block "Deleting critical project directory"
33
- echo "$COMMAND" | grep -qE 'rm\s+(-rf|-fr)\s+\.$' && block "rm -rf current directory"
34
-
35
- # Dangerous SQL
36
- echo "$COMMAND" | grep -qiE 'DROP\s+(TABLE|DATABASE|SCHEMA)\s' && block "DROP TABLE/DATABASE/SCHEMA"
37
- echo "$COMMAND" | grep -qiE 'TRUNCATE\s+TABLE\s' && block "TRUNCATE TABLE"
38
- echo "$COMMAND" | grep -qiE 'DELETE\s+FROM\s+\w+\s*;' && block "DELETE without WHERE"
39
-
40
- # Dangerous git
41
- echo "$COMMAND" | grep -qE 'git\s+push\s+.*--force($|\s)' && ! echo "$COMMAND" | grep -qE '\-\-force-with-lease' && block "git push --force (use --force-with-lease)"
42
- echo "$COMMAND" | grep -qE 'git\s+reset\s+--hard' && block "git reset --hard discards work"
43
- echo "$COMMAND" | grep -qE 'git\s+clean\s+-[a-z]*f' && block "git clean -f deletes untracked files"
44
-
45
- # Supabase destructive
46
- echo "$COMMAND" | grep -qE 'supabase\s+functions\s+delete' && block "supabase functions delete"
47
- echo "$COMMAND" | grep -qE 'supabase\s+secrets\s+unset' && block "supabase secrets unset"
48
- echo "$COMMAND" | grep -qE 'supabase\s+projects\s+delete' && block "supabase projects delete"
49
-
50
- # Infrastructure
51
- echo "$COMMAND" | grep -qE 'kubectl\s+delete\s' && block "kubectl delete"
52
- echo "$COMMAND" | grep -qE 'docker\s+(rm|rmi)\s+-f' && block "docker force remove"
53
-
54
- # Platform
55
- echo "$COMMAND" | grep -qiE 'supabase\s+db\s+reset' && block "supabase db reset destroys database"
56
- echo "$COMMAND" | grep -qiE 'vercel\s+(rm|remove)\s' && block "vercel rm/remove"
57
- echo "$COMMAND" | grep -qiE 'npm\s+unpublish' && block "npm unpublish"
58
-
59
- exit 0
@@ -1,77 +0,0 @@
1
- #!/bin/bash
2
- # Migration validation — checks SQL for destructive ops and missing RLS
3
- source "$(dirname "$0")/qualia-colors.sh"
4
-
5
- if [ ! -t 0 ]; then
6
- INPUT=$(cat)
7
- FILE_PATH=$(echo "$INPUT" | node -e "try{const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));process.stdout.write(d.tool_input?.file_path||'')}catch(e){}" 2>/dev/null)
8
- if [ -z "$FILE_PATH" ]; then
9
- COMMAND=$(echo "$INPUT" | node -e "try{const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));process.stdout.write(d.tool_input?.command||d.tool_input||'')}catch(e){}" 2>/dev/null)
10
- fi
11
- fi
12
-
13
- DESTRUCTIVE=0
14
- WARNINGS_COUNT=0
15
-
16
- check_sql_file() {
17
- local file="$1"
18
- [ ! -f "$file" ] && return 0
19
-
20
- # Destructive ops → block
21
- if grep -iE '\bDROP\s+(TABLE|SCHEMA|DATABASE)\b' "$file" > /dev/null 2>&1; then
22
- q_fail "DROP TABLE/SCHEMA in ${file}"
23
- DESTRUCTIVE=$((DESTRUCTIVE + 1))
24
- fi
25
- if grep -iE '\bTRUNCATE\b' "$file" > /dev/null 2>&1; then
26
- q_fail "TRUNCATE in ${file}"
27
- DESTRUCTIVE=$((DESTRUCTIVE + 1))
28
- fi
29
- # DELETE-without-WHERE: count DELETEs vs WHERE clauses (per-statement approximation)
30
- local delete_count=$(grep -ciE '\bDELETE\s+FROM\b' "$file" 2>/dev/null || echo 0)
31
- local where_count=$(grep -ciE '\bWHERE\b' "$file" 2>/dev/null || echo 0)
32
- if [ "$delete_count" -gt 0 ] && [ "$delete_count" -gt "$where_count" ]; then
33
- q_fail "DELETE without WHERE in ${file} (${delete_count} DELETEs, ${where_count} WHEREs)"
34
- DESTRUCTIVE=$((DESTRUCTIVE + 1))
35
- fi
36
- if grep -iE '\bALTER\s+TABLE\b.*\bDROP\s+COLUMN\b' "$file" > /dev/null 2>&1; then
37
- q_fail "DROP COLUMN in ${file}"
38
- DESTRUCTIVE=$((DESTRUCTIVE + 1))
39
- fi
40
- # Missing RLS → warn only (reminder, not destructive)
41
- if grep -iE '\bCREATE\s+TABLE\b' "$file" > /dev/null 2>&1 && ! grep -iE '\bENABLE\s+ROW\s+LEVEL\s+SECURITY\b' "$file" > /dev/null 2>&1; then
42
- q_warn "New table needs RLS in ${file} — tell Claude: 'add RLS policies to the new table'"
43
- WARNINGS_COUNT=$((WARNINGS_COUNT + 1))
44
- fi
45
- }
46
-
47
- TRIGGERED=false
48
-
49
- # Mode 1: SQL file written
50
- if [ -n "$FILE_PATH" ] && [[ "$FILE_PATH" == *.sql ]]; then
51
- TRIGGERED=true
52
- check_sql_file "$FILE_PATH"
53
- fi
54
-
55
- # Mode 2: supabase db push — only scan new/modified migrations (not historical)
56
- if [ -n "$COMMAND" ] && echo "$COMMAND" | grep -qE 'supabase\s+db\s+push'; then
57
- TRIGGERED=true
58
- # Scan only uncommitted or recently modified migration files
59
- MODIFIED_MIGRATIONS=$(git diff --name-only HEAD -- supabase/migrations/*.sql 2>/dev/null; git diff --cached --name-only -- supabase/migrations/*.sql 2>/dev/null; git ls-files --others -- supabase/migrations/*.sql 2>/dev/null)
60
- if [ -n "$MODIFIED_MIGRATIONS" ]; then
61
- while IFS= read -r sql_file; do
62
- [ -f "$sql_file" ] && check_sql_file "$sql_file"
63
- done < <(echo "$MODIFIED_MIGRATIONS" | sort -u)
64
- fi
65
- fi
66
-
67
- # Block on destructive ops, warn on missing RLS
68
- if $TRIGGERED && [ "$DESTRUCTIVE" -gt 0 ]; then
69
- printf '{"continue":false,"stopReason":"◆ MIGRATION: %d destructive operation(s) blocked","systemMessage":"◆ MIGRATION BLOCKED: %d destructive operation(s) found. Tell Claude to review the SQL and confirm these operations are intentional."}' "$DESTRUCTIVE" "$DESTRUCTIVE"
70
- exit 2
71
- elif $TRIGGERED && [ "$WARNINGS_COUNT" -gt 0 ]; then
72
- printf '{"continue":true,"systemMessage":"◆ MIGRATION CHECK: %d warning(s) — tell Claude to review missing RLS policies."}' "$WARNINGS_COUNT"
73
- elif $TRIGGERED; then
74
- printf '{"continue":true,"systemMessage":"◆ MIGRATION CHECK: clean"}'
75
- fi
76
-
77
- exit 0
@@ -1,16 +0,0 @@
1
- #!/bin/bash
2
- # Notification hook — passes notification message to TTS
3
- # Reads message from stdin JSON (Claude Code hook protocol)
4
-
5
- TEXT=""
6
- if [ ! -t 0 ]; then
7
- INPUT=$(cat)
8
- TEXT=$(echo "$INPUT" | node -e "try{const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));process.stdout.write(d.message||'')}catch(e){}" 2>/dev/null)
9
- fi
10
-
11
- if [ -n "$TEXT" ]; then
12
- ~/.claude/scripts/speak.sh "$TEXT" &
13
- fi
14
-
15
- printf '{"continue":true}'
16
- exit 0
@@ -1,100 +0,0 @@
1
- #!/bin/bash
2
- # Pre-commit validation — secrets, debug statements, TypeScript, lint
3
- source "$(dirname "$0")/qualia-colors.sh"
4
-
5
- if ! command -v node &>/dev/null; then
6
- [ ! -t 0 ] && cat > /dev/null
7
- printf '{"continue":false,"stopReason":"PRE-COMMIT: node is not installed — cannot verify safety. Install node to proceed."}'
8
- exit 2
9
- fi
10
-
11
- if [ ! -t 0 ]; then
12
- INPUT=$(cat)
13
- COMMAND=$(echo "$INPUT" | node -e "try{const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));process.stdout.write(d.tool_input?.command||d.tool_input||'')}catch(e){}" 2>/dev/null)
14
- else
15
- COMMAND="${1:-}"
16
- fi
17
-
18
- case "$COMMAND" in
19
- git\ commit*) ;;
20
- *) exit 0 ;;
21
- esac
22
-
23
- git rev-parse --is-inside-work-tree &>/dev/null || exit 0
24
-
25
- STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)
26
- [ -z "$STAGED_FILES" ] && exit 0
27
-
28
- q_header "PRE-COMMIT"
29
- BLOCKED=false
30
- FAIL_DETAILS=""
31
-
32
- # Check for secrets
33
- SECRETS_PATTERN="(api[_-]?key|apikey|secret[_-]?key|password|passwd|pwd|token|auth[_-]?token|access[_-]?token|private[_-]?key)[\s]*[=:][\"'\s]*[A-Za-z0-9+/=_-]{20,}"
34
- for file in $STAGED_FILES; do
35
- if [ -f "$file" ] && grep -iE "$SECRETS_PATTERN" "$file" > /dev/null 2>&1; then
36
- q_fail "Secret in ${file}"
37
- FAIL_DETAILS="${FAIL_DETAILS}A password or API key was found in ${file} — tell Claude: 'remove the secret and use an environment variable instead.' "
38
- BLOCKED=true
39
- fi
40
- done
41
-
42
- # Check for .env files
43
- ENV_FILES=$(echo "$STAGED_FILES" | grep -E '\.env($|\.)' | grep -v '.example' | grep -v '.sample' || true)
44
- if [ -n "$ENV_FILES" ]; then
45
- q_fail ".env file staged: ${ENV_FILES}"
46
- FAIL_DETAILS="${FAIL_DETAILS}.env file contains secrets and shouldn't be committed — tell Claude: 'unstage the .env file.' "
47
- BLOCKED=true
48
- fi
49
-
50
- # Debug statements in JS/TS (block in production code, allow in tests/stories)
51
- JS_PROD_FILES=$(echo "$STAGED_FILES" | grep -E '\.(js|jsx|ts|tsx)$' | grep -vE '\.test\.|\.spec\.|__tests__/|\.stories\.' || true)
52
- if [ -n "$JS_PROD_FILES" ]; then
53
- for file in $JS_PROD_FILES; do
54
- if [ -f "$file" ] && grep -E "console\.(log|debug|info)|debugger" "$file" > /dev/null 2>&1; then
55
- q_fail "Debug statement in ${file}"
56
- FAIL_DETAILS="${FAIL_DETAILS}Debug statement in ${file} — tell Claude: 'remove console.log/debugger from production code.' "
57
- BLOCKED=true
58
- fi
59
- done
60
- fi
61
-
62
- # TypeScript check (skip if tsc passed in last 5 minutes — pre-deploy-gate also runs tsc)
63
- TSC_STAMP="/tmp/.tsc-pass-$(echo "$PWD" | md5sum | cut -c1-8)"
64
- if [ -f "tsconfig.json" ]; then
65
- if [ -f "$TSC_STAMP" ]; then
66
- AGE=$(( $(date +%s) - $(stat -c %Y "$TSC_STAMP" 2>/dev/null || echo 0) ))
67
- if [ "$AGE" -lt 300 ]; then
68
- q_pass "TypeScript (cached)"
69
- else
70
- rm -f "$TSC_STAMP"
71
- fi
72
- fi
73
- # Run tsc only if no valid cache
74
- if [ ! -f "$TSC_STAMP" ]; then
75
- if command -v npx &> /dev/null; then
76
- if npx tsc --noEmit 2>/dev/null; then
77
- q_pass "TypeScript"
78
- touch "$TSC_STAMP"
79
- else
80
- q_fail "TypeScript errors"
81
- FAIL_DETAILS="${FAIL_DETAILS}Code errors found — tell Claude: 'fix the TypeScript errors and try committing again.' "
82
- BLOCKED=true
83
- fi
84
- fi
85
- fi
86
- fi
87
-
88
- if $BLOCKED; then
89
- cat <<EOJSON
90
- {
91
- "continue": false,
92
- "stopReason": "◆ Pre-commit: blocked",
93
- "systemMessage": "◆ PRE-COMMIT BLOCKED: ${FAIL_DETAILS}Tell Claude to fix these issues and try committing again."
94
- }
95
- EOJSON
96
- exit 2
97
- fi
98
-
99
- printf '{"continue":true,"systemMessage":"◆ PRE-COMMIT: all checks passed"}'
100
- exit 0