claude-dev-env 1.94.0 → 2.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/_shared/advisor/CLAUDE.md +2 -2
- package/_shared/advisor/advisor-protocol.md +41 -33
- package/_shared/advisor/scripts/config/advisor_scripts_constants/model_tier_run_validator_constants.py +17 -13
- package/_shared/advisor/scripts/model_tier_run_validator.py +27 -18
- package/_shared/advisor/scripts/tests/test_model_tier_run_validator.py +95 -25
- package/_shared/advisor/scripts/tests/test_tier_model_ids.py +17 -17
- package/_shared/advisor/scripts/tier_model_ids.py +18 -18
- package/_shared/pr-loop/CLAUDE.md +1 -0
- package/_shared/pr-loop/scripts/CLAUDE.md +2 -1
- package/_shared/pr-loop/scripts/README.md +1 -0
- package/_shared/pr-loop/scripts/code_rules_gate.py +253 -1980
- package/_shared/pr-loop/scripts/code_rules_gate_parts/CLAUDE.md +32 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/__init__.py +7 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/added_line_maps.py +268 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/enforcer_loading.py +172 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/gate_arguments.py +70 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/gate_running.py +326 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/git_blob_readers.py +85 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/git_file_sets.py +331 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/staged_test_running.py +369 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/conftest.py +14 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_added_line_maps.py +118 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_enforcer_loading.py +17 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_gate_arguments.py +29 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_gate_running.py +99 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_git_blob_readers.py +69 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_git_file_sets.py +137 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_staged_test_running.py +116 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_violation_scoping.py +75 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_wrapper_plumb_check.py +49 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/violation_scoping.py +328 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/wrapper_plumb_check.py +206 -0
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/code_rules_gate_constants.py +24 -17
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/reviews_disabled_constants.py +1 -0
- package/_shared/pr-loop/scripts/reviews_disabled.py +19 -2
- package/_shared/pr-loop/scripts/test_code_rules_gate.py +278 -0
- package/_shared/pr-loop/scripts/tests/test_code_rules_gate_constants.py +6 -39
- package/_shared/pr-loop/scripts/tests/test_reviews_disabled.py +43 -0
- package/_shared/pr-loop/worker-spawn.md +186 -0
- package/agents/code-verifier.md +1 -1
- package/bin/CLAUDE.md +10 -1
- package/bin/ever-shipped-skills.mjs +73 -0
- package/bin/expand_home_directory_tokens.mjs +1 -1
- package/bin/install.mjs +140 -7
- package/bin/install.prune.test.mjs +457 -0
- package/docs/CODE_RULES.md +1 -1
- package/hooks/advisory/refactor_guard.py +3 -4
- package/hooks/blocking/CLAUDE.md +7 -1
- package/hooks/blocking/block_main_commit.py +2 -2
- package/hooks/blocking/claude_md_orphan_file_blocker.py +75 -699
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/CLAUDE.md +28 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/__init__.py +1 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/config/__init__.py +1 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/config/orphan_blocker_constants.py +18 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/decision.py +81 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/references.py +307 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/scan_plan.py +124 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/subtree_scan.py +179 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/conftest.py +10 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/test_decision.py +34 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/test_references.py +42 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/test_scan_plan.py +27 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/test_subtree_scan.py +30 -0
- package/hooks/blocking/code_rules_boolean_mustcheck.py +1 -1
- package/hooks/blocking/code_rules_enforcer.py +4 -0
- package/hooks/blocking/code_rules_mock_completeness.py +1 -1
- package/hooks/blocking/code_rules_optional_params.py +2 -2
- package/hooks/blocking/code_rules_shared.py +83 -1
- package/hooks/blocking/code_rules_test_assertions.py +1 -1
- package/hooks/blocking/code_rules_test_layout.py +9 -3
- package/hooks/blocking/code_rules_typeddict_stub.py +1 -1
- package/hooks/blocking/gh_pr_author_enforcer.py +1 -1
- package/hooks/blocking/inventory_intent_records/CLAUDE.md +26 -0
- package/hooks/blocking/inventory_intent_records/__init__.py +1 -0
- package/hooks/blocking/inventory_intent_records/config/__init__.py +1 -0
- package/hooks/blocking/inventory_intent_records/config/intent_records_constants.py +20 -0
- package/hooks/blocking/inventory_intent_records/records.py +271 -0
- package/hooks/blocking/inventory_intent_records/tests/conftest.py +10 -0
- package/hooks/blocking/inventory_intent_records/tests/test_records.py +80 -0
- package/hooks/blocking/package_inventory_stale_blocker.py +54 -384
- package/hooks/blocking/package_inventory_stale_blocker_parts/CLAUDE.md +26 -0
- package/hooks/blocking/package_inventory_stale_blocker_parts/__init__.py +1 -0
- package/hooks/blocking/package_inventory_stale_blocker_parts/config/__init__.py +1 -0
- package/hooks/blocking/package_inventory_stale_blocker_parts/config/inventory_blocker_constants.py +16 -0
- package/hooks/blocking/package_inventory_stale_blocker_parts/decision.py +84 -0
- package/hooks/blocking/package_inventory_stale_blocker_parts/inventory_detection.py +307 -0
- package/hooks/blocking/package_inventory_stale_blocker_parts/tests/conftest.py +10 -0
- package/hooks/blocking/package_inventory_stale_blocker_parts/tests/test_decision.py +38 -0
- package/hooks/blocking/package_inventory_stale_blocker_parts/tests/test_inventory_detection.py +61 -0
- package/hooks/blocking/pii_payload_scan.py +138 -42
- package/hooks/blocking/pii_prevention_blocker.py +185 -291
- package/hooks/blocking/pii_prevention_blocker_parts/CLAUDE.md +24 -0
- package/hooks/blocking/pii_prevention_blocker_parts/__init__.py +1 -0
- package/hooks/blocking/pii_prevention_blocker_parts/config/__init__.py +1 -0
- package/hooks/blocking/pii_prevention_blocker_parts/config/repository_resolution_constants.py +28 -0
- package/hooks/blocking/pii_prevention_blocker_parts/repository_exemption.py +214 -0
- package/hooks/blocking/pii_prevention_blocker_parts/repository_resolution.py +208 -0
- package/hooks/blocking/plain_language_blocker.py +138 -4
- package/hooks/blocking/pr_description_command_parser.py +8 -4
- package/hooks/blocking/precommit_code_rules_gate.py +3 -3
- package/hooks/blocking/sensitive_file_protector.py +114 -48
- package/hooks/blocking/tdd_enforcer.py +97 -601
- package/hooks/blocking/tdd_enforcer_parts/CLAUDE.md +30 -0
- package/hooks/blocking/tdd_enforcer_parts/__init__.py +1 -0
- package/hooks/blocking/tdd_enforcer_parts/candidate_paths.py +142 -0
- package/hooks/blocking/tdd_enforcer_parts/config/__init__.py +1 -0
- package/hooks/blocking/tdd_enforcer_parts/config/tdd_enforcer_constants.py +32 -0
- package/hooks/blocking/tdd_enforcer_parts/content_analysis.py +268 -0
- package/hooks/blocking/tdd_enforcer_parts/decisions.py +92 -0
- package/hooks/blocking/tdd_enforcer_parts/freshness.py +80 -0
- package/hooks/blocking/tdd_enforcer_parts/git_tracking.py +63 -0
- package/hooks/blocking/tdd_enforcer_parts/path_classification.py +119 -0
- package/hooks/blocking/tdd_enforcer_parts/tests/conftest.py +10 -0
- package/hooks/blocking/tdd_enforcer_parts/tests/test_candidate_paths.py +31 -0
- package/hooks/blocking/tdd_enforcer_parts/tests/test_content_analysis.py +30 -0
- package/hooks/blocking/tdd_enforcer_parts/tests/test_decisions.py +34 -0
- package/hooks/blocking/tdd_enforcer_parts/tests/test_freshness.py +28 -0
- package/hooks/blocking/tdd_enforcer_parts/tests/test_git_tracking.py +48 -0
- package/hooks/blocking/tdd_enforcer_parts/tests/test_path_classification.py +36 -0
- package/hooks/blocking/test_code_rules_enforcer_scratchpad.py +105 -0
- package/hooks/blocking/test_code_rules_shared.py +181 -0
- package/hooks/blocking/test_inventory_deadlock_resolution.py +154 -0
- package/hooks/blocking/test_pii_payload_scan.py +168 -0
- package/hooks/blocking/test_plain_language_blocker_allowlist.py +184 -0
- package/hooks/blocking/test_sensitive_file_protector.py +185 -0
- package/hooks/blocking/test_tdd_enforcer_restore.py +108 -0
- package/hooks/blocking/test_tdd_enforcer_scratchpad.py +105 -0
- package/hooks/blocking/tests/conftest.py +10 -0
- package/hooks/blocking/tests/test_pii_prevention_blocker.py +260 -0
- package/hooks/blocking/tests/test_repository_exemption.py +105 -0
- package/hooks/blocking/tests/test_repository_resolution.py +108 -0
- package/hooks/diagnostic/hook_log_extractor.py +12 -10
- package/hooks/git-hooks/post_commit.py +3 -4
- package/hooks/hooks_constants/CLAUDE.md +4 -2
- package/hooks/hooks_constants/banned_identifiers_constants.py +0 -1
- package/hooks/hooks_constants/code_rules_path_utils_constants.py +1 -1
- package/hooks/hooks_constants/harness_scratchpad_constants.py +17 -0
- package/hooks/hooks_constants/local_identity.py +59 -8
- package/hooks/hooks_constants/pii_prevention_constants.py +0 -6
- package/hooks/hooks_constants/plain_language_blocker_constants.py +5 -0
- package/hooks/hooks_constants/sensitive_file_protector_constants.py +42 -0
- package/hooks/hooks_constants/test_local_identity.py +105 -3
- package/hooks/pyproject.toml +52 -4
- package/hooks/session/plugin_data_dir_cleanup.py +0 -1
- package/hooks/validation/mypy_validator.py +2 -2
- package/hooks/validators/CLAUDE.md +1 -1
- package/hooks/validators/README.md +2 -0
- package/hooks/validators/health_check.py +1 -0
- package/hooks/validators/mypy_integration.py +2 -0
- package/hooks/validators/python_style_checks.py +114 -136
- package/hooks/validators/python_style_helpers.py +95 -0
- package/hooks/validators/ruff_integration.py +3 -0
- package/hooks/validators/test_python_style_checks.py +0 -164
- package/hooks/validators/test_python_style_checks_decorator_gap.py +119 -0
- package/hooks/validators/test_python_style_fixes.py +251 -0
- package/hooks/validators/test_python_style_helpers.py +125 -0
- package/hooks/workflow/auto_formatter.py +5 -4
- package/package.json +1 -1
- package/rules/CLAUDE.md +1 -0
- package/rules/anti-corollary-tests.md +69 -0
- package/rules/bdd.md +1 -3
- package/rules/code-reviews.md +1 -1
- package/rules/gh-paginate.md +1 -1
- package/rules/plain-language.md +2 -0
- package/scripts/CLAUDE.md +4 -0
- package/scripts/dev_env_scripts_constants/CLAUDE.md +6 -4
- package/scripts/dev_env_scripts_constants/code_review_constants.py +71 -0
- package/scripts/dev_env_scripts_constants/grok_worker_constants.py +435 -0
- package/scripts/dev_env_scripts_constants/timing.py +7 -1
- package/scripts/grok_headless_runner.py +294 -0
- package/scripts/grok_worker_preflight.py +410 -0
- package/scripts/invoke_code_review.py +463 -0
- package/scripts/resolve_worker_spawn.py +619 -0
- package/scripts/spawn_grok_batch.py +672 -0
- package/scripts/test_grok_headless_runner.py +626 -0
- package/scripts/test_grok_worker_preflight.py +1054 -0
- package/scripts/test_invoke_code_review.py +672 -0
- package/scripts/test_resolve_worker_spawn.py +1014 -0
- package/scripts/test_spawn_grok_batch.py +1017 -0
- package/skills/CLAUDE.md +6 -3
- package/skills/_shared/pr-loop/scripts/build_audit_prompt.py +72 -13
- package/skills/_shared/pr-loop/scripts/build_fix_prompt.py +121 -14
- package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py +78 -0
- package/skills/_shared/pr-loop/scripts/test_build_audit_prompt.py +121 -0
- package/skills/_shared/pr-loop/scripts/test_build_fix_prompt.py +196 -6
- package/skills/autoconverge/CLAUDE.md +3 -3
- package/skills/autoconverge/SKILL.md +9 -3
- package/skills/autoconverge/reference/CLAUDE.md +2 -2
- package/skills/autoconverge/reference/convergence.md +33 -11
- package/skills/autoconverge/reference/stop-conditions.md +16 -5
- package/skills/autoconverge/workflow/CLAUDE.md +2 -1
- package/skills/autoconverge/workflow/converge.clean-audit.test.mjs +7 -2
- package/skills/autoconverge/workflow/converge.codex-gate.test.mjs +300 -0
- package/skills/autoconverge/workflow/converge.contract.test.mjs +5 -5
- package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +29 -29
- package/skills/autoconverge/workflow/converge.fix-progress.test.mjs +1 -1
- package/skills/autoconverge/workflow/converge.mjs +202 -18
- package/skills/bugteam/CLAUDE.md +2 -2
- package/skills/bugteam/CONSTRAINTS.md +3 -2
- package/skills/bugteam/PROMPTS.md +7 -6
- package/skills/bugteam/SKILL.md +18 -13
- package/skills/bugteam/reference/README.md +2 -3
- package/skills/bugteam/reference/audit-and-teammates.md +215 -35
- package/skills/bugteam/reference/design-rationale.md +1 -1
- package/skills/bugteam/reference/obstacles/CLAUDE.md +1 -1
- package/skills/bugteam/reference/team-setup.md +8 -2
- package/skills/closeout/SKILL.md +153 -0
- package/skills/closeout/reference/handoff-prompt-template.md +72 -0
- package/skills/closeout/reference/issue-body-templates.md +108 -0
- package/skills/closeout/reference/pii-redaction-checklist.md +36 -0
- package/skills/codex-review/CLAUDE.md +46 -0
- package/skills/codex-review/SKILL.md +181 -0
- package/skills/codex-review/reference/CLAUDE.md +15 -0
- package/skills/codex-review/reference/cli-contract.md +253 -0
- package/skills/codex-review/reference/loop-integration.md +118 -0
- package/skills/codex-review/scripts/codex_down_classifier.py +98 -0
- package/skills/codex-review/scripts/codex_review_scripts_constants/CLAUDE.md +18 -0
- package/skills/codex-review/scripts/codex_review_scripts_constants/__init__.py +1 -0
- package/skills/codex-review/scripts/codex_review_scripts_constants/classifier_constants.py +35 -0
- package/skills/codex-review/scripts/codex_review_scripts_constants/codex_usage_probe_constants.py +86 -0
- package/skills/codex-review/scripts/codex_review_scripts_constants/findings_constants.py +18 -0
- package/skills/codex-review/scripts/codex_review_scripts_constants/run_constants.py +45 -0
- package/skills/codex-review/scripts/codex_usage_probe.py +573 -0
- package/skills/codex-review/scripts/fixtures/auth_failure_synthetic.txt +1 -0
- package/skills/codex-review/scripts/fixtures/config_load_failure_v0.125.0.txt +1 -0
- package/skills/codex-review/scripts/fixtures/freeform_findings_v0.144.3.txt +6 -0
- package/skills/codex-review/scripts/fixtures/model_rejection_v0.125.0.jsonl +5 -0
- package/skills/codex-review/scripts/fixtures/structured_findings.txt +13 -0
- package/skills/codex-review/scripts/fixtures/success_stream_v0.144.3.jsonl +6 -0
- package/skills/codex-review/scripts/fixtures/unknown_failure_synthetic.txt +1 -0
- package/skills/codex-review/scripts/fixtures/usage_limit_synthetic.txt +1 -0
- package/skills/codex-review/scripts/parse_codex_findings.py +207 -0
- package/skills/codex-review/scripts/run_codex_review.py +415 -0
- package/skills/codex-review/scripts/test_codex_down_classifier.py +143 -0
- package/skills/codex-review/scripts/test_codex_usage_probe.py +678 -0
- package/skills/codex-review/scripts/test_parse_codex_findings.py +130 -0
- package/skills/codex-review/scripts/test_run_codex_review.py +812 -0
- package/skills/codex-review/test_skill_scaffold.py +192 -0
- package/skills/grok-spawn/CLAUDE.md +28 -0
- package/skills/grok-spawn/SKILL.md +226 -0
- package/skills/grok-spawn/reference/flag-profiles.md +132 -0
- package/skills/grok-spawn/reference/worker-briefs.md +152 -0
- package/skills/grokify/SKILL.md +9 -1
- package/skills/grokify/capability-claims.test.mjs +28 -0
- package/skills/grokify/evals/README.md +72 -0
- package/skills/grokify/evals/parse-payload.test.mjs +171 -0
- package/skills/grokify/evals/run-capability-evals.mjs +545 -0
- package/skills/orchestrator/SKILL.md +32 -22
- package/skills/orchestrator-refresh/SKILL.md +12 -8
- package/skills/pr-converge/CLAUDE.md +1 -1
- package/skills/pr-converge/SKILL.md +34 -13
- package/skills/pr-converge/reference/convergence-gates.md +42 -15
- package/skills/pr-converge/reference/fix-protocol.md +1 -1
- package/skills/pr-converge/reference/ground-rules.md +1 -1
- package/skills/pr-converge/reference/per-tick.md +130 -42
- package/skills/pr-converge/reference/state-schema.md +10 -0
- package/skills/pr-converge/scripts/CLAUDE.md +2 -0
- package/skills/pr-converge/scripts/_pr_converge_path_setup.py +5 -1
- package/skills/pr-converge/scripts/check_convergence.py +605 -29
- package/skills/pr-converge/scripts/check_convergence_availability.py +232 -0
- package/skills/pr-converge/scripts/check_convergence_gates.py +279 -235
- package/skills/pr-converge/scripts/check_convergence_thread_gates.py +1 -1
- package/skills/pr-converge/scripts/pr_converge_scripts_constants/convergence_gate_constants.py +36 -2
- package/skills/pr-converge/scripts/test__pr_converge_path_setup.py +4 -0
- package/skills/pr-converge/scripts/test_check_convergence.py +71 -3
- package/skills/pr-converge/scripts/test_check_convergence_availability.py +326 -0
- package/skills/pr-converge/scripts/test_check_convergence_codex.py +507 -0
- package/skills/pr-converge/scripts/test_check_convergence_contract.py +89 -17
- package/skills/pr-converge/scripts/test_check_convergence_fixture.py +179 -0
- package/skills/pr-converge/scripts/test_check_convergence_gates.py +84 -68
- package/skills/pr-converge/scripts/test_check_convergence_thread_gates.py +24 -0
- package/skills/pr-converge/test_step5_host_branch.py +106 -0
- package/skills/pr-fix-protocol/SKILL.md +65 -0
- package/skills/pr-loop-cloud-transport/SKILL.md +2 -0
- package/skills/reviewer-gates/SKILL.md +7 -5
- package/skills/skill-builder/references/skill-modularity.md +1 -1
- package/skills/team-advisor/SKILL.md +16 -12
- package/system-prompts/software-engineer.xml +7 -6
- package/hooks/validators/test_verify_paths.py +0 -32
- package/hooks/validators/verify_paths.py +0 -57
|
@@ -48,6 +48,7 @@ PLUGIN_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__
|
|
|
48
48
|
HOOKS_DIR = os.path.join(PLUGIN_ROOT, "hooks") + os.sep
|
|
49
49
|
PYTHON_FORMAT_TIMEOUT_SECONDS = 12
|
|
50
50
|
JS_FORMAT_TIMEOUT_SECONDS = 30
|
|
51
|
+
GIT_LS_FILES_TIMEOUT_SECONDS = 5
|
|
51
52
|
PRETTIER_CONFIG_NAMES = {
|
|
52
53
|
".prettierrc",
|
|
53
54
|
".prettierrc.json",
|
|
@@ -99,10 +100,10 @@ def is_untracked_in_git(file_path: str) -> bool:
|
|
|
99
100
|
try:
|
|
100
101
|
git_check = subprocess.run(
|
|
101
102
|
["git", "ls-files", "--error-unmatch", file_path],
|
|
102
|
-
capture_output=True,
|
|
103
|
+
check=False, capture_output=True,
|
|
103
104
|
text=True,
|
|
104
105
|
cwd=containing_directory,
|
|
105
|
-
timeout=
|
|
106
|
+
timeout=GIT_LS_FILES_TIMEOUT_SECONDS,
|
|
106
107
|
)
|
|
107
108
|
return git_check.returncode != 0
|
|
108
109
|
except (FileNotFoundError, subprocess.TimeoutExpired):
|
|
@@ -150,7 +151,7 @@ def main() -> None:
|
|
|
150
151
|
[sys.executable, "-m", "black", file_path],
|
|
151
152
|
]:
|
|
152
153
|
try:
|
|
153
|
-
format_run = subprocess.run(each_formatter_command, capture_output=True, text=True, timeout=PYTHON_FORMAT_TIMEOUT_SECONDS)
|
|
154
|
+
format_run = subprocess.run(each_formatter_command, check=False, capture_output=True, text=True, timeout=PYTHON_FORMAT_TIMEOUT_SECONDS)
|
|
154
155
|
if format_run.returncode == 0:
|
|
155
156
|
formatter_name = each_formatter_command[0] if each_formatter_command[0] != sys.executable else each_formatter_command[2]
|
|
156
157
|
send_format_notification(file_path, formatter_name)
|
|
@@ -165,7 +166,7 @@ def main() -> None:
|
|
|
165
166
|
try:
|
|
166
167
|
prettier_run = subprocess.run(
|
|
167
168
|
["npx", "--yes", "prettier", "--write", file_path],
|
|
168
|
-
capture_output=True,
|
|
169
|
+
check=False, capture_output=True,
|
|
169
170
|
text=True,
|
|
170
171
|
timeout=JS_FORMAT_TIMEOUT_SECONDS,
|
|
171
172
|
)
|
package/package.json
CHANGED
package/rules/CLAUDE.md
CHANGED
|
@@ -12,6 +12,7 @@ Rule files installed into `~/.claude/rules/` by `bin/install.mjs`. Claude Code l
|
|
|
12
12
|
| File | Rule |
|
|
13
13
|
|---|---|
|
|
14
14
|
| `agent-spawn-protocol.md` | Protocol for spawning subagents: context sufficiency check, prompt generation via `/prompt-generator`, then spawn |
|
|
15
|
+
| `anti-corollary-tests.md` | Tests must carry information: no corollary matrices over canonical reductions, no suite that only matches a dead-implementation default, stated mutation in the audit lane |
|
|
15
16
|
| `ask-user-question-required.md` | Every user-directed question goes through the `AskUserQuestion` tool — no plain-text questions |
|
|
16
17
|
| `bdd.md` | BDD discovery-driven development workflow and Example Mapping reference |
|
|
17
18
|
| `claude-md-orphan-file.md` | Every backticked bare filename in a per-directory `CLAUDE.md` table's first column names a file in that directory's subtree |
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/test_*.py"
|
|
4
|
+
- "**/*_test.py"
|
|
5
|
+
- "**/*.test.*"
|
|
6
|
+
- "**/*.spec.*"
|
|
7
|
+
- "**/conftest.py"
|
|
8
|
+
- "**/tests/**"
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Anti-Corollary Tests
|
|
12
|
+
|
|
13
|
+
**When this applies:** Any Write or Edit that adds or changes tests.
|
|
14
|
+
|
|
15
|
+
## Rule
|
|
16
|
+
|
|
17
|
+
A large green suite can prove almost nothing. Before you keep a case, answer three questions. If any answer fails, cut the case or replace it with one that carries information.
|
|
18
|
+
|
|
19
|
+
## The three questions
|
|
20
|
+
|
|
21
|
+
### 1. Is this a corollary?
|
|
22
|
+
|
|
23
|
+
When the code reduces each input to a canonical form and then compares the forms, every pairwise combination of input spellings follows once the reduction is proven canonical. Walking the full N×N matrix restates that fact. It adds cases and runtime, and it buries the few cases that carry information.
|
|
24
|
+
|
|
25
|
+
**Do this:** test the reduction once. Test the comparison with a few discriminating cases. Do not walk the cross product of spellings.
|
|
26
|
+
|
|
27
|
+
### 2. Could this test pass if the mechanism were dead?
|
|
28
|
+
|
|
29
|
+
Name the degenerate value a dead implementation would return — empty string, `None`, `False`, a blanket refusal, an empty collection. When the test's expected value equals that default, the test passes whether the mechanism works or not. On its own it proves nothing.
|
|
30
|
+
|
|
31
|
+
**Do this:** keep at least one case that expects the **non-default** answer, and drive the real code path — not a mock that only records that a call happened.
|
|
32
|
+
|
|
33
|
+
### 3. What single change to the code would make this test fail?
|
|
34
|
+
|
|
35
|
+
When the honest answer is "none," or "only a change that also breaks everything else," the test is decoration. Drop it or rewrite it so one named mutation kills it.
|
|
36
|
+
|
|
37
|
+
## What a mechanism with a degenerate failure mode needs
|
|
38
|
+
|
|
39
|
+
1. **At least one non-default case** that exercises the live path and expects the non-default answer.
|
|
40
|
+
2. **A stated mutation (audit lane):** name one specific change to the code and record how many tests it kills. A mutation that kills zero tests means the suite proves nothing. A reviewer or an audit skill checks this; a hook does not compute it.
|
|
41
|
+
3. **A few discriminating cases** in place of a large matrix.
|
|
42
|
+
|
|
43
|
+
## Worked shape (sanitized)
|
|
44
|
+
|
|
45
|
+
A write guard decides whether a write is about to hit a production database. It reduces each database URL to a canonical endpoint identity, then compares identities.
|
|
46
|
+
|
|
47
|
+
Two independent mutations show the two halves of a useful suite:
|
|
48
|
+
|
|
49
|
+
- Gut the reduction so it always returns the empty string: the guard fails **closed** and refuses everything. Only the *allow*-expecting cases die.
|
|
50
|
+
- Abandon the reduction and compare raw hostnames: the guard fails **open** and allows a production write. Only the *refuse*-expecting cases die.
|
|
51
|
+
|
|
52
|
+
Opposite breaks kill opposite halves. A suite with only one half cannot see one of those breaks. Build both halves; skip the spelling matrix once the reduction is covered.
|
|
53
|
+
|
|
54
|
+
## What this is not
|
|
55
|
+
|
|
56
|
+
A structural hook is the wrong tool here. "Is this a corollary?" and "would this pass against a dead implementation?" need the intent of the code under test. A hook that pattern-matches `parametrize` breadth or counts assertions fires on correct suites and trains people to ignore it. A false-positive gate on a judgment call is worse than no gate. This rule stays judgment-only, with the stated-mutation check in the audit lane — the same pattern as other judgment rules in this package that have no Write/Edit blocker.
|
|
57
|
+
|
|
58
|
+
## Sibling rules
|
|
59
|
+
|
|
60
|
+
| Rule | Role |
|
|
61
|
+
|---|---|
|
|
62
|
+
| `tdd.md` | Write a failing test before production code |
|
|
63
|
+
| `testing.md` | Mocks and test infrastructure standards |
|
|
64
|
+
| `paired-test-coverage.md` | Every public function in an established suite gets a behavioral test |
|
|
65
|
+
| `anti-corollary-tests.md` | Each test carries information; no corollary matrices; no suite that only matches the dead default |
|
|
66
|
+
|
|
67
|
+
## Enforcement
|
|
68
|
+
|
|
69
|
+
The AI review lane and audit skills carry this rule: an agent applies it to the test lines a PR changes. No blocking hook backs it, because corollary and dead-default judgments need meaning a regex cannot read.
|
package/rules/bdd.md
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
**Canonical detail:** `~/.claude/system-prompts/software-engineer.xml` → `<behavior_protocol>`.
|
|
4
4
|
|
|
5
|
-
**On-demand depth:** `@~/.claude/skills/bdd-protocol/SKILL.md` (Example Mapping §6.4, §7.6 catalog, solo patterns). Tracking design: [jl-cmd/claude-dev-env#82](https://github.com/jl-cmd/claude-dev-env/issues/82).
|
|
6
|
-
|
|
7
5
|
**Optional long-form references (load when needed):**
|
|
8
6
|
|
|
9
7
|
- `@~/.claude/docs/BDD_SCENARIO_QUALITY.md` — seven scenario quality patterns (§7.6-style)
|
|
@@ -21,7 +19,7 @@ Conversation is the essential practice: if discovery is skipped, structured form
|
|
|
21
19
|
|
|
22
20
|
## Solo developer
|
|
23
21
|
|
|
24
|
-
You are often the stakeholder. Use **Example Mapping** in chat ("the one where …", probes, parking lot).
|
|
22
|
+
You are often the stakeholder. Use **Example Mapping** in chat ("the one where …", probes, parking lot). See the optional long-form references above for the full algorithm and anti-pattern list.
|
|
25
23
|
|
|
26
24
|
## Naming
|
|
27
25
|
|
package/rules/code-reviews.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**When this applies:** GitHub PR review feedback on a branch you are fixing.
|
|
4
4
|
|
|
5
|
-
**MANDATORY PROTOCOL
|
|
5
|
+
**MANDATORY PROTOCOL:**
|
|
6
6
|
|
|
7
7
|
1. Fetch ALL reviewer comments BEFORE any fixes
|
|
8
8
|
2. Create TodoWrite checklist - One item per comment
|
package/rules/gh-paginate.md
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
# gh API Pagination
|
|
2
2
|
|
|
3
|
-
Every `gh api` read of a paginated GitHub list endpoint (PR `reviews`/`comments`/`files`, issue `comments`, `pulls`, `issues`) uses `--paginate --slurp` piped to **external** `jq` — `gh`'s built-in `--jq` runs per page, so cross-page operations like `sort_by | last` give wrong-but-confident results. Single-object endpoints (`pulls/<n>`, `issues/<n>`) skip pagination and may use `--jq` directly.
|
|
3
|
+
Every `gh api` read of a paginated GitHub list endpoint (PR `reviews`/`comments`/`files`, issue `comments`, `pulls`, `issues`) uses `--paginate --slurp` piped to **external** `jq` — `gh`'s built-in `--jq` runs per page, so cross-page operations like `sort_by | last` give wrong-but-confident results. Single-object endpoints (`pulls/<n>`, `issues/<n>`) skip pagination and may use `--jq` directly. For a newest-first walk, sort the slurped array and take the last element; for single-page bounds, cap with a `per_page` query parameter.
|
package/rules/plain-language.md
CHANGED
|
@@ -3,3 +3,5 @@
|
|
|
3
3
|
All prose a person reads (chat, `AskUserQuestion`, docs, PR/issue bodies, commits): everyday words, short active sentences, lead with the answer, define jargon on first use, and give only the detail the reader needs to act (progressive disclosure). Aim for first-pass readability by a non-specialist. Exact identifiers, file paths, and API names stay exact; code is out of scope.
|
|
4
4
|
|
|
5
5
|
The `plain_language_blocker` PreToolUse hook (AskUserQuestion + `.md` Write/Edit/MultiEdit) blocks a heavy word and names the everyday swap; code fences, inline code, blockquotes, URLs, and file paths are skipped.
|
|
6
|
+
|
|
7
|
+
A project can keep its own domain words out of the check with a `.claude/plain-language-allow.json` file: a JSON array of terms. An exact, case-insensitive, whole-word match on any term passes. The hook reads this file only from inside the project tree, up to the repository root, so each project's allowlist stays with its own code.
|
package/scripts/CLAUDE.md
CHANGED
|
@@ -8,9 +8,13 @@ Utility scripts installed into `~/.claude/scripts/` by `bin/install.mjs`. Each s
|
|
|
8
8
|
|---|---|
|
|
9
9
|
| `claude_chain_runner.py` | Runs a `claude` invocation through a config-driven fallback chain (`~/.claude/claude-chain.json`): the leading binary serves the call, and only a usage-limit failure falls over to the next logged-in binary; usable as an imported module (`run_claude`) or a CLI. Copy `claude-chain.example.json` to `~/.claude/claude-chain.json` and list your binaries in fallback order |
|
|
10
10
|
| `gh_artifact_upload.py` | Uploads a file to a repo's durable `artifacts` prerelease under a timestamped asset name and prints the permanent download URL a GitHub post can link |
|
|
11
|
+
| `grok_headless_runner.py` | Runs one worker as headless `grok`: builds argv, mints a unique leader socket, captures streams, kills on timeout with grace, classifies ok/usage_limit/auth_failure/timeout/error; imported by `spawn_grok_batch.py` |
|
|
12
|
+
| `grok_worker_preflight.py` | Soft gate for the headless grok tier: binary on PATH, `grok models` auth, install manifest + role agents, opt-in cached live ping; non-zero exit is fallthrough, not failure |
|
|
11
13
|
| `setup_project_paths.py` | One-time bootstrap: discovers git repos via `es.exe` (Everything) and writes `~/.claude/project-paths.json`; never hardcodes scan roots |
|
|
14
|
+
| `spawn_grok_batch.py` | Launches a fleet of headless grok workers from a JSON batch spec: gates once through the preflight, assembles each prompt from part files, staggers starts, runs each through `grok_headless_runner.py`, and emits one batch summary JSON |
|
|
12
15
|
| `sweep_empty_dirs.py` | Deletes empty directories older than a configurable age under a given root; runs once (`--once`) or in continuous-watch mode |
|
|
13
16
|
| `sync_to_cursor.py` | Entry point for syncing Claude rules to Cursor `.mdc` files; delegates to the `sync_to_cursor/` package |
|
|
17
|
+
| `resolve_worker_spawn.py` | Dispatches a worker role through grok then claude fallback tiers (preflight, headless grok, `claude_agent_required` handoff, optional claude headless); protocol: [`../_shared/pr-loop/worker-spawn.md`](../_shared/pr-loop/worker-spawn.md) |
|
|
14
18
|
|
|
15
19
|
## PowerShell scripts
|
|
16
20
|
|
|
@@ -6,11 +6,13 @@ Named constants for scripts in `scripts/`. Follows the project convention that t
|
|
|
6
6
|
|
|
7
7
|
| File | Constants for |
|
|
8
8
|
|---|---|
|
|
9
|
-
| `timing.py` | `sweep_empty_dirs.py`
|
|
10
|
-
| `gh_artifact_upload_constants.py` | `gh_artifact_upload.py`
|
|
11
|
-
| `claude_chain_constants.py` | `claude_chain_runner.py`
|
|
9
|
+
| `timing.py` | `sweep_empty_dirs.py` - `DEFAULT_AGE_SECONDS` (smallest age before an empty directory is eligible for removal) and `DEFAULT_POLL_INTERVAL` (seconds between sweep passes in continuous-watch mode); `spawn_grok_batch.py` - `WORKER_STAGGER_SECONDS` (seconds between staggered headless grok worker starts); `invoke_code_review.py` - `DEFAULT_CODE_REVIEW_TIMEOUT_SECONDS` (timeout for one headless `/code-review` chain run) |
|
|
10
|
+
| `gh_artifact_upload_constants.py` | `gh_artifact_upload.py` - the `artifacts` release tag, title, and notes body, the GitHub CLI binary name, the asset-name timestamp format and template, the asset download URL template, the notes-file suffix, and the text encoding |
|
|
11
|
+
| `claude_chain_constants.py` | `claude_chain_runner.py` - the chain config filename and home subdirectory, the usage-limit signature text, the per-binary status labels, the default timeout, CLI flag and separator tokens, config JSON keys, invalid-shape reason text, config-error and exhausted-chain message templates, and CLI exit codes |
|
|
12
|
+
| `grok_worker_constants.py` | `grok_worker_preflight.py`, `grok_headless_runner.py`, and `spawn_grok_batch.py` - the `grok` binary name and CLI flags, model and subcommand tokens, leader-socket and scratch-file name parts, auth and usage-limit signature lists, outcome classifications, fallthrough reasons, tool-profile names and prompt headers, timeouts and turn caps (including launch-failure return code and post-kill grace), ping-cache keys and TTL, batch-spec and summary JSON keys, the prompt-part and report-stream join separators, and the CLI launch-error stderr prefix |
|
|
13
|
+
| `code_review_constants.py` | `invoke_code_review.py` - the `/code-review high --fix` prompt, opus model alias, permission-mode flag and value, result mode and JSON keys, session-model CLI flag, git dirty-check tokens, and in-session return markers |
|
|
12
14
|
| `__init__.py` | Empty package marker |
|
|
13
15
|
|
|
14
16
|
## Convention
|
|
15
17
|
|
|
16
|
-
Every constant is `UPPER_SNAKE_CASE` with an explicit type annotation and a docstring. Scripts import from here rather than embedding literal values in their bodies.
|
|
18
|
+
Every constant is `UPPER_SNAKE_CASE` with an explicit type annotation and a docstring. Scripts import from here rather than embedding literal values in their bodies.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""Named constants for the host-aware `/code-review` invoker.
|
|
2
|
+
|
|
3
|
+
`invoke_code_review.py` imports every scalar and structural constant it
|
|
4
|
+
needs from this module (and shared flag tokens from
|
|
5
|
+
`grok_worker_constants`) so the prompt, model alias, and JSON keys are
|
|
6
|
+
never hardcoded twice.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
CODE_REVIEW_SLASH_COMMAND: str = "/code-review"
|
|
12
|
+
"""Built-in Claude Code slash command that runs the repository review."""
|
|
13
|
+
|
|
14
|
+
CODE_REVIEW_EFFORT: str = "high"
|
|
15
|
+
"""Effort level passed to the built-in review slash command."""
|
|
16
|
+
|
|
17
|
+
CODE_REVIEW_FIX_FLAG: str = "--fix"
|
|
18
|
+
"""Slash-command flag that applies automatic fixes for review findings."""
|
|
19
|
+
|
|
20
|
+
CODE_REVIEW_PROMPT: str = (
|
|
21
|
+
f"{CODE_REVIEW_SLASH_COMMAND} {CODE_REVIEW_EFFORT} {CODE_REVIEW_FIX_FLAG}"
|
|
22
|
+
)
|
|
23
|
+
"""Single-turn prompt that runs the built-in review slash command with fixes."""
|
|
24
|
+
|
|
25
|
+
CODE_REVIEW_MODEL_ALIAS: str = "opus"
|
|
26
|
+
"""CLI `--model` short alias the review always pins to."""
|
|
27
|
+
|
|
28
|
+
PERMISSION_MODE_FLAG: str = "--permission-mode"
|
|
29
|
+
"""CLI flag that selects how the headless claude process handles tool permission prompts."""
|
|
30
|
+
|
|
31
|
+
PERMISSION_MODE_BYPASS: str = "bypassPermissions"
|
|
32
|
+
"""Permission-mode value that auto-approves tools for unattended chain runs."""
|
|
33
|
+
|
|
34
|
+
MODE_IN_SESSION: str = "in_session"
|
|
35
|
+
"""Result mode when the host is Claude and the session already runs opus."""
|
|
36
|
+
|
|
37
|
+
MODE_CHAIN: str = "chain"
|
|
38
|
+
"""Result mode when the helper spawns a headless claude chain for the review."""
|
|
39
|
+
|
|
40
|
+
RESULT_KEY_MODE: str = "mode"
|
|
41
|
+
"""JSON result key naming the review mode (`in_session` or `chain`)."""
|
|
42
|
+
|
|
43
|
+
RESULT_KEY_SERVED_COMMAND: str = "served_command"
|
|
44
|
+
"""JSON result key naming the chain binary that served the call, or null."""
|
|
45
|
+
|
|
46
|
+
RESULT_KEY_RETURNCODE: str = "returncode"
|
|
47
|
+
"""JSON result key holding the process return code from the chain run."""
|
|
48
|
+
|
|
49
|
+
RESULT_KEY_DIRTY_TREE: str = "dirty_tree"
|
|
50
|
+
"""JSON result key holding whether the working tree is dirty after the review."""
|
|
51
|
+
|
|
52
|
+
CLI_SESSION_MODEL_FLAG: str = "--session-model"
|
|
53
|
+
"""CLI flag naming the caller's current session model short alias."""
|
|
54
|
+
|
|
55
|
+
GIT_BINARY: str = "git"
|
|
56
|
+
"""Executable name resolved on PATH for working-tree dirty checks."""
|
|
57
|
+
|
|
58
|
+
GIT_STATUS_SUBCOMMAND: str = "status"
|
|
59
|
+
"""Git subcommand used to detect an uncommitted dirty working tree."""
|
|
60
|
+
|
|
61
|
+
GIT_PORCELAIN_FLAG: str = "--porcelain"
|
|
62
|
+
"""Git status flag that prints machine-readable dirty-path lines."""
|
|
63
|
+
|
|
64
|
+
IN_SESSION_RETURNCODE: int = 0
|
|
65
|
+
"""Return code reported when the helper hands the review back to the in-session skill."""
|
|
66
|
+
|
|
67
|
+
HOST_PROFILE_ERROR_RETURNCODE: int = 1
|
|
68
|
+
"""Return code when host-profile detection raises ValueError at the CLI boundary."""
|
|
69
|
+
|
|
70
|
+
SUCCESSFUL_REVIEW_RETURNCODE: int = 0
|
|
71
|
+
"""Return code required before a clean stamp may advance past CODE_REVIEW."""
|