oh-my-customcodex 0.1.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 (351) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +327 -0
  3. package/dist/cli/index.js +32054 -0
  4. package/dist/index.js +5469 -0
  5. package/package.json +89 -0
  6. package/templates/.claude/agents/arch-documenter.md +38 -0
  7. package/templates/.claude/agents/arch-speckit-agent.md +66 -0
  8. package/templates/.claude/agents/be-django-expert.md +47 -0
  9. package/templates/.claude/agents/be-express-expert.md +31 -0
  10. package/templates/.claude/agents/be-fastapi-expert.md +45 -0
  11. package/templates/.claude/agents/be-go-backend-expert.md +45 -0
  12. package/templates/.claude/agents/be-nestjs-expert.md +29 -0
  13. package/templates/.claude/agents/be-springboot-expert.md +42 -0
  14. package/templates/.claude/agents/db-alembic-expert.md +73 -0
  15. package/templates/.claude/agents/db-postgres-expert.md +38 -0
  16. package/templates/.claude/agents/db-redis-expert.md +38 -0
  17. package/templates/.claude/agents/db-supabase-expert.md +37 -0
  18. package/templates/.claude/agents/de-airflow-expert.md +48 -0
  19. package/templates/.claude/agents/de-dbt-expert.md +36 -0
  20. package/templates/.claude/agents/de-kafka-expert.md +83 -0
  21. package/templates/.claude/agents/de-pipeline-expert.md +34 -0
  22. package/templates/.claude/agents/de-snowflake-expert.md +38 -0
  23. package/templates/.claude/agents/de-spark-expert.md +38 -0
  24. package/templates/.claude/agents/fe-design-expert.md +120 -0
  25. package/templates/.claude/agents/fe-flutter-agent.md +48 -0
  26. package/templates/.claude/agents/fe-svelte-agent.md +33 -0
  27. package/templates/.claude/agents/fe-vercel-agent.md +40 -0
  28. package/templates/.claude/agents/fe-vuejs-agent.md +34 -0
  29. package/templates/.claude/agents/infra-aws-expert.md +49 -0
  30. package/templates/.claude/agents/infra-docker-expert.md +49 -0
  31. package/templates/.claude/agents/lang-golang-expert.md +46 -0
  32. package/templates/.claude/agents/lang-java21-expert.md +42 -0
  33. package/templates/.claude/agents/lang-kotlin-expert.md +45 -0
  34. package/templates/.claude/agents/lang-python-expert.md +45 -0
  35. package/templates/.claude/agents/lang-rust-expert.md +45 -0
  36. package/templates/.claude/agents/lang-typescript-expert.md +45 -0
  37. package/templates/.claude/agents/mgr-claude-code-bible.md +62 -0
  38. package/templates/.claude/agents/mgr-creator.md +57 -0
  39. package/templates/.claude/agents/mgr-gitnerd.md +50 -0
  40. package/templates/.claude/agents/mgr-sauron.md +163 -0
  41. package/templates/.claude/agents/mgr-supplier.md +39 -0
  42. package/templates/.claude/agents/mgr-updater.md +40 -0
  43. package/templates/.claude/agents/qa-engineer.md +36 -0
  44. package/templates/.claude/agents/qa-planner.md +78 -0
  45. package/templates/.claude/agents/qa-writer.md +32 -0
  46. package/templates/.claude/agents/sec-codeql-expert.md +56 -0
  47. package/templates/.claude/agents/slack-cli-expert.md +98 -0
  48. package/templates/.claude/agents/souls/lang-golang-expert.soul.md +21 -0
  49. package/templates/.claude/agents/sys-memory-keeper.md +123 -0
  50. package/templates/.claude/agents/sys-naggy.md +76 -0
  51. package/templates/.claude/agents/tool-bun-expert.md +26 -0
  52. package/templates/.claude/agents/tool-npm-expert.md +31 -0
  53. package/templates/.claude/agents/tool-optimizer.md +37 -0
  54. package/templates/.claude/agents/wiki-curator.md +72 -0
  55. package/templates/.claude/config/required-plugins.json +30 -0
  56. package/templates/.claude/contexts/dev.md +20 -0
  57. package/templates/.claude/contexts/ecomode.md +110 -0
  58. package/templates/.claude/contexts/index.yaml +41 -0
  59. package/templates/.claude/contexts/research.md +28 -0
  60. package/templates/.claude/contexts/review.md +23 -0
  61. package/templates/.claude/hooks/hooks.json +533 -0
  62. package/templates/.claude/hooks/scripts/adaptive-harness-scan.sh +45 -0
  63. package/templates/.claude/hooks/scripts/agent-start-recorder.sh +40 -0
  64. package/templates/.claude/hooks/scripts/agent-teams-advisor.sh +76 -0
  65. package/templates/.claude/hooks/scripts/audit-log.sh +64 -0
  66. package/templates/.claude/hooks/scripts/auto-continue-guard.sh +33 -0
  67. package/templates/.claude/hooks/scripts/content-hash-validator.sh +75 -0
  68. package/templates/.claude/hooks/scripts/context-budget-advisor.sh +107 -0
  69. package/templates/.claude/hooks/scripts/cost-cap-advisor.sh +71 -0
  70. package/templates/.claude/hooks/scripts/cwd-change-detector.sh +36 -0
  71. package/templates/.claude/hooks/scripts/eval-core-batch-save.sh +46 -0
  72. package/templates/.claude/hooks/scripts/feedback-collector.sh +92 -0
  73. package/templates/.claude/hooks/scripts/file-change-validator.sh +26 -0
  74. package/templates/.claude/hooks/scripts/git-delegation-guard.sh +57 -0
  75. package/templates/.claude/hooks/scripts/model-escalation-advisor.sh +106 -0
  76. package/templates/.claude/hooks/scripts/omcodex-auto-update.sh +4 -0
  77. package/templates/.claude/hooks/scripts/omcustom-auto-update.sh +177 -0
  78. package/templates/.claude/hooks/scripts/rtk-intercept.sh +77 -0
  79. package/templates/.claude/hooks/scripts/rule-deletion-guard.sh +60 -0
  80. package/templates/.claude/hooks/scripts/schema-validator.sh +106 -0
  81. package/templates/.claude/hooks/scripts/secret-filter.sh +100 -0
  82. package/templates/.claude/hooks/scripts/session-autofix-prompt.sh +34 -0
  83. package/templates/.claude/hooks/scripts/session-autofix.sh +146 -0
  84. package/templates/.claude/hooks/scripts/session-env-check.sh +254 -0
  85. package/templates/.claude/hooks/scripts/skill-extractor-analyzer.sh +49 -0
  86. package/templates/.claude/hooks/scripts/stage-blocker.sh +16 -0
  87. package/templates/.claude/hooks/scripts/stale-todo-scanner.sh +91 -0
  88. package/templates/.claude/hooks/scripts/stall-detection-advisor.sh +112 -0
  89. package/templates/.claude/hooks/scripts/stop-console-audit.sh +46 -0
  90. package/templates/.claude/hooks/scripts/stuck-detector.sh +199 -0
  91. package/templates/.claude/hooks/scripts/task-outcome-recorder.sh +119 -0
  92. package/templates/.claude/hooks/scripts/task-state-precompact.sh +58 -0
  93. package/templates/.claude/hooks/scripts/user-prompt-preprocessor.sh +32 -0
  94. package/templates/.claude/hooks/skill-count-reminder.sh +34 -0
  95. package/templates/.claude/install-hooks.sh +100 -0
  96. package/templates/.claude/ontology/agents.yaml +546 -0
  97. package/templates/.claude/ontology/graphs/agent-skill.json +102 -0
  98. package/templates/.claude/ontology/graphs/full-graph.json +629 -0
  99. package/templates/.claude/ontology/graphs/routing.json +112 -0
  100. package/templates/.claude/ontology/graphs/skill-rule.json +78 -0
  101. package/templates/.claude/ontology/rules.yaml +251 -0
  102. package/templates/.claude/ontology/schema.yaml +144 -0
  103. package/templates/.claude/ontology/skills.yaml +575 -0
  104. package/templates/.claude/rules/MAY-optimization.md +42 -0
  105. package/templates/.claude/rules/MUST-agent-design.md +340 -0
  106. package/templates/.claude/rules/MUST-agent-identification.md +77 -0
  107. package/templates/.claude/rules/MUST-agent-teams.md +293 -0
  108. package/templates/.claude/rules/MUST-completion-verification.md +112 -0
  109. package/templates/.claude/rules/MUST-continuous-improvement.md +69 -0
  110. package/templates/.claude/rules/MUST-enforcement-policy.md +50 -0
  111. package/templates/.claude/rules/MUST-intent-transparency.md +74 -0
  112. package/templates/.claude/rules/MUST-language-policy.md +28 -0
  113. package/templates/.claude/rules/MUST-orchestrator-coordination.md +399 -0
  114. package/templates/.claude/rules/MUST-parallel-execution.md +184 -0
  115. package/templates/.claude/rules/MUST-permissions.md +32 -0
  116. package/templates/.claude/rules/MUST-safety.md +23 -0
  117. package/templates/.claude/rules/MUST-sync-verification.md +145 -0
  118. package/templates/.claude/rules/MUST-tool-identification.md +97 -0
  119. package/templates/.claude/rules/SHOULD-ecomode.md +123 -0
  120. package/templates/.claude/rules/SHOULD-error-handling.md +33 -0
  121. package/templates/.claude/rules/SHOULD-hud-statusline.md +51 -0
  122. package/templates/.claude/rules/SHOULD-interaction.md +77 -0
  123. package/templates/.claude/rules/SHOULD-memory-integration.md +371 -0
  124. package/templates/.claude/rules/SHOULD-ontology-rag-routing.md +49 -0
  125. package/templates/.claude/rules/SHOULD-wiki-sync.md +73 -0
  126. package/templates/.claude/rules/index.yaml +141 -0
  127. package/templates/.claude/schemas/tool-inputs.json +62 -0
  128. package/templates/.claude/skills/action-validator/SKILL.md +89 -0
  129. package/templates/.claude/skills/adaptive-harness/SKILL.md +335 -0
  130. package/templates/.claude/skills/adversarial-review/SKILL.md +80 -0
  131. package/templates/.claude/skills/agora/SKILL.md +194 -0
  132. package/templates/.claude/skills/airflow-best-practices/SKILL.md +94 -0
  133. package/templates/.claude/skills/alembic-best-practices/SKILL.md +295 -0
  134. package/templates/.claude/skills/ambiguity-gate/SKILL.md +94 -0
  135. package/templates/.claude/skills/analysis/SKILL.md +223 -0
  136. package/templates/.claude/skills/audit-agents/SKILL.md +118 -0
  137. package/templates/.claude/skills/aws-best-practices/SKILL.md +281 -0
  138. package/templates/.claude/skills/claude-code-bible/SKILL.md +93 -0
  139. package/templates/.claude/skills/claude-code-bible/scripts/fetch-docs.js +244 -0
  140. package/templates/.claude/skills/claude-native/SKILL.md +215 -0
  141. package/templates/.claude/skills/codex-exec/SKILL.md +206 -0
  142. package/templates/.claude/skills/codex-exec/scripts/codex-wrapper.cjs +430 -0
  143. package/templates/.claude/skills/create-agent/SKILL.md +94 -0
  144. package/templates/.claude/skills/cve-triage/SKILL.md +91 -0
  145. package/templates/.claude/skills/dag-orchestration/SKILL.md +201 -0
  146. package/templates/.claude/skills/dbt-best-practices/SKILL.md +55 -0
  147. package/templates/.claude/skills/de-lead-routing/SKILL.md +230 -0
  148. package/templates/.claude/skills/deep-plan/SKILL.md +344 -0
  149. package/templates/.claude/skills/deep-verify/SKILL.md +111 -0
  150. package/templates/.claude/skills/dev-lead-routing/SKILL.md +161 -0
  151. package/templates/.claude/skills/dev-refactor/SKILL.md +234 -0
  152. package/templates/.claude/skills/dev-review/SKILL.md +172 -0
  153. package/templates/.claude/skills/django-best-practices/SKILL.md +334 -0
  154. package/templates/.claude/skills/docker-best-practices/SKILL.md +276 -0
  155. package/templates/.claude/skills/evaluator-optimizer/SKILL.md +421 -0
  156. package/templates/.claude/skills/fastapi-best-practices/SKILL.md +271 -0
  157. package/templates/.claude/skills/fix-refs/SKILL.md +109 -0
  158. package/templates/.claude/skills/flutter-best-practices/SKILL.md +325 -0
  159. package/templates/.claude/skills/gemini-exec/SKILL.md +215 -0
  160. package/templates/.claude/skills/gemini-exec/scripts/gemini-wrapper.cjs +485 -0
  161. package/templates/.claude/skills/go-backend-best-practices/SKILL.md +135 -0
  162. package/templates/.claude/skills/go-best-practices/SKILL.md +204 -0
  163. package/templates/.claude/skills/hada-scout/SKILL.md +92 -0
  164. package/templates/.claude/skills/harness-eval/SKILL.md +95 -0
  165. package/templates/.claude/skills/harness-synthesizer/SKILL.md +145 -0
  166. package/templates/.claude/skills/help/SKILL.md +127 -0
  167. package/templates/.claude/skills/idea/SKILL.md +88 -0
  168. package/templates/.claude/skills/impeccable-design/SKILL.md +173 -0
  169. package/templates/.claude/skills/intent-detection/SKILL.md +293 -0
  170. package/templates/.claude/skills/intent-detection/patterns/agent-triggers.yaml +438 -0
  171. package/templates/.claude/skills/java21-best-practices/SKILL.md +190 -0
  172. package/templates/.claude/skills/jinja2-prompts/SKILL.md +86 -0
  173. package/templates/.claude/skills/kafka-best-practices/SKILL.md +53 -0
  174. package/templates/.claude/skills/kotlin-best-practices/SKILL.md +257 -0
  175. package/templates/.claude/skills/lists/SKILL.md +80 -0
  176. package/templates/.claude/skills/memory-management/SKILL.md +196 -0
  177. package/templates/.claude/skills/memory-recall/SKILL.md +172 -0
  178. package/templates/.claude/skills/memory-save/SKILL.md +128 -0
  179. package/templates/.claude/skills/model-escalation/SKILL.md +62 -0
  180. package/templates/.claude/skills/monitoring-setup/SKILL.md +215 -0
  181. package/templates/.claude/skills/multi-model-verification/SKILL.md +130 -0
  182. package/templates/.claude/skills/npm-audit/SKILL.md +74 -0
  183. package/templates/.claude/skills/npm-publish/SKILL.md +65 -0
  184. package/templates/.claude/skills/npm-version/SKILL.md +104 -0
  185. package/templates/.claude/skills/omcodex-auto-improve/SKILL.md +136 -0
  186. package/templates/.claude/skills/omcodex-feedback/SKILL.md +205 -0
  187. package/templates/.claude/skills/omcodex-improve-report/SKILL.md +65 -0
  188. package/templates/.claude/skills/omcodex-loop/SKILL.md +45 -0
  189. package/templates/.claude/skills/omcodex-release-notes/SKILL.md +117 -0
  190. package/templates/.claude/skills/omcodex-takeover/SKILL.md +115 -0
  191. package/templates/.claude/skills/omcodex-web/SKILL.md +95 -0
  192. package/templates/.claude/skills/optimize-analyze/SKILL.md +57 -0
  193. package/templates/.claude/skills/optimize-bundle/SKILL.md +69 -0
  194. package/templates/.claude/skills/optimize-report/SKILL.md +76 -0
  195. package/templates/.claude/skills/peer-messaging/SKILL.md +59 -0
  196. package/templates/.claude/skills/pipeline/SKILL.md +103 -0
  197. package/templates/.claude/skills/pipeline-architecture-patterns/SKILL.md +84 -0
  198. package/templates/.claude/skills/pipeline-guards/SKILL.md +173 -0
  199. package/templates/.claude/skills/post-release-followup/SKILL.md +134 -0
  200. package/templates/.claude/skills/postgres-best-practices/SKILL.md +67 -0
  201. package/templates/.claude/skills/pr-auto-improve/SKILL.md +129 -0
  202. package/templates/.claude/skills/professor-triage/SKILL.md +321 -0
  203. package/templates/.claude/skills/python-best-practices/SKILL.md +223 -0
  204. package/templates/.claude/skills/qa-lead-routing/SKILL.md +104 -0
  205. package/templates/.claude/skills/react-best-practices/SKILL.md +102 -0
  206. package/templates/.claude/skills/reasoning-sandwich/SKILL.md +64 -0
  207. package/templates/.claude/skills/redis-best-practices/SKILL.md +84 -0
  208. package/templates/.claude/skills/release-plan/SKILL.md +207 -0
  209. package/templates/.claude/skills/research/SKILL.md +493 -0
  210. package/templates/.claude/skills/result-aggregation/SKILL.md +165 -0
  211. package/templates/.claude/skills/rtk-exec/SKILL.md +199 -0
  212. package/templates/.claude/skills/rtk-exec/scripts/rtk-wrapper.cjs +377 -0
  213. package/templates/.claude/skills/rust-best-practices/SKILL.md +268 -0
  214. package/templates/.claude/skills/sauron-watch/SKILL.md +239 -0
  215. package/templates/.claude/skills/scout/SKILL.md +250 -0
  216. package/templates/.claude/skills/sdd/SKILL.md +24 -0
  217. package/templates/.claude/skills/sdd-dev/SKILL.md +257 -0
  218. package/templates/.claude/skills/sdd-development/SKILL.md +24 -0
  219. package/templates/.claude/skills/secretary-routing/SKILL.md +132 -0
  220. package/templates/.claude/skills/skill-extractor/SKILL.md +155 -0
  221. package/templates/.claude/skills/skills-sh-search/SKILL.md +210 -0
  222. package/templates/.claude/skills/snowflake-best-practices/SKILL.md +66 -0
  223. package/templates/.claude/skills/spark-best-practices/SKILL.md +53 -0
  224. package/templates/.claude/skills/springboot-best-practices/SKILL.md +74 -0
  225. package/templates/.claude/skills/springboot-best-practices/examples/config-properties-example.java +22 -0
  226. package/templates/.claude/skills/springboot-best-practices/examples/controller-example.java +28 -0
  227. package/templates/.claude/skills/springboot-best-practices/examples/controller-test-example.java +33 -0
  228. package/templates/.claude/skills/springboot-best-practices/examples/entity-example.java +22 -0
  229. package/templates/.claude/skills/springboot-best-practices/examples/exception-handler-example.java +30 -0
  230. package/templates/.claude/skills/springboot-best-practices/examples/repository-example.java +17 -0
  231. package/templates/.claude/skills/springboot-best-practices/examples/repository-test-example.java +23 -0
  232. package/templates/.claude/skills/springboot-best-practices/examples/security-config-example.java +27 -0
  233. package/templates/.claude/skills/springboot-best-practices/examples/service-example.java +33 -0
  234. package/templates/.claude/skills/status/SKILL.md +155 -0
  235. package/templates/.claude/skills/structured-dev-cycle/SKILL.md +200 -0
  236. package/templates/.claude/skills/stuck-recovery/SKILL.md +80 -0
  237. package/templates/.claude/skills/supabase-postgres-best-practices/SKILL.md +100 -0
  238. package/templates/.claude/skills/systematic-debugging/SKILL.md +288 -0
  239. package/templates/.claude/skills/systematic-debugging/condition-based-waiting-example.ts +278 -0
  240. package/templates/.claude/skills/systematic-debugging/condition-based-waiting.md +240 -0
  241. package/templates/.claude/skills/systematic-debugging/defense-in-depth.md +252 -0
  242. package/templates/.claude/skills/systematic-debugging/find-polluter.sh +147 -0
  243. package/templates/.claude/skills/systematic-debugging/root-cause-tracing.md +87 -0
  244. package/templates/.claude/skills/task-decomposition/SKILL.md +197 -0
  245. package/templates/.claude/skills/typescript-best-practices/SKILL.md +322 -0
  246. package/templates/.claude/skills/update-docs/SKILL.md +142 -0
  247. package/templates/.claude/skills/update-external/SKILL.md +169 -0
  248. package/templates/.claude/skills/vercel-deploy/SKILL.md +75 -0
  249. package/templates/.claude/skills/web-design-guidelines/SKILL.md +119 -0
  250. package/templates/.claude/skills/wiki/SKILL.md +426 -0
  251. package/templates/.claude/skills/wiki-rag/SKILL.md +154 -0
  252. package/templates/.claude/skills/worker-reviewer-pipeline/SKILL.md +165 -0
  253. package/templates/.claude/skills/writing-clearly-and-concisely/SKILL.md +66 -0
  254. package/templates/.claude/statusline.sh +380 -0
  255. package/templates/.claude/uninstall-hooks.sh +52 -0
  256. package/templates/.github/workflows/wiki-sync.yml +132 -0
  257. package/templates/AGENTS.md.en +255 -0
  258. package/templates/AGENTS.md.ko +255 -0
  259. package/templates/CLAUDE.md +263 -0
  260. package/templates/CLAUDE.md.en +256 -0
  261. package/templates/CLAUDE.md.ko +256 -0
  262. package/templates/deprecated-files.json +10 -0
  263. package/templates/guides/agents-md-quality/README.md +110 -0
  264. package/templates/guides/airflow/README.md +47 -0
  265. package/templates/guides/alembic/README.md +438 -0
  266. package/templates/guides/aws/common-patterns.md +169 -0
  267. package/templates/guides/aws/index.yaml +26 -0
  268. package/templates/guides/aws/well-architected.md +143 -0
  269. package/templates/guides/cc-token-saver/README.md +97 -0
  270. package/templates/guides/claude-code/01-overview.md +42 -0
  271. package/templates/guides/claude-code/03-tools.md +107 -0
  272. package/templates/guides/claude-code/04-agent-skills.md +90 -0
  273. package/templates/guides/claude-code/05-agent-sdk.md +129 -0
  274. package/templates/guides/claude-code/06-mcp.md +165 -0
  275. package/templates/guides/claude-code/07-prompt-engineering.md +100 -0
  276. package/templates/guides/claude-code/08-testing.md +56 -0
  277. package/templates/guides/claude-code/09-guardrails.md +78 -0
  278. package/templates/guides/claude-code/10-monitoring.md +87 -0
  279. package/templates/guides/claude-code/11-sub-agents.md +159 -0
  280. package/templates/guides/claude-code/12-workflow-patterns.md +182 -0
  281. package/templates/guides/claude-code/13-cli-flags.md +151 -0
  282. package/templates/guides/claude-code/index.yaml +61 -0
  283. package/templates/guides/dbt/README.md +32 -0
  284. package/templates/guides/django-best-practices/README.md +476 -0
  285. package/templates/guides/docker/compose-best-practices.md +284 -0
  286. package/templates/guides/docker/dockerfile-best-practices.md +262 -0
  287. package/templates/guides/docker/index.yaml +26 -0
  288. package/templates/guides/drizzle-orm/README.md +69 -0
  289. package/templates/guides/elements-of-style/elements-of-style.html +2609 -0
  290. package/templates/guides/fastapi/best-practices.md +232 -0
  291. package/templates/guides/fastapi/index.yaml +21 -0
  292. package/templates/guides/flutter/architecture.md +141 -0
  293. package/templates/guides/flutter/fundamentals.md +119 -0
  294. package/templates/guides/flutter/index.yaml +44 -0
  295. package/templates/guides/flutter/performance.md +119 -0
  296. package/templates/guides/flutter/security.md +120 -0
  297. package/templates/guides/flutter/state-management.md +144 -0
  298. package/templates/guides/flutter/testing.md +155 -0
  299. package/templates/guides/git-worktree-workflow/README.md +138 -0
  300. package/templates/guides/go-backend/index.yaml +26 -0
  301. package/templates/guides/go-backend/project-layout.md +243 -0
  302. package/templates/guides/go-backend/uber-style.md +212 -0
  303. package/templates/guides/golang/concurrency.md +282 -0
  304. package/templates/guides/golang/effective-go.md +309 -0
  305. package/templates/guides/golang/error-handling.md +250 -0
  306. package/templates/guides/golang/index.yaml +27 -0
  307. package/templates/guides/hook-data-flow/README.md +135 -0
  308. package/templates/guides/iceberg/README.md +49 -0
  309. package/templates/guides/impeccable-design/color-and-contrast.md +278 -0
  310. package/templates/guides/impeccable-design/index.yaml +12 -0
  311. package/templates/guides/impeccable-design/motion-design.md +390 -0
  312. package/templates/guides/impeccable-design/typography.md +386 -0
  313. package/templates/guides/impeccable-design/ux-writing.md +400 -0
  314. package/templates/guides/index.yaml +265 -0
  315. package/templates/guides/java21/index.yaml +29 -0
  316. package/templates/guides/java21/java-style-guide.md +248 -0
  317. package/templates/guides/java21/modern-java21.md +303 -0
  318. package/templates/guides/kafka/README.md +32 -0
  319. package/templates/guides/kotlin/coding-conventions.md +247 -0
  320. package/templates/guides/kotlin/idioms.md +234 -0
  321. package/templates/guides/kotlin/index.yaml +26 -0
  322. package/templates/guides/multi-model-routing/README.md +101 -0
  323. package/templates/guides/multi-provider-exec/README.md +83 -0
  324. package/templates/guides/postgres/README.md +58 -0
  325. package/templates/guides/python/index.yaml +26 -0
  326. package/templates/guides/python/pep8-style-guide.md +202 -0
  327. package/templates/guides/python/zen-of-python.md +79 -0
  328. package/templates/guides/redis/README.md +50 -0
  329. package/templates/guides/rust/error-handling.md +262 -0
  330. package/templates/guides/rust/index.yaml +26 -0
  331. package/templates/guides/rust/ownership.md +180 -0
  332. package/templates/guides/skill-bundle-design/README.md +106 -0
  333. package/templates/guides/slack-cli/README.md +145 -0
  334. package/templates/guides/snowflake/README.md +32 -0
  335. package/templates/guides/spark/README.md +32 -0
  336. package/templates/guides/springboot/best-practices.md +361 -0
  337. package/templates/guides/springboot/index.yaml +22 -0
  338. package/templates/guides/supabase-postgres/README.md +32 -0
  339. package/templates/guides/supabase-postgres/index.yaml +19 -0
  340. package/templates/guides/typescript/advanced-types.md +225 -0
  341. package/templates/guides/typescript/index.yaml +26 -0
  342. package/templates/guides/typescript/type-system.md +219 -0
  343. package/templates/guides/web-design/accessibility.md +66 -0
  344. package/templates/guides/web-design/index.yaml +20 -0
  345. package/templates/guides/web-design/performance.md +102 -0
  346. package/templates/guides/web-scraping/README.md +926 -0
  347. package/templates/guides/web-scraping/index.yaml +19 -0
  348. package/templates/guides/worktree-lifecycle/README.md +104 -0
  349. package/templates/index.yaml +18 -0
  350. package/templates/manifest.json +49 -0
  351. package/templates/workflows/auto-dev.yaml +46 -0
@@ -0,0 +1,240 @@
1
+ # Condition-Based Waiting
2
+
3
+ <!-- Source: https://github.com/tmdgusya/engineering-disciplines (MIT License) -->
4
+
5
+ ## Overview
6
+
7
+ Arbitrary delays (`sleep`, `setTimeout`, `await new Promise(r => setTimeout(r, 1000))`) are a debugging anti-pattern. They hide timing issues, make tests slow, and still fail intermittently.
8
+
9
+ **Core principle:** Replace arbitrary delays with condition-based polling that waits for the actual state you need.
10
+
11
+ ## When to Use
12
+
13
+ **Use when:**
14
+ - Tests use `await sleep(1000)` or similar arbitrary waits
15
+ - Code has `setTimeout` for "giving time" to async operations
16
+ - Tests are flaky because timing depends on system speed
17
+ - You need to wait for: file to exist, process to start, server to be ready, database record to appear
18
+
19
+ ## The Problem with Arbitrary Delays
20
+
21
+ ```typescript
22
+ // ❌ Arbitrary delay - fragile and slow
23
+ await fs.writeFile(path, content);
24
+ await sleep(500); // "Give it time to write"
25
+ const result = await fs.readFile(path);
26
+
27
+ // Problems:
28
+ // 1. 500ms may not be enough on slow systems
29
+ // 2. 500ms is always wasted on fast systems
30
+ // 3. The actual condition (file readable) is never verified
31
+ ```
32
+
33
+ ## The Solution: Condition-Based Waiting
34
+
35
+ ```typescript
36
+ // ✓ Condition-based - fast and reliable
37
+ await fs.writeFile(path, content);
38
+ await waitUntil(() => fs.access(path).then(() => true).catch(() => false));
39
+ const result = await fs.readFile(path);
40
+
41
+ // Benefits:
42
+ // 1. Proceeds as soon as condition is met (fast on fast systems)
43
+ // 2. Has a timeout for safety (catches real failures)
44
+ // 3. The actual condition is explicit and verified
45
+ ```
46
+
47
+ ## Core Implementation
48
+
49
+ ```typescript
50
+ interface WaitOptions {
51
+ timeout?: number; // Max wait time in ms (default: 5000)
52
+ interval?: number; // Poll interval in ms (default: 100)
53
+ message?: string; // Error message on timeout
54
+ }
55
+
56
+ async function waitUntil(
57
+ condition: () => boolean | Promise<boolean>,
58
+ options: WaitOptions = {}
59
+ ): Promise<void> {
60
+ const { timeout = 5000, interval = 100, message = 'Condition not met' } = options;
61
+ const deadline = Date.now() + timeout;
62
+
63
+ while (Date.now() < deadline) {
64
+ const result = await condition();
65
+ if (result) return;
66
+ await new Promise(resolve => setTimeout(resolve, interval));
67
+ }
68
+
69
+ throw new Error(`waitUntil timeout after ${timeout}ms: ${message}`);
70
+ }
71
+ ```
72
+
73
+ See `condition-based-waiting-example.ts` for the complete implementation with all utilities.
74
+
75
+ ## Common Patterns
76
+
77
+ ### Wait for File to Exist
78
+
79
+ ```typescript
80
+ // ❌ Arbitrary delay
81
+ await triggerFileCreation();
82
+ await sleep(1000);
83
+ const content = await fs.readFile(outputPath, 'utf-8');
84
+
85
+ // ✓ Condition-based
86
+ await triggerFileCreation();
87
+ await waitUntil(
88
+ () => fs.access(outputPath).then(() => true).catch(() => false),
89
+ { timeout: 5000, message: `File not created: ${outputPath}` }
90
+ );
91
+ const content = await fs.readFile(outputPath, 'utf-8');
92
+ ```
93
+
94
+ ### Wait for Process to Start
95
+
96
+ ```typescript
97
+ // ❌ Arbitrary delay
98
+ startServer();
99
+ await sleep(2000); // "Give server time to start"
100
+ const response = await fetch('http://localhost:3000/health');
101
+
102
+ // ✓ Condition-based
103
+ startServer();
104
+ await waitUntil(
105
+ async () => {
106
+ try {
107
+ const res = await fetch('http://localhost:3000/health');
108
+ return res.ok;
109
+ } catch {
110
+ return false;
111
+ }
112
+ },
113
+ { timeout: 10000, message: 'Server did not start within 10s' }
114
+ );
115
+ const response = await fetch('http://localhost:3000/health');
116
+ ```
117
+
118
+ ### Wait for Database Record
119
+
120
+ ```typescript
121
+ // ❌ Arbitrary delay
122
+ await triggerAsyncOperation();
123
+ await sleep(500);
124
+ const record = await db.find({ id: expectedId });
125
+
126
+ // ✓ Condition-based
127
+ await triggerAsyncOperation();
128
+ await waitUntil(
129
+ async () => {
130
+ const record = await db.find({ id: expectedId });
131
+ return record !== null;
132
+ },
133
+ { timeout: 3000, message: `Record ${expectedId} not created` }
134
+ );
135
+ const record = await db.find({ id: expectedId });
136
+ ```
137
+
138
+ ### Wait for Log Output
139
+
140
+ ```typescript
141
+ // ❌ Arbitrary delay
142
+ process.spawn('my-command');
143
+ await sleep(1000);
144
+ expect(logOutput).toContain('Server started');
145
+
146
+ // ✓ Condition-based
147
+ const logOutput: string[] = [];
148
+ const proc = process.spawn('my-command');
149
+ proc.stdout.on('data', (chunk) => logOutput.push(chunk.toString()));
150
+
151
+ await waitUntil(
152
+ () => logOutput.some(line => line.includes('Server started')),
153
+ { timeout: 10000, message: 'Server start message not seen in logs' }
154
+ );
155
+ ```
156
+
157
+ ### Wait for Count to Reach Expected Value
158
+
159
+ ```typescript
160
+ // ❌ Arbitrary delay
161
+ await triggerBatchOperation();
162
+ await sleep(2000);
163
+ const items = await db.findAll();
164
+ expect(items.length).toBe(10);
165
+
166
+ // ✓ Condition-based
167
+ await triggerBatchOperation();
168
+ await waitUntil(
169
+ async () => {
170
+ const items = await db.findAll();
171
+ return items.length >= 10;
172
+ },
173
+ { timeout: 5000, message: 'Batch did not complete: expected 10 items' }
174
+ );
175
+ const items = await db.findAll();
176
+ expect(items.length).toBe(10);
177
+ ```
178
+
179
+ ## Choosing Timeout and Interval Values
180
+
181
+ | Scenario | Timeout | Interval | Rationale |
182
+ |----------|---------|----------|-----------|
183
+ | File write | 2s | 50ms | Fast local I/O |
184
+ | Process start | 10s | 200ms | Process startup varies |
185
+ | HTTP server ready | 15s | 300ms | Server may need to compile |
186
+ | Database record | 3s | 100ms | DB writes are fast |
187
+ | CI environment | 2-3x local | same | CI is often slower |
188
+
189
+ **Rule of thumb:**
190
+ - Interval: 10-20% of expected wait time, minimum 50ms
191
+ - Timeout: 3-5x the typical wait time
192
+ - Add a buffer for CI: multiply timeout by 2-3x
193
+
194
+ ## Testing the Waiters Themselves
195
+
196
+ ```typescript
197
+ // Test that waitUntil resolves when condition becomes true
198
+ it('resolves when condition becomes true', async () => {
199
+ let ready = false;
200
+ setTimeout(() => { ready = true; }, 100);
201
+
202
+ await expect(
203
+ waitUntil(() => ready, { timeout: 1000 })
204
+ ).resolves.toBeUndefined();
205
+ });
206
+
207
+ // Test that waitUntil rejects on timeout
208
+ it('rejects with timeout error when condition never met', async () => {
209
+ await expect(
210
+ waitUntil(() => false, { timeout: 100, message: 'test condition' })
211
+ ).rejects.toThrow('waitUntil timeout after 100ms: test condition');
212
+ });
213
+ ```
214
+
215
+ ## Migration Guide
216
+
217
+ When refactoring existing `sleep` calls:
218
+
219
+ 1. **Identify what the sleep is "waiting for"** — read surrounding code
220
+ 2. **Find the observable state change** — what becomes true when the operation completes?
221
+ 3. **Replace with `waitUntil(condition)`** — poll for that state
222
+ 4. **Set appropriate timeout** — 3-5x the typical wait time
223
+ 5. **Add descriptive message** — what should have happened?
224
+
225
+ ```typescript
226
+ // Before
227
+ await startProcess();
228
+ await sleep(2000);
229
+ checkResult();
230
+
231
+ // After - step 1: what is sleep waiting for? Process to be ready.
232
+ // After - step 2: observable state? Process responds to health check.
233
+ // After - step 3-5:
234
+ await startProcess();
235
+ await waitUntil(
236
+ () => isProcessReady(),
237
+ { timeout: 10000, message: 'Process did not become ready' }
238
+ );
239
+ checkResult();
240
+ ```
@@ -0,0 +1,252 @@
1
+ # Defense-in-Depth Validation
2
+
3
+ <!-- Source: https://github.com/tmdgusya/engineering-disciplines (MIT License) -->
4
+
5
+ ## Overview
6
+
7
+ Instead of fixing bugs reactively, add validation at every layer so bugs become structurally impossible. Each layer catches what the previous layer missed.
8
+
9
+ **Core principle:** Don't just fix the bug. Add a guard that makes the bug impossible at every layer that should have caught it.
10
+
11
+ ## When to Use
12
+
13
+ **Use when:**
14
+ - The same class of bug keeps appearing in different places
15
+ - A bug got through multiple layers that should have caught it
16
+ - You want to prevent regression of a hard-to-reproduce bug
17
+ - Building new features where invalid state could cause harm
18
+
19
+ ## The Four Layers
20
+
21
+ ### Layer 1: Input Validation (Entry Points)
22
+
23
+ Validate at the boundary where data enters your system.
24
+
25
+ ```typescript
26
+ // ❌ No validation - bug can enter the system
27
+ async function createSession(projectDir: string): Promise<Session> {
28
+ return new Session(projectDir);
29
+ }
30
+
31
+ // ✓ Validate at entry - bug is caught immediately
32
+ async function createSession(projectDir: string): Promise<Session> {
33
+ if (!projectDir || projectDir.trim() === '') {
34
+ throw new Error(`createSession: projectDir must be a non-empty string, got: ${JSON.stringify(projectDir)}`);
35
+ }
36
+ return new Session(projectDir);
37
+ }
38
+ ```
39
+
40
+ **What to validate at entry points:**
41
+ - Non-empty strings for required path/name fields
42
+ - Valid ranges for numeric values
43
+ - Required fields exist in objects
44
+ - File/directory exists when required
45
+
46
+ ### Layer 2: Constructor Guards (Object Creation)
47
+
48
+ Validate in constructors so objects can never be created in invalid state.
49
+
50
+ ```typescript
51
+ // ❌ Object can be created with invalid state
52
+ class Session {
53
+ constructor(private projectDir: string) {}
54
+ }
55
+
56
+ // ✓ Constructor prevents invalid state
57
+ class Session {
58
+ constructor(private projectDir: string) {
59
+ if (!projectDir || projectDir.trim() === '') {
60
+ throw new Error(
61
+ `Session: projectDir must be non-empty, got: ${JSON.stringify(projectDir)}`
62
+ );
63
+ }
64
+ }
65
+ }
66
+ ```
67
+
68
+ **Constructor guard pattern:**
69
+ ```typescript
70
+ class WorktreeManager {
71
+ constructor(private baseDir: string, private sessionId: string) {
72
+ if (!baseDir) throw new Error('WorktreeManager: baseDir is required');
73
+ if (!sessionId) throw new Error('WorktreeManager: sessionId is required');
74
+ }
75
+ }
76
+ ```
77
+
78
+ ### Layer 3: Method Preconditions (Critical Operations)
79
+
80
+ Add guards before operations that could cause harm if called with bad state.
81
+
82
+ ```typescript
83
+ // ❌ No precondition - git init could run in wrong directory
84
+ async function initializeWorktree(): Promise<void> {
85
+ await execFileAsync('git', ['init'], { cwd: this.projectDir });
86
+ }
87
+
88
+ // ✓ Precondition - verify state is valid before dangerous operation
89
+ async function initializeWorktree(): Promise<void> {
90
+ if (!this.projectDir) {
91
+ throw new Error(
92
+ `initializeWorktree: projectDir is not set. ` +
93
+ `This likely means the object was created with an empty path.`
94
+ );
95
+ }
96
+ await execFileAsync('git', ['init'], { cwd: this.projectDir });
97
+ }
98
+ ```
99
+
100
+ **When to add method preconditions:**
101
+ - Before file system operations (read, write, delete)
102
+ - Before network calls with user-provided data
103
+ - Before database writes
104
+ - Before spawning processes with user-provided arguments
105
+
106
+ ### Layer 4: Test Assertions (Regression Prevention)
107
+
108
+ Add assertions in tests that would catch the bug early and clearly.
109
+
110
+ ```typescript
111
+ // ❌ Test doesn't verify the path is correct
112
+ it('should initialize session', async () => {
113
+ const session = await createSession(tempDir);
114
+ expect(session).toBeDefined();
115
+ });
116
+
117
+ // ✓ Test verifies the critical invariant
118
+ it('should initialize session with correct project directory', async () => {
119
+ const session = await createSession(tempDir);
120
+ expect(session).toBeDefined();
121
+ // Assert the invariant that was violated
122
+ expect(session.projectDir).toBe(tempDir);
123
+ expect(session.projectDir).not.toBe('');
124
+ expect(session.projectDir).not.toBe(process.cwd());
125
+ });
126
+ ```
127
+
128
+ **Test assertion patterns:**
129
+ ```typescript
130
+ // Assert paths are absolute and within expected location
131
+ expect(path.isAbsolute(result.dir)).toBe(true);
132
+ expect(result.dir.startsWith(tempDir)).toBe(true);
133
+
134
+ // Assert values match what was provided (not defaults or fallbacks)
135
+ expect(result.name).toBe(providedName);
136
+ expect(result.id).not.toBe('');
137
+ ```
138
+
139
+ ## Applying Defense-in-Depth
140
+
141
+ When you find a bug, don't just fix it. Add guards at ALL four layers:
142
+
143
+ ### Step 1: Fix the immediate bug
144
+
145
+ ```typescript
146
+ // Fix the actual bug first
147
+ const context = setupCoreTest();
148
+ await context.initialize(); // Add the missing initialization
149
+ ```
150
+
151
+ ### Step 2: Add input validation
152
+
153
+ ```typescript
154
+ export function createProject(name: string, dir: string): Project {
155
+ if (!dir || dir.trim() === '') {
156
+ throw new Error(`createProject: dir must be non-empty`);
157
+ }
158
+ return new Project(name, dir);
159
+ }
160
+ ```
161
+
162
+ ### Step 3: Add constructor guard
163
+
164
+ ```typescript
165
+ class Project {
166
+ constructor(name: string, dir: string) {
167
+ if (!dir) throw new Error('Project: dir is required');
168
+ this.dir = dir;
169
+ }
170
+ }
171
+ ```
172
+
173
+ ### Step 4: Add method precondition
174
+
175
+ ```typescript
176
+ async clone(): Promise<Project> {
177
+ if (!this.dir) {
178
+ throw new Error('Project.clone: dir must be set before cloning');
179
+ }
180
+ // ... clone logic
181
+ }
182
+ ```
183
+
184
+ ### Step 5: Add regression test
185
+
186
+ ```typescript
187
+ it('should not use empty string as project dir', async () => {
188
+ const project = await createProject('test', tempDir);
189
+ expect(project.dir).toBe(tempDir);
190
+ expect(project.dir).not.toBe('');
191
+ });
192
+ ```
193
+
194
+ ## Error Message Quality
195
+
196
+ Good error messages reduce debugging time from hours to minutes.
197
+
198
+ ```typescript
199
+ // ❌ Unhelpful error
200
+ throw new Error('Invalid directory');
201
+
202
+ // ✓ Helpful error - includes what, where, why, and the actual value
203
+ throw new Error(
204
+ `WorktreeManager.createWorktree: projectDir must be an absolute path to an existing directory.\n` +
205
+ `Got: ${JSON.stringify(projectDir)}\n` +
206
+ `Hint: Check that the project was initialized before calling this method.`
207
+ );
208
+ ```
209
+
210
+ **Error message template:**
211
+ ```
212
+ {ClassName}.{methodName}: {what went wrong}.
213
+ Got: {actual value}
214
+ Expected: {what was expected}
215
+ Hint: {likely cause or fix}
216
+ ```
217
+
218
+ ## Common Validation Patterns
219
+
220
+ ```typescript
221
+ // Non-empty string
222
+ if (!value || typeof value !== 'string' || value.trim() === '') {
223
+ throw new Error(`${context}: ${fieldName} must be a non-empty string, got: ${JSON.stringify(value)}`);
224
+ }
225
+
226
+ // Positive number
227
+ if (typeof value !== 'number' || value <= 0 || !isFinite(value)) {
228
+ throw new Error(`${context}: ${fieldName} must be a positive number, got: ${value}`);
229
+ }
230
+
231
+ // Valid enum value
232
+ const validValues = ['draft', 'active', 'archived'] as const;
233
+ if (!validValues.includes(value)) {
234
+ throw new Error(`${context}: ${fieldName} must be one of [${validValues.join(', ')}], got: ${JSON.stringify(value)}`);
235
+ }
236
+
237
+ // Required object field
238
+ if (!obj || typeof obj !== 'object') {
239
+ throw new Error(`${context}: ${fieldName} must be an object, got: ${typeof obj}`);
240
+ }
241
+ ```
242
+
243
+ ## Result
244
+
245
+ After applying defense-in-depth to the session initialization bug:
246
+
247
+ - Layer 1 caught: Invalid input at `createSession()` entry point
248
+ - Layer 2 caught: Empty string in `Session` constructor
249
+ - Layer 3 caught: Unset `projectDir` before `git init`
250
+ - Layer 4 caught: Test assertion verified correct path was used
251
+
252
+ The bug class is now structurally impossible — it would be caught at the earliest possible point with a clear error message pointing to the root cause.
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env bash
2
+ # find-polluter.sh — Binary search for test pollution source
3
+ # Source: https://github.com/tmdgusya/engineering-disciplines (MIT License)
4
+ #
5
+ # Usage: ./find-polluter.sh <test-runner-cmd> <failing-test-pattern>
6
+ # Example: ./find-polluter.sh "bun test" "should not have side effects"
7
+ #
8
+ # How it works:
9
+ # 1. Runs all tests to confirm the failure exists
10
+ # 2. Binary searches through the test list to find which test causes pollution
11
+ # 3. Reports the polluter and its position in the test order
12
+ #
13
+ # Requirements: Test runner must support running specific test files
14
+ # Works with: jest, vitest, bun test, mocha
15
+
16
+ set -euo pipefail
17
+
18
+ # Configuration
19
+ TEST_CMD="${1:-bun test}"
20
+ FAILING_TEST="${2:-}"
21
+ TIMEOUT="${3:-60}" # seconds per test run
22
+
23
+ if [[ -z "$FAILING_TEST" ]]; then
24
+ echo "Usage: $0 <test-runner-cmd> <failing-test-pattern> [timeout-seconds]"
25
+ echo "Example: $0 'bun test' 'should not have side effects' 60"
26
+ exit 1
27
+ fi
28
+
29
+ # Colors for output
30
+ RED='\033[0;31m'
31
+ GREEN='\033[0;32m'
32
+ YELLOW='\033[1;33m'
33
+ NC='\033[0m' # No Color
34
+
35
+ log_info() { echo -e "${GREEN}[INFO]${NC} $*"; }
36
+ log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
37
+ log_error() { echo -e "${RED}[ERROR]${NC} $*"; }
38
+
39
+ # Step 1: Collect all test files
40
+ log_info "Collecting test files..."
41
+ mapfile -t ALL_TEST_FILES < <(find . -name "*.test.ts" -o -name "*.test.js" -o -name "*.spec.ts" -o -name "*.spec.js" | grep -v node_modules | sort)
42
+
43
+ if [[ ${#ALL_TEST_FILES[@]} -eq 0 ]]; then
44
+ log_error "No test files found"
45
+ exit 1
46
+ fi
47
+
48
+ log_info "Found ${#ALL_TEST_FILES[@]} test files"
49
+
50
+ # Step 2: Confirm the failure exists when running all tests
51
+ log_info "Confirming failure exists with full test suite..."
52
+ if timeout "$TIMEOUT" bash -c "$TEST_CMD 2>&1" | grep -q "$FAILING_TEST"; then
53
+ if timeout "$TIMEOUT" bash -c "$TEST_CMD 2>&1" | grep -q "FAIL\|✗\|× "; then
54
+ log_info "Failure confirmed in full suite"
55
+ else
56
+ log_warn "Test pattern found but no failures detected - check pattern matches failing test"
57
+ fi
58
+ else
59
+ log_error "Failing test pattern '$FAILING_TEST' not found in test output"
60
+ log_error "Check that the test exists and the pattern is correct"
61
+ exit 1
62
+ fi
63
+
64
+ # Step 3: Confirm the test passes in isolation
65
+ FAILING_TEST_FILE=""
66
+ for f in "${ALL_TEST_FILES[@]}"; do
67
+ if grep -l "$FAILING_TEST" "$f" &>/dev/null; then
68
+ FAILING_TEST_FILE="$f"
69
+ break
70
+ fi
71
+ done
72
+
73
+ if [[ -z "$FAILING_TEST_FILE" ]]; then
74
+ log_error "Could not find file containing test: $FAILING_TEST"
75
+ exit 1
76
+ fi
77
+
78
+ log_info "Failing test is in: $FAILING_TEST_FILE"
79
+ log_info "Testing in isolation..."
80
+
81
+ if timeout "$TIMEOUT" bash -c "$TEST_CMD $FAILING_TEST_FILE 2>&1" | grep -q "FAIL\|✗\|× "; then
82
+ log_warn "Test fails even in isolation - this is not a pollution issue"
83
+ log_warn "The test itself has a bug, not pollution from another test"
84
+ exit 0
85
+ else
86
+ log_info "Test passes in isolation - pollution confirmed"
87
+ fi
88
+
89
+ # Step 4: Binary search for the polluter
90
+ # Remove the failing test file from the list of candidates
91
+ CANDIDATE_FILES=()
92
+ for f in "${ALL_TEST_FILES[@]}"; do
93
+ if [[ "$f" != "$FAILING_TEST_FILE" ]]; then
94
+ CANDIDATE_FILES+=("$f")
95
+ fi
96
+ done
97
+
98
+ log_info "Binary searching through ${#CANDIDATE_FILES[@]} candidate files..."
99
+
100
+ low=0
101
+ high=$((${#CANDIDATE_FILES[@]} - 1))
102
+ found_polluter=""
103
+
104
+ while [[ $low -le $high ]]; do
105
+ mid=$(( (low + high) / 2 ))
106
+
107
+ # Test with files from 0 to mid, plus the failing test
108
+ SUBSET=("${CANDIDATE_FILES[@]:0:$((mid + 1))}" "$FAILING_TEST_FILE")
109
+
110
+ log_info "Testing subset of $((mid + 1)) files (indices 0-$mid) + failing test..."
111
+
112
+ # Build file list for the test command
113
+ FILE_LIST="${SUBSET[*]}"
114
+
115
+ if timeout "$TIMEOUT" bash -c "$TEST_CMD $FILE_LIST 2>&1" | grep -q "FAIL\|✗\|× "; then
116
+ log_info "Failure reproduced with subset 0-$mid"
117
+ high=$((mid - 1))
118
+ found_polluter="${CANDIDATE_FILES[$mid]}"
119
+ else
120
+ log_info "No failure with subset 0-$mid, polluter is in higher range"
121
+ low=$((mid + 1))
122
+ fi
123
+ done
124
+
125
+ # Step 5: Report results
126
+ echo ""
127
+ echo "=========================================="
128
+ if [[ -n "$found_polluter" ]]; then
129
+ log_info "POLLUTER FOUND: $found_polluter"
130
+ echo ""
131
+ echo "This test file causes '$FAILING_TEST' to fail when run before it."
132
+ echo ""
133
+ echo "To verify:"
134
+ echo " $TEST_CMD $found_polluter $FAILING_TEST_FILE"
135
+ echo ""
136
+ echo "Next steps:"
137
+ echo " 1. Open $found_polluter"
138
+ echo " 2. Look for: global state mutations, missing afterEach/afterAll cleanup"
139
+ echo " 3. Check for: database records not deleted, files not cleaned up"
140
+ echo " 4. Check for: environment variables set but not restored"
141
+ echo " 5. Add proper cleanup in afterEach/afterAll"
142
+ else
143
+ log_warn "Polluter not found via binary search"
144
+ log_warn "This may happen if multiple tests together cause the pollution"
145
+ log_warn "Try running subsets manually to narrow down"
146
+ fi
147
+ echo "=========================================="