claude-dev-env 4.3.0 → 7.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 (480) hide show
  1. package/.agents/agents/pr-description-writer.md +2 -2
  2. package/.agents/agents/test_agent_frontmatter.py +2 -2
  3. package/.agents/agents/test_pr_description_writer_style.py +1 -3
  4. package/.agents/skills/e-code-review/SKILL.md +12 -12
  5. package/.agents/skills/e-code-review/preflight-proposal.contract.test.mjs +20 -0
  6. package/.agents/skills/e-code-review/reference/fix.md +15 -17
  7. package/.agents/skills/e-code-review/reference/loop.md +35 -39
  8. package/.agents/skills/e-code-review/reference/mode-contract.test.mjs +2 -1
  9. package/.agents/skills/e-code-review/reference/preflight-proposal.md +44 -9
  10. package/.agents/skills/e-code-review/reference/runner-selection.md +13 -14
  11. package/.agents/skills/issue-tracker/SKILL.md +5 -4
  12. package/.agents/skills/pull-request/SKILL.md +11 -13
  13. package/.agents/skills/pull-request/reference/publication-tasks.md +3 -3
  14. package/.agents/skills/pull-request/scripts/github_pr_command_constants/config/constants.py +9 -1
  15. package/.agents/skills/pull-request/scripts/pull_request.py +35 -44
  16. package/.agents/skills/pull-request/scripts/test_github_pr_command_constants.py +9 -0
  17. package/.agents/skills/pull-request/scripts/test_pull_request.py +35 -3
  18. package/.agents/skills/session-continuity/README.md +189 -0
  19. package/.agents/skills/session-continuity/SKILL.md +114 -0
  20. package/.agents/skills/session-continuity/continuity.mjs +375 -0
  21. package/.agents/skills/session-continuity/continuity.test.mjs +303 -0
  22. package/.agents/skills/skill-builder/SKILL.md +3 -196
  23. package/.agents/skills/syncing-submodules/scripts/test_sync_parent_pointer.py +0 -7
  24. package/.agents/skills/windows-scheduled-task/SKILL.md +153 -0
  25. package/_shared/pr-loop/scripts/pr_loop_shared_constants/terminology_sweep_constants.py +6 -0
  26. package/_shared/pr-loop/scripts/terminology_sweep.py +64 -19
  27. package/_shared/pr-loop/scripts/tests/test_terminology_sweep.py +59 -0
  28. package/bin/cde.mjs +36 -8
  29. package/bin/cde.test.mjs +48 -0
  30. package/bin/ever-shipped-skills.mjs +2 -20
  31. package/bin/ever-shipped-skills.test.mjs +8 -0
  32. package/bin/expand_home_directory_tokens.mjs +4 -5
  33. package/bin/expand_home_directory_tokens.test.mjs +128 -0
  34. package/bin/git_hooks_installer.mjs +22 -3
  35. package/bin/git_hooks_installer.test.mjs +159 -5
  36. package/bin/install-session-continuity.mjs +78 -0
  37. package/bin/install-session-continuity.test.mjs +42 -0
  38. package/bin/install.agents-home.test.mjs +15 -13
  39. package/bin/install.codex-rules.test.mjs +5 -2
  40. package/bin/install.cursor-rules.test.mjs +5 -2
  41. package/bin/install.mjs +506 -63
  42. package/bin/install.policy-lint.test.mjs +130 -0
  43. package/bin/install.profiles.test.mjs +10 -0
  44. package/bin/install.prune.test.mjs +286 -37
  45. package/bin/install.pstack-plugin.test.mjs +114 -0
  46. package/bin/install.test.mjs +537 -120
  47. package/bin/install.transaction.test.mjs +3 -3
  48. package/bin/refresh-pstack-plugin-skills.test.mjs +211 -0
  49. package/docs/CODE_RULES.md +1 -1
  50. package/hooks/advisory/pr_done_reminder.py +342 -0
  51. package/hooks/advisory/test_pr_done_reminder.py +249 -0
  52. package/hooks/blocking/bash_post_call_dispatcher.py +53 -6
  53. package/hooks/blocking/code_rules_banned_identifiers.py +3 -0
  54. package/hooks/blocking/code_rules_paired_test.py +22 -15
  55. package/hooks/blocking/precommit_code_rules_gate.py +5 -8
  56. package/hooks/blocking/test_bash_dispatcher_interpreter_starts.py +7 -52
  57. package/hooks/blocking/test_bash_post_call_dispatcher.py +65 -4
  58. package/hooks/blocking/test_bash_pre_tool_use_dispatcher.py +0 -69
  59. package/hooks/blocking/test_code_rules_banned_identifiers.py +64 -0
  60. package/hooks/blocking/test_code_rules_enforcer_paired_test.py +36 -29
  61. package/hooks/blocking/test_code_rules_js_resume_task_enumeration.py +4 -4
  62. package/hooks/blocking/test_code_rules_js_returns_object_schemaless.py +5 -5
  63. package/hooks/blocking/test_pre_tool_use_dispatcher.py +43 -342
  64. package/hooks/blocking/test_pre_tool_use_dispatcher_native.py +20 -51
  65. package/hooks/blocking/test_shared_stdin_adoption.py +1 -47
  66. package/hooks/git-hooks/git_hooks_constants/staged_policy_lint.py +12 -0
  67. package/hooks/git-hooks/git_hooks_constants/verification_notice_constants.py +116 -0
  68. package/hooks/git-hooks/post_commit.py +33 -0
  69. package/hooks/git-hooks/pre_commit.py +18 -49
  70. package/hooks/git-hooks/pre_push.py +45 -541
  71. package/hooks/git-hooks/test_installed_policy_lint.py +208 -0
  72. package/hooks/git-hooks/test_native_hook_support.py +129 -0
  73. package/hooks/git-hooks/test_native_policy_commit.py +120 -0
  74. package/hooks/git-hooks/test_post_commit.py +43 -0
  75. package/hooks/git-hooks/test_pre_commit.py +38 -148
  76. package/hooks/git-hooks/test_pre_push.py +48 -1631
  77. package/hooks/git-hooks/test_verification_notice.py +60 -0
  78. package/hooks/git-hooks/test_verification_start.py +173 -0
  79. package/hooks/git-hooks/verification_notice.py +192 -0
  80. package/hooks/git-hooks/verification_notice_context.py +253 -0
  81. package/hooks/git-hooks/verification_notice_state.py +237 -0
  82. package/hooks/git-hooks/verification_start.py +100 -0
  83. package/hooks/hooks.json +1 -120
  84. package/hooks/hooks_constants/banned_identifiers_constants.py +4 -0
  85. package/hooks/hooks_constants/bash_post_call_dispatcher_constants.py +14 -1
  86. package/hooks/hooks_constants/bash_pre_tool_use_dispatcher_constants.py +1 -15
  87. package/hooks/hooks_constants/post_tool_use_dispatcher_constants.py +0 -4
  88. package/hooks/hooks_constants/pr_done_reminder_constants.py +98 -0
  89. package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +10 -93
  90. package/hooks/hooks_constants/stop_dispatcher_constants.py +1 -4
  91. package/hooks/hooks_constants/test_bash_post_call_dispatcher_constants.py +19 -2
  92. package/hooks/hooks_constants/test_bash_pre_tool_use_dispatcher_constants.py +3 -66
  93. package/hooks/hooks_constants/test_pr_done_reminder_constants.py +40 -0
  94. package/hooks/hooks_constants/test_pre_tool_use_dispatcher_constants.py +46 -201
  95. package/hooks/hooks_constants/test_stop_dispatcher_constants.py +3 -25
  96. package/hooks/validation/test_post_tool_use_dispatcher.py +35 -298
  97. package/hooks/validators/run_all_validators.py +5 -1
  98. package/hooks/validators/security_checks.py +57 -2
  99. package/hooks/validators/test_hook_timing_harness.py +2 -5
  100. package/hooks/validators/test_run_all_validators_mutation_tool_parity.py +3 -11
  101. package/hooks/validators/test_run_all_validators_policy_lint.py +36 -0
  102. package/hooks/validators/test_security_checks.py +57 -0
  103. package/package.json +2 -2
  104. package/rules/confirm-implementation-forks.md +2 -0
  105. package/rules/durable-post-artifacts.md +2 -1
  106. package/rules/git-workflow.md +18 -6
  107. package/rules/pstack-host-mapping.md +48 -0
  108. package/rules/vault-context.md +3 -5
  109. package/rules/verify-runtime-state.md +7 -0
  110. package/scripts/audit-hooks-cli.mjs +5 -0
  111. package/scripts/audit-hooks.mjs +72 -16
  112. package/scripts/automatic_advisory/__init__.py +1 -0
  113. package/scripts/automatic_advisory/checkout.py +51 -0
  114. package/scripts/automatic_advisory/cli.py +334 -0
  115. package/scripts/automatic_advisory/config/__init__.py +1 -0
  116. package/scripts/automatic_advisory/config/constants.py +93 -0
  117. package/scripts/automatic_advisory/config/timing.py +4 -0
  118. package/scripts/automatic_advisory/configuration.py +197 -0
  119. package/scripts/automatic_advisory/execution.py +350 -0
  120. package/scripts/automatic_advisory/git.py +69 -0
  121. package/scripts/automatic_advisory/model.py +107 -0
  122. package/scripts/automatic_advisory/process_host.py +32 -0
  123. package/scripts/automatic_advisory/publisher.py +84 -0
  124. package/scripts/automatic_advisory/runner.py +399 -0
  125. package/scripts/automatic_advisory/state.py +116 -0
  126. package/scripts/automatic_advisory/window_flags.py +41 -0
  127. package/scripts/automatic_advisory/windows_job.py +122 -0
  128. package/scripts/check.ps1 +0 -1
  129. package/{.agents/skills/run-claude-dev-env/driver.mjs → scripts/ci/installer-lifecycle.mjs} +3 -28
  130. package/scripts/ci/installer-lifecycle.test.mjs +26 -0
  131. package/scripts/ci/windows-installer-lifecycle.ps1 +1 -11
  132. package/scripts/codex_compat_materializer.py +99 -13
  133. package/scripts/dev_env_scripts_constants/shared_tree_constants.py +4 -5
  134. package/{.agents/skills/_shared/pr-loop/scripts → scripts}/durable_post_lint.py +35 -43
  135. package/{.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/durable_post_lint_constants.py → scripts/durable_post_lint_config/config/constants.py} +10 -10
  136. package/{.agents/skills/_shared/pr-loop/scripts/test_durable_post_lint_constants.py → scripts/durable_post_lint_config/config/test_constants.py} +14 -1
  137. package/scripts/local_report_cli.py +184 -0
  138. package/scripts/local_report_core.py +247 -0
  139. package/scripts/local_report_publisher.py +12 -0
  140. package/scripts/local_report_validation.py +357 -0
  141. package/scripts/local_verification/__init__.py +23 -0
  142. package/scripts/local_verification/check_runner.py +364 -0
  143. package/scripts/local_verification/check_support.py +99 -0
  144. package/scripts/local_verification/cli.py +158 -0
  145. package/scripts/local_verification/command_runner.py +84 -0
  146. package/scripts/local_verification/config/__init__.py +1 -0
  147. package/scripts/local_verification/config/constants.py +89 -0
  148. package/scripts/local_verification/config/timing.py +1 -0
  149. package/scripts/local_verification/git_state.py +146 -0
  150. package/scripts/local_verification/manifest.py +224 -0
  151. package/scripts/local_verification/model.py +174 -0
  152. package/scripts/local_verification/runner.py +234 -0
  153. package/scripts/policy_lint/adapter_detectors.py +13 -6
  154. package/scripts/policy_lint/adapter_pairing.py +58 -3
  155. package/scripts/policy_lint/adapters.py +7 -4
  156. package/scripts/policy_lint/config/approved_test_pairs.py +323 -0
  157. package/scripts/policy_lint/config/constants.py +5 -0
  158. package/scripts/policy_lint/engine.py +48 -4
  159. package/scripts/policy_lint/model.py +1 -0
  160. package/scripts/policy_lint/registry.py +1 -1
  161. package/scripts/policy_lint/selection.py +2 -1
  162. package/scripts/policy_lint/selection_git.py +2 -0
  163. package/scripts/pr_verification/__init__.py +1 -0
  164. package/scripts/pr_verification/branch_refs.py +114 -0
  165. package/scripts/pr_verification/config/__init__.py +1 -0
  166. package/scripts/pr_verification/config/constants.py +84 -0
  167. package/scripts/pr_verification/config/timing.py +5 -0
  168. package/scripts/pr_verification/github.py +137 -0
  169. package/scripts/pr_verification/github_api.py +376 -0
  170. package/scripts/pr_verification/github_labels.py +88 -0
  171. package/scripts/pr_verification/github_parsing.py +182 -0
  172. package/scripts/pr_verification/github_transport.py +91 -0
  173. package/scripts/pr_verification/lock.py +122 -0
  174. package/scripts/pr_verification/model.py +43 -0
  175. package/scripts/pr_verification/requirements.txt +1 -0
  176. package/scripts/refresh_pstack_plugin_skills.mjs +200 -0
  177. package/scripts/shared_tree_paths.py +32 -3
  178. package/{.agents/skills/_shared/pr-loop/scripts → scripts}/test_durable_post_lint.py +97 -0
  179. package/scripts/test_shared_tree_paths.py +33 -0
  180. package/scripts/tests/test-audit-hooks-cli.mjs +150 -0
  181. package/scripts/tests/test-audit-hooks.mjs +94 -2
  182. package/scripts/tests/test_automatic_advisory.py +376 -0
  183. package/scripts/tests/test_automatic_advisory_job_cleanup.py +71 -0
  184. package/scripts/tests/test_automatic_advisory_polling.py +216 -0
  185. package/scripts/tests/test_automatic_advisory_recovery.py +320 -0
  186. package/scripts/tests/test_automatic_advisory_repairs.py +400 -0
  187. package/scripts/tests/test_automatic_advisory_settings.py +48 -0
  188. package/scripts/tests/test_automatic_advisory_window_flags.py +163 -0
  189. package/scripts/tests/test_closed_pr_label.py +157 -0
  190. package/scripts/tests/test_codex_compat_materializer.py +189 -6
  191. package/scripts/tests/test_github_labels.py +101 -0
  192. package/scripts/tests/test_github_transport.py +125 -0
  193. package/scripts/tests/test_local_report_publisher.py +396 -0
  194. package/scripts/tests/test_local_report_publisher_cli.py +85 -0
  195. package/scripts/tests/test_local_verification.py +348 -0
  196. package/scripts/tests/test_local_verification_cli.py +98 -0
  197. package/scripts/tests/test_policy_lint_rules_archive.py +120 -0
  198. package/scripts/tests/test_policy_lint_rules_engine.py +25 -4
  199. package/scripts/tests/test_policy_lint_rules_installed_loader.py +29 -0
  200. package/scripts/tests/test_policy_lint_rules_pairing.py +163 -0
  201. package/scripts/tests/test_policy_lint_rules_registry.py +227 -13
  202. package/scripts/tests/test_policy_lint_selection.py +25 -2
  203. package/scripts/tests/test_policy_lint_selection_native_index.py +30 -0
  204. package/scripts/tests/test_pr_verification_github.py +392 -0
  205. package/scripts/tests/test_pr_verification_lock.py +168 -0
  206. package/scripts/tests/test_rules.py +3 -7
  207. package/scripts/tests/test_verification_notice.py +347 -0
  208. package/.agents/skills/_shared/pr-loop/.claude/CLAUDE.md +0 -1
  209. package/.agents/skills/_shared/pr-loop/audit-contract.md +0 -5
  210. package/.agents/skills/_shared/pr-loop/audit-reply-template.md +0 -5
  211. package/.agents/skills/_shared/pr-loop/code-rules-gate.md +0 -5
  212. package/.agents/skills/_shared/pr-loop/fix-protocol.md +0 -5
  213. package/.agents/skills/_shared/pr-loop/gh-payloads.md +0 -5
  214. package/.agents/skills/_shared/pr-loop/portable-driver.md +0 -149
  215. package/.agents/skills/_shared/pr-loop/post-audit-thread-contract.md +0 -5
  216. package/.agents/skills/_shared/pr-loop/precatch-rubric.md +0 -5
  217. package/.agents/skills/_shared/pr-loop/preflight-proposal.contract.test.mjs +0 -119
  218. package/.agents/skills/_shared/pr-loop/preflight-proposal.md +0 -5
  219. package/.agents/skills/_shared/pr-loop/prompts/.claude/CLAUDE.md +0 -1
  220. package/.agents/skills/_shared/pr-loop/prompts/AGENTS.md +0 -1
  221. package/.agents/skills/_shared/pr-loop/prompts/pr-consistency-audit.xml +0 -324
  222. package/.agents/skills/_shared/pr-loop/scripts/.claude/CLAUDE.md +0 -1
  223. package/.agents/skills/_shared/pr-loop/scripts/AGENTS.md +0 -1
  224. package/.agents/skills/_shared/pr-loop/scripts/RUNTIME_SCRIPTS.md +0 -29
  225. package/.agents/skills/_shared/pr-loop/scripts/_cli_utils.py +0 -22
  226. package/.agents/skills/_shared/pr-loop/scripts/_path_resolver.py +0 -186
  227. package/.agents/skills/_shared/pr-loop/scripts/_xml_utils.py +0 -20
  228. package/.agents/skills/_shared/pr-loop/scripts/audit_category_schema.py +0 -355
  229. package/.agents/skills/_shared/pr-loop/scripts/build_audit_prompt.py +0 -289
  230. package/.agents/skills/_shared/pr-loop/scripts/build_converge_task_list.py +0 -310
  231. package/.agents/skills/_shared/pr-loop/scripts/build_fix_prompt.py +0 -292
  232. package/.agents/skills/_shared/pr-loop/scripts/init_loop_state.py +0 -134
  233. package/.agents/skills/_shared/pr-loop/scripts/portable_converge_driver.py +0 -1646
  234. package/.agents/skills/_shared/pr-loop/scripts/preflight_worktree.py +0 -392
  235. package/.agents/skills/_shared/pr-loop/scripts/select_converge_pacer.py +0 -215
  236. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/.claude/CLAUDE.md +0 -1
  237. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/AGENTS.md +0 -1
  238. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/__init__.py +0 -0
  239. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/audit_category_schema_constants.py +0 -37
  240. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/converge_task_list_constants.py +0 -56
  241. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/handoff_constants.py +0 -45
  242. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/pacer_constants.py +0 -47
  243. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py +0 -157
  244. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/portable_driver_constants.py +0 -177
  245. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/preflight_constants.py +0 -70
  246. package/.agents/skills/_shared/pr-loop/scripts/teardown_worktrees.py +0 -172
  247. package/.agents/skills/_shared/pr-loop/scripts/test__path_resolver.py +0 -106
  248. package/.agents/skills/_shared/pr-loop/scripts/test_audit_category_schema.py +0 -94
  249. package/.agents/skills/_shared/pr-loop/scripts/test_build_audit_prompt.py +0 -499
  250. package/.agents/skills/_shared/pr-loop/scripts/test_build_converge_task_list.py +0 -140
  251. package/.agents/skills/_shared/pr-loop/scripts/test_build_fix_prompt.py +0 -262
  252. package/.agents/skills/_shared/pr-loop/scripts/test_init_loop_state.py +0 -71
  253. package/.agents/skills/_shared/pr-loop/scripts/test_portable_converge_driver.py +0 -1119
  254. package/.agents/skills/_shared/pr-loop/scripts/test_preflight_worktree.py +0 -287
  255. package/.agents/skills/_shared/pr-loop/scripts/test_select_converge_pacer.py +0 -207
  256. package/.agents/skills/_shared/pr-loop/scripts/test_teardown_worktrees.py +0 -59
  257. package/.agents/skills/_shared/pr-loop/scripts/test_write_handoff.py +0 -201
  258. package/.agents/skills/_shared/pr-loop/scripts/write_audit_outcomes.py +0 -182
  259. package/.agents/skills/_shared/pr-loop/scripts/write_fix_outcomes.py +0 -206
  260. package/.agents/skills/_shared/pr-loop/scripts/write_handoff.py +0 -309
  261. package/.agents/skills/_shared/pr-loop/state-schema.md +0 -5
  262. package/.agents/skills/_shared/pr-loop/worker-spawn.md +0 -5
  263. package/.agents/skills/autoconverge/.claude/CLAUDE.md +0 -1
  264. package/.agents/skills/autoconverge/AGENTS.md +0 -1
  265. package/.agents/skills/autoconverge/SKILL.md +0 -431
  266. package/.agents/skills/autoconverge/reference/.claude/CLAUDE.md +0 -1
  267. package/.agents/skills/autoconverge/reference/AGENTS.md +0 -1
  268. package/.agents/skills/autoconverge/reference/closing-report.md +0 -93
  269. package/.agents/skills/autoconverge/reference/convergence-gates.md +0 -31
  270. package/.agents/skills/autoconverge/reference/convergence.md +0 -219
  271. package/.agents/skills/autoconverge/reference/copilot-findings.md +0 -51
  272. package/.agents/skills/autoconverge/reference/gotchas.md +0 -66
  273. package/.agents/skills/autoconverge/reference/headless-safety.md +0 -44
  274. package/.agents/skills/autoconverge/reference/multi-pr.md +0 -128
  275. package/.agents/skills/autoconverge/reference/self-closing-loop.md +0 -84
  276. package/.agents/skills/autoconverge/reference/stop-conditions.md +0 -127
  277. package/.agents/skills/autoconverge/test_portable_pacer_gate.py +0 -54
  278. package/.agents/skills/autoconverge/workflow/.claude/CLAUDE.md +0 -1
  279. package/.agents/skills/autoconverge/workflow/AGENTS.md +0 -1
  280. package/.agents/skills/autoconverge/workflow/aggregate_runs.py +0 -371
  281. package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/.claude/CLAUDE.md +0 -1
  282. package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/AGENTS.md +0 -1
  283. package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/__init__.py +0 -0
  284. package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/render_report_constants.py +0 -250
  285. package/.agents/skills/autoconverge/workflow/converge.clean-audit.test.mjs +0 -665
  286. package/.agents/skills/autoconverge/workflow/converge.codex-gate.test.mjs +0 -472
  287. package/.agents/skills/autoconverge/workflow/converge.contract.test.mjs +0 -64
  288. package/.agents/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +0 -1009
  289. package/.agents/skills/autoconverge/workflow/converge.fix-progress.test.mjs +0 -107
  290. package/.agents/skills/autoconverge/workflow/converge.fix-recovery.test.mjs +0 -33
  291. package/.agents/skills/autoconverge/workflow/converge.merge-conflict.test.mjs +0 -15
  292. package/.agents/skills/autoconverge/workflow/converge.mjs +0 -3132
  293. package/.agents/skills/autoconverge/workflow/converge.p2-advance.test.mjs +0 -202
  294. package/.agents/skills/autoconverge/workflow/converge.path-aware.test.mjs +0 -47
  295. package/.agents/skills/autoconverge/workflow/converge.precatch.test.mjs +0 -152
  296. package/.agents/skills/autoconverge/workflow/converge.run-input.test.mjs +0 -116
  297. package/.agents/skills/autoconverge/workflow/converge_multi.mjs +0 -169
  298. package/.agents/skills/autoconverge/workflow/converge_multi.run-input.test.mjs +0 -173
  299. package/.agents/skills/autoconverge/workflow/convergence_summary.py +0 -110
  300. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a11d903476b803493.jsonl +0 -2
  301. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a26213978adeef6fb.jsonl +0 -2
  302. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a3def0d15ed9d9110.jsonl +0 -2
  303. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a41f41b1b708ee3b7.jsonl +0 -2
  304. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a758b880abecc3ff7.jsonl +0 -2
  305. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a8897b89656b1bd16.jsonl +0 -2
  306. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-ab1c2d3e4f5a6b7c8.jsonl +0 -2
  307. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-abd463d744a1437bc.jsonl +0 -2
  308. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-ad19d027ae8ee1816.jsonl +0 -2
  309. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/workflows/wf_881252e6-700.json +0 -266
  310. package/.agents/skills/autoconverge/workflow/render_report.py +0 -1024
  311. package/.agents/skills/autoconverge/workflow/test_aggregate_runs.py +0 -134
  312. package/.agents/skills/autoconverge/workflow/test_convergence_summary.py +0 -149
  313. package/.agents/skills/autoconverge/workflow/test_render_report.py +0 -812
  314. package/.agents/skills/hitl/SKILL.md +0 -45
  315. package/.agents/skills/pr-cleanup/SKILL.md +0 -140
  316. package/.agents/skills/pr-cleanup/reference/process-inventory.md +0 -17
  317. package/.agents/skills/pr-cleanup/reference/task-seeds.md +0 -22
  318. package/.agents/skills/pr-name-by-capability/SKILL.md +0 -73
  319. package/.agents/skills/pr-name-by-capability/reference/fetch-commands.md +0 -29
  320. package/.agents/skills/pr-name-by-capability/reference/offense-examples.md +0 -32
  321. package/.agents/skills/pr-name-by-capability/reference/report-template.md +0 -29
  322. package/.agents/skills/pr-name-by-capability/reference/rule-checklist.md +0 -38
  323. package/.agents/skills/pr-name-by-capability/reference/task-seeds.md +0 -10
  324. package/.agents/skills/pr-plain-language-cleanup/SKILL.md +0 -93
  325. package/.agents/skills/pr-refinement/SKILL.md +0 -31
  326. package/.agents/skills/pr-shared-extraction/SKILL.md +0 -177
  327. package/.agents/skills/pr-shared-extraction/reference/examples.md +0 -46
  328. package/.agents/skills/pr-shared-extraction/reference/offense-taxonomy.md +0 -100
  329. package/.agents/skills/pr-small-cl/SKILL.md +0 -52
  330. package/.agents/skills/pr-title-description/SKILL.md +0 -96
  331. package/.agents/skills/prototype/SKILL.md +0 -85
  332. package/.agents/skills/prototype/reference/honest-limitations.md +0 -23
  333. package/.agents/skills/prototype/reference/promotion-tasks.md +0 -23
  334. package/.agents/skills/prototype/scripts/build_sandbox_settings.py +0 -249
  335. package/.agents/skills/prototype/scripts/conftest.py +0 -15
  336. package/.agents/skills/prototype/scripts/launch_sandbox.py +0 -205
  337. package/.agents/skills/prototype/scripts/probe_sandbox_safety.py +0 -311
  338. package/.agents/skills/prototype/scripts/prototype_scripts_constants/__init__.py +0 -1
  339. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/__init__.py +0 -0
  340. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/build_sandbox_settings_constants.py +0 -41
  341. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/launch_sandbox_constants.py +0 -23
  342. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/probe_sandbox_safety_constants.py +0 -45
  343. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/prototype_common_constants.py +0 -10
  344. package/.agents/skills/prototype/scripts/test_build_sandbox_settings.py +0 -275
  345. package/.agents/skills/prototype/scripts/test_launch_sandbox.py +0 -303
  346. package/.agents/skills/prototype/scripts/test_probe_sandbox_safety.py +0 -312
  347. package/.agents/skills/prototype/workflows/promotion.md +0 -25
  348. package/.agents/skills/prototype/workflows/sandbox.md +0 -35
  349. package/.agents/skills/rebase/.claude/CLAUDE.md +0 -1
  350. package/.agents/skills/rebase/AGENTS.md +0 -1
  351. package/.agents/skills/rebase/SKILL.md +0 -178
  352. package/.agents/skills/review-router/SKILL.md +0 -51
  353. package/.agents/skills/review-router/reference/route-policy.json +0 -7
  354. package/.agents/skills/review-router/reference/task-seeds.md +0 -1
  355. package/.agents/skills/review-router/scripts/conftest.py +0 -4
  356. package/.agents/skills/review-router/scripts/review_router.py +0 -50
  357. package/.agents/skills/review-router/scripts/review_router_cli.py +0 -211
  358. package/.agents/skills/review-router/scripts/review_router_constants/__init__.py +0 -1
  359. package/.agents/skills/review-router/scripts/review_router_constants/config/__init__.py +0 -0
  360. package/.agents/skills/review-router/scripts/review_router_constants/config/constants.py +0 -13
  361. package/.agents/skills/review-router/scripts/test_review_router.py +0 -23
  362. package/.agents/skills/review-router/scripts/test_review_router_cli.py +0 -47
  363. package/.agents/skills/review-tier/SKILL.md +0 -56
  364. package/.agents/skills/review-tier/reference/task-seeds.md +0 -1
  365. package/.agents/skills/review-tier/reference/tier-policy.json +0 -9
  366. package/.agents/skills/review-tier/scripts/conftest.py +0 -4
  367. package/.agents/skills/review-tier/scripts/review_tier.py +0 -359
  368. package/.agents/skills/review-tier/scripts/review_tier_constants/__init__.py +0 -1
  369. package/.agents/skills/review-tier/scripts/review_tier_constants/config/__init__.py +0 -0
  370. package/.agents/skills/review-tier/scripts/review_tier_constants/config/constants.py +0 -29
  371. package/.agents/skills/review-tier/scripts/test_generation.py +0 -159
  372. package/.agents/skills/review-tier/scripts/test_review_tier.py +0 -33
  373. package/.agents/skills/run-claude-dev-env/SKILL.md +0 -84
  374. package/.agents/skills/session-log/.claude/CLAUDE.md +0 -1
  375. package/.agents/skills/session-log/AGENTS.md +0 -1
  376. package/.agents/skills/session-log/SKILL.md +0 -170
  377. package/.agents/skills/session-log/templates/frontmatter.md +0 -40
  378. package/.agents/skills/session-tidy/.claude/CLAUDE.md +0 -1
  379. package/.agents/skills/session-tidy/AGENTS.md +0 -1
  380. package/.agents/skills/session-tidy/SKILL.md +0 -191
  381. package/.agents/skills/skill-builder/references/.claude/CLAUDE.md +0 -1
  382. package/.agents/skills/skill-builder/references/AGENTS.md +0 -1
  383. package/.agents/skills/skill-builder/references/delegation-map.md +0 -130
  384. package/.agents/skills/skill-builder/references/description-field.md +0 -111
  385. package/.agents/skills/skill-builder/references/deterministic-elements.md +0 -218
  386. package/.agents/skills/skill-builder/references/progressive-disclosure.md +0 -122
  387. package/.agents/skills/skill-builder/references/self-audit-checklist.md +0 -126
  388. package/.agents/skills/skill-builder/references/skill-modularity.md +0 -111
  389. package/.agents/skills/skill-builder/references/skill-types.md +0 -232
  390. package/.agents/skills/skill-builder/references/thariq-x-post-skills.json +0 -33
  391. package/.agents/skills/skill-builder/templates/.claude/CLAUDE.md +0 -1
  392. package/.agents/skills/skill-builder/templates/AGENTS.md +0 -1
  393. package/.agents/skills/skill-builder/templates/gap-analysis.md +0 -87
  394. package/.agents/skills/skill-builder/workflows/.claude/CLAUDE.md +0 -1
  395. package/.agents/skills/skill-builder/workflows/AGENTS.md +0 -1
  396. package/.agents/skills/skill-builder/workflows/improve-skill.md +0 -136
  397. package/.agents/skills/skill-builder/workflows/new-skill.md +0 -179
  398. package/.agents/skills/skill-builder/workflows/polish-skill.md +0 -139
  399. package/.agents/skills/source-command-sr-loop/SKILL.md +0 -82
  400. package/.agents/skills/update/.claude/CLAUDE.md +0 -1
  401. package/.agents/skills/update/AGENTS.md +0 -1
  402. package/.agents/skills/update/SKILL.md +0 -190
  403. package/_shared/pr-loop/AGENTS.md +0 -1
  404. package/_shared/pr-loop/audit-contract.md +0 -183
  405. package/_shared/pr-loop/audit-reply-template.md +0 -151
  406. package/_shared/pr-loop/code-rules-gate.md +0 -65
  407. package/_shared/pr-loop/fix-protocol.md +0 -60
  408. package/_shared/pr-loop/gh-payloads.md +0 -75
  409. package/_shared/pr-loop/post-audit-thread-contract.md +0 -51
  410. package/_shared/pr-loop/precatch-rubric.md +0 -66
  411. package/_shared/pr-loop/preflight-proposal.md +0 -56
  412. package/_shared/pr-loop/scripts/post_audit_thread.py +0 -1242
  413. package/_shared/pr-loop/scripts/pr_loop_shared_constants/post_audit_thread_constants.py +0 -199
  414. package/_shared/pr-loop/scripts/tests/test_post_audit_thread.py +0 -1115
  415. package/_shared/pr-loop/scripts/tests/test_post_audit_thread_constants.py +0 -129
  416. package/_shared/pr-loop/state-schema.md +0 -45
  417. package/_shared/pr-loop/worker-spawn.md +0 -189
  418. package/hooks/blocking/ask_user_question_shape_blocker.py +0 -83
  419. package/hooks/blocking/bot_mention_comment_blocker.py +0 -76
  420. package/hooks/blocking/claude_md_orphan_file_blocker.py +0 -129
  421. package/hooks/blocking/cursor_cli_python_misfire_blocker.py +0 -108
  422. package/hooks/blocking/destructive_command_blocker.py +0 -2073
  423. package/hooks/blocking/fable_spawn_gate.py +0 -187
  424. package/hooks/blocking/luna_fast_mode_gate.py +0 -160
  425. package/hooks/blocking/nas_ssh_binary_enforcer.py +0 -163
  426. package/hooks/blocking/orchestrator_refresh_reschedule_gate.py +0 -260
  427. package/hooks/blocking/package_inventory_stale_blocker.py +0 -107
  428. package/hooks/blocking/pii_prevention_blocker.py +0 -365
  429. package/hooks/blocking/piped_pytest_blocker.py +0 -1223
  430. package/hooks/blocking/question_to_user_enforcer.py +0 -130
  431. package/hooks/blocking/send_user_file_open_locally_blocker.py +0 -71
  432. package/hooks/blocking/sensitive_file_protector.py +0 -167
  433. package/hooks/blocking/session_edit_stage_gate.py +0 -684
  434. package/hooks/blocking/session_handoff_blocker.py +0 -182
  435. package/hooks/blocking/shell_substitution_blocker.py +0 -350
  436. package/hooks/blocking/test_ask_user_question_shape.py +0 -69
  437. package/hooks/blocking/test_bot_mention_comment_blocker.py +0 -131
  438. package/hooks/blocking/test_claude_md_orphan_file_blocker.py +0 -1277
  439. package/hooks/blocking/test_cursor_cli_python_misfire_blocker.py +0 -208
  440. package/hooks/blocking/test_destructive_command_blocker.py +0 -2024
  441. package/hooks/blocking/test_destructive_command_blocker_deny_mode.py +0 -105
  442. package/hooks/blocking/test_destructive_command_blocker_no_verify.py +0 -122
  443. package/hooks/blocking/test_destructive_command_blocker_patterns.py +0 -133
  444. package/hooks/blocking/test_fable_spawn_gate.py +0 -381
  445. package/hooks/blocking/test_inventory_deadlock_resolution.py +0 -154
  446. package/hooks/blocking/test_luna_fast_mode_gate.py +0 -211
  447. package/hooks/blocking/test_nas_ssh_binary_enforcer.py +0 -225
  448. package/hooks/blocking/test_orchestrator_refresh_reschedule_gate.py +0 -231
  449. package/hooks/blocking/test_package_inventory_stale_blocker.py +0 -382
  450. package/hooks/blocking/test_pii_prevention_blocker.py +0 -1222
  451. package/hooks/blocking/test_pii_prevention_windows_git_path.py +0 -41
  452. package/hooks/blocking/test_pii_write_surface_ephemeral.py +0 -221
  453. package/hooks/blocking/test_piped_pytest_blocker.py +0 -587
  454. package/hooks/blocking/test_precommit_code_rules_gate_native_owner.py +0 -233
  455. package/hooks/blocking/test_question_to_user_enforcer.py +0 -169
  456. package/hooks/blocking/test_send_user_file_open_locally_blocker.py +0 -118
  457. package/hooks/blocking/test_sensitive_file_protector.py +0 -365
  458. package/hooks/blocking/test_session_edit_stage_gate.py +0 -537
  459. package/hooks/blocking/test_session_edit_stage_gate_staging.py +0 -64
  460. package/hooks/blocking/test_session_edit_stage_gate_support.py +0 -204
  461. package/hooks/blocking/test_session_edit_stage_gate_tracker.py +0 -116
  462. package/hooks/blocking/test_session_handoff_blocker.py +0 -318
  463. package/hooks/blocking/test_shell_substitution_blocker.py +0 -298
  464. package/hooks/blocking/test_unscoped_search_blocker.py +0 -102
  465. package/hooks/blocking/test_write_existing_file_blocker.py +0 -122
  466. package/hooks/blocking/tests/test_pii_prevention_blocker.py +0 -259
  467. package/hooks/blocking/unscoped_search_blocker.py +0 -391
  468. package/hooks/blocking/write_existing_file_blocker.py +0 -124
  469. package/hooks/hooks_constants/bot_mention_comment_blocker_constants.py +0 -19
  470. package/hooks/hooks_constants/cursor_cli_python_misfire_blocker_constants.py +0 -79
  471. package/hooks/hooks_constants/fable_spawn_gate_constants.py +0 -61
  472. package/hooks/hooks_constants/luna_fast_mode_gate_constants.py +0 -45
  473. package/hooks/hooks_constants/nas_ssh_binary_enforcer_constants.py +0 -20
  474. package/hooks/hooks_constants/orchestrator_refresh_reschedule_gate_constants.py +0 -57
  475. package/hooks/hooks_constants/send_user_file_open_locally_blocker_constants.py +0 -17
  476. package/hooks/hooks_constants/sensitive_file_protector_constants.py +0 -40
  477. package/hooks/hooks_constants/session_handoff_blocker_constants.py +0 -10
  478. package/hooks/hooks_constants/shell_substitution_blocker_constants.py +0 -80
  479. /package/.agents/skills/{_shared/pr-loop → session-continuity}/AGENTS.md +0 -0
  480. /package/{_shared/pr-loop → .agents/skills/session-continuity}/CLAUDE.md +0 -0
@@ -1,201 +0,0 @@
1
- """Tests for write_handoff: the durable per-run handoff writer."""
2
-
3
- from __future__ import annotations
4
-
5
- import importlib.util
6
- import json
7
- import sys
8
- from pathlib import Path
9
- from types import ModuleType
10
-
11
- import pytest
12
-
13
- _SCRIPTS_DIR = Path(__file__).resolve().parent
14
- if str(_SCRIPTS_DIR) not in sys.path:
15
- sys.path.insert(0, str(_SCRIPTS_DIR))
16
-
17
-
18
- def _load_write_handoff_module() -> ModuleType:
19
- module_path = _SCRIPTS_DIR / "write_handoff.py"
20
- spec = importlib.util.spec_from_file_location("write_handoff", module_path)
21
- assert spec is not None
22
- assert spec.loader is not None
23
- module = importlib.util.module_from_spec(spec)
24
- spec.loader.exec_module(module)
25
- return module
26
-
27
-
28
- write_handoff = _load_write_handoff_module()
29
-
30
-
31
- _FROZEN_TIMESTAMP = "2026-07-03T12:00:00+00:00"
32
-
33
-
34
- def _point_base_dir_at(monkeypatch: pytest.MonkeyPatch, base: Path) -> None:
35
- monkeypatch.setattr(write_handoff, "_handoff_base_dir", lambda: base)
36
- monkeypatch.setattr(write_handoff, "_now_iso", lambda: _FROZEN_TIMESTAMP)
37
-
38
-
39
- def test_resolve_handoff_dir_joins_run_name_under_base(
40
- tmp_path: Path, monkeypatch: pytest.MonkeyPatch
41
- ) -> None:
42
- """resolve_handoff_dir places the run's directory under the durable base."""
43
- _point_base_dir_at(monkeypatch, tmp_path)
44
- resolved = write_handoff.resolve_handoff_dir("bugteam-pr-4")
45
- assert resolved == tmp_path / "bugteam-pr-4"
46
-
47
-
48
- def test_handoff_base_dir_lives_under_home_runtime_pr_loop(
49
- tmp_path: Path, monkeypatch: pytest.MonkeyPatch
50
- ) -> None:
51
- """The durable base sits under the user home, not the OS temp directory."""
52
- monkeypatch.setenv("USERPROFILE", str(tmp_path))
53
- monkeypatch.setenv("HOME", str(tmp_path))
54
- base = write_handoff._handoff_base_dir()
55
- assert base == tmp_path / ".claude" / "runtime" / "pr-loop"
56
-
57
-
58
- def test_write_handoff_records_resume_command_and_phase(
59
- tmp_path: Path, monkeypatch: pytest.MonkeyPatch
60
- ) -> None:
61
- """write_handoff writes handoff.json and HANDOFF.md carrying the resume
62
- command, phase, run id, completed steps, and a timestamp."""
63
- _point_base_dir_at(monkeypatch, tmp_path)
64
- handoff_dir = write_handoff.write_handoff(
65
- pr_number=4,
66
- head_ref="feat/pr-loop-durable-handoff",
67
- phase="tick",
68
- resume_command="claude --resume /pr-converge",
69
- run_id="wf_abc123",
70
- all_completed_steps=["preflight", "audit"],
71
- note="Copilot wait-gate still open.",
72
- )
73
- assert handoff_dir == tmp_path / "bugteam-pr-4"
74
-
75
- payload = json.loads((handoff_dir / "handoff.json").read_text(encoding="utf-8"))
76
- assert payload["resume_command"] == "claude --resume /pr-converge"
77
- assert payload["phase"] == "tick"
78
- assert payload["run_id"] == "wf_abc123"
79
- assert payload["completed_steps"] == ["preflight", "audit"]
80
- assert payload["timestamp"] == _FROZEN_TIMESTAMP
81
-
82
- markdown = (handoff_dir / "HANDOFF.md").read_text(encoding="utf-8")
83
- assert "claude --resume /pr-converge" in markdown
84
- assert "preflight" in markdown
85
- assert "Copilot wait-gate still open." in markdown
86
-
87
-
88
- def test_write_handoff_copies_state_file_when_given(
89
- tmp_path: Path, monkeypatch: pytest.MonkeyPatch
90
- ) -> None:
91
- """A supplied --state-file is copied to state-copy.json and the copy path is
92
- recorded in handoff.json."""
93
- _point_base_dir_at(monkeypatch, tmp_path)
94
- source_state = tmp_path / "loop-state.json"
95
- source_state.write_text('{"loop_count": 3}', encoding="utf-8")
96
-
97
- handoff_dir = write_handoff.write_handoff(
98
- pr_number=4,
99
- head_ref="feat/branch",
100
- phase="teardown",
101
- resume_command="claude --resume /autoconverge",
102
- state_file=source_state,
103
- )
104
-
105
- state_copy = handoff_dir / "state-copy.json"
106
- assert json.loads(state_copy.read_text(encoding="utf-8")) == {"loop_count": 3}
107
- payload = json.loads((handoff_dir / "handoff.json").read_text(encoding="utf-8"))
108
- assert payload["state_file"] == state_copy.as_posix()
109
-
110
-
111
- def test_write_handoff_omits_state_copy_when_absent(
112
- tmp_path: Path, monkeypatch: pytest.MonkeyPatch
113
- ) -> None:
114
- """With no --state-file, no state-copy.json is written and state_file is null."""
115
- _point_base_dir_at(monkeypatch, tmp_path)
116
- handoff_dir = write_handoff.write_handoff(
117
- pr_number=4,
118
- head_ref="feat/branch",
119
- phase="tick",
120
- resume_command="claude --resume /pr-converge",
121
- )
122
- assert not (handoff_dir / "state-copy.json").exists()
123
- payload = json.loads((handoff_dir / "handoff.json").read_text(encoding="utf-8"))
124
- assert payload["state_file"] is None
125
-
126
-
127
- def test_parse_arguments_reads_completed_steps_value() -> None:
128
- """The CLI captures the raw comma-separated --completed-steps value."""
129
- arguments = write_handoff.parse_arguments(
130
- [
131
- "--pr-number",
132
- "4",
133
- "--head-ref",
134
- "feat/branch",
135
- "--phase",
136
- "tick",
137
- "--resume-command",
138
- "claude --resume /pr-converge",
139
- "--completed-steps",
140
- "preflight,audit,fix",
141
- ]
142
- )
143
- assert arguments.completed_steps == "preflight,audit,fix"
144
-
145
-
146
- def test_main_writes_handoff_and_prints_dir(
147
- tmp_path: Path,
148
- monkeypatch: pytest.MonkeyPatch,
149
- capsys: pytest.CaptureFixture[str],
150
- ) -> None:
151
- """main writes the handoff files and prints the durable directory path."""
152
- _point_base_dir_at(monkeypatch, tmp_path)
153
- exit_code = write_handoff.main(
154
- [
155
- "--pr-number",
156
- "4",
157
- "--head-ref",
158
- "feat/branch",
159
- "--phase",
160
- "tick",
161
- "--resume-command",
162
- "claude --resume /pr-converge",
163
- "--completed-steps",
164
- "preflight,audit",
165
- ]
166
- )
167
- assert exit_code == 0
168
- printed = capsys.readouterr().out.strip()
169
- assert "\\" not in printed
170
- assert printed.endswith("bugteam-pr-4")
171
- payload = json.loads(
172
- (tmp_path / "bugteam-pr-4" / "handoff.json").read_text(encoding="utf-8")
173
- )
174
- assert payload["completed_steps"] == ["preflight", "audit"]
175
-
176
-
177
- def test_main_returns_one_on_non_utf8_state_file(
178
- tmp_path: Path,
179
- monkeypatch: pytest.MonkeyPatch,
180
- capsys: pytest.CaptureFixture[str],
181
- ) -> None:
182
- """main exits 1 rather than crashing when --state-file holds non-UTF-8 bytes."""
183
- _point_base_dir_at(monkeypatch, tmp_path)
184
- bad_state = tmp_path / "loop-state.json"
185
- bad_state.write_bytes(b"\xff\xfe not valid utf-8")
186
- exit_code = write_handoff.main(
187
- [
188
- "--pr-number",
189
- "4",
190
- "--head-ref",
191
- "feat/branch",
192
- "--phase",
193
- "teardown",
194
- "--resume-command",
195
- "claude --resume /autoconverge",
196
- "--state-file",
197
- str(bad_state),
198
- ]
199
- )
200
- assert exit_code == 1
201
- assert "write_handoff failed" in capsys.readouterr().err
@@ -1,182 +0,0 @@
1
- """Validate Shape A/B contract and write <bugteam_audit> XML at the canonical path.
2
-
3
- Usage:
4
- python scripts/write_audit_outcomes.py --pr-number 422 --loop 3 --review-url <URL> --findings-json <PATH> --worktree-path <PATH>
5
- """
6
-
7
- from __future__ import annotations
8
-
9
- import argparse
10
- import json
11
- import sys
12
- from pathlib import Path
13
- from xml.etree.ElementTree import Element, SubElement
14
-
15
- _self_dir = Path(__file__).resolve().parent
16
- if str(_self_dir) not in sys.path:
17
- sys.path.insert(0, str(_self_dir))
18
-
19
- from _cli_utils import require_file
20
- from _path_resolver import outcome_xml_path
21
- from _xml_utils import emit_pretty_xml
22
- from skills_pr_loop_constants.path_resolver_constants import ALL_FINDING_BODY_ELEMENT_KEYS
23
-
24
-
25
- def build_audit_xml(
26
- *,
27
- pr_number: int,
28
- loop: int,
29
- review_url: str,
30
- findings_json_path: Path,
31
- ) -> Element:
32
- """Build the <bugteam_audit> XML element from findings data.
33
-
34
- Args:
35
- pr_number: Pull request number.
36
- loop: Loop iteration number.
37
- review_url: URL of the GitHub review.
38
- findings_json_path: Path to the findings JSON file.
39
-
40
- Returns:
41
- Root <bugteam_audit> element.
42
-
43
- Raises:
44
- SystemExit: When findings-json is not a JSON array of objects.
45
- """
46
- findings_data = json.loads(findings_json_path.read_text(encoding="utf-8"))
47
- if not isinstance(findings_data, list):
48
- print("findings-json must contain a JSON array", file=sys.stderr)
49
- raise SystemExit(1)
50
- for each_index, each_finding in enumerate(findings_data):
51
- if not isinstance(each_finding, dict):
52
- print(
53
- f"findings-json[{each_index}]: each entry must be a JSON object",
54
- file=sys.stderr,
55
- )
56
- raise SystemExit(1)
57
- root = Element("bugteam_audit", {
58
- "pr": str(pr_number),
59
- "loop": str(loop),
60
- "review_url": review_url,
61
- })
62
-
63
- findings_elem = SubElement(root, "findings")
64
- _populate_findings(findings_elem, findings_data)
65
- return root
66
-
67
-
68
- def _populate_findings(parent: Element, findings_data: list[dict[str, object]]) -> None:
69
- """Populate <finding> elements from a validated list of finding dicts.
70
-
71
- Scalar finding fields become XML attributes on `<finding>`; the
72
- body fields named in `ALL_FINDING_BODY_ELEMENT_KEYS` (defined in
73
- `packages/claude-dev-env/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py`
74
- and currently `("title", "excerpt", "description")`) become child elements.
75
- Nested dicts or lists in scalar slots are flattened to string form
76
- so attribute serialization stays well-defined.
77
-
78
- Args:
79
- parent: Parent XML element (typically `<findings>`).
80
- findings_data: Validated list of finding dicts (caller must have
81
- confirmed each entry is a dict via the build_audit_xml gate).
82
- """
83
- all_finding_body_element_keys = ALL_FINDING_BODY_ELEMENT_KEYS
84
- for each_finding in findings_data:
85
- finding_elem = SubElement(parent, "finding")
86
- for each_key, each_field_detail in each_finding.items():
87
- field_text = (
88
- str(each_field_detail) if each_field_detail is not None else ""
89
- )
90
- if each_key in all_finding_body_element_keys:
91
- child = SubElement(finding_elem, each_key)
92
- child.text = field_text
93
- else:
94
- finding_elem.set(each_key, field_text)
95
-
96
-
97
- def write_audit_xml(
98
- *,
99
- pr_number: int,
100
- loop: int,
101
- review_url: str,
102
- findings_json_path: Path,
103
- worktree_path: Path,
104
- ) -> Path:
105
- """Write the <bugteam_audit> XML to the canonical outcome path.
106
-
107
- Args:
108
- pr_number: Pull request number.
109
- loop: Loop iteration number.
110
- review_url: URL of the GitHub review.
111
- findings_json_path: Path to the findings JSON file.
112
- worktree_path: Path to the git worktree.
113
-
114
- Returns:
115
- Path to the written XML file.
116
- """
117
- root = build_audit_xml(
118
- pr_number=pr_number,
119
- loop=loop,
120
- review_url=review_url,
121
- findings_json_path=findings_json_path,
122
- )
123
- xml_string = emit_pretty_xml(root)
124
-
125
- output_path = outcome_xml_path(worktree_path, pr_number, loop)
126
- output_path.write_text(xml_string, encoding="utf-8")
127
- return output_path
128
-
129
-
130
- def parse_arguments(all_argv: list[str]) -> argparse.Namespace:
131
- """Parse command-line arguments.
132
-
133
- Args:
134
- all_argv: Command-line argument list.
135
-
136
- Returns:
137
- Parsed namespace with pr_number, loop, review_url, findings_json, and worktree_path.
138
- """
139
- parser = argparse.ArgumentParser(description=__doc__)
140
- parser.add_argument("--pr-number", type=int, required=True)
141
- parser.add_argument("--loop", type=int, required=True)
142
- parser.add_argument("--review-url", required=True)
143
- parser.add_argument("--findings-json", type=Path, required=True)
144
- parser.add_argument("--worktree-path", type=Path, required=True)
145
- return parser.parse_args(all_argv)
146
-
147
-
148
- def main(all_arguments: list[str]) -> int:
149
- """Entry point: write <bugteam_audit> XML at the canonical path.
150
-
151
- Args:
152
- all_arguments: Command-line arguments.
153
-
154
- Returns:
155
- 0 on success, 1 on validation or write failure.
156
- """
157
- arguments = parse_arguments(all_arguments)
158
- findings_path = getattr(arguments, "findings_json")
159
-
160
- early_exit = require_file(findings_path, "findings-json")
161
- if early_exit is not None:
162
- return early_exit
163
-
164
- try:
165
- output_path = write_audit_xml(
166
- pr_number=getattr(arguments, "pr_number"),
167
- loop=arguments.loop,
168
- review_url=getattr(arguments, "review_url"),
169
- findings_json_path=findings_path,
170
- worktree_path=getattr(arguments, "worktree_path"),
171
- )
172
- except SystemExit:
173
- return 1
174
- except (json.JSONDecodeError, OSError) as exc:
175
- print(f"write_audit_xml failed: {exc}", file=sys.stderr)
176
- return 1
177
- print(output_path)
178
- return 0
179
-
180
-
181
- if __name__ == "__main__":
182
- raise SystemExit(main(sys.argv[1:]))
@@ -1,206 +0,0 @@
1
- """Validate status enum values and write <bugteam_fix> XML at the canonical path.
2
-
3
- Status enum (canonical source: `ALL_VALID_FIX_STATUSES` in
4
- `packages/claude-dev-env/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py`):
5
- fixed | could_not_address | hook_blocked | unverified_fixed.
6
-
7
- Each outcome's scalar fields become XML attributes on `<outcome>`; the
8
- body fields named in `ALL_FIX_OUTCOME_BODY_ELEMENT_KEYS` (currently
9
- `("reason", "hook_output")`) become child elements.
10
-
11
- Usage:
12
- python scripts/write_fix_outcomes.py --pr-number 422 --loop 3 --commit-sha abc1234 --outcomes-json <PATH> --worktree-path <PATH>
13
- """
14
-
15
- from __future__ import annotations
16
-
17
- import argparse
18
- import json
19
- import sys
20
- from pathlib import Path
21
- from xml.etree.ElementTree import Element, SubElement
22
-
23
- _self_dir = Path(__file__).resolve().parent
24
- if str(_self_dir) not in sys.path:
25
- sys.path.insert(0, str(_self_dir))
26
-
27
- from _cli_utils import require_file
28
- from _path_resolver import fix_outcome_xml_path
29
- from _xml_utils import emit_pretty_xml
30
- from skills_pr_loop_constants.path_resolver_constants import (
31
- ALL_FIX_OUTCOME_BODY_ELEMENT_KEYS,
32
- ALL_VALID_FIX_STATUSES,
33
- )
34
-
35
-
36
- def validate_fix_statuses(all_outcomes: list[dict[str, object]]) -> list[str]:
37
- """Validate that every outcome entry has a recognized status.
38
-
39
- Args:
40
- all_outcomes: List of outcome dicts, each expected to have a 'status' key.
41
-
42
- Returns:
43
- List of validation error messages (empty when valid).
44
- """
45
- valid_statuses = ALL_VALID_FIX_STATUSES
46
- errors: list[str] = []
47
- for each_index, each_outcome in enumerate(all_outcomes):
48
- status = each_outcome.get("status")
49
- if not isinstance(status, str):
50
- errors.append(f"outcome[{each_index}]: status missing or not a string")
51
- continue
52
- if status not in valid_statuses:
53
- errors.append(
54
- f"outcome[{each_index}]: invalid status '{status}' "
55
- f"(expected one of {sorted(valid_statuses)})"
56
- )
57
- return errors
58
-
59
-
60
- def build_fix_xml(
61
- *,
62
- pr_number: int,
63
- loop: int,
64
- commit_sha: str,
65
- outcomes_json_path: Path,
66
- ) -> Element:
67
- """Build the <bugteam_fix> XML element from outcomes data.
68
-
69
- Args:
70
- pr_number: Pull request number.
71
- loop: Loop iteration number.
72
- commit_sha: Commit SHA of the fix commit.
73
- outcomes_json_path: Path to the outcomes JSON file.
74
-
75
- Returns:
76
- Root <bugteam_fix> element.
77
-
78
- Raises:
79
- SystemExit: When outcomes-json is not a JSON array of objects, or
80
- when status validation fails.
81
- """
82
- outcomes_data = json.loads(outcomes_json_path.read_text(encoding="utf-8"))
83
- if not isinstance(outcomes_data, list):
84
- print("outcomes-json must contain a JSON array", file=sys.stderr)
85
- raise SystemExit(1)
86
- for each_index, each_entry in enumerate(outcomes_data):
87
- if not isinstance(each_entry, dict):
88
- print(
89
- f"outcomes-json[{each_index}]: each entry must be a JSON object",
90
- file=sys.stderr,
91
- )
92
- raise SystemExit(1)
93
- errors = validate_fix_statuses(outcomes_data)
94
- if errors:
95
- for each_error in errors:
96
- print(each_error, file=sys.stderr)
97
- raise SystemExit(1)
98
-
99
- root = Element("bugteam_fix", {
100
- "pr": str(pr_number),
101
- "loop": str(loop),
102
- "commit_sha": commit_sha,
103
- })
104
-
105
- all_fix_outcome_body_element_keys = ALL_FIX_OUTCOME_BODY_ELEMENT_KEYS
106
- outcomes_elem = SubElement(root, "outcomes")
107
- for each_outcome in outcomes_data:
108
- outcome_elem = SubElement(outcomes_elem, "outcome")
109
- for each_key, each_field_detail in each_outcome.items():
110
- field_text = (
111
- str(each_field_detail) if each_field_detail is not None else ""
112
- )
113
- if each_key in all_fix_outcome_body_element_keys:
114
- child = SubElement(outcome_elem, each_key)
115
- child.text = field_text
116
- else:
117
- outcome_elem.set(each_key, field_text)
118
- return root
119
-
120
-
121
- def write_fix_xml(
122
- *,
123
- pr_number: int,
124
- loop: int,
125
- commit_sha: str,
126
- outcomes_json_path: Path,
127
- worktree_path: Path,
128
- ) -> Path:
129
- """Write the <bugteam_fix> XML to the canonical outcome path.
130
-
131
- Args:
132
- pr_number: Pull request number.
133
- loop: Loop iteration number.
134
- commit_sha: Commit SHA of the fix commit.
135
- outcomes_json_path: Path to the outcomes JSON file.
136
- worktree_path: Path to the git worktree.
137
-
138
- Returns:
139
- Path to the written XML file.
140
- """
141
- root = build_fix_xml(
142
- pr_number=pr_number,
143
- loop=loop,
144
- commit_sha=commit_sha,
145
- outcomes_json_path=outcomes_json_path,
146
- )
147
- xml_string = emit_pretty_xml(root)
148
-
149
- output_path = fix_outcome_xml_path(worktree_path, pr_number, loop)
150
- output_path.write_text(xml_string, encoding="utf-8")
151
- return output_path
152
-
153
-
154
- def parse_arguments(all_argv: list[str]) -> argparse.Namespace:
155
- """Parse command-line arguments.
156
-
157
- Args:
158
- all_argv: Command-line argument list.
159
-
160
- Returns:
161
- Parsed namespace with pr_number, loop, commit_sha, outcomes_json, and worktree_path.
162
- """
163
- parser = argparse.ArgumentParser(description=__doc__)
164
- parser.add_argument("--pr-number", type=int, required=True)
165
- parser.add_argument("--loop", type=int, required=True)
166
- parser.add_argument("--commit-sha", required=True)
167
- parser.add_argument("--outcomes-json", type=Path, required=True)
168
- parser.add_argument("--worktree-path", type=Path, required=True)
169
- return parser.parse_args(all_argv)
170
-
171
-
172
- def main(all_arguments: list[str]) -> int:
173
- """Entry point: write <bugteam_fix> XML at the canonical path.
174
-
175
- Args:
176
- all_arguments: Command-line arguments.
177
-
178
- Returns:
179
- 0 on success, 1 on validation or write failure.
180
- """
181
- arguments = parse_arguments(all_arguments)
182
- outcomes_path = getattr(arguments, "outcomes_json")
183
-
184
- early_exit = require_file(outcomes_path, "outcomes-json")
185
- if early_exit is not None:
186
- return early_exit
187
-
188
- try:
189
- output_path = write_fix_xml(
190
- pr_number=getattr(arguments, "pr_number"),
191
- loop=arguments.loop,
192
- commit_sha=getattr(arguments, "commit_sha"),
193
- outcomes_json_path=outcomes_path,
194
- worktree_path=getattr(arguments, "worktree_path"),
195
- )
196
- except SystemExit:
197
- return 1
198
- except (json.JSONDecodeError, OSError) as exc:
199
- print(f"write_fix_xml failed: {exc}", file=sys.stderr)
200
- return 1
201
- print(output_path)
202
- return 0
203
-
204
-
205
- if __name__ == "__main__":
206
- raise SystemExit(main(sys.argv[1:]))