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,287 +0,0 @@
1
- """Tests for preflight_worktree against real git working trees."""
2
-
3
- from __future__ import annotations
4
-
5
- import importlib.util
6
- import subprocess
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_preflight() -> ModuleType:
19
- module_path = _SCRIPTS_DIR / "preflight_worktree.py"
20
- spec = importlib.util.spec_from_file_location("preflight_worktree", module_path)
21
- assert spec is not None
22
- assert spec.loader is not None
23
- module = importlib.util.module_from_spec(spec)
24
- sys.modules["preflight_worktree"] = module
25
- spec.loader.exec_module(module)
26
- return module
27
-
28
-
29
- preflight = _load_preflight()
30
-
31
- GIT_TIMEOUT = 30
32
- CLAUDE_REMOTE = "https://github.com/jl-cmd/claude-dev-env.git"
33
- GIT_CEILING_DIRECTORIES = "GIT_CEILING_DIRECTORIES"
34
-
35
-
36
- @pytest.fixture(autouse=True)
37
- def _isolate_git_from_ancestor_repos(
38
- tmp_path: Path, monkeypatch: pytest.MonkeyPatch
39
- ) -> None:
40
- monkeypatch.setenv(GIT_CEILING_DIRECTORIES, str(tmp_path))
41
-
42
-
43
- def _git(repo_dir: Path, *args: str) -> None:
44
- subprocess.run(
45
- ["git", "-C", str(repo_dir), *args],
46
- check=True,
47
- capture_output=True,
48
- text=True,
49
- timeout=GIT_TIMEOUT,
50
- )
51
-
52
-
53
- def _init_repo(repo_dir: Path, origin_url: str | None) -> Path:
54
- repo_dir.mkdir(parents=True, exist_ok=True)
55
- subprocess.run(
56
- ["git", "init", "-q", str(repo_dir)],
57
- check=True,
58
- capture_output=True,
59
- text=True,
60
- timeout=GIT_TIMEOUT,
61
- )
62
- if origin_url is not None:
63
- _git(repo_dir, "remote", "add", "origin", origin_url)
64
- return repo_dir
65
-
66
-
67
- @pytest.mark.parametrize(
68
- ("remote_url", "expected_owner", "expected_repo"),
69
- [
70
- (
71
- "https://github.com/jl-cmd/claude-dev-env.git",
72
- "jl-cmd",
73
- "claude-dev-env",
74
- ),
75
- (
76
- "https://github.com/jl-cmd/claude-dev-env",
77
- "jl-cmd",
78
- "claude-dev-env",
79
- ),
80
- ("git@github.com:Example/llm-settings.git", "example", "llm-settings"),
81
- (
82
- "ssh://git@github.com/jl-cmd/Claude-Dev-Env",
83
- "jl-cmd",
84
- "claude-dev-env",
85
- ),
86
- ("https://github.com/jl-cmd/repo/", "jl-cmd", "repo"),
87
- ],
88
- )
89
- def test_parse_repo_identity_accepts_every_github_remote_form(
90
- remote_url: str, expected_owner: str, expected_repo: str
91
- ) -> None:
92
- identity = preflight.parse_repo_identity(remote_url)
93
- assert identity is not None
94
- assert identity.owner == expected_owner
95
- assert identity.repo == expected_repo
96
-
97
-
98
- @pytest.mark.parametrize(
99
- "remote_url",
100
- ["https://gitlab.com/foo/bar.git", "", "not-a-url"],
101
- )
102
- def test_parse_repo_identity_rejects_non_github_remotes(remote_url: str) -> None:
103
- assert preflight.parse_repo_identity(remote_url) is None
104
-
105
-
106
- def test_is_inside_work_tree_true_in_git_repo(tmp_path: Path) -> None:
107
- repo_dir = _init_repo(tmp_path / "session", None)
108
- assert preflight.is_inside_work_tree(repo_dir) is True
109
-
110
-
111
- def test_is_inside_work_tree_false_in_plain_directory(tmp_path: Path) -> None:
112
- plain_dir = tmp_path / "home"
113
- plain_dir.mkdir()
114
- assert preflight.is_inside_work_tree(plain_dir) is False
115
-
116
-
117
- def test_worktree_machinery_is_healthy_true_in_git_repo(tmp_path: Path) -> None:
118
- repo_dir = _init_repo(tmp_path / "session", None)
119
- assert preflight.worktree_machinery_is_healthy(repo_dir) is True
120
-
121
-
122
- def test_worktree_machinery_is_healthy_false_in_plain_directory(
123
- tmp_path: Path,
124
- ) -> None:
125
- plain_dir = tmp_path / "home"
126
- plain_dir.mkdir()
127
- assert preflight.worktree_machinery_is_healthy(plain_dir) is False
128
-
129
-
130
- def test_classify_same_repo_when_origin_matches_pr(tmp_path: Path) -> None:
131
- repo_dir = _init_repo(tmp_path / "session", CLAUDE_REMOTE)
132
- pr_identity = preflight.RepoIdentity("jl-cmd", "claude-dev-env")
133
- verdict = preflight.classify_environment(repo_dir, pr_identity)
134
- assert verdict.outcome == preflight.OUTCOME_SAME_REPO
135
- assert verdict.cwd_identity == pr_identity
136
- assert verdict.has_healthy_worktree_machinery is True
137
-
138
-
139
- def test_classify_different_repo_when_origin_is_another_github_repo(
140
- tmp_path: Path,
141
- ) -> None:
142
- repo_dir = _init_repo(
143
- tmp_path / "session", "https://github.com/example/llm-settings.git"
144
- )
145
- pr_identity = preflight.RepoIdentity("jl-cmd", "claude-dev-env")
146
- verdict = preflight.classify_environment(repo_dir, pr_identity)
147
- assert verdict.outcome == preflight.OUTCOME_DIFFERENT_REPO
148
- assert verdict.cwd_identity == preflight.RepoIdentity("example", "llm-settings")
149
-
150
-
151
- def test_classify_different_repo_when_origin_is_non_github(tmp_path: Path) -> None:
152
- repo_dir = _init_repo(tmp_path / "session", "https://gitlab.com/foo/bar.git")
153
- pr_identity = preflight.RepoIdentity("jl-cmd", "claude-dev-env")
154
- verdict = preflight.classify_environment(repo_dir, pr_identity)
155
- assert verdict.outcome == preflight.OUTCOME_DIFFERENT_REPO
156
- assert verdict.cwd_identity is None
157
-
158
-
159
- def test_classify_re_rooted_when_origin_is_absent(tmp_path: Path) -> None:
160
- repo_dir = _init_repo(tmp_path / "session", None)
161
- pr_identity = preflight.RepoIdentity("jl-cmd", "claude-dev-env")
162
- verdict = preflight.classify_environment(repo_dir, pr_identity)
163
- assert verdict.outcome == preflight.OUTCOME_RE_ROOTED
164
-
165
-
166
- def test_classify_re_rooted_when_directory_is_not_a_work_tree(
167
- tmp_path: Path,
168
- ) -> None:
169
- plain_dir = tmp_path / "home"
170
- plain_dir.mkdir()
171
- pr_identity = preflight.RepoIdentity("jl-cmd", "claude-dev-env")
172
- verdict = preflight.classify_environment(plain_dir, pr_identity)
173
- assert verdict.outcome == preflight.OUTCOME_RE_ROOTED
174
- assert verdict.has_healthy_worktree_machinery is False
175
-
176
-
177
- @pytest.mark.parametrize(
178
- ("outcome", "is_healthy", "mode", "expected_exit"),
179
- [
180
- ("same_repo", True, "strict", 0),
181
- ("same_repo", True, "classify", 0),
182
- ("same_repo", False, "strict", 1),
183
- ("same_repo", False, "classify", 1),
184
- ("different_repo", True, "strict", 1),
185
- ("different_repo", True, "classify", 0),
186
- ("re_rooted", False, "strict", 1),
187
- ("re_rooted", False, "classify", 1),
188
- ],
189
- )
190
- def test_decide_exit_code_matrix(
191
- outcome: str, is_healthy: bool, mode: str, expected_exit: int
192
- ) -> None:
193
- verdict = preflight.PreflightVerdict(
194
- outcome=outcome,
195
- cwd_identity=None,
196
- has_healthy_worktree_machinery=is_healthy,
197
- )
198
- assert preflight.decide_exit_code(verdict, mode) == expected_exit
199
-
200
-
201
- def test_build_report_lines_marks_outcome_and_routes_cross_repo() -> None:
202
- verdict = preflight.PreflightVerdict(
203
- outcome=preflight.OUTCOME_DIFFERENT_REPO,
204
- cwd_identity=preflight.RepoIdentity("example", "llm-settings"),
205
- has_healthy_worktree_machinery=True,
206
- )
207
- pr_identity = preflight.RepoIdentity("jl-cmd", "claude-dev-env")
208
- classify_lines = preflight.build_report_lines(
209
- verdict, "classify", Path("/tmp/x"), pr_identity
210
- )
211
- assert classify_lines[0] == "PREFLIGHT_OUTCOME=different_repo"
212
- assert any("ROUTE" in line for line in classify_lines)
213
- strict_lines = preflight.build_report_lines(
214
- verdict, "strict", Path("/tmp/x"), pr_identity
215
- )
216
- assert any("ABORT" in line for line in strict_lines)
217
-
218
-
219
- def test_build_report_lines_aborts_on_broken_worktree_machinery() -> None:
220
- verdict = preflight.PreflightVerdict(
221
- outcome=preflight.OUTCOME_SAME_REPO,
222
- cwd_identity=preflight.RepoIdentity("jl-cmd", "claude-dev-env"),
223
- has_healthy_worktree_machinery=False,
224
- )
225
- pr_identity = preflight.RepoIdentity("jl-cmd", "claude-dev-env")
226
- lines = preflight.build_report_lines(verdict, "strict", Path("/tmp/x"), pr_identity)
227
- assert lines[0] == "PREFLIGHT_OUTCOME=same_repo"
228
- assert any("git worktree prune" in line for line in lines)
229
-
230
-
231
- def test_main_strict_passes_in_matching_repo(
232
- tmp_path: Path, monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
233
- ) -> None:
234
- repo_dir = _init_repo(tmp_path / "session", CLAUDE_REMOTE)
235
- monkeypatch.chdir(repo_dir)
236
- exit_code = preflight.main(
237
- ["--owner", "jl-cmd", "--repo", "claude-dev-env", "--mode", "strict"]
238
- )
239
- captured = capsys.readouterr()
240
- assert exit_code == preflight.EXIT_PREFLIGHT_OK
241
- assert "PREFLIGHT_OUTCOME=same_repo" in captured.out
242
-
243
-
244
- def test_main_strict_aborts_when_session_rooted_in_other_repo(
245
- tmp_path: Path, monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
246
- ) -> None:
247
- repo_dir = _init_repo(
248
- tmp_path / "session", "https://github.com/example/llm-settings.git"
249
- )
250
- monkeypatch.chdir(repo_dir)
251
- exit_code = preflight.main(
252
- ["--owner", "jl-cmd", "--repo", "claude-dev-env", "--mode", "strict"]
253
- )
254
- captured = capsys.readouterr()
255
- assert exit_code == preflight.EXIT_PREFLIGHT_ABORT
256
- assert "PREFLIGHT_OUTCOME=different_repo" in captured.out
257
- assert "ABORT" in captured.out
258
-
259
-
260
- def test_main_classify_routes_cross_repo_without_abort(
261
- tmp_path: Path, monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
262
- ) -> None:
263
- repo_dir = _init_repo(
264
- tmp_path / "session", "https://github.com/example/llm-settings.git"
265
- )
266
- monkeypatch.chdir(repo_dir)
267
- exit_code = preflight.main(
268
- ["--owner", "jl-cmd", "--repo", "claude-dev-env", "--mode", "classify"]
269
- )
270
- captured = capsys.readouterr()
271
- assert exit_code == preflight.EXIT_PREFLIGHT_OK
272
- assert "PREFLIGHT_OUTCOME=different_repo" in captured.out
273
- assert "ROUTE" in captured.out
274
-
275
-
276
- def test_main_classify_aborts_when_re_rooted(
277
- tmp_path: Path, monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
278
- ) -> None:
279
- plain_dir = tmp_path / "home"
280
- plain_dir.mkdir()
281
- monkeypatch.chdir(plain_dir)
282
- exit_code = preflight.main(
283
- ["--owner", "jl-cmd", "--repo", "claude-dev-env", "--mode", "classify"]
284
- )
285
- captured = capsys.readouterr()
286
- assert exit_code == preflight.EXIT_PREFLIGHT_ABORT
287
- assert "PREFLIGHT_OUTCOME=re_rooted" in captured.out
@@ -1,207 +0,0 @@
1
- """Tests for select_converge_pacer — host tool surface → pacer mapping."""
2
-
3
- from __future__ import annotations
4
-
5
- import json
6
- import subprocess
7
- import sys
8
- from pathlib import Path
9
-
10
- import pytest
11
-
12
- _SCRIPTS_DIR = Path(__file__).resolve().parent
13
- if str(_SCRIPTS_DIR) not in sys.path:
14
- sys.path.insert(0, str(_SCRIPTS_DIR))
15
-
16
- import select_converge_pacer as pacer_module # noqa: E402
17
- from skills_pr_loop_constants.pacer_constants import ( # noqa: E402
18
- CLI_HAS_SCHEDULE_WAKEUP_FLAG,
19
- CLI_HAS_WORKFLOW_FLAG,
20
- CLI_SKILL_FLAG,
21
- ENTRY_SKILL_AUTOCONVERGE,
22
- ENTRY_SKILL_PR_CONVERGE,
23
- EXIT_SUCCESS,
24
- EXIT_USAGE_ERROR,
25
- PACER_PORTABLE,
26
- PACER_SCHEDULE_WAKEUP,
27
- PACER_WORKFLOW,
28
- RESULT_KEY_ENTRY_SKILL,
29
- RESULT_KEY_HAS_SCHEDULE_WAKEUP,
30
- RESULT_KEY_HAS_WORKFLOW,
31
- RESULT_KEY_PACER,
32
- )
33
-
34
- SCRIPT_PATH = _SCRIPTS_DIR / "select_converge_pacer.py"
35
-
36
-
37
- def test_autoconverge_with_workflow_selects_workflow() -> None:
38
- selection = pacer_module.select_converge_pacer(
39
- entry_skill=ENTRY_SKILL_AUTOCONVERGE,
40
- has_workflow=True,
41
- has_schedule_wakeup=False,
42
- )
43
- assert selection.pacer == PACER_WORKFLOW
44
- assert selection.entry_skill == ENTRY_SKILL_AUTOCONVERGE
45
-
46
-
47
- def test_autoconverge_without_workflow_selects_portable() -> None:
48
- selection = pacer_module.select_converge_pacer(
49
- entry_skill=ENTRY_SKILL_AUTOCONVERGE,
50
- has_workflow=False,
51
- has_schedule_wakeup=True,
52
- )
53
- assert selection.pacer == PACER_PORTABLE
54
-
55
-
56
- def test_pr_converge_with_schedule_wakeup_selects_schedule_wakeup() -> None:
57
- selection = pacer_module.select_converge_pacer(
58
- entry_skill=ENTRY_SKILL_PR_CONVERGE,
59
- has_workflow=False,
60
- has_schedule_wakeup=True,
61
- )
62
- assert selection.pacer == PACER_SCHEDULE_WAKEUP
63
- assert selection.entry_skill == ENTRY_SKILL_PR_CONVERGE
64
-
65
-
66
- def test_pr_converge_without_schedule_wakeup_selects_portable() -> None:
67
- selection = pacer_module.select_converge_pacer(
68
- entry_skill=ENTRY_SKILL_PR_CONVERGE,
69
- has_workflow=True,
70
- has_schedule_wakeup=False,
71
- )
72
- assert selection.pacer == PACER_PORTABLE
73
-
74
-
75
- def test_third_party_surface_selects_portable_for_both_entries() -> None:
76
- for each_skill in (ENTRY_SKILL_AUTOCONVERGE, ENTRY_SKILL_PR_CONVERGE):
77
- selection = pacer_module.select_converge_pacer(
78
- entry_skill=each_skill,
79
- has_workflow=False,
80
- has_schedule_wakeup=False,
81
- )
82
- assert selection.pacer == PACER_PORTABLE, each_skill
83
-
84
-
85
- def test_unknown_entry_skill_raises() -> None:
86
- with pytest.raises(ValueError, match="entry skill must be one of"):
87
- pacer_module.select_converge_pacer(
88
- entry_skill="bugteam",
89
- has_workflow=False,
90
- has_schedule_wakeup=False,
91
- )
92
-
93
-
94
- def test_parse_bool_flag_accepts_common_tokens() -> None:
95
- assert pacer_module.parse_bool_flag("1") is True
96
- assert pacer_module.parse_bool_flag("true") is True
97
- assert pacer_module.parse_bool_flag("YES") is True
98
- assert pacer_module.parse_bool_flag("0") is False
99
- assert pacer_module.parse_bool_flag("false") is False
100
- assert pacer_module.parse_bool_flag("OFF") is False
101
-
102
-
103
- def test_parse_bool_flag_rejects_unknown_token() -> None:
104
- with pytest.raises(ValueError, match="boolean token"):
105
- pacer_module.parse_bool_flag("maybe")
106
-
107
-
108
- def test_selection_as_json_dict_uses_stable_keys() -> None:
109
- selection = pacer_module.select_converge_pacer(
110
- entry_skill=ENTRY_SKILL_PR_CONVERGE,
111
- has_workflow=False,
112
- has_schedule_wakeup=False,
113
- )
114
- payload = pacer_module.selection_as_json_dict(selection)
115
- assert payload[RESULT_KEY_PACER] == PACER_PORTABLE
116
- assert payload[RESULT_KEY_ENTRY_SKILL] == ENTRY_SKILL_PR_CONVERGE
117
- assert payload[RESULT_KEY_HAS_WORKFLOW] is False
118
- assert payload[RESULT_KEY_HAS_SCHEDULE_WAKEUP] is False
119
-
120
-
121
- def test_cli_prints_json_and_exits_zero() -> None:
122
- completed = subprocess.run(
123
- [
124
- sys.executable,
125
- str(SCRIPT_PATH),
126
- "--skill",
127
- ENTRY_SKILL_AUTOCONVERGE,
128
- "--has-workflow",
129
- "0",
130
- "--has-schedule-wakeup",
131
- "0",
132
- ],
133
- check=False,
134
- capture_output=True,
135
- text=True,
136
- )
137
- assert completed.returncode == EXIT_SUCCESS, completed.stderr
138
- payload = json.loads(completed.stdout)
139
- assert payload[RESULT_KEY_PACER] == PACER_PORTABLE
140
- assert payload[RESULT_KEY_ENTRY_SKILL] == ENTRY_SKILL_AUTOCONVERGE
141
-
142
-
143
- def test_cli_rejects_bad_bool_with_usage_exit() -> None:
144
- completed = subprocess.run(
145
- [
146
- sys.executable,
147
- str(SCRIPT_PATH),
148
- "--skill",
149
- ENTRY_SKILL_PR_CONVERGE,
150
- "--has-workflow",
151
- "nope",
152
- "--has-schedule-wakeup",
153
- "0",
154
- ],
155
- check=False,
156
- capture_output=True,
157
- text=True,
158
- )
159
- assert completed.returncode == EXIT_USAGE_ERROR
160
- assert "boolean token" in completed.stderr
161
-
162
-
163
- def test_main_returns_usage_error_on_value_error(
164
- monkeypatch: pytest.MonkeyPatch,
165
- ) -> None:
166
- def raise_value_error(**_kwargs: object) -> object:
167
- raise ValueError("entry skill must be one of")
168
-
169
- monkeypatch.setattr(
170
- pacer_module, "select_converge_pacer", raise_value_error
171
- )
172
- exit_code = pacer_module.main(
173
- [
174
- "--skill",
175
- ENTRY_SKILL_PR_CONVERGE,
176
- "--has-workflow",
177
- "0",
178
- "--has-schedule-wakeup",
179
- "0",
180
- ]
181
- )
182
- assert exit_code == EXIT_USAGE_ERROR
183
-
184
-
185
- def test_build_argument_parser_requires_skill_and_host_flags() -> None:
186
- parser = pacer_module.build_argument_parser()
187
- all_option_strings = {
188
- each_option
189
- for each_action in parser._actions
190
- for each_option in each_action.option_strings
191
- }
192
- assert CLI_SKILL_FLAG in all_option_strings
193
- assert CLI_HAS_WORKFLOW_FLAG in all_option_strings
194
- assert CLI_HAS_SCHEDULE_WAKEUP_FLAG in all_option_strings
195
- parsed_namespace = parser.parse_args(
196
- [
197
- CLI_SKILL_FLAG,
198
- ENTRY_SKILL_AUTOCONVERGE,
199
- CLI_HAS_WORKFLOW_FLAG,
200
- "1",
201
- CLI_HAS_SCHEDULE_WAKEUP_FLAG,
202
- "0",
203
- ]
204
- )
205
- assert parsed_namespace.skill == ENTRY_SKILL_AUTOCONVERGE
206
- assert parsed_namespace.has_workflow == "1"
207
- assert parsed_namespace.has_schedule_wakeup == "0"
@@ -1,59 +0,0 @@
1
- """Tests for teardown_worktrees.teardown_run consuming the typed workspace."""
2
-
3
- from __future__ import annotations
4
-
5
- import importlib.util
6
- import sys
7
- from pathlib import Path
8
- from types import ModuleType
9
-
10
- _SCRIPTS_DIR = Path(__file__).resolve().parent
11
- if str(_SCRIPTS_DIR) not in sys.path:
12
- sys.path.insert(0, str(_SCRIPTS_DIR))
13
-
14
-
15
- def _load_teardown_module() -> ModuleType:
16
- module_path = _SCRIPTS_DIR / "teardown_worktrees.py"
17
- spec = importlib.util.spec_from_file_location("teardown_worktrees", module_path)
18
- assert spec is not None
19
- assert spec.loader is not None
20
- module = importlib.util.module_from_spec(spec)
21
- spec.loader.exec_module(module)
22
- return module
23
-
24
-
25
- teardown_worktrees = _load_teardown_module()
26
-
27
-
28
- def test_teardown_run_returns_zero_when_no_worktrees_exist(tmp_path: Path) -> None:
29
- """With absent worktrees, teardown_run removes nothing and reports zero,
30
- reading each worktree path from the typed PerPrWorkspace.worktree attribute
31
- rather than a dict lookup."""
32
- run_temp_dir = tmp_path / "run"
33
- run_temp_dir.mkdir()
34
- all_pr_entries: list[dict[str, object]] = [
35
- {"number": 7, "owner": "owner", "repo": "repo"},
36
- ]
37
- removed_count = teardown_worktrees.teardown_run(
38
- run_temp_dir=run_temp_dir,
39
- all_pr_entries=all_pr_entries,
40
- )
41
- assert removed_count == 0
42
- assert not run_temp_dir.exists()
43
-
44
-
45
- def test_teardown_run_skips_entries_without_integer_number(tmp_path: Path) -> None:
46
- """A PR entry whose number is not an integer is skipped before any workspace
47
- resolution, so teardown_run reports zero removals and still clears the run
48
- temp directory."""
49
- run_temp_dir = tmp_path / "run"
50
- run_temp_dir.mkdir()
51
- all_pr_entries: list[dict[str, object]] = [
52
- {"number": "not-an-int", "owner": "owner", "repo": "repo"},
53
- ]
54
- removed_count = teardown_worktrees.teardown_run(
55
- run_temp_dir=run_temp_dir,
56
- all_pr_entries=all_pr_entries,
57
- )
58
- assert removed_count == 0
59
- assert not run_temp_dir.exists()