claude-dev-env 1.38.0 → 1.39.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 (271) hide show
  1. package/CLAUDE.md +10 -36
  2. package/_shared/pr-loop/audit-reply-template.md +147 -0
  3. package/_shared/pr-loop/fix-protocol.md +25 -4
  4. package/_shared/pr-loop/gh-payloads.md +37 -50
  5. package/_shared/pr-loop/scripts/code_rules_gate.py +0 -60
  6. package/_shared/pr-loop/scripts/config/post_audit_thread_constants.py +189 -0
  7. package/_shared/pr-loop/scripts/post_audit_thread.py +947 -0
  8. package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +0 -19
  9. package/_shared/pr-loop/scripts/tests/test_post_audit_thread.py +923 -0
  10. package/_shared/pr-loop/scripts/tests/test_post_audit_thread_constants.py +127 -0
  11. package/_shared/pr-loop/state-schema.md +1 -1
  12. package/agents/clean-coder.md +2 -2
  13. package/bin/install.mjs +6 -7
  14. package/bin/install.test.mjs +8 -0
  15. package/commands/doc-gist.md +16 -0
  16. package/commands/plan.md +0 -2
  17. package/commands/review-plan.md +1 -1
  18. package/docs/CODE_RULES.md +122 -2
  19. package/hooks/blocking/bot_mention_comment_blocker.py +75 -0
  20. package/hooks/blocking/code_rules_enforcer.py +1236 -161
  21. package/hooks/blocking/convergence_gate_blocker.py +130 -0
  22. package/hooks/blocking/destructive_command_blocker.py +74 -0
  23. package/hooks/blocking/gh_body_arg_blocker.py +30 -0
  24. package/hooks/blocking/md_to_html_blocker.py +119 -0
  25. package/hooks/blocking/test_bot_mention_comment_blocker.py +131 -0
  26. package/hooks/blocking/test_code_rules_enforcer.py +21 -0
  27. package/hooks/blocking/test_code_rules_enforcer_any_exempt_files.py +70 -0
  28. package/hooks/blocking/test_code_rules_enforcer_any_imports_and_cast.py +92 -0
  29. package/hooks/blocking/test_code_rules_enforcer_banned_import_alias.py +143 -0
  30. package/hooks/blocking/test_code_rules_enforcer_banned_prefixes.py +152 -0
  31. package/hooks/blocking/test_code_rules_enforcer_bare_except.py +120 -0
  32. package/hooks/blocking/test_code_rules_enforcer_boundary_types.py +175 -0
  33. package/hooks/blocking/test_code_rules_enforcer_cap_meta.py +0 -1
  34. package/hooks/blocking/test_code_rules_enforcer_collection_prefix.py +50 -0
  35. package/hooks/blocking/test_code_rules_enforcer_docstring_format.py +255 -0
  36. package/hooks/blocking/test_code_rules_enforcer_inline_tuple_string_magic.py +130 -0
  37. package/hooks/blocking/test_code_rules_enforcer_stub_implementations.py +141 -0
  38. package/hooks/blocking/test_code_rules_enforcer_test_branching.py +143 -0
  39. package/hooks/blocking/test_code_rules_enforcer_thin_wrapper_files.py +169 -0
  40. package/hooks/blocking/test_code_rules_enforcer_todo_markers.py +99 -0
  41. package/hooks/blocking/test_code_rules_enforcer_typed_dict_pairs.py +141 -0
  42. package/hooks/blocking/test_code_rules_enforcer_unused_imports.py +158 -0
  43. package/hooks/blocking/test_convergence_gate_blocker.py +63 -0
  44. package/hooks/blocking/test_destructive_command_blocker.py +146 -0
  45. package/hooks/blocking/test_destructive_command_blocker_no_verify.py +102 -0
  46. package/hooks/blocking/test_gh_body_arg_blocker.py +45 -0
  47. package/hooks/blocking/test_md_to_html_blocker.py +317 -0
  48. package/hooks/config/any_type_config.py +7 -0
  49. package/hooks/config/banned_identifiers_constants.py +11 -0
  50. package/hooks/config/blocking_check_limits.py +38 -0
  51. package/hooks/config/bot_mention_comment_blocker_constants.py +20 -0
  52. package/hooks/config/code_rules_enforcer_constants.py +53 -0
  53. package/hooks/config/convergence_branch_constants.py +9 -0
  54. package/hooks/config/doc_gist_auto_publish_constants.py +18 -0
  55. package/hooks/config/html_companion_constants.py +20 -0
  56. package/hooks/config/inline_tuple_string_magic_constants.py +22 -0
  57. package/hooks/config/test_banned_identifiers_constants.py +17 -0
  58. package/hooks/hooks.json +28 -20
  59. package/hooks/pyproject.toml +69 -0
  60. package/hooks/validators/mypy_integration.py +47 -1
  61. package/hooks/validators/run_all_validators.py +3 -3
  62. package/hooks/validators/test_mypy_integration.py +50 -1
  63. package/hooks/workflow/doc_gist_auto_publish.py +144 -0
  64. package/hooks/workflow/md_to_html_companion.py +365 -0
  65. package/hooks/workflow/test_doc_gist_auto_publish.py +117 -0
  66. package/hooks/workflow/test_md_to_html_companion.py +452 -0
  67. package/package.json +1 -1
  68. package/rules/gh-body-file.md +2 -0
  69. package/scripts/Install-SweepEmptyDirs.ps1 +111 -0
  70. package/scripts/check.ps1 +106 -0
  71. package/scripts/config/timing.py +11 -0
  72. package/scripts/sweep_empty_dirs.py +138 -0
  73. package/scripts/sync_to_cursor/rules.py +1 -1
  74. package/scripts/test_sweep_empty_dirs.py +183 -0
  75. package/skills/_shared/pr-loop/prompts/pr-consistency-audit.xml +323 -0
  76. package/skills/_shared/pr-loop/scripts/_cli_utils.py +22 -0
  77. package/skills/_shared/pr-loop/scripts/_path_resolver.py +165 -0
  78. package/skills/_shared/pr-loop/scripts/_xml_utils.py +20 -0
  79. package/skills/_shared/pr-loop/scripts/build_audit_prompt.py +182 -0
  80. package/skills/_shared/pr-loop/scripts/build_fix_prompt.py +185 -0
  81. package/skills/_shared/pr-loop/scripts/config/__init__.py +0 -0
  82. package/skills/_shared/pr-loop/scripts/config/path_resolver_constants.py +78 -0
  83. package/skills/_shared/pr-loop/scripts/init_loop_state.py +135 -0
  84. package/skills/_shared/pr-loop/scripts/teardown_worktrees.py +175 -0
  85. package/skills/_shared/pr-loop/scripts/write_audit_outcomes.py +182 -0
  86. package/skills/_shared/pr-loop/scripts/write_fix_outcomes.py +206 -0
  87. package/skills/bugteam/CONSTRAINTS.md +21 -22
  88. package/skills/bugteam/EXAMPLES.md +3 -3
  89. package/skills/bugteam/PROMPTS.md +227 -67
  90. package/skills/bugteam/SKILL.md +114 -455
  91. package/skills/bugteam/reference/README.md +1 -1
  92. package/skills/bugteam/reference/audit-and-teammates.md +112 -39
  93. package/skills/bugteam/reference/audit-contract.md +4 -22
  94. package/skills/bugteam/reference/copilot-gap-analysis.md +8 -5
  95. package/skills/bugteam/reference/design-rationale.md +2 -2
  96. package/skills/bugteam/reference/github-pr-reviews.md +50 -57
  97. package/skills/bugteam/reference/obstacles/audit-assign-ids.md +13 -0
  98. package/skills/bugteam/reference/obstacles/audit-capture-excerpts.md +13 -0
  99. package/skills/bugteam/reference/obstacles/audit-walk-categories.md +13 -0
  100. package/skills/bugteam/reference/obstacles/audit-write-xml.md +13 -0
  101. package/skills/bugteam/reference/obstacles/fix-append-summary.md +13 -0
  102. package/skills/bugteam/reference/obstacles/fix-apply-fixes.md +13 -0
  103. package/skills/bugteam/reference/obstacles/fix-git-add-commit.md +13 -0
  104. package/skills/bugteam/reference/obstacles/fix-git-push.md +13 -0
  105. package/skills/bugteam/reference/obstacles/fix-post-reply.md +13 -0
  106. package/skills/bugteam/reference/obstacles/fix-publish-summary.md +13 -0
  107. package/skills/bugteam/reference/obstacles/fix-py-compile.md +13 -0
  108. package/skills/bugteam/reference/obstacles/fix-read-files.md +13 -0
  109. package/skills/bugteam/reference/obstacles/fix-resolve-thread.md +13 -0
  110. package/skills/bugteam/reference/obstacles/fix-test-suite.md +13 -0
  111. package/skills/bugteam/reference/obstacles/fix-violation-count.md +13 -0
  112. package/skills/bugteam/reference/obstacles/fix-write-xml.md +13 -0
  113. package/skills/bugteam/reference/team-setup.md +106 -9
  114. package/skills/bugteam/reference/teardown-publish-permissions.md +39 -8
  115. package/skills/bugteam/scripts/README.md +60 -0
  116. package/skills/bugteam/scripts/_claude_permissions_common.py +358 -0
  117. package/skills/bugteam/scripts/bugteam_code_rules_gate.py +976 -0
  118. package/skills/bugteam/scripts/bugteam_fix_hookspath.py +375 -0
  119. package/skills/bugteam/scripts/bugteam_preflight.py +294 -0
  120. package/skills/bugteam/scripts/config/bugteam_code_rules_gate_constants.py +25 -0
  121. package/skills/bugteam/scripts/config/bugteam_fix_hookspath_constants.py +26 -0
  122. package/skills/bugteam/scripts/config/bugteam_preflight_constants.py +35 -0
  123. package/skills/bugteam/scripts/config/claude_permissions_common_constants.py +20 -0
  124. package/skills/bugteam/scripts/config/probe_code_rules_enforcer_check_constants.py +12 -0
  125. package/skills/bugteam/scripts/config/windows_safe_rmtree_constants.py +7 -0
  126. package/skills/bugteam/scripts/grant_project_claude_permissions.py +175 -0
  127. package/skills/bugteam/scripts/probe_code_rules_enforcer_check.py +107 -0
  128. package/skills/bugteam/scripts/revoke_project_claude_permissions.py +220 -0
  129. package/skills/bugteam/scripts/test__claude_permissions_common.py +112 -0
  130. package/skills/bugteam/scripts/test_bugteam_code_rules_gate.py +400 -0
  131. package/skills/bugteam/scripts/test_bugteam_fix_hookspath.py +384 -0
  132. package/skills/bugteam/scripts/test_bugteam_preflight.py +268 -0
  133. package/skills/bugteam/scripts/test_claude_permissions_common.py +195 -0
  134. package/skills/bugteam/scripts/test_grant_project_claude_permissions.py +55 -0
  135. package/skills/bugteam/scripts/test_probe_code_rules_enforcer_check.py +76 -0
  136. package/skills/bugteam/scripts/test_revoke_project_claude_permissions.py +55 -0
  137. package/skills/bugteam/scripts/test_windows_safe_rmtree.py +108 -0
  138. package/skills/bugteam/scripts/windows_safe_rmtree.py +100 -0
  139. package/skills/bugteam/test_skill_additions.py +1 -11
  140. package/skills/code/SKILL.md +176 -0
  141. package/skills/doc-gist/SKILL.md +99 -0
  142. package/skills/doc-gist/references/examples/01-exploration-code-approaches.html +453 -0
  143. package/skills/doc-gist/references/examples/02-exploration-visual-designs.html +515 -0
  144. package/skills/doc-gist/references/examples/03-code-review-pr.html +638 -0
  145. package/skills/doc-gist/references/examples/04-code-understanding.html +491 -0
  146. package/skills/doc-gist/references/examples/05-design-system.html +629 -0
  147. package/skills/doc-gist/references/examples/06-component-variants.html +605 -0
  148. package/skills/doc-gist/references/examples/07-prototype-animation.html +455 -0
  149. package/skills/doc-gist/references/examples/08-prototype-interaction.html +396 -0
  150. package/skills/doc-gist/references/examples/09-slide-deck.html +592 -0
  151. package/skills/doc-gist/references/examples/10-svg-illustrations.html +492 -0
  152. package/skills/doc-gist/references/examples/11-status-report.html +528 -0
  153. package/skills/doc-gist/references/examples/12-incident-report.html +596 -0
  154. package/skills/doc-gist/references/examples/13-flowchart-diagram.html +395 -0
  155. package/skills/doc-gist/references/examples/14-research-feature-explainer.html +381 -0
  156. package/skills/doc-gist/references/examples/15-research-concept-explainer.html +368 -0
  157. package/skills/doc-gist/references/examples/16-implementation-plan.html +702 -0
  158. package/skills/doc-gist/references/examples/17-pr-writeup.html +595 -0
  159. package/skills/doc-gist/references/examples/18-editor-triage-board.html +573 -0
  160. package/skills/doc-gist/references/examples/19-editor-feature-flags.html +663 -0
  161. package/skills/doc-gist/references/examples/20-editor-prompt-tuner.html +722 -0
  162. package/skills/doc-gist/references/examples/README.md +5 -0
  163. package/skills/doc-gist/scripts/config/__init__.py +0 -0
  164. package/skills/doc-gist/scripts/config/gist_upload_constants.py +16 -0
  165. package/skills/doc-gist/scripts/gist_upload.py +177 -0
  166. package/skills/doc-gist/scripts/test_gist_upload.py +51 -0
  167. package/skills/findbugs/SKILL.md +68 -2
  168. package/skills/monitor-open-prs/SKILL.md +13 -32
  169. package/skills/monitor-open-prs/test_skill_contract.py +0 -11
  170. package/skills/pr-consistency-audit/SKILL.md +112 -0
  171. package/skills/pr-consistency-audit/reference/detection-rules.md +96 -0
  172. package/skills/pr-consistency-audit/reference/illustrations.md +78 -0
  173. package/skills/pr-converge/SKILL.md +227 -23
  174. package/skills/pr-converge/config/__init__.py +0 -0
  175. package/skills/pr-converge/config/constants.py +62 -0
  176. package/skills/pr-converge/reference/convergence-gates.md +138 -44
  177. package/skills/pr-converge/reference/examples.md +43 -11
  178. package/skills/pr-converge/reference/fix-protocol.md +6 -5
  179. package/skills/pr-converge/reference/ground-rules.md +5 -3
  180. package/skills/pr-converge/reference/multi-pr-orchestration.md +44 -19
  181. package/skills/pr-converge/reference/obstacles/fix-post-replies.md +13 -0
  182. package/skills/pr-converge/reference/obstacles/fix-publish-summary.md +13 -0
  183. package/skills/pr-converge/reference/obstacles/fix-push.md +13 -0
  184. package/skills/pr-converge/reference/obstacles/fix-read-filelines.md +13 -0
  185. package/skills/pr-converge/reference/obstacles/fix-reset-state.md +13 -0
  186. package/skills/pr-converge/reference/obstacles/fix-resolve-threads.md +13 -0
  187. package/skills/pr-converge/reference/obstacles/fix-spawn-clean-coder.md +13 -0
  188. package/skills/pr-converge/reference/obstacles/fix-stage-commit.md +13 -0
  189. package/skills/pr-converge/reference/obstacles/fix-trigger-bugbot.md +13 -0
  190. package/skills/pr-converge/reference/obstacles/fix-write-test.md +13 -0
  191. package/skills/pr-converge/reference/per-tick.md +90 -31
  192. package/skills/pr-converge/reference/state-schema.md +22 -1
  193. package/skills/pr-converge/reference/stop-conditions.md +9 -7
  194. package/skills/pr-converge/scripts/README.md +34 -46
  195. package/skills/pr-converge/scripts/check_bugbot_ci.py +174 -0
  196. package/skills/pr-converge/scripts/check_convergence.py +497 -0
  197. package/skills/pr-converge/scripts/check_pending_reviews.py +154 -0
  198. package/skills/pr-converge/scripts/config/pr_converge_constants.py +118 -0
  199. package/skills/pr-converge/scripts/fetch_copilot_reviews.py +134 -0
  200. package/skills/pr-converge/scripts/post_fix_reply.py +168 -0
  201. package/skills/pr-converge/workflows/schedule-wakeup-loop.md +5 -12
  202. package/skills/qbug/SKILL.md +132 -27
  203. package/skills/session-log/SKILL.md +216 -114
  204. package/skills/session-tidy/SKILL.md +1 -1
  205. package/skills/skill-builder/SKILL.md +138 -56
  206. package/skills/skill-builder/references/delegation-map.md +72 -113
  207. package/skills/skill-builder/references/progressive-disclosure.md +122 -0
  208. package/skills/skill-builder/references/self-audit-checklist.md +92 -0
  209. package/skills/skill-builder/references/skill-types.md +228 -0
  210. package/skills/skill-builder/references/thariq-x-post-skills.json +33 -0
  211. package/skills/skill-builder/templates/gap-analysis.md +15 -8
  212. package/skills/skill-builder/workflows/improve-skill.md +86 -57
  213. package/skills/skill-builder/workflows/new-skill.md +80 -168
  214. package/skills/skill-builder/workflows/polish-skill.md +78 -54
  215. package/skills/structure-prompt/SKILL.md +50 -0
  216. package/skills/structure-prompt/reference/adversarial-tuning.md +62 -0
  217. package/skills/structure-prompt/reference/block-classification.md +27 -0
  218. package/skills/structure-prompt/reference/canonical-case.md +48 -0
  219. package/skills/structure-prompt/reference/citation-depth.md +70 -0
  220. package/skills/structure-prompt/reference/cleanup.md +33 -0
  221. package/skills/structure-prompt/reference/constraints.md +33 -0
  222. package/skills/structure-prompt/reference/directives.md +37 -0
  223. package/skills/structure-prompt/reference/examples.md +72 -0
  224. package/skills/structure-prompt/reference/instantiation.md +51 -0
  225. package/skills/structure-prompt/reference/output-contract.md +72 -0
  226. package/skills/structure-prompt/reference/per-category.md +23 -0
  227. package/skills/structure-prompt/reference/persona.md +38 -0
  228. package/skills/structure-prompt/reference/research.md +33 -0
  229. package/skills/structure-prompt/reference/structure.md +28 -0
  230. package/agents/code-standards-agent.md +0 -93
  231. package/agents/groq-coder.md +0 -113
  232. package/agents/plan-executor.md +0 -226
  233. package/agents/project-docs-analyzer.md +0 -53
  234. package/agents/project-structure-organizer-agent.md +0 -72
  235. package/agents/skill-to-agent-converter.md +0 -370
  236. package/agents/skill-writer-agent.md +0 -470
  237. package/agents/user-docs-writer.md +0 -67
  238. package/agents/workflow-visual-documenter.md +0 -82
  239. package/commands/readability-review.md +0 -20
  240. package/hooks/mypy.ini +0 -2
  241. package/hooks/notification/attention_needed_notify.py +0 -71
  242. package/hooks/notification/claude_notification_handler.py +0 -67
  243. package/hooks/notification/notification_utils.py +0 -267
  244. package/hooks/notification/subagent_complete_notify.py +0 -381
  245. package/hooks/notification/test_attention_needed_notify.py +0 -47
  246. package/hooks/notification/test_claude_notification_handler.py +0 -54
  247. package/hooks/notification/test_notification_utils.py +0 -91
  248. package/hooks/notification/test_subagent_complete_notify.py +0 -79
  249. package/scripts/config/groq_bugteam_config.py +0 -230
  250. package/scripts/config/test_groq_bugteam_config.py +0 -83
  251. package/scripts/config/test_spec_implementer_prompt.py +0 -32
  252. package/scripts/groq_bugteam.README.md +0 -131
  253. package/scripts/groq_bugteam.py +0 -647
  254. package/scripts/groq_bugteam_dotenv.py +0 -40
  255. package/scripts/groq_bugteam_spec.py +0 -226
  256. package/scripts/test_groq_bugteam.py +0 -529
  257. package/scripts/test_groq_bugteam_apply_fix_from_spec.py +0 -426
  258. package/scripts/test_groq_bugteam_dotenv.py +0 -66
  259. package/scripts/test_groq_bugteam_spec.py +0 -338
  260. package/skills/bugteam/SKILL_EVALS.md +0 -309
  261. package/skills/dream/SKILL.md +0 -118
  262. package/skills/ingest/SKILL.md +0 -40
  263. package/skills/npm-creator/SKILL.md +0 -187
  264. package/skills/readability-review/SKILL.md +0 -127
  265. package/skills/resume-review/SKILL.md +0 -261
  266. package/skills/rule-audit/SKILL.md +0 -307
  267. package/skills/rule-creator/SKILL.md +0 -150
  268. package/skills/searching-obsidian-vault/SKILL.md +0 -131
  269. package/skills/skill-writer/REFERENCE.md +0 -284
  270. package/skills/skill-writer/SKILL.md +0 -222
  271. package/skills/tdd-team/SKILL.md +0 -128
@@ -1,230 +0,0 @@
1
- """Centralized configuration for groq_bugteam.py.
2
-
3
- All module-level scalar constants live here per the repo's ``constants-location``
4
- rule. Import into the script and bind local aliases where needed.
5
- """
6
-
7
- GROQ_API_ENDPOINT = "https://api.groq.com/openai/v1/chat/completions"
8
- GROQ_PRIMARY_MODEL = "llama-3.3-70b-versatile"
9
- GROQ_FALLBACK_MODEL = "llama-3.1-8b-instant"
10
- GROQ_REQUEST_TIMEOUT_SECONDS = 90
11
- GROQ_AUDIT_MAX_COMPLETION_TOKENS = 2500
12
- GROQ_FIX_MAX_COMPLETION_TOKENS = 8000
13
- GROQ_AUDIT_TEMPERATURE = 0.1
14
- GROQ_FIX_TEMPERATURE = 0.1
15
-
16
- MAXIMUM_FILE_CONTENT_CHARACTERS = 60000
17
- MAXIMUM_DIFF_CHARACTERS = 80000
18
- MAXIMUM_FINDINGS_PER_PR = 20
19
-
20
- GROQ_RETRY_BACKOFF_SECONDS = (2, 4, 8)
21
-
22
- REVIEW_BODY_HEADER_TEMPLATE = "## groq-bugteam audit: {p0} P0 / {p1} P1 / {p2} P2"
23
- NO_FINDINGS_REVIEW_BODY = (
24
- "## groq-bugteam audit: clean\n\n"
25
- "Groq ({model}) reviewed the diff against categories A-K and found no issues."
26
- )
27
-
28
- AUDIT_SYSTEM_PROMPT = """You are an adversarial code reviewer auditing a pull request diff.
29
-
30
- Inspect ONLY lines added or modified in the diff. Pre-existing code on
31
- untouched lines is out of scope. Cite file:line for every finding -- the line
32
- number MUST refer to the NEW side of the diff (post-change line number).
33
-
34
- Investigate these eleven categories. Skip a category silently when you find
35
- nothing; do not emit verified-clean entries. For the canonical rubric and
36
- sub-bucket decomposition for each category, see
37
- packages/claude-dev-env/audit-rubrics/category_rubrics/. For ready-to-send
38
- Variant C audit prompts (each containing a PR/repo-independent generalized
39
- skeleton above a `---` separator and a worked example against an authentic
40
- PR below it), see packages/claude-dev-env/audit-rubrics/prompts/.
41
-
42
- A. API contract verification (signatures, return types, async/await)
43
- B. Selector / query / engine compatibility
44
- C. Resource cleanup and lifecycle (file handles, connections, processes, locks)
45
- D. Variable scoping, ordering, unbound references
46
- E. Dead code, unused imports, dead parameters
47
- F. Silent failures (catch-all excepts, unconditional success returns)
48
- G. Off-by-one, bounds, integer overflow
49
- H. Security boundaries (injection, path traversal, auth bypass, secret leakage)
50
- I. Concurrency hazards (race conditions, missing awaits, shared mutable state)
51
- J. Magic values and configuration drift
52
- K. Codebase conflicts (a change updates one site of a pattern but a parallel
53
- site in unchanged code stays stale, producing contradictory behavior;
54
- diff is internally consistent, bug emerges only against unchanged code)
55
-
56
- Severity rubric:
57
- - P0: crashes, data loss, security breach, broken production invariant
58
- - P1: incorrect behavior, resource leak, regression on common path
59
- - P2: style, dead code, minor DRY violations
60
-
61
- Respond with JSON only -- no prose outside the JSON object. Shape:
62
-
63
- {
64
- "findings": [
65
- {
66
- "severity": "P0" | "P1" | "P2",
67
- "category": "A" | ... | "K",
68
- "file": "relative path from repo root",
69
- "line": int,
70
- "title": "one-line summary",
71
- "description": "2-3 sentences with concrete trace; reference the diff line"
72
- }
73
- ]
74
- }
75
-
76
- Cap findings at the top 20 most important. If no bugs, return {"findings": []}.
77
-
78
- FILE-TYPE GUARDRAILS. Do not apply code-specific categories to non-code files:
79
- - JSON / YAML / TOML / INI / Markdown / plain text: only flag CATEGORY H
80
- (security) or J (real configuration drift that breaks something). Do NOT
81
- flag E (dead code), A (API contract), or D (variable scoping) on these
82
- files. A version string in package.json is NOT a magic value.
83
- - Lockfiles and auto-generated manifests: skip entirely.
84
- - Changelogs: skip entirely.
85
-
86
- QUALITY BAR. Only emit a finding if you can point at the specific line in
87
- the DIFF that introduced it AND describe the failure mode concretely. Skip
88
- speculative style complaints.
89
- """
90
-
91
- FIX_SYSTEM_PROMPT = """You are a focused bug-fixer. You receive one file's full
92
- contents plus a list of findings that apply to that file. Produce the full
93
- corrected file contents.
94
-
95
- Rules:
96
- 1. Address every listed finding. If a finding is not actionable, leave the
97
- file unchanged and explain in the ``skipped`` array.
98
- 2. Modify ONLY the lines required to address the findings. Preserve all other
99
- code exactly -- comments, whitespace, blank lines, import order.
100
- 3. Do not add new comments or docstrings unless the finding explicitly asks
101
- for one.
102
- 4. Do not introduce new imports unless required by a fix.
103
- 5. Output JSON only. Shape:
104
-
105
- {
106
- "updated_content": "full corrected file contents",
107
- "applied_finding_indexes": [0, 2, ...],
108
- "skipped": [
109
- {"finding_index": 1, "reason": "one-line reason"}
110
- ]
111
- }
112
-
113
- When you cannot produce a safe fix, set ``updated_content`` equal to the input
114
- BYTE-FOR-BYTE (same whitespace, same trailing newline, same indentation) and
115
- list every finding in ``skipped``. NEVER reformat or re-indent a file whose
116
- findings you are skipping.
117
-
118
- If ``applied_finding_indexes`` is empty, ``updated_content`` MUST equal the
119
- input exactly.
120
- """
121
-
122
- SPEC_IMPLEMENTER_SYSTEM_PROMPT = """<groq_spec_implementer>
123
-
124
- <role>
125
- Apply a Claude-authored fix-spec to a single file. Treat each spec as an executable patch instruction authored by a higher-reasoning agent that already validated the bug and decided the fix. Perform mechanical edits only. Never re-evaluate whether the finding is real, relevant, or well-scoped — Claude already decided that. Produce the patched file contents and a self-assessment of every acceptance criterion stated in the spec.
126
- </role>
127
-
128
- <inputs>
129
- Every invocation provides exactly two inputs:
130
-
131
- 1. The current contents of one file, as a single UTF-8 string.
132
-
133
- 2. A fix-spec array targeting that file. Each spec entry has these fields:
134
-
135
- - finding_index (int, stable across audit and fix)
136
- - severity (P0 | P1 | P2)
137
- - category (single letter A–K)
138
- - file (relative path, must match the file being patched)
139
- - target_line_start (int, 1-based, inclusive)
140
- - target_line_end (int, 1-based, inclusive; equals target_line_start for single-line edits)
141
- - intended_change (natural-language description of the edit)
142
- - replacement_code (optional literal text to splice in; absent when Claude wanted Groq to derive the edit from intended_change + acceptance_criteria)
143
- - acceptance_criteria (array of observable post-fix assertions; each is a standalone sentence a reader can check against the patched file)
144
-
145
- Treat every field as authoritative. Accept the finding_index exactly as provided and echo it in the output.
146
- </inputs>
147
-
148
- <rules>
149
-
150
- <rule_1_mechanical_only>
151
- Apply the spec verbatim. Skip every form of re-analysis. Only edit lines covered by target_line_start..target_line_end, plus any new lines explicitly required by intended_change (for example, adding a new import when intended_change requires the fix to import a module).
152
- </rule_1_mechanical_only>
153
-
154
- <rule_2_replacement_code_when_present>
155
- When replacement_code is present, splice it in so the resulting file replaces lines target_line_start..target_line_end with the exact text of replacement_code. Preserve the newline character at the end of the replaced span so the file's line structure remains consistent.
156
- </rule_2_replacement_code_when_present>
157
-
158
- <rule_3_derive_minimally_when_replacement_absent>
159
- When replacement_code is absent, implement the smallest edit that satisfies intended_change AND every acceptance_criterion. Choose the minimum number of lines within the target range required to pass the acceptance checks.
160
- </rule_3_derive_minimally_when_replacement_absent>
161
-
162
- <rule_4_byte_for_byte_outside_edit>
163
- Preserve every byte outside the edited region: leading whitespace, trailing whitespace, trailing newline presence or absence, indent style (tabs versus spaces), blank-line placement, import order, existing comment placement, and line-ending style. Read the input file's trailing-newline state and reproduce it exactly in the output.
164
- </rule_4_byte_for_byte_outside_edit>
165
-
166
- <rule_5_no_stylistic_additions>
167
- Add zero new comments, docstrings, type hints, or defensive code unless the spec explicitly requires one. Reject every impulse to refactor, rename, reorder, or "clean up" nearby code. Keep the diff as narrow as the spec allows.
168
- </rule_5_no_stylistic_additions>
169
-
170
- <rule_6_never_invent_authorization>
171
- Only apply edits covered by a spec entry. When a spec says "replace line 42" and line 42 does not exist or is empty, skip the finding with a one-line reason. Never fabricate lines Claude did not authorize. Never generalize the spec to adjacent lines.
172
- </rule_6_never_invent_authorization>
173
-
174
- <rule_7_acceptance_self_check>
175
- For every finding marked applied, evaluate each acceptance_criterion against the patched file contents. Record the result in acceptance_checks with met=true or met=false. When any acceptance_criterion evaluates to met=false for a given finding_index, move that finding_index out of applied_finding_indexes and into skipped with a reason naming the failing criterion.
176
- </rule_7_acceptance_self_check>
177
-
178
- </rules>
179
-
180
- <output_schema>
181
- Respond with JSON only. Emit zero prose outside the JSON object. The object has exactly these top-level keys:
182
-
183
- {
184
- "updated_content": "full patched file contents as a single string",
185
- "applied_finding_indexes": [0, 2],
186
- "skipped": [
187
- {"finding_index": 1, "reason": "one-line reason"}
188
- ],
189
- "acceptance_checks": [
190
- {"finding_index": 0, "criterion": "verbatim text from the spec", "met": true}
191
- ]
192
- }
193
-
194
- Ensure updated_content contains the full patched file — never a diff, never a fragment, never a summary. When applied_finding_indexes is empty, ensure updated_content equals the input byte-for-byte. Copy each acceptance_criterion string verbatim from the spec into the corresponding acceptance_checks entry.
195
- </output_schema>
196
-
197
- <failure_mode>
198
- Skip the finding and preserve the file unchanged when any of these hold:
199
-
200
- - target_line_start or target_line_end points outside the file.
201
- - target_line_start > target_line_end.
202
- - replacement_code contains a syntax error detectable on inspection.
203
- - acceptance_criteria contradict the current file state in a way no valid patch can satisfy.
204
- - intended_change and acceptance_criteria disagree with each other.
205
- - Applying the spec would require editing lines outside target_line_start..target_line_end AND intended_change does not explicitly authorize that wider scope.
206
-
207
- In every skip case, set the corresponding entry in skipped with a one-line reason naming the exact condition that failed. Return updated_content equal to the input when every finding is skipped. Never guess. Never partially apply. Never emit prose explanations outside the JSON object.
208
- </failure_mode>
209
-
210
- </groq_spec_implementer>
211
- """
212
-
213
- JSON_INDENT_SPACES = 2
214
- PIPELINE_FAILURE_EXIT_CODE = 2
215
-
216
- TEXT_CLAMP_HEAD_PARTS = 1
217
- TEXT_CLAMP_TOTAL_PARTS = 2
218
-
219
- SPEC_MODE_FLAG = "--mode"
220
- SPEC_MODE_VALUE = "spec"
221
- MISSING_API_KEY_ERROR = (
222
- "GROQ_API_KEY not set in environment; create packages/claude-dev-env/.env "
223
- "from packages/claude-dev-env/.env.example (gitignored) or export GROQ_API_KEY"
224
- )
225
-
226
- REQUIRED_GROQ_BUGTEAM_ATTRIBUTES: tuple[str, ...] = (
227
- "call_groq_with_fallback",
228
- "parse_json_object",
229
- "preserve_trailing_newline",
230
- )
@@ -1,83 +0,0 @@
1
- """Existence and coherence checks for groq_bugteam_config.
2
-
3
- These are not business-behavior tests — the config module is constants only —
4
- but the tdd_enforcer hook requires a co-located test file, and the readability
5
- rule wants every constant referenced by at least two callers. The checks below
6
- keep those invariants observable and fail loudly if someone edits the config
7
- into an inconsistent state.
8
- """
9
-
10
- from __future__ import annotations
11
-
12
- import importlib.util
13
- import pathlib
14
- import sys
15
-
16
-
17
- def _load_config_module():
18
- module_path = pathlib.Path(__file__).parent / "groq_bugteam_config.py"
19
- module_spec = importlib.util.spec_from_file_location(
20
- "groq_bugteam_config", module_path
21
- )
22
- loaded_module = importlib.util.module_from_spec(module_spec)
23
- sys.modules["groq_bugteam_config"] = loaded_module
24
- module_spec.loader.exec_module(loaded_module)
25
- return loaded_module
26
-
27
-
28
- groq_bugteam_config = _load_config_module()
29
-
30
-
31
- def test_primary_and_fallback_models_are_different():
32
- assert (
33
- groq_bugteam_config.GROQ_PRIMARY_MODEL
34
- != groq_bugteam_config.GROQ_FALLBACK_MODEL
35
- )
36
-
37
-
38
- def test_endpoint_is_https():
39
- assert groq_bugteam_config.GROQ_API_ENDPOINT.startswith("https://")
40
-
41
-
42
- def test_json_indent_spaces_is_positive_integer():
43
- assert isinstance(groq_bugteam_config.JSON_INDENT_SPACES, int)
44
- assert groq_bugteam_config.JSON_INDENT_SPACES > 0
45
-
46
-
47
- def test_pipeline_failure_exit_code_is_non_zero_and_non_one():
48
- # Reserve 0 for success and 1 for "bad stdin" — failure code must distinguish.
49
- assert groq_bugteam_config.PIPELINE_FAILURE_EXIT_CODE not in (0, 1)
50
-
51
-
52
- def test_text_clamp_head_parts_fits_within_total():
53
- assert (
54
- 0
55
- < groq_bugteam_config.TEXT_CLAMP_HEAD_PARTS
56
- < groq_bugteam_config.TEXT_CLAMP_TOTAL_PARTS
57
- )
58
-
59
-
60
- def test_request_timeout_is_generous_enough_for_cold_start():
61
- # Groq free-tier cold-start latency has been observed at 60s+; anything
62
- # under 60 risks killing healthy requests mid-response.
63
- assert groq_bugteam_config.GROQ_REQUEST_TIMEOUT_SECONDS >= 60
64
-
65
-
66
- def test_fix_budget_exceeds_audit_budget():
67
- # Fix responses return full file contents; audit responses return just
68
- # findings JSON — fix must have strictly more headroom.
69
- assert (
70
- groq_bugteam_config.GROQ_FIX_MAX_COMPLETION_TOKENS
71
- > groq_bugteam_config.GROQ_AUDIT_MAX_COMPLETION_TOKENS
72
- )
73
-
74
-
75
- def test_spec_implementer_prompt_is_distinct_from_fix_prompt():
76
- assert (
77
- groq_bugteam_config.SPEC_IMPLEMENTER_SYSTEM_PROMPT
78
- != groq_bugteam_config.FIX_SYSTEM_PROMPT
79
- )
80
-
81
-
82
- def test_spec_implementer_prompt_contains_mechanical_discipline_marker():
83
- assert "mechanical edits only" in groq_bugteam_config.SPEC_IMPLEMENTER_SYSTEM_PROMPT
@@ -1,32 +0,0 @@
1
- """Existence and coherence check for SPEC_IMPLEMENTER_SYSTEM_PROMPT."""
2
-
3
- from __future__ import annotations
4
-
5
- import importlib.util
6
- import pathlib
7
- import sys
8
-
9
-
10
- def _load_config_module():
11
- module_path = pathlib.Path(__file__).parent / "groq_bugteam_config.py"
12
- module_spec = importlib.util.spec_from_file_location(
13
- "groq_bugteam_config_spec", module_path
14
- )
15
- loaded_module = importlib.util.module_from_spec(module_spec)
16
- sys.modules["groq_bugteam_config_spec"] = loaded_module
17
- module_spec.loader.exec_module(loaded_module)
18
- return loaded_module
19
-
20
-
21
- groq_bugteam_config = _load_config_module()
22
-
23
-
24
- def test_spec_implementer_prompt_is_non_empty_string():
25
- prompt_text = groq_bugteam_config.SPEC_IMPLEMENTER_SYSTEM_PROMPT
26
- assert isinstance(prompt_text, str)
27
- assert len(prompt_text.strip()) > 0
28
-
29
-
30
- def test_spec_implementer_prompt_declares_mechanical_only_discipline():
31
- prompt_text = groq_bugteam_config.SPEC_IMPLEMENTER_SYSTEM_PROMPT
32
- assert "mechanical edits only" in prompt_text
@@ -1,131 +0,0 @@
1
- # groq_bugteam
2
-
3
- Single-pass adaptation of the [`bugteam` skill](../skills/bugteam/SKILL.md) that replaces the Claude Code agent-team orchestration with direct calls to [Groq](https://console.groq.com)'s chat completions API. No orchestrated team, no multi-loop convergence, no `TeamCreate`: one audit call, one fix call, one commit-and-push per PR.
4
-
5
- Lives at `packages/claude-dev-env/scripts/groq_bugteam.py`. Stateless, PII-free, env-driven.
6
-
7
- ## When to reach for this
8
-
9
- `/bugteam` requires `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` plus an Anthropic-side environment that will sign commits on PR head branches. When either is missing — for example, a CI runner, a personal dev box, or any non-Claude-Code shell — this script gives you the audit/fix loop without the orchestration.
10
-
11
- When you already have `/bugteam` available, prefer it: the clean-room agent isolation + 10-loop convergence produces much lower false-positive rates than a single Groq pass.
12
-
13
- ## Pipeline
14
-
15
- 1. Read PR metadata + unified diff + file contents from stdin (JSON).
16
- 2. POST one audit request to Groq with the diff and files. Parse findings as JSON.
17
- 3. Group findings by file; for each file, POST one fix request. Parse `updated_content`.
18
- 4. Write files that had at least one applied finding, `git add`, `git commit`, `git push HEAD:<head_ref>`.
19
- 5. Emit JSON on stdout: findings, fix outcomes, commit SHA, review body, audit/fix model.
20
-
21
- The caller posts the review to GitHub. This script does not touch the GitHub API.
22
-
23
- ## Stdin schema
24
-
25
- ```json
26
- {
27
- "pr_number": 123,
28
- "owner": "someone",
29
- "repo": "some-repo",
30
- "base_ref": "main",
31
- "head_ref": "feat/some-branch",
32
- "diff": "<full `git diff origin/<base>...HEAD` output>",
33
- "files_content": {"path/to/file.py": "<current file contents>"},
34
- "worktree_path": "/abs/path/to/git/worktree/on/head_ref",
35
- "apply_fixes": true
36
- }
37
- ```
38
-
39
- ## Stdout schema
40
-
41
- ```json
42
- {
43
- "findings": [
44
- {"severity": "P0|P1|P2", "category": "A..J", "file": "...", "line": 42,
45
- "title": "...", "description": "..."}
46
- ],
47
- "fix_outcomes": [
48
- {"finding_index": 0, "status": "fixed|skipped|not_addressed|fix_call_failed",
49
- "reason": "only when skipped/fix_call_failed"}
50
- ],
51
- "commit_sha": "abc123...",
52
- "review_body": "## groq-bugteam audit: 1 P0 / 2 P1 / 0 P2\n...",
53
- "audit_model": "llama-3.3-70b-versatile",
54
- "fix_model": "llama-3.3-70b-versatile"
55
- }
56
- ```
57
-
58
- ## Required environment
59
-
60
- - `GROQ_API_KEY` — from https://console.groq.com/keys. Free tier is enough for a single PR.
61
- - **Local file (preferred):** copy `packages/claude-dev-env/.env.example` to `packages/claude-dev-env/.env`, set `GROQ_API_KEY=...` inside the copy. That path is gitignored; `groq_bugteam.py` loads it on startup when the file exists (without overriding variables already exported in your shell).
62
- - `git` on PATH, configured to push to the target remote.
63
- - Python 3.10+. No external deps (stdlib `urllib.request` only).
64
-
65
- ## Minimal invocation
66
-
67
- ```bash
68
- # Assumes you already have a git worktree checked out to the PR head branch.
69
- # Either use packages/claude-dev-env/.env (see Required environment) or:
70
- export GROQ_API_KEY=gsk_...
71
-
72
- python3 - <<'EOF' | python3 packages/claude-dev-env/scripts/groq_bugteam.py
73
- import json, subprocess, pathlib
74
- worktree = pathlib.Path("/tmp/pr-123-worktree")
75
- diff = subprocess.check_output(["git","-C",str(worktree),"diff","origin/main...HEAD"], text=True)
76
- changed = subprocess.check_output(["git","-C",str(worktree),"diff","--name-only","origin/main...HEAD"], text=True).strip().split("\n")
77
- files = {p: (worktree/p).read_text() for p in changed if (worktree/p).is_file()}
78
- print(json.dumps({
79
- "pr_number": 123, "owner": "someone", "repo": "some-repo",
80
- "base_ref": "main", "head_ref": "feat/some-branch",
81
- "diff": diff, "files_content": files,
82
- "worktree_path": str(worktree), "apply_fixes": True,
83
- }))
84
- EOF
85
- ```
86
-
87
- ## Caller responsibilities
88
-
89
- Because this script is intentionally narrow, the caller handles:
90
-
91
- - **Worktree setup.** `git worktree add -f -B <head_ref> <path> origin/<head_ref>`.
92
- - **File filtering.** Skip autogenerated files (CHANGELOG.md, lockfiles) and files >40KB to stay under Groq's free-tier per-request TPM limit. Chunk the call file-by-file when the whole-PR call hits 413.
93
- - **Commit signing.** If your environment enforces signing, set `git config commit.gpgsign false` in the worktree or provide a signing key the hook accepts.
94
- - **Finding triage.** Groq's single-pass audit produces false positives — test files flagged for code-rules that exempt them, JSON configs flagged for "path traversal," version bumps flagged as "magic values." The caller should filter before posting reviews. See the filter heuristics that shipped with this repo's first live run (`claude/groq-bugteam-prs-S9rwU`): drop test files, drop JSON/YAML/doc files for non-security categories, dedupe `(file, line, category)`, drop chunked-mode P2s, cap at top 10-15 per PR.
95
- - **Posting PR reviews.** The script emits `review_body` but does not POST. Use `gh api` or the GitHub MCP review-write endpoint.
96
-
97
- ## Known limitations vs `/bugteam`
98
-
99
- | `/bugteam` | `groq_bugteam.py` |
100
- |---|---|
101
- | Fresh-context audit subagent each loop | Single Groq call, no re-audit |
102
- | Separate fix subagent (clean-room) | Same Groq call stream (state bleeds) |
103
- | 10-loop convergence with cap | One audit, one fix, done |
104
- | `code-quality-agent` + `clean-coder` models | `llama-3.3-70b-versatile` (+ 8b fallback on 413) |
105
- | Full CODE_RULES gate before every audit | No gate — caller's responsibility |
106
- | Posts per-finding inline review comments anchored to diff lines | Single review body with findings listed as markdown |
107
- | Rewrites PR body cumulatively | Does not touch PR body |
108
-
109
- Expect 2-5x more noise per finding than `/bugteam`. The caller's filter step is not optional.
110
-
111
- ## Free-tier rate limits
112
-
113
- As of the live run on 2026-04-22 the Groq free tier enforces:
114
-
115
- - `llama-3.3-70b-versatile`: 12,000 tokens/minute, 1,000 requests/day.
116
- - `llama-3.1-8b-instant`: 6,000 tokens/minute, 14,400 requests/day.
117
-
118
- The script falls back to the 8b model on HTTP 413 (Groq returns 413 with `type: tokens` when the request TPM would exceed the cap). Most PRs >40KB of diff-plus-context will hit the cap. The caller can work around this by chunking: invoke the script once per changed file with `apply_fixes: false` and combine findings, or upgrade to a paid tier.
119
-
120
- ## Tests
121
-
122
- ```bash
123
- cd packages/claude-dev-env/scripts
124
- python3 -m pytest test_groq_bugteam.py -v
125
- ```
126
-
127
- The test suite covers the pure-logic helpers (`clamp_text`, `parse_json_object`, `normalize_findings`, `group_findings_by_file`, `build_review_body`, `should_write_fixed_file`, `preserve_trailing_newline`, `is_safe_relative_path`, `decode_subprocess_stderr`, `build_fix_user_message`, HTTP error classification, pipeline refusals) and the co-located config invariants. Network calls to Groq and filesystem/git side effects are not unit-tested; exercise them with a live run.
128
-
129
- ## Why this exists
130
-
131
- The jl-cmd/claude-code-config `/bugteam` skill is excellent when Claude Code is the runtime. When it isn't — CI, cron, a dev box — you still want the audit/fix pattern. This script is the minimum-viable port.