claude-dev-env 4.2.0 → 7.0.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 (350) 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 +7 -0
  12. package/.agents/skills/pull-request/SKILL.md +216 -0
  13. package/.agents/skills/pull-request/reference/publication-tasks.md +18 -0
  14. package/.agents/skills/pull-request/scripts/github_pr_command_constants/__init__.py +1 -0
  15. package/.agents/skills/pull-request/scripts/github_pr_command_constants/config/__init__.py +1 -0
  16. package/.agents/skills/pull-request/scripts/github_pr_command_constants/config/constants.py +69 -0
  17. package/.agents/skills/pull-request/scripts/pull_request.py +265 -0
  18. package/.agents/skills/pull-request/scripts/recover_legacy_author.py +251 -0
  19. package/.agents/skills/pull-request/scripts/test_github_pr_command_constants.py +58 -0
  20. package/.agents/skills/pull-request/scripts/test_pull_request.py +396 -0
  21. package/.agents/skills/pull-request/scripts/test_recover_legacy_author.py +221 -0
  22. package/.agents/skills/skill-builder/SKILL.md +3 -196
  23. package/.agents/skills/test-runner/SKILL.md +69 -0
  24. package/.agents/skills/test-runner/scripts/preflight_checks.py +365 -0
  25. package/.agents/skills/test-runner/scripts/run_tests.py +316 -0
  26. package/.agents/skills/test-runner/scripts/test_preflight_checks.py +185 -0
  27. package/.agents/skills/test-runner/scripts/test_run_tests.py +281 -0
  28. package/.agents/skills/test-runner/scripts/test_runner_constants/__init__.py +1 -0
  29. package/.agents/skills/test-runner/scripts/test_runner_constants/config/__init__.py +1 -0
  30. package/.agents/skills/test-runner/scripts/test_runner_constants/config/constants.py +96 -0
  31. package/.agents/skills-archived/pr-loop-cloud-transport/reference/identity-and-hooks.md +1 -1
  32. package/_shared/pr-loop/scripts/pr_loop_shared_constants/terminology_sweep_constants.py +6 -0
  33. package/_shared/pr-loop/scripts/terminology_sweep.py +64 -19
  34. package/_shared/pr-loop/scripts/tests/test_terminology_sweep.py +59 -0
  35. package/bin/ever-shipped-skills.mjs +2 -0
  36. package/bin/ever-shipped-skills.test.mjs +8 -0
  37. package/bin/install.agents-home.test.mjs +15 -13
  38. package/bin/install.mjs +37 -1
  39. package/bin/install.policy-lint.test.mjs +78 -0
  40. package/bin/install.prune.test.mjs +149 -20
  41. package/bin/install.pstack-plugin.test.mjs +114 -0
  42. package/bin/install.test.mjs +61 -7
  43. package/bin/refresh-pstack-plugin-skills.test.mjs +211 -0
  44. package/hooks/advisory/pr_done_reminder.py +342 -0
  45. package/hooks/advisory/test_pr_done_reminder.py +249 -0
  46. package/hooks/blocking/bash_post_call_dispatcher.py +53 -6
  47. package/hooks/blocking/code_rules_paired_test.py +22 -15
  48. package/hooks/blocking/pii_prevention_blocker.py +32 -51
  49. package/hooks/blocking/test_bash_post_call_dispatcher.py +55 -17
  50. package/hooks/blocking/test_bash_pre_tool_use_dispatcher.py +1 -4
  51. package/hooks/blocking/test_code_rules_command_dispatch.py +2 -2
  52. package/hooks/blocking/test_code_rules_enforcer_paired_test.py +36 -29
  53. package/hooks/blocking/test_code_rules_js_resume_task_enumeration.py +4 -4
  54. package/hooks/blocking/test_code_rules_js_returns_object_schemaless.py +5 -5
  55. package/hooks/blocking/test_pii_prevention_blocker.py +37 -89
  56. package/hooks/blocking/test_pre_tool_use_dispatcher.py +68 -133
  57. package/hooks/blocking/test_pre_tool_use_dispatcher_native.py +20 -51
  58. package/hooks/blocking/test_precommit_code_rules_gate_native_owner.py +18 -18
  59. package/hooks/gh_post_body_texts.py +195 -0
  60. package/hooks/git-hooks/git_hooks_constants/staged_policy_lint.py +12 -0
  61. package/hooks/git-hooks/pre_commit.py +52 -11
  62. package/hooks/git-hooks/test_installed_policy_lint.py +159 -0
  63. package/hooks/git-hooks/test_native_policy_commit.py +87 -0
  64. package/hooks/git-hooks/test_pre_commit.py +246 -0
  65. package/hooks/hooks.json +1 -16
  66. package/hooks/hooks_constants/bash_post_call_dispatcher_constants.py +14 -2
  67. package/hooks/hooks_constants/bash_pre_tool_use_dispatcher_constants.py +0 -8
  68. package/hooks/hooks_constants/gh_post_body_texts_constants.py +12 -0
  69. package/hooks/hooks_constants/pr_done_reminder_constants.py +98 -0
  70. package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +10 -43
  71. package/hooks/hooks_constants/test_bash_post_call_dispatcher_constants.py +17 -7
  72. package/hooks/hooks_constants/test_bash_pre_tool_use_dispatcher_constants.py +0 -7
  73. package/hooks/hooks_constants/test_failure_recorder_constants.py +3 -3
  74. package/hooks/hooks_constants/test_gh_post_body_texts_constants.py +19 -0
  75. package/hooks/hooks_constants/test_pr_done_reminder_constants.py +40 -0
  76. package/hooks/hooks_constants/test_pre_tool_use_dispatcher_constants.py +20 -32
  77. package/hooks/observability/test_failure_recorder.py +1 -1
  78. package/hooks/pyproject.toml +1 -1
  79. package/hooks/test_gh_post_body_texts.py +79 -0
  80. package/package.json +2 -2
  81. package/rules/durable-post-artifacts.md +32 -20
  82. package/rules/gh-cli-conventions.md +23 -13
  83. package/rules/git-workflow.md +21 -8
  84. package/scripts/check.ps1 +0 -1
  85. package/{.agents/skills/run-claude-dev-env/driver.mjs → scripts/ci/installer-lifecycle.mjs} +3 -28
  86. package/scripts/ci/installer-lifecycle.test.mjs +26 -0
  87. package/scripts/ci/windows-installer-lifecycle.ps1 +1 -11
  88. package/scripts/dev_env_scripts_constants/shared_tree_constants.py +4 -5
  89. package/scripts/durable_post_lint.py +206 -0
  90. package/scripts/durable_post_lint_config/config/constants.py +96 -0
  91. package/scripts/durable_post_lint_config/config/test_constants.py +25 -0
  92. package/scripts/policy_lint/adapter_configuration.py +53 -12
  93. package/scripts/policy_lint/adapter_detectors.py +13 -6
  94. package/scripts/policy_lint/adapters.py +7 -4
  95. package/scripts/policy_lint/config/constants.py +5 -0
  96. package/scripts/policy_lint/engine.py +48 -4
  97. package/scripts/policy_lint/model.py +1 -0
  98. package/scripts/policy_lint/registry.py +1 -1
  99. package/scripts/policy_lint/selection.py +2 -1
  100. package/scripts/policy_lint/selection_git.py +2 -0
  101. package/scripts/refresh_pstack_plugin_skills.mjs +200 -0
  102. package/scripts/repository_checks/config/constants.py +0 -5
  103. package/scripts/shared_tree_paths.py +32 -3
  104. package/scripts/test_durable_post_lint.py +332 -0
  105. package/scripts/test_shared_tree_paths.py +33 -0
  106. package/scripts/tests/test_adapter_configuration.py +54 -0
  107. package/scripts/tests/test_policy_lint_rules_archive.py +120 -0
  108. package/scripts/tests/test_policy_lint_rules_engine.py +25 -4
  109. package/scripts/tests/test_policy_lint_rules_installed_loader.py +29 -0
  110. package/scripts/tests/test_policy_lint_rules_registry.py +227 -13
  111. package/scripts/tests/test_policy_lint_selection.py +25 -2
  112. package/scripts/tests/test_policy_lint_selection_native_index.py +30 -0
  113. package/scripts/tests/test_rules.py +3 -7
  114. package/.agents/skills/_shared/pr-loop/.claude/CLAUDE.md +0 -1
  115. package/.agents/skills/_shared/pr-loop/AGENTS.md +0 -1
  116. package/.agents/skills/_shared/pr-loop/audit-contract.md +0 -5
  117. package/.agents/skills/_shared/pr-loop/audit-reply-template.md +0 -5
  118. package/.agents/skills/_shared/pr-loop/code-rules-gate.md +0 -5
  119. package/.agents/skills/_shared/pr-loop/fix-protocol.md +0 -5
  120. package/.agents/skills/_shared/pr-loop/gh-payloads.md +0 -5
  121. package/.agents/skills/_shared/pr-loop/portable-driver.md +0 -149
  122. package/.agents/skills/_shared/pr-loop/post-audit-thread-contract.md +0 -5
  123. package/.agents/skills/_shared/pr-loop/precatch-rubric.md +0 -5
  124. package/.agents/skills/_shared/pr-loop/preflight-proposal.contract.test.mjs +0 -119
  125. package/.agents/skills/_shared/pr-loop/preflight-proposal.md +0 -5
  126. package/.agents/skills/_shared/pr-loop/prompts/.claude/CLAUDE.md +0 -1
  127. package/.agents/skills/_shared/pr-loop/prompts/AGENTS.md +0 -1
  128. package/.agents/skills/_shared/pr-loop/prompts/pr-consistency-audit.xml +0 -324
  129. package/.agents/skills/_shared/pr-loop/scripts/.claude/CLAUDE.md +0 -1
  130. package/.agents/skills/_shared/pr-loop/scripts/AGENTS.md +0 -1
  131. package/.agents/skills/_shared/pr-loop/scripts/RUNTIME_SCRIPTS.md +0 -29
  132. package/.agents/skills/_shared/pr-loop/scripts/_cli_utils.py +0 -22
  133. package/.agents/skills/_shared/pr-loop/scripts/_path_resolver.py +0 -186
  134. package/.agents/skills/_shared/pr-loop/scripts/_xml_utils.py +0 -20
  135. package/.agents/skills/_shared/pr-loop/scripts/audit_category_schema.py +0 -355
  136. package/.agents/skills/_shared/pr-loop/scripts/build_audit_prompt.py +0 -289
  137. package/.agents/skills/_shared/pr-loop/scripts/build_converge_task_list.py +0 -310
  138. package/.agents/skills/_shared/pr-loop/scripts/build_fix_prompt.py +0 -292
  139. package/.agents/skills/_shared/pr-loop/scripts/init_loop_state.py +0 -134
  140. package/.agents/skills/_shared/pr-loop/scripts/portable_converge_driver.py +0 -1646
  141. package/.agents/skills/_shared/pr-loop/scripts/preflight_worktree.py +0 -392
  142. package/.agents/skills/_shared/pr-loop/scripts/select_converge_pacer.py +0 -215
  143. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/.claude/CLAUDE.md +0 -1
  144. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/AGENTS.md +0 -1
  145. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/__init__.py +0 -0
  146. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/audit_category_schema_constants.py +0 -37
  147. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/converge_task_list_constants.py +0 -56
  148. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/handoff_constants.py +0 -45
  149. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/pacer_constants.py +0 -47
  150. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py +0 -157
  151. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/portable_driver_constants.py +0 -177
  152. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/preflight_constants.py +0 -70
  153. package/.agents/skills/_shared/pr-loop/scripts/teardown_worktrees.py +0 -172
  154. package/.agents/skills/_shared/pr-loop/scripts/test__path_resolver.py +0 -106
  155. package/.agents/skills/_shared/pr-loop/scripts/test_audit_category_schema.py +0 -94
  156. package/.agents/skills/_shared/pr-loop/scripts/test_build_audit_prompt.py +0 -499
  157. package/.agents/skills/_shared/pr-loop/scripts/test_build_converge_task_list.py +0 -140
  158. package/.agents/skills/_shared/pr-loop/scripts/test_build_fix_prompt.py +0 -262
  159. package/.agents/skills/_shared/pr-loop/scripts/test_init_loop_state.py +0 -71
  160. package/.agents/skills/_shared/pr-loop/scripts/test_portable_converge_driver.py +0 -1119
  161. package/.agents/skills/_shared/pr-loop/scripts/test_preflight_worktree.py +0 -287
  162. package/.agents/skills/_shared/pr-loop/scripts/test_select_converge_pacer.py +0 -207
  163. package/.agents/skills/_shared/pr-loop/scripts/test_teardown_worktrees.py +0 -59
  164. package/.agents/skills/_shared/pr-loop/scripts/test_write_handoff.py +0 -201
  165. package/.agents/skills/_shared/pr-loop/scripts/write_audit_outcomes.py +0 -182
  166. package/.agents/skills/_shared/pr-loop/scripts/write_fix_outcomes.py +0 -206
  167. package/.agents/skills/_shared/pr-loop/scripts/write_handoff.py +0 -309
  168. package/.agents/skills/_shared/pr-loop/state-schema.md +0 -5
  169. package/.agents/skills/_shared/pr-loop/worker-spawn.md +0 -5
  170. package/.agents/skills/autoconverge/.claude/CLAUDE.md +0 -1
  171. package/.agents/skills/autoconverge/AGENTS.md +0 -1
  172. package/.agents/skills/autoconverge/SKILL.md +0 -431
  173. package/.agents/skills/autoconverge/reference/.claude/CLAUDE.md +0 -1
  174. package/.agents/skills/autoconverge/reference/AGENTS.md +0 -1
  175. package/.agents/skills/autoconverge/reference/closing-report.md +0 -93
  176. package/.agents/skills/autoconverge/reference/convergence-gates.md +0 -31
  177. package/.agents/skills/autoconverge/reference/convergence.md +0 -219
  178. package/.agents/skills/autoconverge/reference/copilot-findings.md +0 -51
  179. package/.agents/skills/autoconverge/reference/gotchas.md +0 -66
  180. package/.agents/skills/autoconverge/reference/headless-safety.md +0 -44
  181. package/.agents/skills/autoconverge/reference/multi-pr.md +0 -128
  182. package/.agents/skills/autoconverge/reference/self-closing-loop.md +0 -84
  183. package/.agents/skills/autoconverge/reference/stop-conditions.md +0 -127
  184. package/.agents/skills/autoconverge/test_portable_pacer_gate.py +0 -54
  185. package/.agents/skills/autoconverge/workflow/.claude/CLAUDE.md +0 -1
  186. package/.agents/skills/autoconverge/workflow/AGENTS.md +0 -1
  187. package/.agents/skills/autoconverge/workflow/aggregate_runs.py +0 -371
  188. package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/.claude/CLAUDE.md +0 -1
  189. package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/AGENTS.md +0 -1
  190. package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/__init__.py +0 -0
  191. package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/render_report_constants.py +0 -250
  192. package/.agents/skills/autoconverge/workflow/converge.clean-audit.test.mjs +0 -665
  193. package/.agents/skills/autoconverge/workflow/converge.codex-gate.test.mjs +0 -472
  194. package/.agents/skills/autoconverge/workflow/converge.contract.test.mjs +0 -64
  195. package/.agents/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +0 -1009
  196. package/.agents/skills/autoconverge/workflow/converge.fix-progress.test.mjs +0 -107
  197. package/.agents/skills/autoconverge/workflow/converge.fix-recovery.test.mjs +0 -33
  198. package/.agents/skills/autoconverge/workflow/converge.merge-conflict.test.mjs +0 -15
  199. package/.agents/skills/autoconverge/workflow/converge.mjs +0 -3132
  200. package/.agents/skills/autoconverge/workflow/converge.p2-advance.test.mjs +0 -202
  201. package/.agents/skills/autoconverge/workflow/converge.path-aware.test.mjs +0 -47
  202. package/.agents/skills/autoconverge/workflow/converge.precatch.test.mjs +0 -152
  203. package/.agents/skills/autoconverge/workflow/converge.run-input.test.mjs +0 -116
  204. package/.agents/skills/autoconverge/workflow/converge_multi.mjs +0 -169
  205. package/.agents/skills/autoconverge/workflow/converge_multi.run-input.test.mjs +0 -173
  206. package/.agents/skills/autoconverge/workflow/convergence_summary.py +0 -110
  207. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a11d903476b803493.jsonl +0 -2
  208. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a26213978adeef6fb.jsonl +0 -2
  209. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a3def0d15ed9d9110.jsonl +0 -2
  210. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a41f41b1b708ee3b7.jsonl +0 -2
  211. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a758b880abecc3ff7.jsonl +0 -2
  212. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a8897b89656b1bd16.jsonl +0 -2
  213. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-ab1c2d3e4f5a6b7c8.jsonl +0 -2
  214. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-abd463d744a1437bc.jsonl +0 -2
  215. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-ad19d027ae8ee1816.jsonl +0 -2
  216. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/workflows/wf_881252e6-700.json +0 -266
  217. package/.agents/skills/autoconverge/workflow/render_report.py +0 -1024
  218. package/.agents/skills/autoconverge/workflow/test_aggregate_runs.py +0 -134
  219. package/.agents/skills/autoconverge/workflow/test_convergence_summary.py +0 -149
  220. package/.agents/skills/autoconverge/workflow/test_render_report.py +0 -812
  221. package/.agents/skills/hitl/SKILL.md +0 -45
  222. package/.agents/skills/pr-cleanup/SKILL.md +0 -140
  223. package/.agents/skills/pr-cleanup/reference/process-inventory.md +0 -17
  224. package/.agents/skills/pr-cleanup/reference/task-seeds.md +0 -22
  225. package/.agents/skills/pr-name-by-capability/SKILL.md +0 -73
  226. package/.agents/skills/pr-name-by-capability/reference/fetch-commands.md +0 -29
  227. package/.agents/skills/pr-name-by-capability/reference/offense-examples.md +0 -32
  228. package/.agents/skills/pr-name-by-capability/reference/report-template.md +0 -29
  229. package/.agents/skills/pr-name-by-capability/reference/rule-checklist.md +0 -38
  230. package/.agents/skills/pr-name-by-capability/reference/task-seeds.md +0 -10
  231. package/.agents/skills/pr-plain-language-cleanup/SKILL.md +0 -93
  232. package/.agents/skills/pr-refinement/SKILL.md +0 -31
  233. package/.agents/skills/pr-shared-extraction/SKILL.md +0 -177
  234. package/.agents/skills/pr-shared-extraction/reference/examples.md +0 -46
  235. package/.agents/skills/pr-shared-extraction/reference/offense-taxonomy.md +0 -100
  236. package/.agents/skills/pr-small-cl/SKILL.md +0 -52
  237. package/.agents/skills/pr-title-description/SKILL.md +0 -96
  238. package/.agents/skills/prototype/SKILL.md +0 -85
  239. package/.agents/skills/prototype/reference/honest-limitations.md +0 -23
  240. package/.agents/skills/prototype/reference/promotion-tasks.md +0 -23
  241. package/.agents/skills/prototype/scripts/build_sandbox_settings.py +0 -249
  242. package/.agents/skills/prototype/scripts/conftest.py +0 -15
  243. package/.agents/skills/prototype/scripts/launch_sandbox.py +0 -205
  244. package/.agents/skills/prototype/scripts/probe_sandbox_safety.py +0 -311
  245. package/.agents/skills/prototype/scripts/prototype_scripts_constants/__init__.py +0 -1
  246. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/__init__.py +0 -0
  247. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/build_sandbox_settings_constants.py +0 -41
  248. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/launch_sandbox_constants.py +0 -23
  249. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/probe_sandbox_safety_constants.py +0 -45
  250. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/prototype_common_constants.py +0 -10
  251. package/.agents/skills/prototype/scripts/test_build_sandbox_settings.py +0 -275
  252. package/.agents/skills/prototype/scripts/test_launch_sandbox.py +0 -303
  253. package/.agents/skills/prototype/scripts/test_probe_sandbox_safety.py +0 -312
  254. package/.agents/skills/prototype/workflows/promotion.md +0 -25
  255. package/.agents/skills/prototype/workflows/sandbox.md +0 -35
  256. package/.agents/skills/rebase/.claude/CLAUDE.md +0 -1
  257. package/.agents/skills/rebase/AGENTS.md +0 -1
  258. package/.agents/skills/rebase/SKILL.md +0 -178
  259. package/.agents/skills/review-router/SKILL.md +0 -51
  260. package/.agents/skills/review-router/reference/route-policy.json +0 -7
  261. package/.agents/skills/review-router/reference/task-seeds.md +0 -1
  262. package/.agents/skills/review-router/scripts/conftest.py +0 -4
  263. package/.agents/skills/review-router/scripts/review_router.py +0 -50
  264. package/.agents/skills/review-router/scripts/review_router_cli.py +0 -211
  265. package/.agents/skills/review-router/scripts/review_router_constants/__init__.py +0 -1
  266. package/.agents/skills/review-router/scripts/review_router_constants/config/__init__.py +0 -0
  267. package/.agents/skills/review-router/scripts/review_router_constants/config/constants.py +0 -13
  268. package/.agents/skills/review-router/scripts/test_review_router.py +0 -23
  269. package/.agents/skills/review-router/scripts/test_review_router_cli.py +0 -47
  270. package/.agents/skills/review-tier/SKILL.md +0 -56
  271. package/.agents/skills/review-tier/reference/task-seeds.md +0 -1
  272. package/.agents/skills/review-tier/reference/tier-policy.json +0 -9
  273. package/.agents/skills/review-tier/scripts/conftest.py +0 -4
  274. package/.agents/skills/review-tier/scripts/review_tier.py +0 -359
  275. package/.agents/skills/review-tier/scripts/review_tier_constants/__init__.py +0 -1
  276. package/.agents/skills/review-tier/scripts/review_tier_constants/config/__init__.py +0 -0
  277. package/.agents/skills/review-tier/scripts/review_tier_constants/config/constants.py +0 -29
  278. package/.agents/skills/review-tier/scripts/test_generation.py +0 -159
  279. package/.agents/skills/review-tier/scripts/test_review_tier.py +0 -33
  280. package/.agents/skills/run-claude-dev-env/SKILL.md +0 -84
  281. package/.agents/skills/session-log/.claude/CLAUDE.md +0 -1
  282. package/.agents/skills/session-log/AGENTS.md +0 -1
  283. package/.agents/skills/session-log/SKILL.md +0 -170
  284. package/.agents/skills/session-log/templates/frontmatter.md +0 -40
  285. package/.agents/skills/session-tidy/.claude/CLAUDE.md +0 -1
  286. package/.agents/skills/session-tidy/AGENTS.md +0 -1
  287. package/.agents/skills/session-tidy/SKILL.md +0 -191
  288. package/.agents/skills/skill-builder/references/.claude/CLAUDE.md +0 -1
  289. package/.agents/skills/skill-builder/references/AGENTS.md +0 -1
  290. package/.agents/skills/skill-builder/references/delegation-map.md +0 -130
  291. package/.agents/skills/skill-builder/references/description-field.md +0 -111
  292. package/.agents/skills/skill-builder/references/deterministic-elements.md +0 -218
  293. package/.agents/skills/skill-builder/references/progressive-disclosure.md +0 -122
  294. package/.agents/skills/skill-builder/references/self-audit-checklist.md +0 -126
  295. package/.agents/skills/skill-builder/references/skill-modularity.md +0 -111
  296. package/.agents/skills/skill-builder/references/skill-types.md +0 -232
  297. package/.agents/skills/skill-builder/references/thariq-x-post-skills.json +0 -33
  298. package/.agents/skills/skill-builder/templates/.claude/CLAUDE.md +0 -1
  299. package/.agents/skills/skill-builder/templates/AGENTS.md +0 -1
  300. package/.agents/skills/skill-builder/templates/gap-analysis.md +0 -87
  301. package/.agents/skills/skill-builder/workflows/.claude/CLAUDE.md +0 -1
  302. package/.agents/skills/skill-builder/workflows/AGENTS.md +0 -1
  303. package/.agents/skills/skill-builder/workflows/improve-skill.md +0 -136
  304. package/.agents/skills/skill-builder/workflows/new-skill.md +0 -179
  305. package/.agents/skills/skill-builder/workflows/polish-skill.md +0 -139
  306. package/.agents/skills/source-command-sr-loop/SKILL.md +0 -82
  307. package/.agents/skills/update/.claude/CLAUDE.md +0 -1
  308. package/.agents/skills/update/AGENTS.md +0 -1
  309. package/.agents/skills/update/SKILL.md +0 -190
  310. package/_shared/pr-loop/AGENTS.md +0 -1
  311. package/_shared/pr-loop/CLAUDE.md +0 -1
  312. package/_shared/pr-loop/audit-contract.md +0 -183
  313. package/_shared/pr-loop/audit-reply-template.md +0 -151
  314. package/_shared/pr-loop/code-rules-gate.md +0 -65
  315. package/_shared/pr-loop/fix-protocol.md +0 -60
  316. package/_shared/pr-loop/gh-payloads.md +0 -75
  317. package/_shared/pr-loop/post-audit-thread-contract.md +0 -51
  318. package/_shared/pr-loop/precatch-rubric.md +0 -66
  319. package/_shared/pr-loop/preflight-proposal.md +0 -56
  320. package/_shared/pr-loop/scripts/post_audit_thread.py +0 -1242
  321. package/_shared/pr-loop/scripts/pr_loop_shared_constants/post_audit_thread_constants.py +0 -199
  322. package/_shared/pr-loop/scripts/tests/test_post_audit_thread.py +0 -1115
  323. package/_shared/pr-loop/scripts/tests/test_post_audit_thread_constants.py +0 -129
  324. package/_shared/pr-loop/state-schema.md +0 -45
  325. package/_shared/pr-loop/worker-spawn.md +0 -189
  326. package/hooks/_gh_pr_author_swap_utils.py +0 -1225
  327. package/hooks/blocking/conventional_pr_title_gate.py +0 -443
  328. package/hooks/blocking/gh_body_arg_blocker.py +0 -176
  329. package/hooks/blocking/gh_pr_author_enforcer.py +0 -487
  330. package/hooks/blocking/gh_pr_author_restore.py +0 -105
  331. package/hooks/blocking/pr_description_writer_gate.py +0 -256
  332. package/hooks/blocking/test_conventional_pr_title_gate.py +0 -640
  333. package/hooks/blocking/test_gh_body_arg_blocker.py +0 -441
  334. package/hooks/blocking/test_gh_pr_author_enforcer.py +0 -1166
  335. package/hooks/blocking/test_gh_pr_author_restore.py +0 -513
  336. package/hooks/blocking/test_gh_pr_author_swap_utils.py +0 -910
  337. package/hooks/blocking/test_pr_description_writer_gate.py +0 -234
  338. package/hooks/blocking/test_preflight_check.py +0 -343
  339. package/hooks/blocking/test_test_preflight_check.py +0 -80
  340. package/hooks/blocking/test_volatile_path_in_post_blocker.py +0 -322
  341. package/hooks/blocking/volatile_path_in_post_blocker.py +0 -461
  342. package/hooks/hooks_constants/conventional_pr_title_gate_constants.py +0 -58
  343. package/hooks/hooks_constants/gh_pr_author_swap_constants.py +0 -76
  344. package/hooks/hooks_constants/pr_description_writer_gate_constants.py +0 -73
  345. package/hooks/hooks_constants/volatile_path_in_post_blocker_constants.py +0 -55
  346. package/hooks/observability/pr_description_writer_spawn_tracker.py +0 -113
  347. package/hooks/observability/test_pr_description_writer_spawn_tracker.py +0 -150
  348. package/hooks/session/gh_pr_author_session_cleanup.py +0 -175
  349. package/hooks/session/test_gh_pr_author_session_cleanup.py +0 -576
  350. package/hooks/test__gh_pr_author_swap_utils.py +0 -333
@@ -0,0 +1,221 @@
1
+ """Contract tests for explicit legacy GitHub author recovery."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import os
7
+ import stat
8
+ import subprocess
9
+ import sys
10
+ from collections.abc import Callable
11
+ from pathlib import Path
12
+ from unittest.mock import Mock
13
+
14
+ import pytest
15
+
16
+ _SCRIPTS_DIRECTORY = Path(__file__).resolve().parent
17
+ if str(_SCRIPTS_DIRECTORY) not in sys.path:
18
+ sys.path.insert(0, str(_SCRIPTS_DIRECTORY))
19
+
20
+ import recover_legacy_author
21
+
22
+ CURRENT_TIME_SECONDS = 2_000_000.0
23
+ CURRENT_USER_ID = 41
24
+ LEGACY_ACCOUNT = "previous-account"
25
+ OTHER_ACCOUNT = "other-account"
26
+ STATE_FILENAME = "gh_pr_author_swap_session-a.json"
27
+
28
+
29
+ def _completion(
30
+ code: int = 0, stdout: str = "", stderr: str = ""
31
+ ) -> subprocess.CompletedProcess[str]:
32
+ return subprocess.CompletedProcess([], code, stdout, stderr)
33
+
34
+
35
+ def _write_state(
36
+ directory: Path,
37
+ *,
38
+ filename: str = STATE_FILENAME,
39
+ payload: object | None = None,
40
+ age_seconds: float = 1801.0,
41
+ ) -> Path:
42
+ state_file = directory / filename
43
+ state_payload = {"original_account": LEGACY_ACCOUNT} if payload is None else payload
44
+ state_file.write_text(json.dumps(state_payload), encoding="utf-8")
45
+ os.utime(
46
+ state_file,
47
+ (CURRENT_TIME_SECONDS - age_seconds, CURRENT_TIME_SECONDS - age_seconds),
48
+ )
49
+ if hasattr(os, "getuid"):
50
+ state_file.chmod(0o600)
51
+ return state_file
52
+
53
+
54
+ def _run(
55
+ state_file: Path,
56
+ command_runner: Callable[..., subprocess.CompletedProcess[str]],
57
+ *,
58
+ confirm_inactive: bool = True,
59
+ ) -> int:
60
+ all_arguments = [str(state_file)]
61
+ if confirm_inactive:
62
+ all_arguments.append("--confirm-inactive")
63
+ return recover_legacy_author.main(
64
+ all_arguments,
65
+ now_seconds=CURRENT_TIME_SECONDS,
66
+ current_user_id=os.getuid() if hasattr(os, "getuid") else None,
67
+ command_runner=command_runner,
68
+ )
69
+
70
+
71
+ def test_success_restores_selected_record_and_preserves_neighbor(
72
+ tmp_path: Path,
73
+ ) -> None:
74
+ selected_file = _write_state(tmp_path)
75
+ neighbor_file = _write_state(
76
+ tmp_path,
77
+ filename="gh_pr_author_swap_session-b.json",
78
+ payload={"original_account": OTHER_ACCOUNT},
79
+ )
80
+ command_runner = Mock(return_value=_completion())
81
+ assert _run(selected_file, command_runner) == 0
82
+ command_runner.assert_called_once_with(
83
+ ["gh", "auth", "switch", "--user", LEGACY_ACCOUNT],
84
+ capture_output=True,
85
+ check=False,
86
+ shell=False,
87
+ text=True,
88
+ )
89
+ assert not selected_file.exists()
90
+ assert neighbor_file.exists()
91
+
92
+
93
+ def test_unconfirmed_record_is_unresolved_without_side_effects(
94
+ tmp_path: Path, capsys: pytest.CaptureFixture[str]
95
+ ) -> None:
96
+ state_file = _write_state(tmp_path)
97
+ command_runner = Mock()
98
+ assert _run(state_file, command_runner, confirm_inactive=False) == 3
99
+ assert "confirm inactive" in capsys.readouterr().err
100
+ command_runner.assert_not_called()
101
+ assert state_file.exists()
102
+
103
+
104
+ def test_active_record_is_rejected_without_side_effects(
105
+ tmp_path: Path, capsys: pytest.CaptureFixture[str]
106
+ ) -> None:
107
+ state_file = _write_state(tmp_path, age_seconds=10.0)
108
+ command_runner = Mock()
109
+ assert _run(state_file, command_runner) == 2
110
+ assert "record is active" in capsys.readouterr().err
111
+ command_runner.assert_not_called()
112
+ assert state_file.exists()
113
+
114
+
115
+ @pytest.mark.parametrize(
116
+ "payload",
117
+ [
118
+ [],
119
+ {},
120
+ {"original_account": ""},
121
+ {"original_account": 7},
122
+ {"original_account": LEGACY_ACCOUNT, "extra": True},
123
+ ],
124
+ )
125
+ def test_invalid_schema_is_rejected(
126
+ tmp_path: Path, payload: object, capsys: pytest.CaptureFixture[str]
127
+ ) -> None:
128
+ state_file = _write_state(tmp_path, payload=payload)
129
+ command_runner = Mock()
130
+ assert _run(state_file, command_runner) == 2
131
+ assert "record is invalid" in capsys.readouterr().err
132
+ command_runner.assert_not_called()
133
+ assert state_file.exists()
134
+
135
+
136
+ def test_invalid_utf8_is_rejected(tmp_path: Path) -> None:
137
+ state_file = _write_state(tmp_path)
138
+ state_file.write_bytes(b"\xff")
139
+ os.utime(state_file, (CURRENT_TIME_SECONDS - 1801, CURRENT_TIME_SECONDS - 1801))
140
+ command_runner = Mock()
141
+ assert _run(state_file, command_runner) == 2
142
+ command_runner.assert_not_called()
143
+ assert state_file.exists()
144
+
145
+
146
+ def test_wrong_filename_is_rejected(tmp_path: Path) -> None:
147
+ state_file = _write_state(tmp_path, filename="other.json")
148
+ command_runner = Mock()
149
+ assert _run(state_file, command_runner) == 2
150
+ command_runner.assert_not_called()
151
+
152
+
153
+ def test_symlink_is_rejected(tmp_path: Path) -> None:
154
+ target_file = _write_state(tmp_path)
155
+ link_file = tmp_path / "gh_pr_author_swap_link.json"
156
+ try:
157
+ link_file.symlink_to(target_file)
158
+ except OSError as error:
159
+ pytest.skip(f"symlink unavailable: {error}")
160
+ command_runner = Mock()
161
+ assert _run(link_file, command_runner) == 2
162
+ command_runner.assert_not_called()
163
+ assert target_file.exists()
164
+
165
+
166
+ def test_failed_restore_preserves_record_and_hides_child_output(
167
+ tmp_path: Path, capsys: pytest.CaptureFixture[str]
168
+ ) -> None:
169
+ state_file = _write_state(tmp_path)
170
+ command_runner = Mock(
171
+ return_value=_completion(1, LEGACY_ACCOUNT, f"unsafe {LEGACY_ACCOUNT}")
172
+ )
173
+ assert _run(state_file, command_runner) == 1
174
+ captured = capsys.readouterr()
175
+ assert captured.err == "error: GitHub account restore failed\n"
176
+ assert LEGACY_ACCOUNT not in captured.out + captured.err
177
+ assert state_file.exists()
178
+
179
+
180
+ def test_restore_launch_failure_preserves_record(
181
+ tmp_path: Path, capsys: pytest.CaptureFixture[str]
182
+ ) -> None:
183
+ state_file = _write_state(tmp_path)
184
+ command_runner = Mock(side_effect=OSError("unavailable"))
185
+ assert _run(state_file, command_runner) == 1
186
+ assert capsys.readouterr().err == "error: GitHub account restore failed\n"
187
+ assert state_file.exists()
188
+
189
+
190
+ def test_changed_record_after_restore_is_preserved(
191
+ tmp_path: Path, capsys: pytest.CaptureFixture[str]
192
+ ) -> None:
193
+ state_file = _write_state(tmp_path)
194
+
195
+ def change_record(
196
+ all_arguments: list[str], **keyword_arguments: object
197
+ ) -> subprocess.CompletedProcess[str]:
198
+ state_file.write_text(
199
+ json.dumps({"original_account": OTHER_ACCOUNT}), encoding="utf-8"
200
+ )
201
+ return _completion()
202
+
203
+ assert _run(state_file, change_record) == 1
204
+ assert "record changed" in capsys.readouterr().err
205
+ assert state_file.exists()
206
+
207
+
208
+ def test_secure_posix_metadata_requires_regular_owner_mode() -> None:
209
+ regular_secure_mode = stat.S_IFREG | 0o600
210
+ assert recover_legacy_author._posix_metadata_is_secure(
211
+ regular_secure_mode, CURRENT_USER_ID, CURRENT_USER_ID
212
+ )
213
+ assert not recover_legacy_author._posix_metadata_is_secure(
214
+ regular_secure_mode, CURRENT_USER_ID + 1, CURRENT_USER_ID
215
+ )
216
+ assert not recover_legacy_author._posix_metadata_is_secure(
217
+ stat.S_IFREG | 0o644, CURRENT_USER_ID, CURRENT_USER_ID
218
+ )
219
+ assert not recover_legacy_author._posix_metadata_is_secure(
220
+ stat.S_IFLNK | 0o600, CURRENT_USER_ID, CURRENT_USER_ID
221
+ )
@@ -1,202 +1,9 @@
1
1
  ---
2
2
  name: skill-builder
3
3
  disable-model-invocation: true
4
- description: >-
5
- Skill lifecycle: classify, scaffold, write via the skill-writer-agent, self-audit, compose
6
- sub-skills, polish description triggers, enforce deterministic scripts. Triggers:
7
- build a skill, new skill workflow, improve this skill, optimize skill description,
8
- skill development lifecycle, skill modularity, skill composition, description
9
- trigger catalog, deterministic skill scripts.
4
+ description: Placeholder for the skill-builder rework to follow pstack philosophy.
10
5
  ---
11
6
 
12
- # Skill Builder
7
+ # Skill builder
13
8
 
14
- **Core principle:** Best-practice-driven craftsman. Knows every proven pattern, applies them intentionally, self-audits after building. The expert that enforces craft standards.
15
-
16
- Sources: [Anthropic best practices](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices), [Lessons from Building Claude Code](references/thariq-x-post-skills.json), model skills (bugteam, pr-converge).
17
-
18
- ## Gotchas
19
-
20
- Highest-signal content. Append a bullet each time a skill build fails in a new way.
21
-
22
- > "The highest-signal content in any skill is the Gotchas section. These sections should be built up from common failure points that Claude runs into when using your skill."
23
-
24
- - Story-form `description` burns always-on context and weakens selection — rewrite to capability stem + `Triggers:` list (`description-field.md`).
25
- - Multi-capability packages fail modularity audit — split or thin orchestrator + named sub-skills (`skill-modularity.md`).
26
- - Skipping the composition plan before Write reintroduces silent reimplementation of peer skills.
27
- - Deterministic steps written only as prose (fenced source, giant `rg` lines, multi-step mechanical sequences) fail audit — extract to `scripts/` / `workflow/` / `templates/` / `reference/` (`deterministic-elements.md`).
28
- - Markdown `- [ ]` checklists as the agent's progress board fail audit when a task tool exists — seed tasks via `TaskCreate` / `TodoWrite` (`deterministic-elements.md`).
29
-
30
- ## When this skill applies
31
-
32
- Trigger for requests to **build**, **improve**, or **polish** a skill. This skill orchestrates the process — it classifies, scaffolds, gathers context, delegates writing to the `skill-writer-agent` agent, and self-audits the result.
33
-
34
- For quick skill syntax questions or one-off SKILL.md edits, spawn the `skill-writer-agent` agent directly.
35
-
36
- **Refusal cases — first match wins:**
37
-
38
- - **No clear task or domain.** Respond exactly: `What should this skill do? Give me a one-sentence description of the capability.`
39
-
40
- ## The Process
41
-
42
- Each workflow file provides step-by-step instructions. After routing below, open the corresponding workflow file and follow it.
43
-
44
- ### Routing
45
-
46
- Assess the user’s intent:
47
-
48
- **Creating a new skill?**
49
- Read `${CLAUDE_SKILL_DIR}/workflows/new-skill.md` and follow it.
50
-
51
- **Improving an existing skill?**
52
- Read `${CLAUDE_SKILL_DIR}/workflows/improve-skill.md` and follow it.
53
-
54
- **Final polish only (description optimization, trigger audit)?**
55
- Read `${CLAUDE_SKILL_DIR}/workflows/polish-skill.md` and follow it.
56
-
57
- **Ambiguous?** Ask: "Are you creating a new skill, improving an existing one, or doing a final polish pass?"
58
-
59
- ### The Claude A / Claude B pattern
60
-
61
- You and the user are **Claude A** — the expert who designs and refines the skill. Subagents running the built skill on real tasks are **Claude B** — the agent using the skill to perform actual work.
62
-
63
- > "Work with one instance of Claude (‘Claude A’) to create a Skill that is used by other instances (‘Claude B’). Claude A helps you design and refine instructions, while Claude B tests them in real tasks."
64
-
65
- The feedback loop: observe Claude B’s behavior, bring insights back, refine the skill, test again.
66
-
67
- ## Skill type routing
68
-
69
- > "After cataloging all of our skills, we noticed they cluster into a few recurring categories."
70
-
71
- Classify into one of 9 types — type sets folder structure. Taxonomy and layouts: [`references/skill-types.md`](references/skill-types.md).
72
-
73
- ## Principles
74
-
75
- These are non-negotiable. Every skill must satisfy them. Enforce via [`references/self-audit-checklist.md`](references/self-audit-checklist.md).
76
-
77
- ### Concision and defaults
78
-
79
- > "Default assumption: Claude is already very smart. Only add context Claude doesn’t already have."
80
-
81
- > "Don’t State the Obvious — focus on information that pushes Claude out of its normal way of thinking."
82
-
83
- Challenge each sentence: "Does Claude really need this?"
84
-
85
- ### Degree of freedom
86
-
87
- > "Match the level of specificity to the task’s fragility and variability."
88
-
89
- High freedom (text guidance) for open fields. Low freedom (exact scripts, no parameters) for narrow bridges with cliffs.
90
-
91
- > "Avoid Railroading Claude — give Claude the information it needs, but give it the flexibility to adapt."
92
-
93
- ### Progressive disclosure
94
-
95
- Hub pattern, line caps, one-level references, TOC and path rules: [`references/progressive-disclosure.md`](references/progressive-disclosure.md).
96
-
97
- ### Modularity and composition
98
-
99
- One skill = one capability. Multi-step work invokes **sub-skills** (peer skills) by name. Prefer compose over reimplement. Full rules: [`references/skill-modularity.md`](references/skill-modularity.md).
100
-
101
- > "You can just reference other skills by name, and the model will invoke them if they are installed."
102
-
103
- New-skill Gather records a composition plan before write. Self-audit modularity items are mandatory.
104
-
105
- ### Description field (trigger catalog)
106
-
107
- The frontmatter `description` is **selection metadata** pre-loaded for every skill. Write a **trigger catalog**, not a story: short capability stem + concrete trigger phrases. No narrative, benefits language, or process dump.
108
-
109
- Full rules: [`references/description-field.md`](references/description-field.md). Polish workflow Step 1 is the dedicated rewrite pass.
110
-
111
- > "The description field is not a summary — it’s a description of when to trigger."
112
-
113
- ### Gotchas
114
-
115
- Mandatory highest-signal section (see Gotchas above). Capture real failure modes; self-audit requires the section present and actionable.
116
-
117
- ### Templates and examples
118
-
119
- > "Provide templates for output format" and "Examples help Claude understand the desired style and level of detail more clearly than descriptions alone."
120
-
121
- Use the template pattern for structured outputs. Use the examples pattern (input/output pairs) for style-dependent work.
122
-
123
- ### Workflows and task seeds
124
-
125
- Multi-step required work is a **task seed list** (plain bullets in a reference file) plus an instruction to register each item on the host task tool (`TaskCreate`, `TodoWrite`, or equivalent). Agents work the task list and mark complete with evidence.
126
-
127
- Do **not** ship markdown `- [ ]` boards as the completion protocol when a task tool is available. Do **not** say "copy this checklist into your response and check it off."
128
-
129
- Quality-critical operations still use feedback loops (run validator → fix → repeat). Spec: [`references/deterministic-elements.md`](references/deterministic-elements.md) (Task-tool tracking).
130
-
131
- ### Scripts
132
-
133
- > "Handle error conditions rather than punting to Claude." "Make clear whether Claude should execute the script or read it as reference."
134
-
135
- > "One of the most powerful tools you can give Claude is code — letting Claude spend its turns on composition rather than reconstructing boilerplate."
136
-
137
- ### Deterministic elements (mandatory classification)
138
-
139
- Any skill element that is **deterministic** (same inputs → same outputs; machine-checkable success) ships as code, a fixed artifact, or a **session task seed** — not prose-only steps or markdown checkbox boards. Judgment, routing, and refusals stay in markdown.
140
-
141
- Full rules, inventory table, task-tool tracking, CODE_RULES bar for skill scripts, and anti-patterns: [`references/deterministic-elements.md`](references/deterministic-elements.md).
142
-
143
- New-skill Gather records a deterministic-elements inventory before write. Self-audit items register as session tasks and are mandatory on every delivery (pure-judgment skills mark script rows N/A with evidence).
144
-
145
- ### Setup and memory
146
-
147
- > "Think through the Setup — some skills may need to be set up with context from the user. A good pattern is to store this in a config.json file."
148
-
149
- > "Data stored in the skill directory may be deleted when you upgrade the skill, so store persistent data in `${CLAUDE_PLUGIN_DATA}`."
150
-
151
- ### Constraints and refusal cases
152
-
153
- > bugteam pattern — non-negotiables separated from guidance, with design rationale. Explicit "first match wins" refusal conditions.
154
-
155
- ### Anti-patterns
156
-
157
- > No Windows paths. Don’t offer too many options — provide a default with escape hatch. Avoid time-sensitive claims. Use consistent terminology. No deeply nested references.
158
-
159
- Also: story-form descriptions; monolith multi-capability skills; silent reimplementation of peer skills; nested folders used as fake sub-skills; deterministic logic only in prose or fenced source; markdown `- [ ]` as the agent's work tracker.
160
-
161
- ## Self-audit
162
-
163
- After every build, improvement, or polish pass, load `${CLAUDE_SKILL_DIR}/references/self-audit-checklist.md`, **register every bullet as a session task**, and complete each with evidence. Every item must pass before delivery. Fix failures, then re-audit.
164
-
165
- ## Delegation to skill-writer-agent
166
-
167
- skill-builder orchestrates; the `skill-writer-agent` agent authors. The caller spawns it with `Agent(subagent_type="skill-writer-agent", ...)`. The handoff packet from Step 4 must include:
168
-
169
- - Skill type and folder structure
170
- - Gap analysis or observation findings (composition plan + description triggers + deterministic inventory)
171
- - Degree of freedom assessment
172
- - Initial gotchas
173
- - Composition plan: related skills, sub-skills to invoke, split decisions
174
- - Description trigger catalog: capability stem + trigger phrases (not prose)
175
- - Deterministic elements inventory: each process step classified; code paths + paired tests
176
- - Any constraints
177
-
178
- See `${CLAUDE_SKILL_DIR}/references/delegation-map.md` for exact patterns.
179
-
180
- ## File index
181
-
182
- | File | Purpose |
183
- |------|---------|
184
- | `SKILL.md` | This hub — principles, process, routing, file index |
185
- | `references/skill-types.md` | 9-type taxonomy with folder structures per type |
186
- | `references/progressive-disclosure.md` | Folder conventions, hub pattern, hard rules |
187
- | `references/skill-modularity.md` | Cross-skill modularity, sub-skills, composition plan |
188
- | `references/description-field.md` | Description as trigger catalog (not story prose) |
189
- | `references/deterministic-elements.md` | Deterministic steps as code/task seeds; CODE_RULES; no markdown checkbox boards |
190
- | `references/self-audit-checklist.md` | Post-build audit task seeds (register via TaskCreate / TodoWrite) |
191
- | `references/delegation-map.md` | Subagent handoff patterns and transcript guidance |
192
- | `workflows/new-skill.md` | Full lifecycle for new skills (6 steps) |
193
- | `workflows/improve-skill.md` | Observation-first flow for existing skills (6 steps) |
194
- | `workflows/polish-skill.md` | Description trigger-catalog audit and final validation (5 steps) |
195
- | `templates/gap-analysis.md` | Gaps, composition plan, description triggers, deterministic inventory |
196
-
197
- ## Folder map
198
-
199
- - `SKILL.md` — hub.
200
- - `references/` — best-practice specifications and the audit checklist.
201
- - `workflows/` — step-by-step workflows for each lifecycle phase.
202
- - `templates/` — reusable templates for skill artifacts.
9
+ TODO: Rework to follow pstack philosophy.
@@ -0,0 +1,69 @@
1
+ ---
2
+ name: test-runner
3
+ description: >-
4
+ Run pytest or Playwright through the repository's test command.
5
+ Checks Django and Playwright readiness before launching the
6
+ selected child process. Use when running tests in a repository with local
7
+ Django or frontend services.
8
+ ---
9
+
10
+ # test-runner
11
+
12
+ Run Django and Playwright readiness checks, then launch the selected test
13
+ command. Pass one supported runner after `--`. The command forwards those
14
+ arguments without a shell.
15
+
16
+ ## Command
17
+
18
+ Run from the repository that owns the tests:
19
+
20
+ ```text
21
+ python "${CLAUDE_SKILL_DIR}/scripts/run_tests.py" -- python -m pytest <pytest-arguments>
22
+ python "${CLAUDE_SKILL_DIR}/scripts/run_tests.py" -- npx playwright test <playwright-arguments>
23
+ ```
24
+
25
+ Use `--project <path>` when the test repository is not the current directory:
26
+
27
+ ```text
28
+ python "${CLAUDE_SKILL_DIR}/scripts/run_tests.py" --project "<repository>" -- python -m pytest <pytest-arguments>
29
+ ```
30
+
31
+ The supported runner forms are `pytest`, `python -m pytest`, `playwright test`,
32
+ and `npx playwright test`. The child receives the exact arguments after `--`,
33
+ inherits the current environment, writes to the current output streams, runs
34
+ with the selected project as its working directory, and returns its exit
35
+ status.
36
+
37
+ ## Preflight
38
+
39
+ The command returns nonzero and launches no child when a required check fails.
40
+
41
+ - A pytest run in a project without `manage.py` runs without preflight.
42
+ - A pytest run in a Django project requires `db.sqlite3` and a healthy Django
43
+ server. The URL defaults to `http://localhost:8000`. A URL in the child
44
+ arguments overrides that default.
45
+ - A Playwright run checks its target server, validates a detected Django
46
+ `runserver` process uses `--test-db`, rejects conflicting Django servers from
47
+ different worktrees, and uses the URL default `http://localhost:3000`.
48
+ - When the project contains `frontend/`, the command runs `npm run build` in
49
+ that directory, then `python manage.py collectstatic --noinput` in the
50
+ project directory before Playwright starts.
51
+
52
+ The command does not parse shell syntax. Keep pipes, redirects, `cd`, and
53
+ background operators outside this command. Run this command directly so its
54
+ exit status reaches the caller.
55
+
56
+ ## Unsupported commands
57
+
58
+ Use the normal runner for anything else. This command accepts only the four
59
+ runner forms listed above. It does not install dependencies, start a server,
60
+ run migrations, or repair a failed preflight.
61
+
62
+ ## Files
63
+
64
+ - `SKILL.md` covers invocation, checks, and the command boundary.
65
+ - `scripts/run_tests.py` parses the command, runs preflight, and launches the child.
66
+ - `scripts/preflight_checks.py` runs Django and Playwright readiness checks.
67
+ - `scripts/test_run_tests.py` covers the command and preflight.
68
+ - `scripts/test_preflight_checks.py` covers the readiness checks.
69
+ - `scripts/test_runner_constants/` holds command names, messages, and limits.