claude-dev-env 4.3.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.
- package/.agents/agents/pr-description-writer.md +2 -2
- package/.agents/agents/test_agent_frontmatter.py +2 -2
- package/.agents/agents/test_pr_description_writer_style.py +1 -3
- package/.agents/skills/e-code-review/SKILL.md +12 -12
- package/.agents/skills/e-code-review/preflight-proposal.contract.test.mjs +20 -0
- package/.agents/skills/e-code-review/reference/fix.md +15 -17
- package/.agents/skills/e-code-review/reference/loop.md +35 -39
- package/.agents/skills/e-code-review/reference/mode-contract.test.mjs +2 -1
- package/.agents/skills/e-code-review/reference/preflight-proposal.md +44 -9
- package/.agents/skills/e-code-review/reference/runner-selection.md +13 -14
- package/.agents/skills/issue-tracker/SKILL.md +5 -4
- package/.agents/skills/pull-request/SKILL.md +11 -13
- package/.agents/skills/pull-request/reference/publication-tasks.md +3 -3
- package/.agents/skills/pull-request/scripts/github_pr_command_constants/config/constants.py +9 -1
- package/.agents/skills/pull-request/scripts/pull_request.py +33 -44
- package/.agents/skills/pull-request/scripts/test_github_pr_command_constants.py +9 -0
- package/.agents/skills/pull-request/scripts/test_pull_request.py +1 -3
- package/.agents/skills/skill-builder/SKILL.md +3 -196
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/terminology_sweep_constants.py +6 -0
- package/_shared/pr-loop/scripts/terminology_sweep.py +64 -19
- package/_shared/pr-loop/scripts/tests/test_terminology_sweep.py +59 -0
- package/bin/install.agents-home.test.mjs +15 -13
- package/bin/install.mjs +28 -0
- package/bin/install.policy-lint.test.mjs +78 -0
- package/bin/install.prune.test.mjs +59 -20
- package/bin/install.pstack-plugin.test.mjs +114 -0
- package/bin/install.test.mjs +37 -0
- package/bin/refresh-pstack-plugin-skills.test.mjs +211 -0
- package/hooks/advisory/pr_done_reminder.py +342 -0
- package/hooks/advisory/test_pr_done_reminder.py +249 -0
- package/hooks/blocking/bash_post_call_dispatcher.py +53 -6
- package/hooks/blocking/code_rules_paired_test.py +22 -15
- package/hooks/blocking/test_bash_post_call_dispatcher.py +65 -4
- package/hooks/blocking/test_code_rules_enforcer_paired_test.py +36 -29
- package/hooks/blocking/test_code_rules_js_resume_task_enumeration.py +4 -4
- package/hooks/blocking/test_code_rules_js_returns_object_schemaless.py +5 -5
- package/hooks/blocking/test_pre_tool_use_dispatcher.py +68 -133
- package/hooks/blocking/test_pre_tool_use_dispatcher_native.py +20 -51
- package/hooks/blocking/test_precommit_code_rules_gate_native_owner.py +18 -18
- package/hooks/git-hooks/git_hooks_constants/staged_policy_lint.py +12 -0
- package/hooks/git-hooks/pre_commit.py +52 -11
- package/hooks/git-hooks/test_installed_policy_lint.py +159 -0
- package/hooks/git-hooks/test_native_policy_commit.py +87 -0
- package/hooks/git-hooks/test_pre_commit.py +246 -0
- package/hooks/hooks.json +1 -1
- package/hooks/hooks_constants/bash_post_call_dispatcher_constants.py +14 -1
- package/hooks/hooks_constants/pr_done_reminder_constants.py +98 -0
- package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +10 -43
- package/hooks/hooks_constants/test_bash_post_call_dispatcher_constants.py +19 -2
- package/hooks/hooks_constants/test_pr_done_reminder_constants.py +40 -0
- package/hooks/hooks_constants/test_pre_tool_use_dispatcher_constants.py +20 -32
- package/package.json +2 -2
- package/rules/durable-post-artifacts.md +2 -1
- package/rules/git-workflow.md +6 -6
- package/scripts/check.ps1 +0 -1
- package/{.agents/skills/run-claude-dev-env/driver.mjs → scripts/ci/installer-lifecycle.mjs} +3 -28
- package/scripts/ci/installer-lifecycle.test.mjs +26 -0
- package/scripts/ci/windows-installer-lifecycle.ps1 +1 -11
- package/scripts/dev_env_scripts_constants/shared_tree_constants.py +4 -5
- package/{.agents/skills/_shared/pr-loop/scripts → scripts}/durable_post_lint.py +5 -41
- package/{.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/durable_post_lint_constants.py → scripts/durable_post_lint_config/config/constants.py} +0 -10
- package/{.agents/skills/_shared/pr-loop/scripts/test_durable_post_lint_constants.py → scripts/durable_post_lint_config/config/test_constants.py} +1 -1
- package/scripts/policy_lint/adapter_detectors.py +13 -6
- package/scripts/policy_lint/adapters.py +7 -4
- package/scripts/policy_lint/config/constants.py +5 -0
- package/scripts/policy_lint/engine.py +48 -4
- package/scripts/policy_lint/model.py +1 -0
- package/scripts/policy_lint/registry.py +1 -1
- package/scripts/policy_lint/selection.py +2 -1
- package/scripts/policy_lint/selection_git.py +2 -0
- package/scripts/refresh_pstack_plugin_skills.mjs +200 -0
- package/scripts/shared_tree_paths.py +32 -3
- package/scripts/test_shared_tree_paths.py +33 -0
- package/scripts/tests/test_policy_lint_rules_archive.py +120 -0
- package/scripts/tests/test_policy_lint_rules_engine.py +25 -4
- package/scripts/tests/test_policy_lint_rules_installed_loader.py +29 -0
- package/scripts/tests/test_policy_lint_rules_registry.py +227 -13
- package/scripts/tests/test_policy_lint_selection.py +25 -2
- package/scripts/tests/test_policy_lint_selection_native_index.py +30 -0
- package/scripts/tests/test_rules.py +3 -7
- package/.agents/skills/_shared/pr-loop/.claude/CLAUDE.md +0 -1
- package/.agents/skills/_shared/pr-loop/AGENTS.md +0 -1
- package/.agents/skills/_shared/pr-loop/audit-contract.md +0 -5
- package/.agents/skills/_shared/pr-loop/audit-reply-template.md +0 -5
- package/.agents/skills/_shared/pr-loop/code-rules-gate.md +0 -5
- package/.agents/skills/_shared/pr-loop/fix-protocol.md +0 -5
- package/.agents/skills/_shared/pr-loop/gh-payloads.md +0 -5
- package/.agents/skills/_shared/pr-loop/portable-driver.md +0 -149
- package/.agents/skills/_shared/pr-loop/post-audit-thread-contract.md +0 -5
- package/.agents/skills/_shared/pr-loop/precatch-rubric.md +0 -5
- package/.agents/skills/_shared/pr-loop/preflight-proposal.contract.test.mjs +0 -119
- package/.agents/skills/_shared/pr-loop/preflight-proposal.md +0 -5
- package/.agents/skills/_shared/pr-loop/prompts/.claude/CLAUDE.md +0 -1
- package/.agents/skills/_shared/pr-loop/prompts/AGENTS.md +0 -1
- package/.agents/skills/_shared/pr-loop/prompts/pr-consistency-audit.xml +0 -324
- package/.agents/skills/_shared/pr-loop/scripts/.claude/CLAUDE.md +0 -1
- package/.agents/skills/_shared/pr-loop/scripts/AGENTS.md +0 -1
- package/.agents/skills/_shared/pr-loop/scripts/RUNTIME_SCRIPTS.md +0 -29
- package/.agents/skills/_shared/pr-loop/scripts/_cli_utils.py +0 -22
- package/.agents/skills/_shared/pr-loop/scripts/_path_resolver.py +0 -186
- package/.agents/skills/_shared/pr-loop/scripts/_xml_utils.py +0 -20
- package/.agents/skills/_shared/pr-loop/scripts/audit_category_schema.py +0 -355
- package/.agents/skills/_shared/pr-loop/scripts/build_audit_prompt.py +0 -289
- package/.agents/skills/_shared/pr-loop/scripts/build_converge_task_list.py +0 -310
- package/.agents/skills/_shared/pr-loop/scripts/build_fix_prompt.py +0 -292
- package/.agents/skills/_shared/pr-loop/scripts/init_loop_state.py +0 -134
- package/.agents/skills/_shared/pr-loop/scripts/portable_converge_driver.py +0 -1646
- package/.agents/skills/_shared/pr-loop/scripts/preflight_worktree.py +0 -392
- package/.agents/skills/_shared/pr-loop/scripts/select_converge_pacer.py +0 -215
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/.claude/CLAUDE.md +0 -1
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/AGENTS.md +0 -1
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/__init__.py +0 -0
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/audit_category_schema_constants.py +0 -37
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/converge_task_list_constants.py +0 -56
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/handoff_constants.py +0 -45
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/pacer_constants.py +0 -47
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py +0 -157
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/portable_driver_constants.py +0 -177
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/preflight_constants.py +0 -70
- package/.agents/skills/_shared/pr-loop/scripts/teardown_worktrees.py +0 -172
- package/.agents/skills/_shared/pr-loop/scripts/test__path_resolver.py +0 -106
- package/.agents/skills/_shared/pr-loop/scripts/test_audit_category_schema.py +0 -94
- package/.agents/skills/_shared/pr-loop/scripts/test_build_audit_prompt.py +0 -499
- package/.agents/skills/_shared/pr-loop/scripts/test_build_converge_task_list.py +0 -140
- package/.agents/skills/_shared/pr-loop/scripts/test_build_fix_prompt.py +0 -262
- package/.agents/skills/_shared/pr-loop/scripts/test_init_loop_state.py +0 -71
- package/.agents/skills/_shared/pr-loop/scripts/test_portable_converge_driver.py +0 -1119
- package/.agents/skills/_shared/pr-loop/scripts/test_preflight_worktree.py +0 -287
- package/.agents/skills/_shared/pr-loop/scripts/test_select_converge_pacer.py +0 -207
- package/.agents/skills/_shared/pr-loop/scripts/test_teardown_worktrees.py +0 -59
- package/.agents/skills/_shared/pr-loop/scripts/test_write_handoff.py +0 -201
- package/.agents/skills/_shared/pr-loop/scripts/write_audit_outcomes.py +0 -182
- package/.agents/skills/_shared/pr-loop/scripts/write_fix_outcomes.py +0 -206
- package/.agents/skills/_shared/pr-loop/scripts/write_handoff.py +0 -309
- package/.agents/skills/_shared/pr-loop/state-schema.md +0 -5
- package/.agents/skills/_shared/pr-loop/worker-spawn.md +0 -5
- package/.agents/skills/autoconverge/.claude/CLAUDE.md +0 -1
- package/.agents/skills/autoconverge/AGENTS.md +0 -1
- package/.agents/skills/autoconverge/SKILL.md +0 -431
- package/.agents/skills/autoconverge/reference/.claude/CLAUDE.md +0 -1
- package/.agents/skills/autoconverge/reference/AGENTS.md +0 -1
- package/.agents/skills/autoconverge/reference/closing-report.md +0 -93
- package/.agents/skills/autoconverge/reference/convergence-gates.md +0 -31
- package/.agents/skills/autoconverge/reference/convergence.md +0 -219
- package/.agents/skills/autoconverge/reference/copilot-findings.md +0 -51
- package/.agents/skills/autoconverge/reference/gotchas.md +0 -66
- package/.agents/skills/autoconverge/reference/headless-safety.md +0 -44
- package/.agents/skills/autoconverge/reference/multi-pr.md +0 -128
- package/.agents/skills/autoconverge/reference/self-closing-loop.md +0 -84
- package/.agents/skills/autoconverge/reference/stop-conditions.md +0 -127
- package/.agents/skills/autoconverge/test_portable_pacer_gate.py +0 -54
- package/.agents/skills/autoconverge/workflow/.claude/CLAUDE.md +0 -1
- package/.agents/skills/autoconverge/workflow/AGENTS.md +0 -1
- package/.agents/skills/autoconverge/workflow/aggregate_runs.py +0 -371
- package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/.claude/CLAUDE.md +0 -1
- package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/AGENTS.md +0 -1
- package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/__init__.py +0 -0
- package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/render_report_constants.py +0 -250
- package/.agents/skills/autoconverge/workflow/converge.clean-audit.test.mjs +0 -665
- package/.agents/skills/autoconverge/workflow/converge.codex-gate.test.mjs +0 -472
- package/.agents/skills/autoconverge/workflow/converge.contract.test.mjs +0 -64
- package/.agents/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +0 -1009
- package/.agents/skills/autoconverge/workflow/converge.fix-progress.test.mjs +0 -107
- package/.agents/skills/autoconverge/workflow/converge.fix-recovery.test.mjs +0 -33
- package/.agents/skills/autoconverge/workflow/converge.merge-conflict.test.mjs +0 -15
- package/.agents/skills/autoconverge/workflow/converge.mjs +0 -3132
- package/.agents/skills/autoconverge/workflow/converge.p2-advance.test.mjs +0 -202
- package/.agents/skills/autoconverge/workflow/converge.path-aware.test.mjs +0 -47
- package/.agents/skills/autoconverge/workflow/converge.precatch.test.mjs +0 -152
- package/.agents/skills/autoconverge/workflow/converge.run-input.test.mjs +0 -116
- package/.agents/skills/autoconverge/workflow/converge_multi.mjs +0 -169
- package/.agents/skills/autoconverge/workflow/converge_multi.run-input.test.mjs +0 -173
- package/.agents/skills/autoconverge/workflow/convergence_summary.py +0 -110
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a11d903476b803493.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a26213978adeef6fb.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a3def0d15ed9d9110.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a41f41b1b708ee3b7.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a758b880abecc3ff7.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a8897b89656b1bd16.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-ab1c2d3e4f5a6b7c8.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-abd463d744a1437bc.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-ad19d027ae8ee1816.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/workflows/wf_881252e6-700.json +0 -266
- package/.agents/skills/autoconverge/workflow/render_report.py +0 -1024
- package/.agents/skills/autoconverge/workflow/test_aggregate_runs.py +0 -134
- package/.agents/skills/autoconverge/workflow/test_convergence_summary.py +0 -149
- package/.agents/skills/autoconverge/workflow/test_render_report.py +0 -812
- package/.agents/skills/hitl/SKILL.md +0 -45
- package/.agents/skills/pr-cleanup/SKILL.md +0 -140
- package/.agents/skills/pr-cleanup/reference/process-inventory.md +0 -17
- package/.agents/skills/pr-cleanup/reference/task-seeds.md +0 -22
- package/.agents/skills/pr-name-by-capability/SKILL.md +0 -73
- package/.agents/skills/pr-name-by-capability/reference/fetch-commands.md +0 -29
- package/.agents/skills/pr-name-by-capability/reference/offense-examples.md +0 -32
- package/.agents/skills/pr-name-by-capability/reference/report-template.md +0 -29
- package/.agents/skills/pr-name-by-capability/reference/rule-checklist.md +0 -38
- package/.agents/skills/pr-name-by-capability/reference/task-seeds.md +0 -10
- package/.agents/skills/pr-plain-language-cleanup/SKILL.md +0 -93
- package/.agents/skills/pr-refinement/SKILL.md +0 -31
- package/.agents/skills/pr-shared-extraction/SKILL.md +0 -177
- package/.agents/skills/pr-shared-extraction/reference/examples.md +0 -46
- package/.agents/skills/pr-shared-extraction/reference/offense-taxonomy.md +0 -100
- package/.agents/skills/pr-small-cl/SKILL.md +0 -52
- package/.agents/skills/pr-title-description/SKILL.md +0 -96
- package/.agents/skills/prototype/SKILL.md +0 -85
- package/.agents/skills/prototype/reference/honest-limitations.md +0 -23
- package/.agents/skills/prototype/reference/promotion-tasks.md +0 -23
- package/.agents/skills/prototype/scripts/build_sandbox_settings.py +0 -249
- package/.agents/skills/prototype/scripts/conftest.py +0 -15
- package/.agents/skills/prototype/scripts/launch_sandbox.py +0 -205
- package/.agents/skills/prototype/scripts/probe_sandbox_safety.py +0 -311
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/__init__.py +0 -1
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/__init__.py +0 -0
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/build_sandbox_settings_constants.py +0 -41
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/launch_sandbox_constants.py +0 -23
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/probe_sandbox_safety_constants.py +0 -45
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/prototype_common_constants.py +0 -10
- package/.agents/skills/prototype/scripts/test_build_sandbox_settings.py +0 -275
- package/.agents/skills/prototype/scripts/test_launch_sandbox.py +0 -303
- package/.agents/skills/prototype/scripts/test_probe_sandbox_safety.py +0 -312
- package/.agents/skills/prototype/workflows/promotion.md +0 -25
- package/.agents/skills/prototype/workflows/sandbox.md +0 -35
- package/.agents/skills/rebase/.claude/CLAUDE.md +0 -1
- package/.agents/skills/rebase/AGENTS.md +0 -1
- package/.agents/skills/rebase/SKILL.md +0 -178
- package/.agents/skills/review-router/SKILL.md +0 -51
- package/.agents/skills/review-router/reference/route-policy.json +0 -7
- package/.agents/skills/review-router/reference/task-seeds.md +0 -1
- package/.agents/skills/review-router/scripts/conftest.py +0 -4
- package/.agents/skills/review-router/scripts/review_router.py +0 -50
- package/.agents/skills/review-router/scripts/review_router_cli.py +0 -211
- package/.agents/skills/review-router/scripts/review_router_constants/__init__.py +0 -1
- package/.agents/skills/review-router/scripts/review_router_constants/config/__init__.py +0 -0
- package/.agents/skills/review-router/scripts/review_router_constants/config/constants.py +0 -13
- package/.agents/skills/review-router/scripts/test_review_router.py +0 -23
- package/.agents/skills/review-router/scripts/test_review_router_cli.py +0 -47
- package/.agents/skills/review-tier/SKILL.md +0 -56
- package/.agents/skills/review-tier/reference/task-seeds.md +0 -1
- package/.agents/skills/review-tier/reference/tier-policy.json +0 -9
- package/.agents/skills/review-tier/scripts/conftest.py +0 -4
- package/.agents/skills/review-tier/scripts/review_tier.py +0 -359
- package/.agents/skills/review-tier/scripts/review_tier_constants/__init__.py +0 -1
- package/.agents/skills/review-tier/scripts/review_tier_constants/config/__init__.py +0 -0
- package/.agents/skills/review-tier/scripts/review_tier_constants/config/constants.py +0 -29
- package/.agents/skills/review-tier/scripts/test_generation.py +0 -159
- package/.agents/skills/review-tier/scripts/test_review_tier.py +0 -33
- package/.agents/skills/run-claude-dev-env/SKILL.md +0 -84
- package/.agents/skills/session-log/.claude/CLAUDE.md +0 -1
- package/.agents/skills/session-log/AGENTS.md +0 -1
- package/.agents/skills/session-log/SKILL.md +0 -170
- package/.agents/skills/session-log/templates/frontmatter.md +0 -40
- package/.agents/skills/session-tidy/.claude/CLAUDE.md +0 -1
- package/.agents/skills/session-tidy/AGENTS.md +0 -1
- package/.agents/skills/session-tidy/SKILL.md +0 -191
- package/.agents/skills/skill-builder/references/.claude/CLAUDE.md +0 -1
- package/.agents/skills/skill-builder/references/AGENTS.md +0 -1
- package/.agents/skills/skill-builder/references/delegation-map.md +0 -130
- package/.agents/skills/skill-builder/references/description-field.md +0 -111
- package/.agents/skills/skill-builder/references/deterministic-elements.md +0 -218
- package/.agents/skills/skill-builder/references/progressive-disclosure.md +0 -122
- package/.agents/skills/skill-builder/references/self-audit-checklist.md +0 -126
- package/.agents/skills/skill-builder/references/skill-modularity.md +0 -111
- package/.agents/skills/skill-builder/references/skill-types.md +0 -232
- package/.agents/skills/skill-builder/references/thariq-x-post-skills.json +0 -33
- package/.agents/skills/skill-builder/templates/.claude/CLAUDE.md +0 -1
- package/.agents/skills/skill-builder/templates/AGENTS.md +0 -1
- package/.agents/skills/skill-builder/templates/gap-analysis.md +0 -87
- package/.agents/skills/skill-builder/workflows/.claude/CLAUDE.md +0 -1
- package/.agents/skills/skill-builder/workflows/AGENTS.md +0 -1
- package/.agents/skills/skill-builder/workflows/improve-skill.md +0 -136
- package/.agents/skills/skill-builder/workflows/new-skill.md +0 -179
- package/.agents/skills/skill-builder/workflows/polish-skill.md +0 -139
- package/.agents/skills/source-command-sr-loop/SKILL.md +0 -82
- package/.agents/skills/update/.claude/CLAUDE.md +0 -1
- package/.agents/skills/update/AGENTS.md +0 -1
- package/.agents/skills/update/SKILL.md +0 -190
- package/_shared/pr-loop/AGENTS.md +0 -1
- package/_shared/pr-loop/CLAUDE.md +0 -1
- package/_shared/pr-loop/audit-contract.md +0 -183
- package/_shared/pr-loop/audit-reply-template.md +0 -151
- package/_shared/pr-loop/code-rules-gate.md +0 -65
- package/_shared/pr-loop/fix-protocol.md +0 -60
- package/_shared/pr-loop/gh-payloads.md +0 -75
- package/_shared/pr-loop/post-audit-thread-contract.md +0 -51
- package/_shared/pr-loop/precatch-rubric.md +0 -66
- package/_shared/pr-loop/preflight-proposal.md +0 -56
- package/_shared/pr-loop/scripts/post_audit_thread.py +0 -1242
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/post_audit_thread_constants.py +0 -199
- package/_shared/pr-loop/scripts/tests/test_post_audit_thread.py +0 -1115
- package/_shared/pr-loop/scripts/tests/test_post_audit_thread_constants.py +0 -129
- package/_shared/pr-loop/state-schema.md +0 -45
- package/_shared/pr-loop/worker-spawn.md +0 -189
- /package/{.agents/skills/_shared/pr-loop/scripts → scripts}/test_durable_post_lint.py +0 -0
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
"""Remove git worktrees and run temp directories for a bugteam run.
|
|
2
|
-
|
|
3
|
-
Usage:
|
|
4
|
-
python scripts/teardown_worktrees.py --run-temp-dir <PATH> --all-pr-jsons <JSON>
|
|
5
|
-
|
|
6
|
-
The JSON array must contain objects with keys: number, owner, repo.
|
|
7
|
-
Tolerates already-removed worktrees and missing directories.
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
from __future__ import annotations
|
|
11
|
-
|
|
12
|
-
import argparse
|
|
13
|
-
import json
|
|
14
|
-
import os
|
|
15
|
-
import shutil
|
|
16
|
-
import stat
|
|
17
|
-
import subprocess
|
|
18
|
-
import sys
|
|
19
|
-
from collections.abc import Callable
|
|
20
|
-
from pathlib import Path
|
|
21
|
-
|
|
22
|
-
_self_dir = Path(__file__).resolve().parent
|
|
23
|
-
if str(_self_dir) not in sys.path:
|
|
24
|
-
sys.path.insert(0, str(_self_dir))
|
|
25
|
-
|
|
26
|
-
from _path_resolver import per_pr_workspace
|
|
27
|
-
from skills_pr_loop_constants.path_resolver_constants import ALL_PYTHON_ONEXC_VERSION
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def _remove_readonly_attribute(
|
|
31
|
-
removal_function: Callable[[str], None],
|
|
32
|
-
target_path: str,
|
|
33
|
-
*_exc_info: object,
|
|
34
|
-
) -> None:
|
|
35
|
-
"""Windows-safe handler: strip ReadOnly attribute and retry the syscall.
|
|
36
|
-
|
|
37
|
-
Args:
|
|
38
|
-
removal_function: The syscall that failed (os.unlink or os.rmdir).
|
|
39
|
-
target_path: Path to the file or directory that triggered the error.
|
|
40
|
-
*_exc_info: Exception information (collapses onerror/onexc signature difference).
|
|
41
|
-
"""
|
|
42
|
-
try:
|
|
43
|
-
os.chmod(target_path, stat.S_IWRITE)
|
|
44
|
-
removal_function(target_path)
|
|
45
|
-
except OSError:
|
|
46
|
-
pass
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
def force_rmtree(target_path: str) -> None:
|
|
50
|
-
"""Remove a directory tree, handling Windows ReadOnly attribute.
|
|
51
|
-
|
|
52
|
-
Args:
|
|
53
|
-
target_path: Path to the directory tree to remove.
|
|
54
|
-
"""
|
|
55
|
-
handler_kw: dict[str, object] = (
|
|
56
|
-
{"onexc": _remove_readonly_attribute}
|
|
57
|
-
if sys.version_info >= ALL_PYTHON_ONEXC_VERSION
|
|
58
|
-
else {"onerror": _remove_readonly_attribute}
|
|
59
|
-
)
|
|
60
|
-
try:
|
|
61
|
-
shutil.rmtree(target_path, **handler_kw)
|
|
62
|
-
except OSError:
|
|
63
|
-
pass
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
def remove_worktree(worktree_path: Path) -> bool:
|
|
67
|
-
"""Remove a single git worktree via `git worktree remove`.
|
|
68
|
-
|
|
69
|
-
Args:
|
|
70
|
-
worktree_path: Path to the worktree directory.
|
|
71
|
-
|
|
72
|
-
Returns:
|
|
73
|
-
True when the worktree was registered and removed, False when
|
|
74
|
-
it was already absent or unregistered.
|
|
75
|
-
"""
|
|
76
|
-
if not worktree_path.exists():
|
|
77
|
-
return False
|
|
78
|
-
completed_process = subprocess.run(
|
|
79
|
-
["git", "worktree", "remove", str(worktree_path)],
|
|
80
|
-
capture_output=True,
|
|
81
|
-
text=True,
|
|
82
|
-
encoding="utf-8",
|
|
83
|
-
errors="replace",
|
|
84
|
-
check=False,
|
|
85
|
-
)
|
|
86
|
-
if completed_process.returncode != 0:
|
|
87
|
-
stderr_text = completed_process.stderr or ""
|
|
88
|
-
if "not a working tree" in stderr_text.lower():
|
|
89
|
-
force_rmtree(str(worktree_path))
|
|
90
|
-
return False
|
|
91
|
-
print(
|
|
92
|
-
f"git worktree remove failed for {worktree_path}: {stderr_text}",
|
|
93
|
-
file=sys.stderr,
|
|
94
|
-
)
|
|
95
|
-
return False
|
|
96
|
-
return True
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
def teardown_run(
|
|
100
|
-
*,
|
|
101
|
-
run_temp_dir: Path,
|
|
102
|
-
all_pr_entries: list[dict[str, object]],
|
|
103
|
-
) -> int:
|
|
104
|
-
"""Remove all worktrees and the run temp directory.
|
|
105
|
-
|
|
106
|
-
Args:
|
|
107
|
-
run_temp_dir: Path to the run's temp directory.
|
|
108
|
-
all_pr_entries: List of dicts with number, owner, and repo keys.
|
|
109
|
-
|
|
110
|
-
Returns:
|
|
111
|
-
Count of worktrees successfully removed via git.
|
|
112
|
-
"""
|
|
113
|
-
removed_count = 0
|
|
114
|
-
for each_entry in all_pr_entries:
|
|
115
|
-
pr_number = each_entry.get("number")
|
|
116
|
-
owner = each_entry.get("owner", "")
|
|
117
|
-
repo = each_entry.get("repo", "")
|
|
118
|
-
if not isinstance(pr_number, int):
|
|
119
|
-
continue
|
|
120
|
-
workspace = per_pr_workspace(run_temp_dir, str(owner), str(repo), pr_number)
|
|
121
|
-
if remove_worktree(workspace.worktree):
|
|
122
|
-
removed_count += 1
|
|
123
|
-
|
|
124
|
-
force_rmtree(str(run_temp_dir))
|
|
125
|
-
return removed_count
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
def parse_arguments(all_argv: list[str]) -> argparse.Namespace:
|
|
129
|
-
"""Parse command-line arguments.
|
|
130
|
-
|
|
131
|
-
Args:
|
|
132
|
-
all_argv: Command-line argument list.
|
|
133
|
-
|
|
134
|
-
Returns:
|
|
135
|
-
Parsed namespace with run_temp_dir and all_pr_jsons.
|
|
136
|
-
"""
|
|
137
|
-
parser = argparse.ArgumentParser(description=__doc__)
|
|
138
|
-
parser.add_argument("--run-temp-dir", type=Path, required=True)
|
|
139
|
-
parser.add_argument("--all-pr-jsons", required=True)
|
|
140
|
-
return parser.parse_args(all_argv)
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
def main(all_arguments: list[str]) -> int:
|
|
144
|
-
"""Entry point: remove worktrees and temp directory.
|
|
145
|
-
|
|
146
|
-
Args:
|
|
147
|
-
all_arguments: Command-line arguments.
|
|
148
|
-
|
|
149
|
-
Returns:
|
|
150
|
-
0 on success, 1 on JSON parse failure.
|
|
151
|
-
"""
|
|
152
|
-
arguments = parse_arguments(all_arguments)
|
|
153
|
-
run_temp_dir = getattr(arguments, "run_temp_dir")
|
|
154
|
-
try:
|
|
155
|
-
all_pr_entries = json.loads(getattr(arguments, "all_pr_jsons"))
|
|
156
|
-
except json.JSONDecodeError as exc:
|
|
157
|
-
print(f"Invalid JSON for --all-pr-jsons: {exc}", file=sys.stderr)
|
|
158
|
-
return 1
|
|
159
|
-
if not isinstance(all_pr_entries, list):
|
|
160
|
-
print("--all-pr-jsons must be a JSON array", file=sys.stderr)
|
|
161
|
-
return 1
|
|
162
|
-
|
|
163
|
-
removed_count = teardown_run(
|
|
164
|
-
run_temp_dir=run_temp_dir,
|
|
165
|
-
all_pr_entries=all_pr_entries,
|
|
166
|
-
)
|
|
167
|
-
print(f"Removed {removed_count} worktree(s), cleaned {run_temp_dir.as_posix()}")
|
|
168
|
-
return 0
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
if __name__ == "__main__":
|
|
172
|
-
raise SystemExit(main(sys.argv[1:]))
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
"""Tests for _path_resolver.per_pr_workspace typed structure."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import dataclasses
|
|
6
|
-
import importlib.util
|
|
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_path_resolver() -> ModuleType:
|
|
19
|
-
module_path = _SCRIPTS_DIR / "_path_resolver.py"
|
|
20
|
-
spec = importlib.util.spec_from_file_location("_path_resolver", 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["_path_resolver"] = module
|
|
25
|
-
spec.loader.exec_module(module)
|
|
26
|
-
return module
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
path_resolver = _load_path_resolver()
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def test_per_pr_workspace_returns_typed_structure_with_concrete_fields() -> None:
|
|
33
|
-
run_temp_dir = Path("/tmp/bugteam-pr-422")
|
|
34
|
-
workspace = path_resolver.per_pr_workspace(
|
|
35
|
-
run_temp_dir, "jl-cmd", "claude-dev-env", 422
|
|
36
|
-
)
|
|
37
|
-
assert isinstance(workspace, path_resolver.PerPrWorkspace)
|
|
38
|
-
assert isinstance(workspace.worktree, Path)
|
|
39
|
-
assert workspace.worktree == run_temp_dir / "pr-422" / "worktree"
|
|
40
|
-
assert isinstance(workspace.diff_patch_template, str)
|
|
41
|
-
assert isinstance(workspace.outcome_xml_template, str)
|
|
42
|
-
assert isinstance(workspace.fix_outcome_xml_template, str)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def test_per_pr_workspace_diff_patch_template_carries_loop_placeholder() -> None:
|
|
46
|
-
run_temp_dir = Path("/tmp/bugteam-pr-7")
|
|
47
|
-
workspace = path_resolver.per_pr_workspace(run_temp_dir, "owner", "repo", 7)
|
|
48
|
-
rendered = workspace.diff_patch_template.format(loop=3)
|
|
49
|
-
assert rendered.endswith("loop-3.patch")
|
|
50
|
-
assert "owner-repo-pr-7" in rendered
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def test_per_pr_workspace_diff_patch_template_uses_forward_slashes() -> None:
|
|
54
|
-
run_temp_dir = Path("C:/Users/example/AppData/Local/Temp/bugteam-pr-376")
|
|
55
|
-
workspace = path_resolver.per_pr_workspace(run_temp_dir, "owner", "repo", 376)
|
|
56
|
-
assert "\\" not in workspace.diff_patch_template
|
|
57
|
-
assert workspace.diff_patch_template == (
|
|
58
|
-
"C:/Users/example/AppData/Local/Temp/bugteam-pr-376/"
|
|
59
|
-
"pr-376/owner-repo-pr-376/loop-{loop}.patch"
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def test_per_pr_workspace_is_frozen() -> None:
|
|
64
|
-
run_temp_dir = Path("/tmp/bugteam-pr-9")
|
|
65
|
-
workspace = path_resolver.per_pr_workspace(run_temp_dir, "owner", "repo", 9)
|
|
66
|
-
with pytest.raises(dataclasses.FrozenInstanceError):
|
|
67
|
-
workspace.worktree = Path("/tmp/other")
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def test_sanitize_branch_name_replaces_filesystem_unsafe_characters() -> None:
|
|
71
|
-
assert path_resolver.sanitize_branch_name("feat/my-branch") == "feat-my-branch"
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def test_build_run_name_uses_pr_number_for_single_pr() -> None:
|
|
75
|
-
assert path_resolver.build_run_name(422, "feat/x", is_multi_pr=False) == "bugteam-pr-422"
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def test_build_run_name_uses_sanitized_branch_for_multi_pr() -> None:
|
|
79
|
-
assert path_resolver.build_run_name(422, "feat/x", is_multi_pr=True) == "bugteam-feat-x"
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
def test_slugify_pr_identity_joins_owner_repo_and_number() -> None:
|
|
83
|
-
assert (
|
|
84
|
-
path_resolver.slugify_pr_identity("jl-cmd", "claude-dev-env", 422)
|
|
85
|
-
== "jl-cmd-claude-dev-env-pr-422"
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
def test_outcome_xml_path_embeds_pr_and_loop() -> None:
|
|
90
|
-
worktree_path = Path("/tmp/worktree")
|
|
91
|
-
outcome_path = path_resolver.outcome_xml_path(worktree_path, 422, 3)
|
|
92
|
-
assert outcome_path == worktree_path / ".bugteam-pr422-loop3.outcomes.xml"
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
def test_fix_outcome_xml_path_embeds_pr_and_loop() -> None:
|
|
96
|
-
worktree_path = Path("/tmp/worktree")
|
|
97
|
-
fix_outcome_path = path_resolver.fix_outcome_xml_path(worktree_path, 422, 3)
|
|
98
|
-
assert fix_outcome_path == worktree_path / ".bugteam-pr422-loop3.fix-outcomes.xml"
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
def test_diff_patch_path_joins_slug_and_loop_filename() -> None:
|
|
102
|
-
run_temp_dir = Path("/tmp/run")
|
|
103
|
-
patch_path = path_resolver.diff_patch_path(
|
|
104
|
-
run_temp_dir, "owner", "repo", 7, 2
|
|
105
|
-
)
|
|
106
|
-
assert patch_path == run_temp_dir / "owner-repo-pr-7" / "loop-2.patch"
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
"""Parity tests for the A-Q audit-category schema and projections."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import importlib.util
|
|
6
|
-
import json
|
|
7
|
-
import sys
|
|
8
|
-
from pathlib import Path
|
|
9
|
-
from types import ModuleType
|
|
10
|
-
|
|
11
|
-
_SCRIPTS_DIR = Path(__file__).resolve().parent
|
|
12
|
-
if str(_SCRIPTS_DIR) not in sys.path:
|
|
13
|
-
sys.path.insert(0, str(_SCRIPTS_DIR))
|
|
14
|
-
|
|
15
|
-
from skills_pr_loop_constants.audit_category_schema_constants import (
|
|
16
|
-
CATEGORY_SLUG_KEY,
|
|
17
|
-
CATEGORY_SUB_BUCKETS_KEY,
|
|
18
|
-
PROMPTS_DIRECTORY,
|
|
19
|
-
SCHEMA_CATEGORIES_KEY,
|
|
20
|
-
SKELETON_PLACEHOLDER_FRAGMENT,
|
|
21
|
-
SKELETON_SEPARATOR_LINE,
|
|
22
|
-
UTF8_ENCODING,
|
|
23
|
-
)
|
|
24
|
-
from skills_pr_loop_constants.path_resolver_constants import ALL_AUDIT_CATEGORY_ENTRIES
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def _load_audit_category_schema() -> ModuleType:
|
|
28
|
-
module_path = _SCRIPTS_DIR / "audit_category_schema.py"
|
|
29
|
-
spec = importlib.util.spec_from_file_location("audit_category_schema", module_path)
|
|
30
|
-
assert spec is not None
|
|
31
|
-
assert spec.loader is not None
|
|
32
|
-
module = importlib.util.module_from_spec(spec)
|
|
33
|
-
sys.modules["audit_category_schema"] = module
|
|
34
|
-
spec.loader.exec_module(module)
|
|
35
|
-
return module
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
audit_category_schema = _load_audit_category_schema()
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def test_schema_lists_a_through_q_in_order() -> None:
|
|
42
|
-
schema = audit_category_schema.load_audit_category_schema()
|
|
43
|
-
all_ids = [each_category["id"] for each_category in schema["categories"]]
|
|
44
|
-
assert all_ids == list("ABCDEFGHIJKLMNOPQ")
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def test_schema_entries_match_constant_export() -> None:
|
|
48
|
-
assert (
|
|
49
|
-
audit_category_schema.category_id_title_entries()
|
|
50
|
-
== list(ALL_AUDIT_CATEGORY_ENTRIES)
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
def test_validate_projections_matches_rubrics_and_prompts() -> None:
|
|
55
|
-
all_findings = audit_category_schema.validate_projections()
|
|
56
|
-
assert all_findings == [], all_findings
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def test_skeleton_projection_is_byte_stable() -> None:
|
|
60
|
-
schema = audit_category_schema.load_audit_category_schema()
|
|
61
|
-
first_render = audit_category_schema.render_skeleton_projections(schema)
|
|
62
|
-
second_render = audit_category_schema.render_skeleton_projections(
|
|
63
|
-
json.loads(json.dumps(schema))
|
|
64
|
-
)
|
|
65
|
-
assert first_render == second_render
|
|
66
|
-
assert "A1" in first_render["A"]
|
|
67
|
-
assert first_render["A"].count("\n") >= 1
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def test_schema_omits_worked_example_prose() -> None:
|
|
71
|
-
schema_path = audit_category_schema.audit_category_schema_path()
|
|
72
|
-
schema_text = schema_path.read_text(encoding="utf-8")
|
|
73
|
-
assert "Examples of Category" not in schema_text
|
|
74
|
-
assert "Sample prompt" not in schema_text
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
def test_no_prompt_skeleton_uses_placeholder_count() -> None:
|
|
78
|
-
"""Migrated prompts state a numeric sub-bucket count, never [N]."""
|
|
79
|
-
schema = audit_category_schema.load_audit_category_schema()
|
|
80
|
-
all_findings = audit_category_schema.validate_projections()
|
|
81
|
-
assert all_findings == [], all_findings
|
|
82
|
-
for each_category in schema[SCHEMA_CATEGORIES_KEY]:
|
|
83
|
-
slug = each_category[CATEGORY_SLUG_KEY]
|
|
84
|
-
assert isinstance(slug, str)
|
|
85
|
-
prompt_path = PROMPTS_DIRECTORY / f"{slug}.md"
|
|
86
|
-
all_skeleton_lines: list[str] = []
|
|
87
|
-
for each_line in prompt_path.read_text(encoding=UTF8_ENCODING).splitlines():
|
|
88
|
-
if each_line == SKELETON_SEPARATOR_LINE:
|
|
89
|
-
break
|
|
90
|
-
all_skeleton_lines.append(each_line)
|
|
91
|
-
skeleton_text = "\n".join(all_skeleton_lines)
|
|
92
|
-
assert SKELETON_PLACEHOLDER_FRAGMENT not in skeleton_text, slug
|
|
93
|
-
sub_bucket_count = len(each_category[CATEGORY_SUB_BUCKETS_KEY])
|
|
94
|
-
assert f"decomposed into {sub_bucket_count} sub-buckets" in skeleton_text, slug
|