claude-dev-env 2.12.0 → 2.14.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.md +61 -0
- package/CLAUDE.md +1 -57
- package/_shared/AGENTS.md +15 -0
- package/_shared/CLAUDE.md +1 -15
- package/_shared/advisor/AGENTS.md +22 -0
- package/_shared/advisor/CLAUDE.md +1 -22
- package/_shared/pr-loop/AGENTS.md +27 -0
- package/_shared/pr-loop/CLAUDE.md +1 -27
- package/_shared/pr-loop/scripts/AGENTS.md +35 -0
- package/_shared/pr-loop/scripts/CLAUDE.md +1 -35
- package/_shared/pr-loop/scripts/code_rules_gate.py +2 -3
- package/_shared/pr-loop/scripts/code_rules_gate_parts/AGENTS.md +42 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/CLAUDE.md +1 -42
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/AGENTS.md +26 -0
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/CLAUDE.md +1 -26
- package/_shared/pr-loop/scripts/test_code_rules_gate.py +0 -26
- package/_shared/pr-loop/scripts/tests/AGENTS.md +44 -0
- package/_shared/pr-loop/scripts/tests/CLAUDE.md +1 -44
- package/_shared/process-tree/AGENTS.md +41 -0
- package/_shared/process-tree/CLAUDE.md +1 -41
- package/agents/AGENTS.md +31 -0
- package/agents/CLAUDE.md +1 -32
- package/agents/clean-coder.md +6 -6
- package/agents/pr-description-writer.md +11 -81
- package/agents/test_agent_frontmatter.py +4 -4
- package/audit-rubrics/AGENTS.md +43 -0
- package/audit-rubrics/CLAUDE.md +1 -43
- package/audit-rubrics/category_rubrics/AGENTS.md +37 -0
- package/audit-rubrics/category_rubrics/CLAUDE.md +1 -37
- package/audit-rubrics/prompts/AGENTS.md +37 -0
- package/audit-rubrics/prompts/CLAUDE.md +1 -37
- package/bin/AGENTS.md +112 -0
- package/bin/CLAUDE.md +1 -112
- package/bin/ever-shipped-skills.mjs +1 -0
- package/bin/install-constants.mjs +6 -7
- package/bin/install.mjs +71 -13
- package/bin/install.prune.test.mjs +26 -0
- package/bin/install.settings-defaults.test.mjs +60 -33
- package/bin/install.test.mjs +36 -4
- package/commands/AGENTS.md +23 -0
- package/commands/CLAUDE.md +1 -23
- package/commands/hook-log-extract.md +3 -3
- package/commands/sr-loop.md +9 -5
- package/docs/AGENTS.md +32 -0
- package/docs/CLAUDE.md +1 -33
- package/docs/CODE_RULES.md +1 -1
- package/docs/imagegen.md +22 -0
- package/docs/references/AGENTS.md +17 -0
- package/docs/references/CLAUDE.md +1 -18
- package/hooks/AGENTS.md +31 -0
- package/hooks/CLAUDE.md +1 -31
- package/hooks/_gh_pr_author_swap_utils.py +14 -0
- package/hooks/advisory/AGENTS.md +16 -0
- package/hooks/advisory/CLAUDE.md +1 -16
- package/hooks/blocking/AGENTS.md +123 -0
- package/hooks/blocking/CLAUDE.md +1 -148
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/AGENTS.md +28 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/CLAUDE.md +1 -28
- package/hooks/blocking/code_rules_banned_identifiers.py +1 -1
- package/hooks/blocking/code_rules_dead_module_constant.py +149 -37
- package/hooks/blocking/code_rules_probe_chains.py +6 -2
- package/hooks/blocking/config/AGENTS.md +10 -0
- package/hooks/blocking/config/CLAUDE.md +1 -22
- package/hooks/blocking/conventional_pr_title_gate.py +1 -2
- package/hooks/blocking/gh_pr_author_restore.py +7 -2
- package/hooks/blocking/intent_only_ending_blocker.py +11 -16
- package/hooks/blocking/inventory_intent_records/AGENTS.md +26 -0
- package/hooks/blocking/inventory_intent_records/CLAUDE.md +1 -26
- package/hooks/blocking/package_inventory_stale_blocker_parts/AGENTS.md +26 -0
- package/hooks/blocking/package_inventory_stale_blocker_parts/CLAUDE.md +1 -26
- package/hooks/blocking/pii_prevention_blocker_parts/AGENTS.md +24 -0
- package/hooks/blocking/pii_prevention_blocker_parts/CLAUDE.md +1 -24
- package/hooks/blocking/send_user_file_open_locally_blocker.py +1 -1
- package/hooks/blocking/stop_dispatcher.py +4 -4
- package/hooks/blocking/tdd_enforcer_parts/AGENTS.md +30 -0
- package/hooks/blocking/tdd_enforcer_parts/CLAUDE.md +1 -30
- package/hooks/blocking/test_bash_pre_tool_use_dispatcher.py +0 -3
- package/hooks/blocking/test_code_rules_enforcer_banned_prefixes.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_dead_module_constant.py +171 -0
- package/hooks/blocking/test_code_rules_enforcer_magic_allowlist.py +1 -1
- package/hooks/blocking/test_gh_pr_author_restore.py +2 -1
- package/hooks/blocking/test_intent_only_ending_blocker.py +4 -0
- package/hooks/blocking/test_pre_tool_use_dispatcher.py +6 -7
- package/hooks/blocking/test_send_user_file_open_locally_blocker.py +4 -3
- package/hooks/blocking/test_shared_stdin_adoption.py +0 -2
- package/hooks/diagnostic/AGENTS.md +43 -0
- package/hooks/diagnostic/CLAUDE.md +1 -43
- package/hooks/diagnostic/hook_log_extractor.py +4 -38
- package/hooks/diagnostic/hook_log_stop_wrapper.py +6 -155
- package/hooks/diagnostic/migrations/AGENTS.md +16 -0
- package/hooks/diagnostic/migrations/CLAUDE.md +1 -16
- package/hooks/diagnostic/queries/AGENTS.md +19 -0
- package/hooks/diagnostic/queries/CLAUDE.md +1 -19
- package/hooks/diagnostic/test_hook_log_extractor.py +10 -23
- package/hooks/diagnostic/test_hook_log_stop_wrapper.py +3 -331
- package/hooks/git-hooks/AGENTS.md +31 -0
- package/hooks/git-hooks/CLAUDE.md +1 -31
- package/hooks/git-hooks/git_hooks_constants/AGENTS.md +21 -0
- package/hooks/git-hooks/git_hooks_constants/CLAUDE.md +1 -21
- package/hooks/git-hooks/git_hooks_constants/__init__.py +4 -12
- package/hooks/git-hooks/pre_push.py +49 -118
- package/hooks/git-hooks/test_pre_push.py +111 -137
- package/hooks/hooks.json +0 -35
- package/hooks/hooks_constants/AGENTS.md +104 -0
- package/hooks/hooks_constants/CLAUDE.md +1 -113
- package/hooks/hooks_constants/bash_pre_tool_use_dispatcher_constants.py +0 -11
- package/hooks/hooks_constants/convergence_branch_constants.py +0 -1
- package/hooks/hooks_constants/fable_spawn_gate_constants.py +3 -4
- package/hooks/hooks_constants/hook_log_extractor_constants.py +1 -2
- package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +0 -8
- package/hooks/hooks_constants/send_user_file_open_locally_blocker_constants.py +1 -6
- package/hooks/hooks_constants/stop_dispatcher_constants.py +0 -1
- package/hooks/hooks_constants/task_list_loop_starter_constants.py +4 -3
- package/hooks/hooks_constants/test_bash_pre_tool_use_dispatcher_constants.py +1 -26
- package/hooks/hooks_constants/test_pre_tool_use_dispatcher_constants.py +0 -5
- package/hooks/hooks_constants/test_stop_dispatcher_constants.py +0 -1
- package/hooks/hooks_constants/working_style_prompt_constants.py +29 -20
- package/hooks/lifecycle/AGENTS.md +18 -0
- package/hooks/lifecycle/CLAUDE.md +1 -20
- package/hooks/observability/AGENTS.md +20 -0
- package/hooks/observability/CLAUDE.md +1 -20
- package/hooks/session/AGENTS.md +33 -0
- package/hooks/session/CLAUDE.md +1 -33
- package/hooks/session/gh_pr_author_session_cleanup.py +7 -2
- package/hooks/session/task_list_loop_starter.py +3 -3
- package/hooks/session/test_gh_pr_author_session_cleanup.py +2 -1
- package/hooks/session/test_task_list_loop_starter.py +10 -2
- package/hooks/session/test_working_style_prompt.py +9 -4
- package/hooks/validation/AGENTS.md +20 -0
- package/hooks/validation/CLAUDE.md +1 -20
- package/hooks/validators/AGENTS.md +51 -0
- package/hooks/validators/CLAUDE.md +1 -51
- package/hooks/validators/health_check.py +52 -19
- package/hooks/validators/python_style_checks.py +1 -1
- package/hooks/validators/test_health_check.py +112 -27
- package/hooks/workflow/AGENTS.md +16 -0
- package/hooks/workflow/CLAUDE.md +1 -16
- package/installable-surfaces.manifest.json +1 -0
- package/output-styles/AGENTS.md +15 -0
- package/output-styles/CLAUDE.md +1 -15
- package/package.json +2 -1
- package/rules/AGENTS.md +61 -0
- package/rules/CLAUDE.md +1 -63
- package/rules/code-standards.md +5 -9
- package/rules/doc-prose-cuts.md +1 -1
- package/rules/gh-cli-conventions.md +0 -1
- package/rules/git-workflow.md +1 -3
- package/scripts/AGENTS.md +62 -0
- package/scripts/CLAUDE.md +1 -63
- package/scripts/_code_review_test_support.py +0 -95
- package/scripts/codex_compat_materializer.py +4 -0
- package/scripts/dev_env_scripts_constants/AGENTS.md +21 -0
- package/scripts/dev_env_scripts_constants/CLAUDE.md +1 -21
- package/scripts/dev_env_scripts_constants/code_review_constants.py +9 -98
- package/scripts/dev_env_scripts_constants/test_code_review_constants.py +1 -44
- package/scripts/invoke_code_review.py +8 -451
- package/scripts/sync_to_cursor/AGENTS.md +23 -0
- package/scripts/sync_to_cursor/CLAUDE.md +1 -23
- package/scripts/test_invoke_code_review.py +5 -61
- package/scripts/test_invoke_code_review_cli.py +1 -45
- package/scripts/test_invoke_code_review_contract.py +1 -118
- package/scripts/test_validate_instruction_pairs.py +90 -0
- package/scripts/test_verify_installable_package.py +5 -1
- package/scripts/tests/AGENTS.md +33 -0
- package/scripts/tests/CLAUDE.md +1 -33
- package/scripts/tests/test_codex_compat_materializer.py +36 -1
- package/scripts/validate_instruction_pairs.py +183 -0
- package/settings.json +1 -10
- package/skills/AGENTS.md +72 -0
- package/skills/CLAUDE.md +1 -64
- package/skills/_shared/AGENTS.md +44 -0
- package/skills/_shared/CLAUDE.md +1 -44
- package/skills/_shared/advisor/AGENTS.md +9 -0
- package/skills/_shared/advisor/CLAUDE.md +1 -9
- package/skills/_shared/pr-loop/AGENTS.md +50 -0
- package/skills/_shared/pr-loop/CLAUDE.md +1 -50
- package/skills/_shared/pr-loop/prompts/AGENTS.md +9 -0
- package/skills/_shared/pr-loop/prompts/CLAUDE.md +1 -9
- package/skills/_shared/pr-loop/scripts/AGENTS.md +35 -0
- package/skills/_shared/pr-loop/scripts/CLAUDE.md +1 -35
- package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/AGENTS.md +24 -0
- package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/CLAUDE.md +1 -24
- package/skills/anthropic-plan/AGENTS.md +34 -0
- package/skills/anthropic-plan/CLAUDE.md +1 -34
- package/skills/anthropic-plan/scripts/AGENTS.md +11 -0
- package/skills/anthropic-plan/scripts/CLAUDE.md +1 -11
- package/skills/anthropic-plan/scripts/anthropic_plan_scripts_constants/AGENTS.md +16 -0
- package/skills/anthropic-plan/scripts/anthropic_plan_scripts_constants/CLAUDE.md +1 -16
- package/skills/anthropic-plan/templates/AGENTS.md +13 -0
- package/skills/anthropic-plan/templates/CLAUDE.md +1 -13
- package/skills/anthropic-plan/workflow/AGENTS.md +14 -0
- package/skills/anthropic-plan/workflow/CLAUDE.md +1 -14
- package/skills/auditing-claude-config/AGENTS.md +21 -0
- package/skills/auditing-claude-config/CLAUDE.md +1 -21
- package/skills/autoconverge/AGENTS.md +36 -0
- package/skills/autoconverge/CLAUDE.md +1 -36
- package/skills/autoconverge/reference/AGENTS.md +16 -0
- package/skills/autoconverge/reference/CLAUDE.md +1 -16
- package/skills/autoconverge/reference/convergence.md +7 -7
- package/skills/autoconverge/reference/gotchas.md +3 -10
- package/skills/autoconverge/workflow/AGENTS.md +26 -0
- package/skills/autoconverge/workflow/CLAUDE.md +1 -26
- package/skills/autoconverge/workflow/autoconverge_report_constants/AGENTS.md +16 -0
- package/skills/autoconverge/workflow/autoconverge_report_constants/CLAUDE.md +1 -16
- package/skills/autoconverge/workflow/converge.contract.test.mjs +53 -1388
- package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +4 -3
- package/skills/autoconverge/workflow/converge.fix-recovery.test.mjs +33 -493
- package/skills/autoconverge/workflow/converge.merge-conflict.test.mjs +15 -97
- package/skills/autoconverge/workflow/converge.mjs +201 -238
- package/skills/autoconverge/workflow/converge.precatch.test.mjs +1 -1
- package/skills/bugteam/AGENTS.md +30 -0
- package/skills/bugteam/CLAUDE.md +1 -30
- package/skills/bugteam/CONSTRAINTS.md +1 -1
- package/skills/bugteam/SKILL.md +9 -0
- package/skills/bugteam/reference/AGENTS.md +20 -0
- package/skills/bugteam/reference/CLAUDE.md +1 -20
- package/skills/bugteam/reference/audit-and-teammates.md +10 -6
- package/skills/bugteam/reference/obstacles/AGENTS.md +24 -0
- package/skills/bugteam/reference/obstacles/CLAUDE.md +1 -24
- package/skills/bugteam/scripts/AGENTS.md +30 -0
- package/skills/bugteam/scripts/CLAUDE.md +1 -30
- package/skills/bugteam/scripts/bugteam_scripts_constants/AGENTS.md +18 -0
- package/skills/bugteam/scripts/bugteam_scripts_constants/CLAUDE.md +1 -18
- package/skills/bugteam/test_skill_additions.py +9 -0
- package/skills/closeout/reference/handoff-prompt-template.md +1 -1
- package/skills/codex-review/AGENTS.md +46 -0
- package/skills/codex-review/CLAUDE.md +1 -46
- package/skills/codex-review/reference/AGENTS.md +15 -0
- package/skills/codex-review/reference/CLAUDE.md +1 -15
- package/skills/codex-review/scripts/codex_review_scripts_constants/AGENTS.md +18 -0
- package/skills/codex-review/scripts/codex_review_scripts_constants/CLAUDE.md +1 -18
- package/skills/codex-review/test_skill_scaffold.py +3 -3
- package/skills/comments/SKILL.md +65 -0
- package/skills/copilot-review/AGENTS.md +18 -0
- package/skills/copilot-review/CLAUDE.md +1 -18
- package/skills/descriptions/SKILL.md +51 -0
- package/skills/emergencies/SKILL.md +42 -0
- package/skills/everything-search/AGENTS.md +17 -0
- package/skills/everything-search/CLAUDE.md +1 -17
- package/skills/fresh-branch/AGENTS.md +14 -0
- package/skills/fresh-branch/CLAUDE.md +1 -14
- package/skills/grok-spawn/AGENTS.md +28 -0
- package/skills/grok-spawn/CLAUDE.md +1 -28
- package/skills/orchestrator/SKILL.md +2 -4
- package/skills/plan-to-pr/SKILL.md +6 -7
- package/skills/plan-to-pr/reference/final-validation-tasks.md +1 -1
- package/skills/plan-to-pr/reference/process-inventory.md +2 -2
- package/skills/plan-to-pr/reference/review-loop.md +2 -2
- package/skills/plan-to-pr/reference/run-record.schema.json +1 -1
- package/skills/plan-to-pr/reference/task-seeds.md +1 -1
- package/skills/plan-to-pr/reference/task-ticket.md +3 -4
- package/skills/plan-to-pr/scripts/config/constants.py +1 -2
- package/skills/plan-to-pr/scripts/test_validate_protocol.py +1 -1
- package/skills/plan-to-pr/test_skill_contract.py +2 -2
- package/skills/pr-converge/AGENTS.md +32 -0
- package/skills/pr-converge/CLAUDE.md +1 -32
- package/skills/pr-converge/SKILL.md +13 -16
- package/skills/pr-converge/pr_converge_skill_constants/AGENTS.md +26 -0
- package/skills/pr-converge/pr_converge_skill_constants/CLAUDE.md +1 -26
- package/skills/pr-converge/reference/AGENTS.md +28 -0
- package/skills/pr-converge/reference/CLAUDE.md +1 -28
- package/skills/pr-converge/reference/obstacles/AGENTS.md +23 -0
- package/skills/pr-converge/reference/obstacles/CLAUDE.md +1 -23
- package/skills/pr-converge/reference/progress-checklist.md +6 -5
- package/skills/pr-converge/reference/state-schema.md +1 -27
- package/skills/pr-converge/scripts/AGENTS.md +46 -0
- package/skills/pr-converge/scripts/CLAUDE.md +1 -46
- package/skills/pr-converge/scripts/pr_converge_scripts_constants/AGENTS.md +18 -0
- package/skills/pr-converge/scripts/pr_converge_scripts_constants/CLAUDE.md +1 -18
- package/skills/pr-converge/workflows/AGENTS.md +16 -0
- package/skills/pr-converge/workflows/CLAUDE.md +1 -16
- package/skills/pr-loop-cloud-transport/SKILL.md +1 -1
- package/skills/pr-loop-cloud-transport/reference/identity-and-hooks.md +3 -3
- package/skills/pr-loop-lifecycle/SKILL.md +1 -1
- package/skills/pr-loop-lifecycle/reference/teardown-publish-permissions.md +1 -1
- package/skills/prototype/SKILL.md +4 -4
- package/skills/prototype/reference/honest-limitations.md +5 -5
- package/skills/prototype/reference/promotion-tasks.md +2 -2
- package/skills/prototype/workflows/promotion.md +4 -6
- package/skills/rebase/AGENTS.md +32 -0
- package/skills/rebase/CLAUDE.md +1 -32
- package/skills/recall/AGENTS.md +30 -0
- package/skills/recall/CLAUDE.md +1 -30
- package/skills/remember/AGENTS.md +31 -0
- package/skills/remember/CLAUDE.md +1 -31
- package/skills/reviews/SKILL.md +85 -0
- package/skills/session-log/AGENTS.md +32 -0
- package/skills/session-log/CLAUDE.md +1 -32
- package/skills/session-tidy/AGENTS.md +36 -0
- package/skills/session-tidy/CLAUDE.md +1 -36
- package/skills/skill-builder/AGENTS.md +49 -0
- package/skills/skill-builder/CLAUDE.md +1 -49
- package/skills/skill-builder/references/AGENTS.md +25 -0
- package/skills/skill-builder/references/CLAUDE.md +1 -25
- package/skills/skill-builder/references/deterministic-elements.md +1 -1
- package/skills/skill-builder/templates/AGENTS.md +14 -0
- package/skills/skill-builder/templates/CLAUDE.md +1 -14
- package/skills/skill-builder/workflows/AGENTS.md +19 -0
- package/skills/skill-builder/workflows/CLAUDE.md +1 -19
- package/skills/small-cl/SKILL.md +52 -0
- package/skills/task-build/AGENTS.md +29 -0
- package/skills/task-build/CLAUDE.md +1 -29
- package/skills/update/AGENTS.md +38 -0
- package/skills/update/CLAUDE.md +1 -38
- package/system-prompts/AGENTS.md +17 -0
- package/system-prompts/CLAUDE.md +1 -17
- package/system-prompts/software-engineer.xml +3 -3
- package/agents/code-verifier.md +0 -74
- package/docs/PR_DESCRIPTION_GUIDE.md +0 -157
- package/docs/references/code-review-enforcement.md +0 -132
- package/hooks/blocking/code_review_enforcement_config_bootstrap.py +0 -53
- package/hooks/blocking/code_review_gate_deny.py +0 -74
- package/hooks/blocking/code_review_pr_create_gate.py +0 -198
- package/hooks/blocking/code_review_push_gate.py +0 -145
- package/hooks/blocking/code_review_stamp_directory_write_blocker.py +0 -348
- package/hooks/blocking/code_review_stamp_store.py +0 -233
- package/hooks/blocking/code_review_stamp_write_blocker_parts/__init__.py +0 -7
- package/hooks/blocking/code_review_stamp_write_blocker_parts/conftest.py +0 -15
- package/hooks/blocking/code_review_stamp_write_blocker_parts/obfuscated_stamp_path_reference.py +0 -212
- package/hooks/blocking/code_review_stamp_write_blocker_parts/split_directory_change_into_stamp.py +0 -138
- package/hooks/blocking/code_review_stamp_write_blocker_parts/test_obfuscated_stamp_path_reference.py +0 -49
- package/hooks/blocking/code_review_stamp_write_blocker_parts/test_split_directory_change_into_stamp.py +0 -38
- package/hooks/blocking/code_verifier_spawn_preflight_gate.py +0 -483
- package/hooks/blocking/config/code_review_enforcement_constants.py +0 -143
- package/hooks/blocking/config/test_code_review_enforcement_constants.py +0 -166
- package/hooks/blocking/config/verified_commit_constants.py +0 -160
- package/hooks/blocking/config/verified_commit_context_constants.py +0 -21
- package/hooks/blocking/config/verified_commit_gate_output_constants.py +0 -14
- package/hooks/blocking/conftest.py +0 -123
- package/hooks/blocking/convergence_gate_blocker.py +0 -310
- package/hooks/blocking/pr_converge_bugteam_enforcer.py +0 -170
- package/hooks/blocking/pr_description_body_audit.py +0 -148
- package/hooks/blocking/pr_description_command_parser.py +0 -237
- package/hooks/blocking/pr_description_enforcer.py +0 -227
- package/hooks/blocking/pr_description_pr_number.py +0 -155
- package/hooks/blocking/pr_description_proof_of_work.py +0 -385
- package/hooks/blocking/pr_description_readability.py +0 -364
- package/hooks/blocking/reviewer_spawn_gate.py +0 -182
- package/hooks/blocking/test_code_review_enforcement_config_bootstrap.py +0 -62
- package/hooks/blocking/test_code_review_gate_deny.py +0 -54
- package/hooks/blocking/test_code_review_pr_create_gate.py +0 -199
- package/hooks/blocking/test_code_review_push_gate.py +0 -205
- package/hooks/blocking/test_code_review_stamp_directory_write_blocker.py +0 -199
- package/hooks/blocking/test_code_review_stamp_store.py +0 -205
- package/hooks/blocking/test_code_verifier_spawn_preflight_gate.py +0 -710
- package/hooks/blocking/test_code_verifier_tools_contract.py +0 -28
- package/hooks/blocking/test_convergence_gate_blocker.py +0 -428
- package/hooks/blocking/test_pr_converge_bugteam_enforcer.py +0 -311
- package/hooks/blocking/test_pr_converge_bugteam_enforcer_state_tolerance.py +0 -184
- package/hooks/blocking/test_pr_description_enforcer.py +0 -221
- package/hooks/blocking/test_pr_description_enforcer_body_audit.py +0 -247
- package/hooks/blocking/test_pr_description_enforcer_body_rules.py +0 -493
- package/hooks/blocking/test_pr_description_enforcer_command_parser.py +0 -366
- package/hooks/blocking/test_pr_description_enforcer_pr_number.py +0 -159
- package/hooks/blocking/test_pr_description_enforcer_proof_gate.py +0 -175
- package/hooks/blocking/test_pr_description_enforcer_readability.py +0 -443
- package/hooks/blocking/test_pr_description_proof_of_work.py +0 -313
- package/hooks/blocking/test_reviewer_spawn_gate.py +0 -230
- package/hooks/blocking/test_verdict_directory_write_blocker.py +0 -804
- package/hooks/blocking/test_verification_verdict_store.py +0 -974
- package/hooks/blocking/test_verified_commit_config_bootstrap.py +0 -67
- package/hooks/blocking/test_verified_commit_docs_delta.py +0 -176
- package/hooks/blocking/test_verified_commit_gate.py +0 -581
- package/hooks/blocking/test_verified_commit_gate_additional_context.py +0 -134
- package/hooks/blocking/test_verified_commit_message_accuracy_blocker.py +0 -131
- package/hooks/blocking/test_verifier_verdict_minter.py +0 -299
- package/hooks/blocking/tests/test_verified_commit_gate.py +0 -41
- package/hooks/blocking/verdict_directory_write_blocker.py +0 -687
- package/hooks/blocking/verification_verdict_store.py +0 -1039
- package/hooks/blocking/verified_commit_config_bootstrap.py +0 -63
- package/hooks/blocking/verified_commit_gate.py +0 -113
- package/hooks/blocking/verified_commit_gate_parts/CLAUDE.md +0 -28
- package/hooks/blocking/verified_commit_gate_parts/__init__.py +0 -1
- package/hooks/blocking/verified_commit_gate_parts/command_tokenization.py +0 -174
- package/hooks/blocking/verified_commit_gate_parts/deny_payload.py +0 -53
- package/hooks/blocking/verified_commit_gate_parts/deny_reason.py +0 -80
- package/hooks/blocking/verified_commit_gate_parts/directory_resolution.py +0 -170
- package/hooks/blocking/verified_commit_gate_parts/gated_invocations.py +0 -217
- package/hooks/blocking/verified_commit_gate_parts/tests/conftest.py +0 -10
- package/hooks/blocking/verified_commit_gate_parts/tests/test_command_tokenization.py +0 -94
- package/hooks/blocking/verified_commit_gate_parts/tests/test_deny_payload.py +0 -17
- package/hooks/blocking/verified_commit_gate_parts/tests/test_deny_reason.py +0 -38
- package/hooks/blocking/verified_commit_gate_parts/tests/test_directory_resolution.py +0 -71
- package/hooks/blocking/verified_commit_gate_parts/tests/test_gated_invocations.py +0 -96
- package/hooks/blocking/verified_commit_message_accuracy_blocker.py +0 -167
- package/hooks/blocking/verifier_verdict_minter.py +0 -280
- package/hooks/hooks_constants/code_verifier_spawn_preflight_gate_constants.py +0 -64
- package/hooks/hooks_constants/convergence_gate_blocker_constants.py +0 -53
- package/hooks/hooks_constants/pr_converge_bugteam_enforcer_constants.py +0 -55
- package/hooks/hooks_constants/pr_converge_bugteam_enforcer_state.py +0 -67
- package/hooks/hooks_constants/pr_description_enforcer_constants.py +0 -167
- package/hooks/hooks_constants/pr_description_proof_of_work_constants.py +0 -107
- package/hooks/hooks_constants/reviewer_spawn_gate_constants.py +0 -41
- package/hooks/hooks_constants/test_pr_description_enforcer_constants.py +0 -292
- package/hooks/lifecycle/pr_converge_bugteam_skill_tracker.py +0 -198
- package/hooks/lifecycle/test_pr_converge_bugteam_skill_tracker.py +0 -283
- package/rules/proof-of-work-pr-comments.md +0 -22
- package/rules/verified-commit-gate-skip.md +0 -4
- package/scripts/Show-Asset.ps1 +0 -106
|
@@ -26,12 +26,15 @@ const PACKAGE_ROOT = join(dirname(fileURLToPath(import.meta.url)), '..');
|
|
|
26
26
|
const PACKAGE_SETTINGS_PATH = join(PACKAGE_ROOT, 'settings.json');
|
|
27
27
|
const INSTALL_ENTRY = join(PACKAGE_ROOT, 'bin', 'install.mjs');
|
|
28
28
|
|
|
29
|
-
const EXPECTED_DENY_ENTRIES = [
|
|
29
|
+
const EXPECTED_DENY_ENTRIES = [];
|
|
30
|
+
const SAMPLE_MANAGED_DENY_ENTRIES = ['Edit($HOME/.claude/managed-test/**)'];
|
|
31
|
+
const LEGACY_MANAGED_DENY_ENTRIES = [
|
|
30
32
|
'Edit($HOME/.claude/verification/**)',
|
|
31
33
|
'Write($HOME/.claude/code-review-stamps/**)',
|
|
32
34
|
'Edit($HOME/.claude/code-review-stamps/**)',
|
|
33
35
|
'MultiEdit($HOME/.claude/code-review-stamps/**)',
|
|
34
36
|
];
|
|
37
|
+
const USER_OWNED_DENY_ENTRY = 'Bash(rm -rf /)';
|
|
35
38
|
|
|
36
39
|
function packageDenyEntries() {
|
|
37
40
|
const packageSettings = JSON.parse(readFileSync(PACKAGE_SETTINGS_PATH, 'utf8'));
|
|
@@ -53,19 +56,18 @@ function runInstallerInSandbox(sandboxHome, installerArguments = []) {
|
|
|
53
56
|
});
|
|
54
57
|
}
|
|
55
58
|
|
|
56
|
-
test('package settings.json publishes
|
|
59
|
+
test('package settings.json publishes no managed deny entries', () => {
|
|
57
60
|
const denyEntries = packageDenyEntries();
|
|
58
|
-
assert.equal(denyEntries.length, 4);
|
|
59
61
|
assert.deepEqual(denyEntries, EXPECTED_DENY_ENTRIES);
|
|
60
62
|
});
|
|
61
63
|
|
|
62
64
|
test('an array-valued permissions field is replaced so managed denies survive a round trip', () => {
|
|
63
65
|
const targetSettings = { permissions: [] };
|
|
64
|
-
const result = mergeManagedPermissionsIntoSettings(targetSettings,
|
|
65
|
-
assert.equal(result.addedCount,
|
|
66
|
+
const result = mergeManagedPermissionsIntoSettings(targetSettings, SAMPLE_MANAGED_DENY_ENTRIES);
|
|
67
|
+
assert.equal(result.addedCount, SAMPLE_MANAGED_DENY_ENTRIES.length);
|
|
66
68
|
assert.equal(Array.isArray(targetSettings.permissions), false);
|
|
67
69
|
const roundTripped = JSON.parse(JSON.stringify(targetSettings));
|
|
68
|
-
assert.deepEqual(roundTripped.permissions.deny,
|
|
70
|
+
assert.deepEqual(roundTripped.permissions.deny, SAMPLE_MANAGED_DENY_ENTRIES);
|
|
69
71
|
});
|
|
70
72
|
|
|
71
73
|
test('npm pack includes package settings.json in the published artifact', () => {
|
|
@@ -88,25 +90,28 @@ test('npm pack includes package settings.json in the published artifact', () =>
|
|
|
88
90
|
);
|
|
89
91
|
});
|
|
90
92
|
|
|
91
|
-
test('mergeManagedPermissionsIntoSettings adds each
|
|
93
|
+
test('mergeManagedPermissionsIntoSettings adds each managed deny exactly once', () => {
|
|
92
94
|
const target = {
|
|
93
95
|
permissions: {
|
|
94
96
|
allow: ['Bash(git status)'],
|
|
95
97
|
deny: ['Bash(rm -rf /)'],
|
|
96
98
|
},
|
|
97
99
|
};
|
|
98
|
-
const first = mergeManagedPermissionsIntoSettings(target,
|
|
99
|
-
assert.equal(first.addedCount,
|
|
100
|
+
const first = mergeManagedPermissionsIntoSettings(target, SAMPLE_MANAGED_DENY_ENTRIES);
|
|
101
|
+
assert.equal(first.addedCount, SAMPLE_MANAGED_DENY_ENTRIES.length);
|
|
100
102
|
assert.equal(first.alreadyPresentCount, 0);
|
|
101
|
-
|
|
103
|
+
const managedDenyCount = target.permissions.deny.filter((each) => (
|
|
104
|
+
SAMPLE_MANAGED_DENY_ENTRIES.includes(each)
|
|
105
|
+
)).length;
|
|
106
|
+
assert.equal(managedDenyCount, SAMPLE_MANAGED_DENY_ENTRIES.length);
|
|
102
107
|
assert.ok(target.permissions.deny.includes('Bash(rm -rf /)'));
|
|
103
108
|
assert.deepEqual(target.permissions.allow, ['Bash(git status)']);
|
|
104
109
|
|
|
105
|
-
const second = mergeManagedPermissionsIntoSettings(target,
|
|
110
|
+
const second = mergeManagedPermissionsIntoSettings(target, SAMPLE_MANAGED_DENY_ENTRIES);
|
|
106
111
|
assert.equal(second.addedCount, 0);
|
|
107
|
-
assert.equal(second.alreadyPresentCount,
|
|
112
|
+
assert.equal(second.alreadyPresentCount, SAMPLE_MANAGED_DENY_ENTRIES.length);
|
|
108
113
|
assert.equal(
|
|
109
|
-
target.permissions.deny.filter((each) => each ===
|
|
114
|
+
target.permissions.deny.filter((each) => each === SAMPLE_MANAGED_DENY_ENTRIES[0]).length,
|
|
110
115
|
1,
|
|
111
116
|
);
|
|
112
117
|
});
|
|
@@ -118,18 +123,18 @@ test('pruneManagedPermissionsFromSettings removes only package-owned deny entrie
|
|
|
118
123
|
ask: ['Edit(./**)'],
|
|
119
124
|
deny: [
|
|
120
125
|
'Bash(rm -rf /)',
|
|
121
|
-
...
|
|
126
|
+
...SAMPLE_MANAGED_DENY_ENTRIES,
|
|
122
127
|
],
|
|
123
128
|
},
|
|
124
129
|
};
|
|
125
|
-
const outcome = pruneManagedPermissionsFromSettings(target,
|
|
126
|
-
assert.equal(outcome.removedCount,
|
|
130
|
+
const outcome = pruneManagedPermissionsFromSettings(target, SAMPLE_MANAGED_DENY_ENTRIES);
|
|
131
|
+
assert.equal(outcome.removedCount, SAMPLE_MANAGED_DENY_ENTRIES.length);
|
|
127
132
|
assert.deepEqual(target.permissions.deny, ['Bash(rm -rf /)']);
|
|
128
133
|
assert.deepEqual(target.permissions.allow, ['Bash(git status)']);
|
|
129
134
|
assert.deepEqual(target.permissions.ask, ['Edit(./**)']);
|
|
130
135
|
});
|
|
131
136
|
|
|
132
|
-
test('sandbox install
|
|
137
|
+
test('sandbox install keeps default managed denies empty on repeat', () => {
|
|
133
138
|
const sandboxHome = mkdtempSync(join(tmpdir(), 'cde-settings-defaults-'));
|
|
134
139
|
try {
|
|
135
140
|
const firstInstall = runInstallerInSandbox(sandboxHome, []);
|
|
@@ -139,30 +144,52 @@ test('sandbox install adds all four deny entries once and is idempotent on repea
|
|
|
139
144
|
assert.ok(existsSync(settingsPath), 'settings.json written');
|
|
140
145
|
const firstSettings = JSON.parse(readFileSync(settingsPath, 'utf8'));
|
|
141
146
|
const firstDeny = firstSettings.permissions?.deny ?? [];
|
|
142
|
-
|
|
143
|
-
assert.ok(firstDeny.includes(eachEntry), `missing deny: ${eachEntry}`);
|
|
144
|
-
assert.equal(
|
|
145
|
-
firstDeny.filter((candidate) => candidate === eachEntry).length,
|
|
146
|
-
1,
|
|
147
|
-
`deny not unique: ${eachEntry}`,
|
|
148
|
-
);
|
|
149
|
-
}
|
|
147
|
+
assert.deepEqual(firstDeny, EXPECTED_DENY_ENTRIES);
|
|
150
148
|
|
|
151
149
|
const manifestPath = join(sandboxHome, '.claude', '.claude-dev-env-manifest.json');
|
|
152
150
|
const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
|
|
153
|
-
assert.deepEqual(manifest.managedPermissions?.deny, EXPECTED_DENY_ENTRIES);
|
|
151
|
+
assert.deepEqual(manifest.managedPermissions?.deny ?? [], EXPECTED_DENY_ENTRIES);
|
|
154
152
|
|
|
155
153
|
const secondInstall = runInstallerInSandbox(sandboxHome, []);
|
|
156
154
|
assert.equal(secondInstall.status, 0, secondInstall.stderr || secondInstall.stdout);
|
|
157
155
|
const secondSettings = JSON.parse(readFileSync(settingsPath, 'utf8'));
|
|
158
156
|
const secondDeny = secondSettings.permissions?.deny ?? [];
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
157
|
+
assert.deepEqual(secondDeny, EXPECTED_DENY_ENTRIES);
|
|
158
|
+
} finally {
|
|
159
|
+
rmSync(sandboxHome, { recursive: true, force: true });
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
test('a normal upgrade retires manifest-owned denies and preserves user entries', () => {
|
|
164
|
+
const sandboxHome = mkdtempSync(join(tmpdir(), 'cde-settings-upgrade-'));
|
|
165
|
+
try {
|
|
166
|
+
const initialInstall = runInstallerInSandbox(sandboxHome, []);
|
|
167
|
+
assert.equal(initialInstall.status, 0, initialInstall.stderr || initialInstall.stdout);
|
|
168
|
+
|
|
169
|
+
const settingsPath = join(sandboxHome, '.claude', 'settings.json');
|
|
170
|
+
const settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
|
|
171
|
+
settings.permissions = {
|
|
172
|
+
allow: ['Bash(git status)'],
|
|
173
|
+
ask: ['Edit(./**)'],
|
|
174
|
+
deny: [USER_OWNED_DENY_ENTRY, ...LEGACY_MANAGED_DENY_ENTRIES],
|
|
175
|
+
};
|
|
176
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 4) + '\n');
|
|
177
|
+
|
|
178
|
+
const manifestPath = join(sandboxHome, '.claude', '.claude-dev-env-manifest.json');
|
|
179
|
+
const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
|
|
180
|
+
manifest.managedPermissions = { deny: LEGACY_MANAGED_DENY_ENTRIES };
|
|
181
|
+
writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
|
|
182
|
+
|
|
183
|
+
const upgradedInstall = runInstallerInSandbox(sandboxHome, []);
|
|
184
|
+
assert.equal(upgradedInstall.status, 0, upgradedInstall.stderr || upgradedInstall.stdout);
|
|
185
|
+
|
|
186
|
+
const upgradedSettings = JSON.parse(readFileSync(settingsPath, 'utf8'));
|
|
187
|
+
assert.deepEqual(upgradedSettings.permissions?.deny, [USER_OWNED_DENY_ENTRY]);
|
|
188
|
+
assert.deepEqual(upgradedSettings.permissions?.allow, ['Bash(git status)']);
|
|
189
|
+
assert.deepEqual(upgradedSettings.permissions?.ask, ['Edit(./**)']);
|
|
190
|
+
|
|
191
|
+
const upgradedManifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
|
|
192
|
+
assert.equal(Object.hasOwn(upgradedManifest, 'managedPermissions'), false);
|
|
166
193
|
} finally {
|
|
167
194
|
rmSync(sandboxHome, { recursive: true, force: true });
|
|
168
195
|
}
|
package/bin/install.test.mjs
CHANGED
|
@@ -42,6 +42,7 @@ import {
|
|
|
42
42
|
pruneRetiredHookEntriesFromSettings,
|
|
43
43
|
retainNewestRunBackupOnly,
|
|
44
44
|
} from './install.mjs';
|
|
45
|
+
import { EVER_SHIPPED_SKILL_NAMES } from './ever-shipped-skills.mjs';
|
|
45
46
|
import {
|
|
46
47
|
expandHomeDirectoryTokens,
|
|
47
48
|
expandHomeDirectoryTokensInSettings,
|
|
@@ -204,6 +205,14 @@ test('CORE_SKILLS ships issue-tracker so the core group installs the skill the S
|
|
|
204
205
|
});
|
|
205
206
|
|
|
206
207
|
|
|
208
|
+
test('EVER_SHIPPED_SKILL_NAMES retains imagegen so reinstall prunes the retired skill', () => {
|
|
209
|
+
assert.ok(
|
|
210
|
+
EVER_SHIPPED_SKILL_NAMES.has('imagegen'),
|
|
211
|
+
'imagegen must remain in the retirement registry after the package stops shipping it',
|
|
212
|
+
);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
|
|
207
216
|
test('CONTENT_DIRECTORIES includes audit-rubrics so installer copies category rubrics and prompts to ~/.claude/audit-rubrics/', () => {
|
|
208
217
|
assert.ok(
|
|
209
218
|
CONTENT_DIRECTORIES.includes('audit-rubrics'),
|
|
@@ -953,7 +962,6 @@ const OLD_FOLDED_HOOKS_SETTINGS = {
|
|
|
953
962
|
{ type: 'command', command: 'py -3 C:/Users/x/.claude/hooks/blocking/state_description_blocker.py', timeout: 10 },
|
|
954
963
|
{ type: 'command', command: 'py -3 C:/Users/x/.claude/hooks/blocking/subprocess_budget_completeness.py', timeout: 10 },
|
|
955
964
|
{ type: 'command', command: 'py -3 C:/Users/x/.claude/hooks/blocking/hook_prose_detector_consistency.py', timeout: 10 },
|
|
956
|
-
{ type: 'command', command: 'py -3 C:/Users/x/.claude/hooks/blocking/verified_commit_message_accuracy_blocker.py', timeout: 10 },
|
|
957
965
|
],
|
|
958
966
|
},
|
|
959
967
|
{
|
|
@@ -971,8 +979,8 @@ const OLD_FOLDED_HOOKS_SETTINGS = {
|
|
|
971
979
|
};
|
|
972
980
|
|
|
973
981
|
|
|
974
|
-
test('FOLDED_HOOK_RELATIVE_PATHS contains all
|
|
975
|
-
assert.equal(FOLDED_HOOK_RELATIVE_PATHS.size,
|
|
982
|
+
test('FOLDED_HOOK_RELATIVE_PATHS contains all 15 hooks removed from hooks.json plus the retired md_to_html_blocker', () => {
|
|
983
|
+
assert.equal(FOLDED_HOOK_RELATIVE_PATHS.size, 16);
|
|
976
984
|
assert.ok(FOLDED_HOOK_RELATIVE_PATHS.has('blocking/write_existing_file_blocker.py'));
|
|
977
985
|
assert.ok(FOLDED_HOOK_RELATIVE_PATHS.has('blocking/plain_language_blocker.py'));
|
|
978
986
|
assert.ok(FOLDED_HOOK_RELATIVE_PATHS.has('blocking/code_rules_enforcer.py'));
|
|
@@ -992,7 +1000,6 @@ test('FOLDED_HOOK_RELATIVE_PATHS lists every hook the PreToolUse dispatcher host
|
|
|
992
1000
|
'blocking/state_description_blocker.py',
|
|
993
1001
|
'blocking/subprocess_budget_completeness.py',
|
|
994
1002
|
'blocking/hook_prose_detector_consistency.py',
|
|
995
|
-
'blocking/verified_commit_message_accuracy_blocker.py',
|
|
996
1003
|
'blocking/workflow_substitution_slot_blocker.py',
|
|
997
1004
|
'blocking/claude_md_orphan_file_blocker.py',
|
|
998
1005
|
'blocking/env_var_table_code_drift_blocker.py',
|
|
@@ -1660,6 +1667,31 @@ test('collectFiles skips every named cache directory and loose bytecode file', (
|
|
|
1660
1667
|
});
|
|
1661
1668
|
|
|
1662
1669
|
|
|
1670
|
+
test('copyTree copies AGENTS.md with agent definitions', () => {
|
|
1671
|
+
const sourceRoot = mkdtempSync(join(tmpdir(), 'cdev-copy-agents-source-'));
|
|
1672
|
+
const destinationRoot = mkdtempSync(join(tmpdir(), 'cdev-copy-agents-destination-'));
|
|
1673
|
+
try {
|
|
1674
|
+
writeFileSync(join(sourceRoot, 'AGENTS.md'), '# Shared guidance\n');
|
|
1675
|
+
const agentDefinitionPath = join(sourceRoot, 'docs-agent.md');
|
|
1676
|
+
writeFileSync(
|
|
1677
|
+
agentDefinitionPath,
|
|
1678
|
+
'---\nname: docs-agent\ndescription: fixture agent\n---\n',
|
|
1679
|
+
);
|
|
1680
|
+
|
|
1681
|
+
const copyStats = copyTree(sourceRoot, destinationRoot);
|
|
1682
|
+
const copiedAgentsPath = join(destinationRoot, 'AGENTS.md');
|
|
1683
|
+
const copiedAgentPath = join(destinationRoot, 'docs-agent.md');
|
|
1684
|
+
|
|
1685
|
+
assert.equal(existsSync(copiedAgentsPath), true, 'the canonical instructions install');
|
|
1686
|
+
assert.equal(existsSync(copiedAgentPath), true, 'the real agent definition installs');
|
|
1687
|
+
assert.deepEqual(copyStats.paths, [copiedAgentsPath, copiedAgentPath]);
|
|
1688
|
+
} finally {
|
|
1689
|
+
rmSync(sourceRoot, { recursive: true, force: true });
|
|
1690
|
+
rmSync(destinationRoot, { recursive: true, force: true });
|
|
1691
|
+
}
|
|
1692
|
+
});
|
|
1693
|
+
|
|
1694
|
+
|
|
1663
1695
|
const SHIPPED_README_NAME = 'README.md';
|
|
1664
1696
|
const INSTALLED_README_NAME = 'Readme.md';
|
|
1665
1697
|
const RETIRED_HOOK_RELATIVE_PATH = 'blocking/retired_gate.py';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# commands
|
|
2
|
+
|
|
3
|
+
Slash-command definitions installed into `~/.claude/commands/` by `bin/install.mjs`. Each `.md` file registers a `/command-name` the user can type in Claude Code. The file name (without `.md`) becomes the command name.
|
|
4
|
+
|
|
5
|
+
## Command files
|
|
6
|
+
|
|
7
|
+
| File | Command | What it does |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| `commit.md` | `/commit` | Commits and pushes changes to GitHub |
|
|
10
|
+
| `docupdate.md` | `/docupdate` | Updates documentation to match current code state |
|
|
11
|
+
| `hook-log-extract.md` | `/hook-log-extract` | Extracts and formats hook log entries for a session |
|
|
12
|
+
| `hook-log-init.md` | `/hook-log-init` | Initializes the Neon Postgres schema that backs the hook-log extractor (one-time per machine) |
|
|
13
|
+
| `implement.md` | `/implement` | Provides full implementation context to a right-sized engineer in XML format |
|
|
14
|
+
| `plan.md` | `/plan` | Plans a feature through the `anthropic-plan` skill and workflow |
|
|
15
|
+
| `pr-comments.md` | `/pr-comments` | Fetches and formats PR review comments for response |
|
|
16
|
+
| `review-plan.md` | `/review-plan` | Reviews the current plan packet against code standards |
|
|
17
|
+
| `right-size.md` | `/right-size` | Checks an implementation against the Right-Sized Engineering rules |
|
|
18
|
+
| `sr-loop.md` | `/sr-loop` | Runs the converging cleanup loop: /simplify passes until clean, then a code-review fix pass |
|
|
19
|
+
| `sum.md` | `/sum` | Generates a formatted session summary for quick pickup in a new session |
|
|
20
|
+
|
|
21
|
+
## Format
|
|
22
|
+
|
|
23
|
+
Each file is plain Markdown. The first paragraph is the command's help text shown in the Claude Code UI. The body is the full instruction set Claude follows when the command runs.
|
package/commands/CLAUDE.md
CHANGED
|
@@ -1,23 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Slash-command definitions installed into `~/.claude/commands/` by `bin/install.mjs`. Each `.md` file registers a `/command-name` the user can type in Claude Code. The file name (without `.md`) becomes the command name.
|
|
4
|
-
|
|
5
|
-
## Command files
|
|
6
|
-
|
|
7
|
-
| File | Command | What it does |
|
|
8
|
-
|---|---|---|
|
|
9
|
-
| `commit.md` | `/commit` | Commits and pushes changes to GitHub |
|
|
10
|
-
| `docupdate.md` | `/docupdate` | Updates documentation to match current code state |
|
|
11
|
-
| `hook-log-extract.md` | `/hook-log-extract` | Extracts and formats hook log entries for a session |
|
|
12
|
-
| `hook-log-init.md` | `/hook-log-init` | Initializes the Neon Postgres schema that backs the hook-log extractor (one-time per machine) |
|
|
13
|
-
| `implement.md` | `/implement` | Provides full implementation context to a right-sized engineer in XML format |
|
|
14
|
-
| `plan.md` | `/plan` | Plans a feature through the `anthropic-plan` skill and workflow |
|
|
15
|
-
| `pr-comments.md` | `/pr-comments` | Fetches and formats PR review comments for response |
|
|
16
|
-
| `review-plan.md` | `/review-plan` | Reviews the current plan packet against code standards |
|
|
17
|
-
| `right-size.md` | `/right-size` | Checks an implementation against the Right-Sized Engineering rules |
|
|
18
|
-
| `sr-loop.md` | `/sr-loop` | Runs the converging cleanup loop: /simplify passes until clean, then a code-review fix pass |
|
|
19
|
-
| `sum.md` | `/sum` | Generates a formatted session summary for quick pickup in a new session |
|
|
20
|
-
|
|
21
|
-
## Format
|
|
22
|
-
|
|
23
|
-
Each file is plain Markdown. The first paragraph is the command's help text shown in the Claude Code UI. The body is the full instruction set Claude follows when the command runs.
|
|
1
|
+
@AGENTS.md
|
|
@@ -38,9 +38,9 @@ suspected of drift.
|
|
|
38
38
|
bws run -- python packages/claude-dev-env/hooks/diagnostic/hook_log_extractor.py --summary
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
their block count and a single truncated command preview
|
|
43
|
-
`
|
|
41
|
+
Run summary mode to print the top-10 blockers of the last 24 hours with
|
|
42
|
+
their block count and a single truncated command preview. An empty window
|
|
43
|
+
prints `Blocked events recorded in the last 24 hours: 0.`.
|
|
44
44
|
|
|
45
45
|
```
|
|
46
46
|
bws run -- python packages/claude-dev-env/hooks/diagnostic/hook_log_extractor.py --query <name>
|
package/commands/sr-loop.md
CHANGED
|
@@ -20,17 +20,21 @@ tool and repeats it until a pass returns zero new findings.
|
|
|
20
20
|
3. Repeat the invocation. **Skips are sticky:** carry every adjudicated skip
|
|
21
21
|
forward into the next pass as "already adjudicated — do not re-report: ..."
|
|
22
22
|
context, or the loop never converges.
|
|
23
|
-
4. Phase A converges when a full pass returns zero new findings
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
4. Phase A converges when a full pass returns zero new findings, or when a
|
|
24
|
+
pass's new findings are all nits — doc phrasing, naming, comment altitude,
|
|
25
|
+
or any fix below a behavior change. On a nit-only pass: apply the fixes,
|
|
26
|
+
test, commit, push, and stop with no confirming pass. When the previous
|
|
27
|
+
pass changed only a line or two, a single combined-lens confirmation agent
|
|
28
|
+
may serve as the final pass.
|
|
26
29
|
|
|
27
30
|
## Phase B — loop /code-review low --fix
|
|
28
31
|
|
|
29
32
|
1. Invoke the `code-review` skill with arguments `low --fix` on the same
|
|
30
33
|
target. Let it report findings and apply its fixes.
|
|
31
34
|
2. After any pass that changed files: test, commit, push as in Phase A.
|
|
32
|
-
3. Repeat until a pass reports zero findings
|
|
33
|
-
|
|
35
|
+
3. Repeat until a pass reports zero findings, or until a pass reports only
|
|
36
|
+
nits — then fix, test, commit, push, and stop with no confirming pass.
|
|
37
|
+
Phase B usually converges in one pass when Phase A ran first.
|
|
34
38
|
|
|
35
39
|
## Finish
|
|
36
40
|
|
package/docs/AGENTS.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# docs
|
|
2
|
+
|
|
3
|
+
Reference documentation installed into `~/.claude/docs/` by `bin/install.mjs`. These files are loaded on demand by rules, skills, and agents — they are not always-on context.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
| File | Purpose |
|
|
8
|
+
|---|---|
|
|
9
|
+
| `CODE_RULES.md` | Compact agent reference for all code rules; ⚡ marks hook-enforced rules; canonical source agents load before writing code |
|
|
10
|
+
| `TEST_QUALITY.md` | Test writing standards: what to test, what to remove, React testing patterns, anti-patterns |
|
|
11
|
+
| `BDD_DISCOVERY_PROTOCOL.md` | Example Mapping algorithm for discovery before implementation; based on Smart & Molak *BDD in Action* §6.4 |
|
|
12
|
+
| `BDD_SCENARIO_QUALITY.md` | Seven scenario quality patterns (§7.6-style catalog) |
|
|
13
|
+
| `BDD_TEST_LAYOUT.md` | `describe/when/should` test layout and soap-opera personas |
|
|
14
|
+
| `DJANGO_PATTERNS.md` | Django-specific coding patterns |
|
|
15
|
+
| `REACT_PATTERNS.md` | React-specific coding patterns |
|
|
16
|
+
| `agent-spawn-protocol.md` | Full agent-spawn protocol behind the `rules/agent-spawn-protocol.md` kernel: context-sufficiency check, `/prompt-generator` prompt crafting, and the spawn step |
|
|
17
|
+
| `nas-ssh-invocation.md` | Full NAS ssh policy behind the `rules/nas-ssh-invocation.md` kernel: the OpenSSH binary form, config sources, and hook enforcement |
|
|
18
|
+
| `worker-completion-gate.md` | Full worker-completion gate behind the `rules/workers-done-before-complete.md` kernel: the checklist, examples, and run-state records |
|
|
19
|
+
| `wsl-docker-cowork-starter-matrix.md` | Host matrix: WSL/Docker/cowork component → starter → required? → shutdown; policy options with costs; no unmeasured `.wslconfig` memory cap |
|
|
20
|
+
| `host-pool-health-monitor.md` | Operator recipe for Windows pool/handle health: thresholds, clean-shell re-run of `Capture-PoolHealth.ps1`, RC2/RC3/RC4 remediation map |
|
|
21
|
+
|
|
22
|
+
## Subdirectory
|
|
23
|
+
|
|
24
|
+
| Entry | Description |
|
|
25
|
+
|---|---|
|
|
26
|
+
| `references/` | Pointer documents to external sources and standard terminology; loaded on demand |
|
|
27
|
+
|
|
28
|
+
## Load pattern
|
|
29
|
+
|
|
30
|
+
A rule points to a doc with the path wrapped in backticks, such as `@~/.claude/docs/<file>.md`. The backticks make it a plain pointer: Claude Code reads the doc only when a rule, skill, or agent opens it, so the doc stays out of session-start context. The same path without backticks expands into context at launch when it sits in a file that loads at session start.
|
|
31
|
+
|
|
32
|
+
The `InstructionsLoaded` hook confirms this: a bare `@`-import fires an `include` load event; a backtick-wrapped path fires none.
|
package/docs/CLAUDE.md
CHANGED
|
@@ -1,33 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Reference documentation installed into `~/.claude/docs/` by `bin/install.mjs`. These files are loaded on demand by rules, skills, and agents — they are not always-on context.
|
|
4
|
-
|
|
5
|
-
## Files
|
|
6
|
-
|
|
7
|
-
| File | Purpose |
|
|
8
|
-
|---|---|
|
|
9
|
-
| `CODE_RULES.md` | Compact agent reference for all code rules; ⚡ marks hook-enforced rules; canonical source agents load before writing code |
|
|
10
|
-
| `TEST_QUALITY.md` | Test writing standards: what to test, what to remove, React testing patterns, anti-patterns |
|
|
11
|
-
| `BDD_DISCOVERY_PROTOCOL.md` | Example Mapping algorithm for discovery before implementation; based on Smart & Molak *BDD in Action* §6.4 |
|
|
12
|
-
| `BDD_SCENARIO_QUALITY.md` | Seven scenario quality patterns (§7.6-style catalog) |
|
|
13
|
-
| `BDD_TEST_LAYOUT.md` | `describe/when/should` test layout and soap-opera personas |
|
|
14
|
-
| `PR_DESCRIPTION_GUIDE.md` | Authoritative reference for the `pr-description-writer` agent; PR body shapes derived from a 120-PR Anthropic corpus |
|
|
15
|
-
| `DJANGO_PATTERNS.md` | Django-specific coding patterns |
|
|
16
|
-
| `REACT_PATTERNS.md` | React-specific coding patterns |
|
|
17
|
-
| `agent-spawn-protocol.md` | Full agent-spawn protocol behind the `rules/agent-spawn-protocol.md` kernel: context-sufficiency check, `/prompt-generator` prompt crafting, and the spawn step |
|
|
18
|
-
| `nas-ssh-invocation.md` | Full NAS ssh policy behind the `rules/nas-ssh-invocation.md` kernel: the OpenSSH binary form, config sources, and hook enforcement |
|
|
19
|
-
| `worker-completion-gate.md` | Full worker-completion gate behind the `rules/workers-done-before-complete.md` kernel: the checklist, examples, and run-state records |
|
|
20
|
-
| `wsl-docker-cowork-starter-matrix.md` | Host matrix: WSL/Docker/cowork component → starter → required? → shutdown; policy options with costs; no unmeasured `.wslconfig` memory cap |
|
|
21
|
-
| `host-pool-health-monitor.md` | Operator recipe for Windows pool/handle health: thresholds, clean-shell re-run of `Capture-PoolHealth.ps1`, RC2/RC3/RC4 remediation map |
|
|
22
|
-
|
|
23
|
-
## Subdirectory
|
|
24
|
-
|
|
25
|
-
| Entry | Description |
|
|
26
|
-
|---|---|
|
|
27
|
-
| `references/` | Pointer documents to external sources and standard terminology; loaded on demand |
|
|
28
|
-
|
|
29
|
-
## Load pattern
|
|
30
|
-
|
|
31
|
-
A rule points to a doc with the path wrapped in backticks, such as `@~/.claude/docs/<file>.md`. The backticks make it a plain pointer: Claude Code reads the doc only when a rule, skill, or agent opens it, so the doc stays out of session-start context. The same path without backticks expands into context at launch when it sits in a file that loads at session start.
|
|
32
|
-
|
|
33
|
-
The `InstructionsLoaded` hook confirms this: a bare `@`-import fires an `include` load event; a backtick-wrapped path fires none.
|
|
1
|
+
@AGENTS.md
|
package/docs/CODE_RULES.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Code Rules Reference
|
|
2
2
|
|
|
3
|
-
Compact **projection** of the
|
|
3
|
+
Compact **projection** of the checked-in review contract [`.cursor/BUGBOT.md`](../../../.cursor/BUGBOT.md). Update this reference alongside the full review contract when review rules change.
|
|
4
4
|
|
|
5
5
|
⚡ marks rules enforced by hand-maintained `code_rules_enforcer.py` — the hook blocks the Write/Edit and returns the corrective detail at violation time, so this document lists those rules by name only. Session policy (question routing, task tracking) lives in `rules/*.md`; see [`code-standards.md`](../rules/code-standards.md).
|
|
6
6
|
|
package/docs/imagegen.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Image generation
|
|
2
|
+
|
|
3
|
+
The canonical image-generation entrypoint lives in the
|
|
4
|
+
`python-automation` repository at `shared_utils.imagegen`.
|
|
5
|
+
|
|
6
|
+
Resolve `python_automation_root` and `python_exe` from the repository's
|
|
7
|
+
`run/tooling.json`, set `PYTHONPATH` to the resolved root, and run:
|
|
8
|
+
|
|
9
|
+
```powershell
|
|
10
|
+
$tooling = Get-Content '<REPO>\\run\\tooling.json' | ConvertFrom-Json
|
|
11
|
+
$python_automation_root = $tooling.python_automation_root
|
|
12
|
+
$python_executable = $tooling.python_exe
|
|
13
|
+
$env:PYTHONPATH = $python_automation_root
|
|
14
|
+
|
|
15
|
+
& $python_executable -m shared_utils.imagegen `
|
|
16
|
+
--prompt-file <PROMPT.txt> `
|
|
17
|
+
--size 2880x2880 `
|
|
18
|
+
--out <IMAGE.png>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Repeat `--reference-image <IMAGE.png>` for up to two visual references.
|
|
22
|
+
The command verifies the decoded PNG dimensions before reporting success.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# docs/references
|
|
2
|
+
|
|
3
|
+
Pointer documents to external sources, standard terminology, and internal tool or skill usage. Files here are loaded on demand by rules that cite them.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
| File | Purpose |
|
|
8
|
+
|---|---|
|
|
9
|
+
| `dead-code-elimination.md` | External sources and standard terms behind CODE_RULES §9.8 (remove code you orphan): DCE, tree shaking, reachability analysis, and the Lava Flow anti-pattern |
|
|
10
|
+
| `prose-style-enforcement.md` | How `CLAUDE_PROSE_STYLE_ENFORCEMENT` arms opinionated prose gates (default off) while AskUserQuestion lean-block stays always on |
|
|
11
|
+
| `advisor-tool.md` | Canonical consult bones for any stronger reviewer: when to call, hard rule before first write, how to treat advice; maps to the Anthropic advisor tool |
|
|
12
|
+
| `team-advisor-skill.md` | `/team-advisor` map: sole-consumer warm bind, ref index, and advisor selection |
|
|
13
|
+
| `weak-executor-advisor.md` | Consult profile a below-advisor-tier executor (Sonnet, Haiku) follows on top of `advisor-tool.md`: spawn-prompt steering, context packaging, two-timing rule, consult budget, failure branches |
|
|
14
|
+
|
|
15
|
+
## Role
|
|
16
|
+
|
|
17
|
+
A file naming an external concept gives a one-line definition and links a direct source. A file naming an internal tool or skill describes what it does and when to use it. They back the rule text in `rules/` and `packages/claude-dev-env/docs/CODE_RULES.md` without embedding full third-party content inline.
|
|
@@ -1,18 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Pointer documents to external sources, standard terminology, and internal tool or skill usage. Files here are loaded on demand by rules that cite them.
|
|
4
|
-
|
|
5
|
-
## Files
|
|
6
|
-
|
|
7
|
-
| File | Purpose |
|
|
8
|
-
|---|---|
|
|
9
|
-
| `dead-code-elimination.md` | External sources and standard terms behind CODE_RULES §9.8 (remove code you orphan): DCE, tree shaking, reachability analysis, and the Lava Flow anti-pattern |
|
|
10
|
-
| `code-review-enforcement.md` | How the code-review gates work: the two required efforts (push at low, PR creation at xhigh), the stamp bound to the branch-surface hash, the single sanctioned minter, the two-layer stamp-directory guard, and the bypass surfaces the gates leave open |
|
|
11
|
-
| `prose-style-enforcement.md` | How `CLAUDE_PROSE_STYLE_ENFORCEMENT` arms opinionated prose gates (default off) while AskUserQuestion lean-block stays always on |
|
|
12
|
-
| `advisor-tool.md` | Canonical consult bones for any stronger reviewer: when to call, hard rule before first write, how to treat advice; maps to the Anthropic advisor tool |
|
|
13
|
-
| `team-advisor-skill.md` | `/team-advisor` map: sole-consumer warm bind, ref index, and advisor selection |
|
|
14
|
-
| `weak-executor-advisor.md` | Consult profile a below-advisor-tier executor (Sonnet, Haiku) follows on top of `advisor-tool.md`: spawn-prompt steering, context packaging, two-timing rule, consult budget, failure branches |
|
|
15
|
-
|
|
16
|
-
## Role
|
|
17
|
-
|
|
18
|
-
A file naming an external concept gives a one-line definition and links a direct source. A file naming an internal tool or skill describes what it does and when to use it. They back the rule text in `rules/` and `packages/claude-dev-env/docs/CODE_RULES.md` without embedding full third-party content inline.
|
|
1
|
+
@AGENTS.md
|
package/hooks/AGENTS.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# hooks
|
|
2
|
+
|
|
3
|
+
Python hook scripts wired into Claude Code's lifecycle via `settings.json`. Each hook answers one or more lifecycle events (`PreToolUse`, `PostToolUse`, `Stop`, `SubagentStop`, `SessionStart`, `SessionEnd`) and either blocks a tool call, annotates it, or performs a side-effect.
|
|
4
|
+
|
|
5
|
+
## Subdirectories
|
|
6
|
+
|
|
7
|
+
| Directory | Role |
|
|
8
|
+
|---|---|
|
|
9
|
+
| `advisory/` | Hooks that warn but do not block (`permissionDecision: "ask"`) |
|
|
10
|
+
| `blocking/` | Hooks that deny tool calls when a rule is violated |
|
|
11
|
+
| `blocking/config/` | Shared constants for blocking hooks |
|
|
12
|
+
| `diagnostic/` | Hooks that record and extract hook-firing records into Neon |
|
|
13
|
+
| `diagnostic/migrations/` | SQL migrations for the `hook_events` Neon schema |
|
|
14
|
+
| `diagnostic/queries/` | Parameterized SQL queries for inspecting blocked commands |
|
|
15
|
+
| `git-hooks/` | Native git hooks (`pre-commit`, `pre-push`, `post-commit`) installed via the git-hooks path |
|
|
16
|
+
| `git-hooks/git_hooks_constants/` | Shared constants for the git-hook scripts |
|
|
17
|
+
| `hooks_constants/` | Shared constant modules imported by multiple hooks across this tree (includes `pii_prevention_constants.py` for personal-data and secret scan patterns) |
|
|
18
|
+
| `lifecycle/` | Hooks that run at session or config-change boundaries |
|
|
19
|
+
| `observability/` | PostToolUse hooks that record agent behavior for diagnostics |
|
|
20
|
+
| `session/` | SessionStart and SessionEnd hooks for per-session cleanup |
|
|
21
|
+
| `validation/` | PostToolUse hooks that validate code quality after a write (mypy, auto-format) |
|
|
22
|
+
| `validators/` | Library modules used by the validation hooks — checks split by concern |
|
|
23
|
+
| `workflow/` | PostToolUse hooks that trigger doc publishing and companion-file generation |
|
|
24
|
+
|
|
25
|
+
## Conventions
|
|
26
|
+
|
|
27
|
+
- **Event mapping:** Every hook reads JSON from stdin and exits 0 (allow) or prints a `hookSpecificOutput` block (block/ask). Blocking hooks set `permissionDecision: "block"`.
|
|
28
|
+
- **Constants companion:** Each hook with more than a handful of tunable strings keeps them in a `hooks_constants/<hook_name>_constants.py` sibling. Import from there; do not repeat literals.
|
|
29
|
+
- **Tests:** Each hook has one or more `test_<hookname>*.py` files beside it. Run with `python -m pytest <test_file>`.
|
|
30
|
+
- **Registration:** Hooks are declared in `settings.json` under the right lifecycle event. The installer (`packages/claude-dev-env/bin/install.mjs`) merges the hook entries during `npx claude-dev-env`.
|
|
31
|
+
- **Top-level utilities:** `_gh_pr_author_swap_utils.py` and `rewrite_plugin_paths.py` are shared helpers imported by multiple blocking hooks. `hooks.json` records the canonical hook-to-event mapping for auditing.
|
package/hooks/CLAUDE.md
CHANGED
|
@@ -1,31 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Python hook scripts wired into Claude Code's lifecycle via `settings.json`. Each hook answers one or more lifecycle events (`PreToolUse`, `PostToolUse`, `Stop`, `SubagentStop`, `SessionStart`, `SessionEnd`) and either blocks a tool call, annotates it, or performs a side-effect.
|
|
4
|
-
|
|
5
|
-
## Subdirectories
|
|
6
|
-
|
|
7
|
-
| Directory | Role |
|
|
8
|
-
|---|---|
|
|
9
|
-
| `advisory/` | Hooks that warn but do not block (`permissionDecision: "ask"`) |
|
|
10
|
-
| `blocking/` | Hooks that deny tool calls when a rule is violated |
|
|
11
|
-
| `blocking/config/` | Shared constants for the verified-commit gate family |
|
|
12
|
-
| `diagnostic/` | Hooks that record and extract hook-firing records into Neon |
|
|
13
|
-
| `diagnostic/migrations/` | SQL migrations for the `hook_events` Neon schema |
|
|
14
|
-
| `diagnostic/queries/` | Parameterized SQL queries for inspecting blocked commands |
|
|
15
|
-
| `git-hooks/` | Native git hooks (`pre-commit`, `pre-push`, `post-commit`) installed via the git-hooks path |
|
|
16
|
-
| `git-hooks/git_hooks_constants/` | Shared constants for the git-hook scripts |
|
|
17
|
-
| `hooks_constants/` | Shared constant modules imported by multiple hooks across this tree (includes `pii_prevention_constants.py` for personal-data and secret scan patterns) |
|
|
18
|
-
| `lifecycle/` | Hooks that run at session or config-change boundaries |
|
|
19
|
-
| `observability/` | PostToolUse hooks that record agent behavior for diagnostics |
|
|
20
|
-
| `session/` | SessionStart and SessionEnd hooks for per-session cleanup |
|
|
21
|
-
| `validation/` | PostToolUse hooks that validate code quality after a write (mypy, auto-format) |
|
|
22
|
-
| `validators/` | Library modules used by the validation hooks — checks split by concern |
|
|
23
|
-
| `workflow/` | PostToolUse hooks that trigger doc publishing and companion-file generation |
|
|
24
|
-
|
|
25
|
-
## Conventions
|
|
26
|
-
|
|
27
|
-
- **Event mapping:** Every hook reads JSON from stdin and exits 0 (allow) or prints a `hookSpecificOutput` block (block/ask). Blocking hooks set `permissionDecision: "block"`.
|
|
28
|
-
- **Constants companion:** Each hook with more than a handful of tunable strings keeps them in a `hooks_constants/<hook_name>_constants.py` sibling. Import from there; do not repeat literals.
|
|
29
|
-
- **Tests:** Each hook has one or more `test_<hookname>*.py` files beside it. Run with `python -m pytest <test_file>`.
|
|
30
|
-
- **Registration:** Hooks are declared in `settings.json` under the right lifecycle event. The installer (`packages/claude-dev-env/bin/install.mjs`) merges the hook entries during `npx claude-dev-env`.
|
|
31
|
-
- **Top-level utilities:** `_gh_pr_author_swap_utils.py` and `rewrite_plugin_paths.py` are shared helpers imported by multiple blocking hooks. `hooks.json` records the canonical hook-to-event mapping for auditing.
|
|
1
|
+
@AGENTS.md
|
|
@@ -155,6 +155,20 @@ def _switch_gh_account(to_account: str) -> bool:
|
|
|
155
155
|
return completed_process.returncode == 0
|
|
156
156
|
|
|
157
157
|
|
|
158
|
+
def _build_restore_failure_message(
|
|
159
|
+
hook_label: str,
|
|
160
|
+
original_account: str,
|
|
161
|
+
state_file: Path,
|
|
162
|
+
state_file_context: str,
|
|
163
|
+
) -> str:
|
|
164
|
+
"""Build the shared diagnostic for a failed account restoration."""
|
|
165
|
+
return (
|
|
166
|
+
f"[{hook_label}] Restore the gh account to {original_account!r}; "
|
|
167
|
+
f"gh account switch requires attention for {state_file_context} {state_file}. "
|
|
168
|
+
"The file remains for the next session."
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
|
|
158
172
|
def _read_original_account(state_file: Path) -> str | None:
|
|
159
173
|
"""Read the original-account login from a swap-state file.
|
|
160
174
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# hooks/advisory
|
|
2
|
+
|
|
3
|
+
Hooks that produce a warning prompt (`permissionDecision: "ask"`) rather than an outright block. The user sees the warning and can continue or cancel.
|
|
4
|
+
|
|
5
|
+
## Key files
|
|
6
|
+
|
|
7
|
+
| File | Event | What it guards |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| `migration_safety_advisor.py` | PreToolUse (Write/Edit) | Django migration files containing `RemoveField`, `RenameField`, `DeleteModel`, or `RenameModel` — warns that these operations must be backwards-compatible during deployment |
|
|
10
|
+
| `refactor_guard.py` | PreToolUse (Edit) | Edits that rename or restructure existing code not present in the current git diff — warns that the change may be out of scope |
|
|
11
|
+
|
|
12
|
+
## Conventions
|
|
13
|
+
|
|
14
|
+
- Both hooks exit 0 (silent) when their trigger condition is not met.
|
|
15
|
+
- `refactor_guard.py` respects a bypass token at `~/.claude/.refactor-bypass-token`; when that file exists the hook stays silent.
|
|
16
|
+
- Tests live beside each hook following the `test_<name>.py` pattern used in `blocking/`. Run with `python -m pytest <test_file>`.
|
package/hooks/advisory/CLAUDE.md
CHANGED
|
@@ -1,16 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Hooks that produce a warning prompt (`permissionDecision: "ask"`) rather than an outright block. The user sees the warning and can continue or cancel.
|
|
4
|
-
|
|
5
|
-
## Key files
|
|
6
|
-
|
|
7
|
-
| File | Event | What it guards |
|
|
8
|
-
|---|---|---|
|
|
9
|
-
| `migration_safety_advisor.py` | PreToolUse (Write/Edit) | Django migration files containing `RemoveField`, `RenameField`, `DeleteModel`, or `RenameModel` — warns that these operations must be backwards-compatible during deployment |
|
|
10
|
-
| `refactor_guard.py` | PreToolUse (Edit) | Edits that rename or restructure existing code not present in the current git diff — warns that the change may be out of scope |
|
|
11
|
-
|
|
12
|
-
## Conventions
|
|
13
|
-
|
|
14
|
-
- Both hooks exit 0 (silent) when their trigger condition is not met.
|
|
15
|
-
- `refactor_guard.py` respects a bypass token at `~/.claude/.refactor-bypass-token`; when that file exists the hook stays silent.
|
|
16
|
-
- Tests live beside each hook following the `test_<name>.py` pattern used in `blocking/`. Run with `python -m pytest <test_file>`.
|
|
1
|
+
@AGENTS.md
|