claude-dev-env 1.38.1 → 1.40.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 (282) 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 +199 -0
  7. package/_shared/pr-loop/scripts/config/reviews_disabled_constants.py +8 -0
  8. package/_shared/pr-loop/scripts/post_audit_thread.py +1242 -0
  9. package/_shared/pr-loop/scripts/preflight.py +129 -2
  10. package/_shared/pr-loop/scripts/reviews_disabled.py +59 -0
  11. package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +0 -19
  12. package/_shared/pr-loop/scripts/tests/test_post_audit_thread.py +1116 -0
  13. package/_shared/pr-loop/scripts/tests/test_post_audit_thread_constants.py +127 -0
  14. package/_shared/pr-loop/scripts/tests/test_preflight.py +41 -0
  15. package/_shared/pr-loop/scripts/tests/test_reviews_disabled.py +36 -0
  16. package/_shared/pr-loop/state-schema.md +1 -1
  17. package/agents/clean-coder.md +2 -2
  18. package/agents/pr-description-writer.md +150 -52
  19. package/bin/install.mjs +6 -7
  20. package/bin/install.test.mjs +8 -0
  21. package/commands/doc-gist.md +16 -0
  22. package/commands/plan.md +0 -2
  23. package/commands/review-plan.md +1 -1
  24. package/docs/CODE_RULES.md +122 -2
  25. package/docs/PR_DESCRIPTION_GUIDE.md +127 -64
  26. package/hooks/blocking/bot_mention_comment_blocker.py +75 -0
  27. package/hooks/blocking/code_rules_enforcer.py +1143 -129
  28. package/hooks/blocking/convergence_gate_blocker.py +130 -0
  29. package/hooks/blocking/destructive_command_blocker.py +74 -0
  30. package/hooks/blocking/gh_body_arg_blocker.py +30 -0
  31. package/hooks/blocking/md_to_html_blocker.py +119 -0
  32. package/hooks/blocking/pr_description_enforcer.py +57 -22
  33. package/hooks/blocking/test_bot_mention_comment_blocker.py +131 -0
  34. package/hooks/blocking/test_code_rules_enforcer.py +21 -0
  35. package/hooks/blocking/test_code_rules_enforcer_any_exempt_files.py +70 -0
  36. package/hooks/blocking/test_code_rules_enforcer_any_imports_and_cast.py +92 -0
  37. package/hooks/blocking/test_code_rules_enforcer_banned_import_alias.py +143 -0
  38. package/hooks/blocking/test_code_rules_enforcer_banned_prefixes.py +152 -0
  39. package/hooks/blocking/test_code_rules_enforcer_bare_except.py +120 -0
  40. package/hooks/blocking/test_code_rules_enforcer_boundary_types.py +175 -0
  41. package/hooks/blocking/test_code_rules_enforcer_cap_meta.py +0 -1
  42. package/hooks/blocking/test_code_rules_enforcer_collection_prefix.py +50 -0
  43. package/hooks/blocking/test_code_rules_enforcer_docstring_format.py +255 -0
  44. package/hooks/blocking/test_code_rules_enforcer_inline_tuple_string_magic.py +130 -0
  45. package/hooks/blocking/test_code_rules_enforcer_stub_implementations.py +141 -0
  46. package/hooks/blocking/test_code_rules_enforcer_test_branching.py +143 -0
  47. package/hooks/blocking/test_code_rules_enforcer_thin_wrapper_files.py +169 -0
  48. package/hooks/blocking/test_code_rules_enforcer_todo_markers.py +99 -0
  49. package/hooks/blocking/test_code_rules_enforcer_typed_dict_pairs.py +141 -0
  50. package/hooks/blocking/test_convergence_gate_blocker.py +63 -0
  51. package/hooks/blocking/test_destructive_command_blocker.py +146 -0
  52. package/hooks/blocking/test_destructive_command_blocker_no_verify.py +102 -0
  53. package/hooks/blocking/test_gh_body_arg_blocker.py +45 -0
  54. package/hooks/blocking/test_md_to_html_blocker.py +317 -0
  55. package/hooks/blocking/test_pr_description_enforcer.py +69 -8
  56. package/hooks/config/any_type_config.py +7 -0
  57. package/hooks/config/banned_identifiers_constants.py +11 -0
  58. package/hooks/config/blocking_check_limits.py +38 -0
  59. package/hooks/config/bot_mention_comment_blocker_constants.py +20 -0
  60. package/hooks/config/code_rules_enforcer_constants.py +53 -0
  61. package/hooks/config/convergence_branch_constants.py +9 -0
  62. package/hooks/config/doc_gist_auto_publish_constants.py +18 -0
  63. package/hooks/config/html_companion_constants.py +20 -0
  64. package/hooks/config/inline_tuple_string_magic_constants.py +22 -0
  65. package/hooks/config/pr_description_enforcer_constants.py +14 -0
  66. package/hooks/config/test_banned_identifiers_constants.py +17 -0
  67. package/hooks/hooks.json +28 -20
  68. package/hooks/pyproject.toml +69 -0
  69. package/hooks/validators/mypy_integration.py +47 -1
  70. package/hooks/validators/run_all_validators.py +3 -3
  71. package/hooks/validators/test_mypy_integration.py +50 -1
  72. package/hooks/workflow/doc_gist_auto_publish.py +144 -0
  73. package/hooks/workflow/md_to_html_companion.py +365 -0
  74. package/hooks/workflow/test_doc_gist_auto_publish.py +117 -0
  75. package/hooks/workflow/test_md_to_html_companion.py +452 -0
  76. package/package.json +1 -1
  77. package/rules/gh-body-file.md +2 -0
  78. package/scripts/Install-SweepEmptyDirs.ps1 +111 -0
  79. package/scripts/check.ps1 +106 -0
  80. package/scripts/config/timing.py +11 -0
  81. package/scripts/sweep_empty_dirs.py +138 -0
  82. package/scripts/sync_to_cursor/rules.py +1 -1
  83. package/scripts/test_sweep_empty_dirs.py +183 -0
  84. package/skills/_shared/pr-loop/prompts/pr-consistency-audit.xml +323 -0
  85. package/skills/_shared/pr-loop/scripts/_cli_utils.py +22 -0
  86. package/skills/_shared/pr-loop/scripts/_path_resolver.py +165 -0
  87. package/skills/_shared/pr-loop/scripts/_xml_utils.py +20 -0
  88. package/skills/_shared/pr-loop/scripts/build_audit_prompt.py +182 -0
  89. package/skills/_shared/pr-loop/scripts/build_fix_prompt.py +185 -0
  90. package/skills/_shared/pr-loop/scripts/config/__init__.py +0 -0
  91. package/skills/_shared/pr-loop/scripts/config/path_resolver_constants.py +78 -0
  92. package/skills/_shared/pr-loop/scripts/init_loop_state.py +135 -0
  93. package/skills/_shared/pr-loop/scripts/teardown_worktrees.py +175 -0
  94. package/skills/_shared/pr-loop/scripts/write_audit_outcomes.py +182 -0
  95. package/skills/_shared/pr-loop/scripts/write_fix_outcomes.py +206 -0
  96. package/skills/bugteam/CONSTRAINTS.md +21 -22
  97. package/skills/bugteam/EXAMPLES.md +3 -3
  98. package/skills/bugteam/PROMPTS.md +227 -67
  99. package/skills/bugteam/SKILL.md +132 -455
  100. package/skills/bugteam/reference/README.md +1 -1
  101. package/skills/bugteam/reference/audit-and-teammates.md +112 -39
  102. package/skills/bugteam/reference/audit-contract.md +4 -22
  103. package/skills/bugteam/reference/copilot-gap-analysis.md +8 -5
  104. package/skills/bugteam/reference/design-rationale.md +2 -2
  105. package/skills/bugteam/reference/github-pr-reviews.md +50 -57
  106. package/skills/bugteam/reference/obstacles/audit-assign-ids.md +13 -0
  107. package/skills/bugteam/reference/obstacles/audit-capture-excerpts.md +13 -0
  108. package/skills/bugteam/reference/obstacles/audit-walk-categories.md +13 -0
  109. package/skills/bugteam/reference/obstacles/audit-write-xml.md +13 -0
  110. package/skills/bugteam/reference/obstacles/fix-append-summary.md +13 -0
  111. package/skills/bugteam/reference/obstacles/fix-apply-fixes.md +13 -0
  112. package/skills/bugteam/reference/obstacles/fix-git-add-commit.md +13 -0
  113. package/skills/bugteam/reference/obstacles/fix-git-push.md +13 -0
  114. package/skills/bugteam/reference/obstacles/fix-post-reply.md +13 -0
  115. package/skills/bugteam/reference/obstacles/fix-publish-summary.md +13 -0
  116. package/skills/bugteam/reference/obstacles/fix-py-compile.md +13 -0
  117. package/skills/bugteam/reference/obstacles/fix-read-files.md +13 -0
  118. package/skills/bugteam/reference/obstacles/fix-resolve-thread.md +13 -0
  119. package/skills/bugteam/reference/obstacles/fix-test-suite.md +13 -0
  120. package/skills/bugteam/reference/obstacles/fix-violation-count.md +13 -0
  121. package/skills/bugteam/reference/obstacles/fix-write-xml.md +13 -0
  122. package/skills/bugteam/reference/team-setup.md +111 -9
  123. package/skills/bugteam/reference/teardown-publish-permissions.md +39 -8
  124. package/skills/bugteam/scripts/README.md +60 -0
  125. package/skills/bugteam/scripts/_claude_permissions_common.py +358 -0
  126. package/skills/bugteam/scripts/bugteam_code_rules_gate.py +976 -0
  127. package/skills/bugteam/scripts/bugteam_fix_hookspath.py +375 -0
  128. package/skills/bugteam/scripts/bugteam_preflight.py +328 -0
  129. package/skills/bugteam/scripts/config/bugteam_code_rules_gate_constants.py +25 -0
  130. package/skills/bugteam/scripts/config/bugteam_fix_hookspath_constants.py +26 -0
  131. package/skills/bugteam/scripts/config/bugteam_preflight_constants.py +35 -0
  132. package/skills/bugteam/scripts/config/claude_permissions_common_constants.py +20 -0
  133. package/skills/bugteam/scripts/config/probe_code_rules_enforcer_check_constants.py +12 -0
  134. package/skills/bugteam/scripts/config/windows_safe_rmtree_constants.py +7 -0
  135. package/skills/bugteam/scripts/grant_project_claude_permissions.py +175 -0
  136. package/skills/bugteam/scripts/probe_code_rules_enforcer_check.py +107 -0
  137. package/skills/bugteam/scripts/revoke_project_claude_permissions.py +220 -0
  138. package/skills/bugteam/scripts/test__claude_permissions_common.py +112 -0
  139. package/skills/bugteam/scripts/test_bugteam_code_rules_gate.py +400 -0
  140. package/skills/bugteam/scripts/test_bugteam_fix_hookspath.py +384 -0
  141. package/skills/bugteam/scripts/test_bugteam_preflight.py +309 -0
  142. package/skills/bugteam/scripts/test_claude_permissions_common.py +195 -0
  143. package/skills/bugteam/scripts/test_grant_project_claude_permissions.py +55 -0
  144. package/skills/bugteam/scripts/test_probe_code_rules_enforcer_check.py +76 -0
  145. package/skills/bugteam/scripts/test_revoke_project_claude_permissions.py +55 -0
  146. package/skills/bugteam/scripts/test_windows_safe_rmtree.py +108 -0
  147. package/skills/bugteam/scripts/windows_safe_rmtree.py +100 -0
  148. package/skills/bugteam/test_skill_additions.py +1 -11
  149. package/skills/code/SKILL.md +176 -0
  150. package/skills/copilot-review/SKILL.md +16 -0
  151. package/skills/doc-gist/SKILL.md +99 -0
  152. package/skills/doc-gist/references/examples/01-exploration-code-approaches.html +453 -0
  153. package/skills/doc-gist/references/examples/02-exploration-visual-designs.html +515 -0
  154. package/skills/doc-gist/references/examples/03-code-review-pr.html +638 -0
  155. package/skills/doc-gist/references/examples/04-code-understanding.html +491 -0
  156. package/skills/doc-gist/references/examples/05-design-system.html +629 -0
  157. package/skills/doc-gist/references/examples/06-component-variants.html +605 -0
  158. package/skills/doc-gist/references/examples/07-prototype-animation.html +455 -0
  159. package/skills/doc-gist/references/examples/08-prototype-interaction.html +396 -0
  160. package/skills/doc-gist/references/examples/09-slide-deck.html +592 -0
  161. package/skills/doc-gist/references/examples/10-svg-illustrations.html +492 -0
  162. package/skills/doc-gist/references/examples/11-status-report.html +528 -0
  163. package/skills/doc-gist/references/examples/12-incident-report.html +596 -0
  164. package/skills/doc-gist/references/examples/13-flowchart-diagram.html +395 -0
  165. package/skills/doc-gist/references/examples/14-research-feature-explainer.html +381 -0
  166. package/skills/doc-gist/references/examples/15-research-concept-explainer.html +368 -0
  167. package/skills/doc-gist/references/examples/16-implementation-plan.html +702 -0
  168. package/skills/doc-gist/references/examples/17-pr-writeup.html +595 -0
  169. package/skills/doc-gist/references/examples/18-editor-triage-board.html +573 -0
  170. package/skills/doc-gist/references/examples/19-editor-feature-flags.html +663 -0
  171. package/skills/doc-gist/references/examples/20-editor-prompt-tuner.html +722 -0
  172. package/skills/doc-gist/references/examples/README.md +5 -0
  173. package/skills/doc-gist/scripts/config/__init__.py +0 -0
  174. package/skills/doc-gist/scripts/config/gist_upload_constants.py +16 -0
  175. package/skills/doc-gist/scripts/gist_upload.py +177 -0
  176. package/skills/doc-gist/scripts/test_gist_upload.py +51 -0
  177. package/skills/findbugs/SKILL.md +96 -2
  178. package/skills/monitor-open-prs/SKILL.md +14 -32
  179. package/skills/monitor-open-prs/test_skill_contract.py +0 -11
  180. package/skills/pr-consistency-audit/SKILL.md +112 -0
  181. package/skills/pr-consistency-audit/reference/detection-rules.md +96 -0
  182. package/skills/pr-consistency-audit/reference/illustrations.md +78 -0
  183. package/skills/pr-converge/SKILL.md +229 -23
  184. package/skills/pr-converge/config/__init__.py +0 -0
  185. package/skills/pr-converge/config/constants.py +63 -0
  186. package/skills/pr-converge/reference/convergence-gates.md +138 -44
  187. package/skills/pr-converge/reference/examples.md +43 -11
  188. package/skills/pr-converge/reference/fix-protocol.md +6 -5
  189. package/skills/pr-converge/reference/ground-rules.md +5 -3
  190. package/skills/pr-converge/reference/multi-pr-orchestration.md +44 -19
  191. package/skills/pr-converge/reference/obstacles/fix-post-replies.md +13 -0
  192. package/skills/pr-converge/reference/obstacles/fix-publish-summary.md +13 -0
  193. package/skills/pr-converge/reference/obstacles/fix-push.md +13 -0
  194. package/skills/pr-converge/reference/obstacles/fix-read-filelines.md +13 -0
  195. package/skills/pr-converge/reference/obstacles/fix-reset-state.md +13 -0
  196. package/skills/pr-converge/reference/obstacles/fix-resolve-threads.md +13 -0
  197. package/skills/pr-converge/reference/obstacles/fix-spawn-clean-coder.md +13 -0
  198. package/skills/pr-converge/reference/obstacles/fix-stage-commit.md +13 -0
  199. package/skills/pr-converge/reference/obstacles/fix-trigger-bugbot.md +13 -0
  200. package/skills/pr-converge/reference/obstacles/fix-write-test.md +13 -0
  201. package/skills/pr-converge/reference/per-tick.md +107 -31
  202. package/skills/pr-converge/reference/state-schema.md +22 -1
  203. package/skills/pr-converge/reference/stop-conditions.md +9 -7
  204. package/skills/pr-converge/scripts/README.md +34 -46
  205. package/skills/pr-converge/scripts/check_bugbot_ci.py +279 -0
  206. package/skills/pr-converge/scripts/check_convergence.py +497 -0
  207. package/skills/pr-converge/scripts/check_pending_reviews.py +154 -0
  208. package/skills/pr-converge/scripts/config/pr_converge_constants.py +118 -0
  209. package/skills/pr-converge/scripts/fetch_copilot_reviews.py +134 -0
  210. package/skills/pr-converge/scripts/post_fix_reply.py +168 -0
  211. package/skills/pr-converge/scripts/test_check_bugbot_ci.py +312 -0
  212. package/skills/pr-converge/workflows/schedule-wakeup-loop.md +5 -12
  213. package/skills/qbug/SKILL.md +157 -27
  214. package/skills/session-log/SKILL.md +216 -114
  215. package/skills/session-tidy/SKILL.md +1 -1
  216. package/skills/skill-builder/SKILL.md +138 -56
  217. package/skills/skill-builder/references/delegation-map.md +72 -113
  218. package/skills/skill-builder/references/progressive-disclosure.md +122 -0
  219. package/skills/skill-builder/references/self-audit-checklist.md +92 -0
  220. package/skills/skill-builder/references/skill-types.md +228 -0
  221. package/skills/skill-builder/references/thariq-x-post-skills.json +33 -0
  222. package/skills/skill-builder/templates/gap-analysis.md +15 -8
  223. package/skills/skill-builder/workflows/improve-skill.md +86 -57
  224. package/skills/skill-builder/workflows/new-skill.md +80 -168
  225. package/skills/skill-builder/workflows/polish-skill.md +78 -54
  226. package/skills/structure-prompt/SKILL.md +50 -0
  227. package/skills/structure-prompt/reference/adversarial-tuning.md +62 -0
  228. package/skills/structure-prompt/reference/block-classification.md +27 -0
  229. package/skills/structure-prompt/reference/canonical-case.md +48 -0
  230. package/skills/structure-prompt/reference/citation-depth.md +70 -0
  231. package/skills/structure-prompt/reference/cleanup.md +33 -0
  232. package/skills/structure-prompt/reference/constraints.md +33 -0
  233. package/skills/structure-prompt/reference/directives.md +37 -0
  234. package/skills/structure-prompt/reference/examples.md +72 -0
  235. package/skills/structure-prompt/reference/instantiation.md +51 -0
  236. package/skills/structure-prompt/reference/output-contract.md +72 -0
  237. package/skills/structure-prompt/reference/per-category.md +23 -0
  238. package/skills/structure-prompt/reference/persona.md +38 -0
  239. package/skills/structure-prompt/reference/research.md +33 -0
  240. package/skills/structure-prompt/reference/structure.md +28 -0
  241. package/agents/code-standards-agent.md +0 -93
  242. package/agents/groq-coder.md +0 -113
  243. package/agents/plan-executor.md +0 -226
  244. package/agents/project-docs-analyzer.md +0 -53
  245. package/agents/project-structure-organizer-agent.md +0 -72
  246. package/agents/skill-to-agent-converter.md +0 -370
  247. package/agents/skill-writer-agent.md +0 -470
  248. package/agents/user-docs-writer.md +0 -67
  249. package/agents/workflow-visual-documenter.md +0 -82
  250. package/commands/readability-review.md +0 -20
  251. package/hooks/mypy.ini +0 -2
  252. package/hooks/notification/attention_needed_notify.py +0 -71
  253. package/hooks/notification/claude_notification_handler.py +0 -67
  254. package/hooks/notification/notification_utils.py +0 -267
  255. package/hooks/notification/subagent_complete_notify.py +0 -381
  256. package/hooks/notification/test_attention_needed_notify.py +0 -47
  257. package/hooks/notification/test_claude_notification_handler.py +0 -54
  258. package/hooks/notification/test_notification_utils.py +0 -91
  259. package/hooks/notification/test_subagent_complete_notify.py +0 -79
  260. package/scripts/config/groq_bugteam_config.py +0 -230
  261. package/scripts/config/test_groq_bugteam_config.py +0 -83
  262. package/scripts/config/test_spec_implementer_prompt.py +0 -32
  263. package/scripts/groq_bugteam.README.md +0 -131
  264. package/scripts/groq_bugteam.py +0 -647
  265. package/scripts/groq_bugteam_dotenv.py +0 -40
  266. package/scripts/groq_bugteam_spec.py +0 -226
  267. package/scripts/test_groq_bugteam.py +0 -529
  268. package/scripts/test_groq_bugteam_apply_fix_from_spec.py +0 -426
  269. package/scripts/test_groq_bugteam_dotenv.py +0 -66
  270. package/scripts/test_groq_bugteam_spec.py +0 -338
  271. package/skills/bugteam/SKILL_EVALS.md +0 -309
  272. package/skills/dream/SKILL.md +0 -118
  273. package/skills/ingest/SKILL.md +0 -40
  274. package/skills/npm-creator/SKILL.md +0 -187
  275. package/skills/readability-review/SKILL.md +0 -127
  276. package/skills/resume-review/SKILL.md +0 -261
  277. package/skills/rule-audit/SKILL.md +0 -307
  278. package/skills/rule-creator/SKILL.md +0 -150
  279. package/skills/searching-obsidian-vault/SKILL.md +0 -131
  280. package/skills/skill-writer/REFERENCE.md +0 -284
  281. package/skills/skill-writer/SKILL.md +0 -222
  282. package/skills/tdd-team/SKILL.md +0 -128
@@ -0,0 +1,118 @@
1
+ """Configuration constants for the pr-converge skill scripts.
2
+
3
+ Path templates accept ``str.format(**kwargs)`` substitution; bugbot strings
4
+ match the literal phrasing the Cursor Bugbot reviewer emits.
5
+
6
+ All runtime and API constants are imported from ``config.constants``.
7
+ Only script-specific constants (CLI args, markdown patterns, reflow
8
+ settings) live here.
9
+ """
10
+
11
+ import re
12
+ from pathlib import Path
13
+
14
+ from config.constants import ( # noqa: F401
15
+ ALL_BUGBOT_CHECK_RUN_ACTIVE_STATUSES,
16
+ ALL_CLAUDE_DIRTY_REVIEW_STATES,
17
+ ALL_COPILOT_DIRTY_REVIEW_STATES,
18
+ ALL_BUGBOT_CHECK_RUN_COMPLETE_CONCLUSIONS,
19
+ BUGBOT_CHECK_RUN_NAME_SUBSTRING,
20
+ BUGBOT_DIRTY_BODY_REGEX,
21
+ BUGBOT_RUN_TRIGGER_PHRASE,
22
+ BUGBOT_RUN_TRIGGER_WAIT_SECONDS,
23
+ CHECK_RUNS_PER_PAGE,
24
+ ALL_CLAUDE_CLEAN_REVIEW_STATES,
25
+ CLAUDE_LOGIN_FILTER_SUBSTRING,
26
+ CLAUDE_REVIEWER_LOGIN,
27
+ CLAUDE_REVIEWER_REQUEST_ID,
28
+ CLAUDE_SOFT_DIRTY_REVIEW_STATE,
29
+ ALL_COPILOT_CLEAN_REVIEW_STATES,
30
+ COPILOT_LOGIN_FILTER_SUBSTRING,
31
+ COPILOT_REVIEWER_LOGIN,
32
+ COPILOT_REVIEWER_REQUEST_ID,
33
+ COPILOT_SOFT_DIRTY_REVIEW_STATE,
34
+ CURSOR_BOT_LOGIN,
35
+ CURSOR_LOGIN_FILTER_SUBSTRING,
36
+ EXIT_CODE_GH_ERROR,
37
+ EXIT_CODE_NOT_FOUND,
38
+ GH_CHECK_RUNS_PATH_TEMPLATE,
39
+ GH_INLINE_COMMENT_CREATE_PATH_TEMPLATE,
40
+ GH_INLINE_COMMENTS_PATH_TEMPLATE,
41
+ GH_ISSUE_COMMENT_CREATE_PATH_TEMPLATE,
42
+ GH_PR_OBJECT_PATH_TEMPLATE,
43
+ GH_REQUESTED_REVIEWERS_FIELD_TEMPLATE,
44
+ GH_REVIEW_COMMENTS_PATH_TEMPLATE,
45
+ GH_REVIEWS_PATH_TEMPLATE,
46
+ )
47
+
48
+ BUGBOT_RUN_TEMPFILE_SUFFIX: str = ".md"
49
+
50
+ BUGBOT_RUN_TEMPFILE_PREFIX: str = "pr-converge-bugbot-run-"
51
+
52
+ PR_CONTEXT_FIELDS: str = "number,url,headRefOid,baseRefName,headRefName,isDraft"
53
+
54
+ PR_DETACHED_HEAD_ARGS_ERROR: str = "--owner and --repo require --number; all three must be provided together for detached-HEAD PR resolution"
55
+
56
+ PR_NUMBER_ARG_FLAG: str = "--number"
57
+
58
+ PR_NUMBER_ARG_HELP: str = "PR number"
59
+
60
+ PR_OWNER_ARG_FLAG: str = "--owner"
61
+
62
+ PR_OWNER_ARG_HELP: str = "GitHub repository owner"
63
+
64
+ PR_REPO_ARG_FLAG: str = "--repo"
65
+
66
+ PR_REPO_ARG_HELP: str = "GitHub repository name"
67
+
68
+ GH_REPO_FLAG: str = "--repo"
69
+
70
+ MERGEABILITY_FIELDS: str = "mergeable,mergeStateStatus,headRefOid"
71
+
72
+ GH_FIELD_BODY_AT_PREFIX: str = "body=@"
73
+
74
+ GH_REPO_ARG_TEMPLATE: str = "{owner}/{repo}"
75
+
76
+ SKILL_REFLOW_MAXIMUM_WIDTH: int = 80
77
+
78
+ PR_CONVERGE_SKILL_PATH: Path = Path(__file__).resolve().parent.parent.parent / "SKILL.md"
79
+
80
+ MARKDOWN_CODE_FENCE_MARKER: str = "```"
81
+
82
+ YAML_FRONT_MATTER_DELIMITER: str = "---"
83
+
84
+ YAML_DESCRIPTION_PREFIX: str = "description: >-"
85
+
86
+ EXAMPLE_OPEN_TAG: str = "<example>"
87
+
88
+ EXAMPLE_CLOSE_TAG: str = "</example>"
89
+
90
+ BASH_FENCE_LANGUAGE: str = "bash"
91
+
92
+ BASH_LINE_CONTINUATION_SUFFIX: str = " \\"
93
+
94
+ BASH_CONTINUATION_INDENT: str = " "
95
+
96
+ REFLOW_FRONT_MATTER_ERROR: str = "expected YAML front matter starting with ---"
97
+
98
+ ORDERED_MARKDOWN_LIST_PATTERN: re.Pattern[str] = re.compile(
99
+ r"^(?P<leading_whitespace>\s*)(?P<marker>\d+\.\s)(?P<body>.*)$"
100
+ )
101
+
102
+ BULLET_MARKDOWN_LIST_PATTERN: re.Pattern[str] = re.compile(
103
+ r"^(?P<leading_whitespace>\s*)(?P<marker>[-*]\s)(?P<body>.*)$"
104
+ )
105
+
106
+ UNFINISHED_MARKDOWN_LINK_TARGET_PATTERN: re.Pattern[str] = re.compile(r"\]\([^)]*$")
107
+
108
+ MARKDOWN_HEADING_PATTERN: re.Pattern[str] = re.compile(r"^#{1,6}\s+.+$")
109
+
110
+ MARKDOWN_REFERENCE_DEFINITION_PATTERN: re.Pattern[str] = re.compile(r"^\[[^\]]+\]:\s+\S+")
111
+
112
+ BASH_LINE_CONTINUATION_MARKER_WIDTH: int = 2
113
+
114
+ CODE_FENCE_MARKER_LENGTH: int = 3
115
+
116
+ BASH_MINIMUM_SEGMENT_WIDTH: int = 1
117
+
118
+ LONG_ROW_PREVIEW_LIMIT: int = 20
@@ -0,0 +1,134 @@
1
+ """Fetch GitHub Copilot reviews for a pull request, newest first.
2
+
3
+ Usage:
4
+ python scripts/fetch_copilot_reviews.py --owner <O> --repo <R> --pr-number <N>
5
+
6
+ Output: JSON array of Copilot reviews to stdout, each with id, state, body,
7
+ commit_id, submitted_at, and html_url.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import argparse
13
+ import json
14
+ import subprocess
15
+ import sys
16
+ from pathlib import Path
17
+
18
+ _pr_converge_dir = Path(__file__).resolve().parent.parent
19
+ if str(_pr_converge_dir) not in sys.path:
20
+ sys.path.insert(0, str(_pr_converge_dir))
21
+
22
+ from config.constants import (
23
+ COPILOT_LOGIN_FILTER_SUBSTRING,
24
+ GH_REVIEWS_PATH_TEMPLATE,
25
+ REVIEWS_PER_PAGE,
26
+ )
27
+
28
+
29
+ def fetch_copilot_reviews(
30
+ *, owner: str, repo: str, number: int
31
+ ) -> list[dict[str, object]]:
32
+ """Return Copilot reviews for a PR, newest first.
33
+
34
+ Args:
35
+ owner: GitHub repository owner.
36
+ repo: GitHub repository name.
37
+ number: Pull request number.
38
+
39
+ Returns:
40
+ List of Copilot review entries sorted by submitted_at descending.
41
+
42
+ Raises:
43
+ SystemExit: When the gh CLI call fails.
44
+ """
45
+ endpoint_path = GH_REVIEWS_PATH_TEMPLATE.format(
46
+ owner=owner, repo=repo, number=number
47
+ )
48
+ completed_process = subprocess.run(
49
+ [
50
+ "gh", "api",
51
+ f"{endpoint_path}?per_page={REVIEWS_PER_PAGE}",
52
+ "--paginate", "--slurp",
53
+ ],
54
+ capture_output=True,
55
+ text=True,
56
+ encoding="utf-8",
57
+ errors="replace",
58
+ check=False,
59
+ )
60
+ if completed_process.returncode != 0:
61
+ print(f"gh api error: {completed_process.stderr}", file=sys.stderr)
62
+ raise SystemExit(1)
63
+ raw_output: object = json.loads(completed_process.stdout)
64
+ if not isinstance(raw_output, list):
65
+ return []
66
+ all_pages: list[list[dict[str, object]]] = [
67
+ each_page for each_page in raw_output if isinstance(each_page, list)
68
+ ]
69
+ all_flat: list[dict[str, object]] = [
70
+ each_item for each_page in all_pages for each_item in each_page
71
+ ]
72
+ copilot_reviews: list[dict[str, object]] = []
73
+ for each_review in all_flat:
74
+ user_object: object = each_review.get("user")
75
+ if not isinstance(user_object, dict):
76
+ continue
77
+ raw_login: object = user_object.get("login")
78
+ if not isinstance(raw_login, str):
79
+ continue
80
+ if COPILOT_LOGIN_FILTER_SUBSTRING not in raw_login.lower():
81
+ continue
82
+ copilot_reviews.append({
83
+ "id": each_review.get("id"),
84
+ "state": each_review.get("state"),
85
+ "body": each_review.get("body"),
86
+ "commit_id": each_review.get("commit_id"),
87
+ "submitted_at": each_review.get("submitted_at"),
88
+ "html_url": each_review.get("html_url"),
89
+ })
90
+ copilot_reviews.sort(
91
+ key=lambda each_review: str(each_review.get("submitted_at", "")),
92
+ reverse=True,
93
+ )
94
+ return copilot_reviews
95
+
96
+
97
+ def parse_arguments(all_argv: list[str]) -> argparse.Namespace:
98
+ """Parse command-line arguments.
99
+
100
+ Args:
101
+ all_argv: Command-line argument list.
102
+
103
+ Returns:
104
+ Parsed namespace with owner, repo, and number.
105
+ """
106
+ parser = argparse.ArgumentParser(description=__doc__)
107
+ parser.add_argument("--owner", required=True, help="GitHub repository owner")
108
+ parser.add_argument("--repo", required=True, help="GitHub repository name")
109
+ parser.add_argument("--pr-number", required=True, type=int, help="Pull request number")
110
+ return parser.parse_args(all_argv)
111
+
112
+
113
+ def main(all_arguments: list[str]) -> int:
114
+ """Entry point for fetch_copilot_reviews.
115
+
116
+ Args:
117
+ all_arguments: Command-line arguments.
118
+
119
+ Returns:
120
+ 0 on success, 1 on error.
121
+ """
122
+ arguments = parse_arguments(all_arguments)
123
+ all_reviews = fetch_copilot_reviews(
124
+ owner=arguments.owner,
125
+ repo=arguments.repo,
126
+ number=getattr(arguments, "pr_number"),
127
+ )
128
+ json.dump(all_reviews, sys.stdout)
129
+ sys.stdout.write("\n")
130
+ return 0
131
+
132
+
133
+ if __name__ == "__main__":
134
+ raise SystemExit(main(sys.argv[1:]))
@@ -0,0 +1,168 @@
1
+ """Post a fix reply to a pull request comment thread or as a general PR comment.
2
+
3
+ Usage:
4
+ # Reply to an inline comment thread
5
+ python scripts/post_fix_reply.py --owner <O> --repo <R> --pr-number <N> \
6
+ --body "Fixed in <sha>" --in-reply-to <COMMENT_ID>
7
+
8
+ python scripts/post_fix_reply.py --owner <O> --repo <R> --pr-number <N> \
9
+ --body "Your reply text"
10
+
11
+ Exit codes:
12
+ 0 — reply posted successfully
13
+ 2 — gh CLI error
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import argparse
19
+ import subprocess
20
+ import sys
21
+ from pathlib import Path
22
+
23
+ _pr_converge_dir = Path(__file__).resolve().parent.parent
24
+ if str(_pr_converge_dir) not in sys.path:
25
+ sys.path.insert(0, str(_pr_converge_dir))
26
+
27
+ from config.constants import (
28
+ EXIT_CODE_GH_ERROR,
29
+ GH_INLINE_COMMENT_REPLY_PATH_TEMPLATE,
30
+ GH_ISSUE_COMMENT_CREATE_PATH_TEMPLATE,
31
+ )
32
+
33
+
34
+ def post_inline_reply(
35
+ *,
36
+ owner: str,
37
+ repo: str,
38
+ number: int,
39
+ body: str,
40
+ in_reply_to: int,
41
+ ) -> int:
42
+ """Post a reply to an inline pull request comment thread.
43
+
44
+ Args:
45
+ owner: GitHub repository owner.
46
+ repo: GitHub repository name.
47
+ number: Pull request number.
48
+ body: Reply body text.
49
+ in_reply_to: The comment ID to reply to.
50
+
51
+ Returns:
52
+ 0 on success, EXIT_CODE_GH_ERROR on failure.
53
+ """
54
+ endpoint_path = GH_INLINE_COMMENT_REPLY_PATH_TEMPLATE.format(
55
+ owner=owner, repo=repo, number=number, comment_id=in_reply_to
56
+ )
57
+ completed_process = subprocess.run(
58
+ [
59
+ "gh",
60
+ "api",
61
+ endpoint_path,
62
+ "-f",
63
+ f"body={body}",
64
+ ],
65
+ capture_output=True,
66
+ text=True,
67
+ encoding="utf-8",
68
+ errors="replace",
69
+ check=False,
70
+ )
71
+ if completed_process.returncode != 0:
72
+ print(f"gh api error: {completed_process.stderr}", file=sys.stderr)
73
+ return EXIT_CODE_GH_ERROR
74
+ return 0
75
+
76
+
77
+ def post_pr_comment(
78
+ *,
79
+ owner: str,
80
+ repo: str,
81
+ number: int,
82
+ body: str,
83
+ ) -> int:
84
+ """Post a general PR comment.
85
+
86
+ Args:
87
+ owner: GitHub repository owner.
88
+ repo: GitHub repository name.
89
+ number: Pull request number (issue_number for PR comments).
90
+ body: Comment body text.
91
+
92
+ Returns:
93
+ 0 on success, EXIT_CODE_GH_ERROR on failure.
94
+ """
95
+ endpoint_path = GH_ISSUE_COMMENT_CREATE_PATH_TEMPLATE.format(
96
+ owner=owner, repo=repo, number=number
97
+ )
98
+ completed_process = subprocess.run(
99
+ [
100
+ "gh",
101
+ "api",
102
+ endpoint_path,
103
+ "-f",
104
+ f"body={body}",
105
+ ],
106
+ capture_output=True,
107
+ text=True,
108
+ encoding="utf-8",
109
+ errors="replace",
110
+ check=False,
111
+ )
112
+ if completed_process.returncode != 0:
113
+ print(f"gh api error: {completed_process.stderr}", file=sys.stderr)
114
+ return EXIT_CODE_GH_ERROR
115
+ return 0
116
+
117
+
118
+ def parse_arguments(all_argv: list[str]) -> argparse.Namespace:
119
+ """Parse command-line arguments.
120
+
121
+ Args:
122
+ all_argv: Command-line argument list.
123
+
124
+ Returns:
125
+ Parsed namespace with owner, repo, number, body, and in_reply_to.
126
+ """
127
+ parser = argparse.ArgumentParser(description=__doc__)
128
+ parser.add_argument("--owner", required=True, help="GitHub repository owner")
129
+ parser.add_argument("--repo", required=True, help="GitHub repository name")
130
+ parser.add_argument("--pr-number", required=True, type=int, help="Pull request number")
131
+ parser.add_argument("--body", required=True, help="Reply body text")
132
+ parser.add_argument(
133
+ "--in-reply-to",
134
+ type=int,
135
+ default=None,
136
+ help="Comment ID to reply to (omit for general PR comment)",
137
+ )
138
+ return parser.parse_args(all_argv)
139
+
140
+
141
+ def main(all_arguments: list[str]) -> int:
142
+ """Entry point for post_fix_reply.
143
+
144
+ Args:
145
+ all_arguments: Command-line arguments.
146
+
147
+ Returns:
148
+ 0 on success, EXIT_CODE_GH_ERROR on failure.
149
+ """
150
+ arguments = parse_arguments(all_arguments)
151
+ if arguments.in_reply_to is not None:
152
+ return post_inline_reply(
153
+ owner=arguments.owner,
154
+ repo=arguments.repo,
155
+ number=getattr(arguments, "pr_number"),
156
+ body=arguments.body,
157
+ in_reply_to=arguments.in_reply_to,
158
+ )
159
+ return post_pr_comment(
160
+ owner=arguments.owner,
161
+ repo=arguments.repo,
162
+ number=getattr(arguments, "pr_number"),
163
+ body=arguments.body,
164
+ )
165
+
166
+
167
+ if __name__ == "__main__":
168
+ raise SystemExit(main(sys.argv[1:]))