claude-dev-env 2.3.0 → 2.5.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/CLAUDE.md +53 -48
- package/_shared/pr-loop/scripts/_claude_permissions_common.py +84 -0
- package/_shared/pr-loop/scripts/code_rules_gate.py +4 -2
- package/_shared/pr-loop/scripts/grant_project_claude_permissions.py +306 -306
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/claude_permissions_constants.py +44 -0
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/copilot_quota_constants.py +24 -24
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/stale_worktree_rule_sweep_constants.py +107 -107
- package/_shared/pr-loop/scripts/revoke_project_claude_permissions.py +290 -48
- package/_shared/pr-loop/scripts/tests/test_claude_permissions_common.py +42 -2
- package/_shared/pr-loop/scripts/tests/test_claude_permissions_constants.py +36 -0
- package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +100 -1
- package/_shared/pr-loop/scripts/tests/test_fix_hookspath.py +497 -497
- package/_shared/pr-loop/scripts/tests/test_revoke_project_claude_permissions.py +311 -2
- package/_shared/pr-loop/scripts/tests/test_stale_worktree_rule_sweep.py +301 -301
- package/_shared/pr-loop/scripts/tests/test_stale_worktree_rule_sweep_constants.py +85 -85
- package/_shared/pr-loop/worker-spawn.md +1 -1
- package/agents/CLAUDE.md +3 -1
- package/agents/caveman.md +0 -1
- package/agents/clasp-deployment-orchestrator.md +0 -1
- package/agents/clean-coder.md +0 -1
- package/agents/code-advisor.md +0 -1
- package/agents/code-quality-agent.md +1 -2
- package/agents/code-verifier.md +3 -4
- package/agents/deep-research.md +0 -1
- package/agents/docs-agent.md +0 -1
- package/agents/git-commit-crafter.md +0 -1
- package/agents/issue-tracker.md +42 -0
- package/agents/plan-packet-validator.md +0 -1
- package/agents/pr-description-writer.md +0 -1
- package/agents/skill-writer-agent.md +84 -0
- package/agents/test_agent_frontmatter.py +67 -18
- package/audit-rubrics/category_rubrics/category-o-docstring-vs-impl-drift.md +105 -3
- package/audit-rubrics/prompts/category-o-docstring-vs-impl-drift.md +29 -13
- package/bin/CLAUDE.md +68 -5
- package/bin/ever-shipped-skills.mjs +1 -0
- package/bin/install-constants.mjs +88 -0
- package/bin/install.mjs +1138 -114
- package/bin/install.prune.test.mjs +869 -19
- package/bin/install.test.mjs +906 -2
- package/commands/implement.md +1 -1
- package/commands/right-size.md +1 -1
- package/docs/CLAUDE.md +2 -0
- package/docs/host-pool-health-monitor.md +102 -0
- package/docs/references/CLAUDE.md +5 -2
- package/docs/references/advisor-tool.md +13 -0
- package/docs/references/code-review-enforcement.md +107 -0
- package/docs/references/team-advisor-skill.md +14 -0
- package/docs/wsl-docker-cowork-starter-matrix.md +89 -0
- package/hooks/blocking/CLAUDE.md +9 -1
- package/hooks/blocking/code_review_enforcement_config_bootstrap.py +53 -0
- package/hooks/blocking/code_review_gate_deny.py +74 -0
- package/hooks/blocking/code_review_pr_create_gate.py +198 -0
- package/hooks/blocking/code_review_push_gate.py +145 -0
- package/hooks/blocking/code_review_stamp_directory_write_blocker.py +348 -0
- package/hooks/blocking/code_review_stamp_store.py +233 -0
- package/hooks/blocking/code_review_stamp_write_blocker_parts/__init__.py +7 -0
- package/hooks/blocking/code_review_stamp_write_blocker_parts/conftest.py +15 -0
- package/hooks/blocking/code_review_stamp_write_blocker_parts/obfuscated_stamp_path_reference.py +212 -0
- package/hooks/blocking/code_review_stamp_write_blocker_parts/split_directory_change_into_stamp.py +138 -0
- package/hooks/blocking/code_review_stamp_write_blocker_parts/test_obfuscated_stamp_path_reference.py +49 -0
- package/hooks/blocking/code_review_stamp_write_blocker_parts/test_split_directory_change_into_stamp.py +38 -0
- package/hooks/blocking/code_verifier_spawn_preflight_gate.py +39 -27
- package/hooks/blocking/config/__init__.py +5 -5
- package/hooks/blocking/config/code_review_enforcement_constants.py +113 -0
- package/hooks/blocking/config/test_code_review_enforcement_constants.py +113 -0
- package/hooks/blocking/config/verified_commit_constants.py +160 -155
- package/hooks/blocking/conftest.py +2 -0
- package/hooks/blocking/convergence_gate_blocker.py +112 -23
- package/hooks/blocking/destructive_command_blocker.py +19 -6
- package/hooks/blocking/orchestrator_refresh_reschedule_gate.py +256 -0
- package/hooks/blocking/pr_description_proof_of_work.py +52 -34
- package/hooks/blocking/pre_tool_use_dispatcher.py +24 -24
- package/hooks/blocking/test_bash_pre_tool_use_dispatcher.py +4 -1
- package/hooks/blocking/test_code_review_enforcement_config_bootstrap.py +62 -0
- package/hooks/blocking/test_code_review_gate_deny.py +54 -0
- package/hooks/blocking/test_code_review_pr_create_gate.py +199 -0
- package/hooks/blocking/test_code_review_push_gate.py +205 -0
- package/hooks/blocking/test_code_review_stamp_directory_write_blocker.py +199 -0
- package/hooks/blocking/test_code_review_stamp_store.py +205 -0
- package/hooks/blocking/test_code_verifier_spawn_preflight_gate.py +124 -2
- package/hooks/blocking/test_convergence_gate_blocker.py +153 -5
- package/hooks/blocking/test_destructive_command_blocker.py +1 -1
- package/hooks/blocking/test_destructive_command_blocker_deny_mode.py +45 -0
- package/hooks/blocking/test_orchestrator_refresh_reschedule_gate.py +231 -0
- package/hooks/blocking/test_pr_description_proof_of_work.py +151 -0
- package/hooks/blocking/test_pre_tool_use_dispatcher.py +17 -8
- package/hooks/blocking/test_verdict_directory_write_blocker.py +808 -808
- package/hooks/blocking/test_verification_verdict_store.py +974 -903
- package/hooks/blocking/test_verified_commit_gate.py +581 -581
- package/hooks/blocking/test_verified_commit_message_accuracy_blocker.py +131 -131
- package/hooks/blocking/test_volatile_path_in_post_blocker.py +114 -2
- package/hooks/blocking/verdict_directory_write_blocker.py +687 -687
- package/hooks/blocking/verification_verdict_store.py +1039 -1014
- package/hooks/blocking/verified_commit_gate_parts/gated_invocations.py +29 -17
- package/hooks/blocking/verified_commit_gate_parts/tests/test_gated_invocations.py +35 -0
- package/hooks/blocking/verified_commit_message_accuracy_blocker.py +167 -167
- package/hooks/blocking/verifier_verdict_minter.py +280 -280
- package/hooks/blocking/volatile_path_in_post_blocker.py +69 -8
- package/hooks/git-hooks/git_hooks_constants/__init__.py +6 -0
- package/hooks/git-hooks/pre_push.py +89 -2
- package/hooks/git-hooks/test_pre_push.py +128 -0
- package/hooks/hooks.json +26 -1
- package/hooks/hooks_constants/CLAUDE.md +3 -1
- package/hooks/hooks_constants/bash_pre_tool_use_dispatcher_constants.py +8 -0
- package/hooks/hooks_constants/code_rules_path_utils_constants.py +1 -0
- package/hooks/hooks_constants/code_verifier_spawn_preflight_gate_constants.py +26 -11
- package/hooks/hooks_constants/convergence_gate_blocker_constants.py +20 -3
- package/hooks/hooks_constants/destructive_command_segment_constants.py +3 -1
- package/hooks/hooks_constants/enter_worktree_prefetch_constants.py +18 -18
- package/hooks/hooks_constants/orchestrator_refresh_reschedule_gate_constants.py +48 -0
- package/hooks/hooks_constants/pr_description_proof_of_work_constants.py +0 -4
- package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +4 -0
- package/hooks/hooks_constants/pyproject_config_discovery_constants.py +16 -0
- package/hooks/hooks_constants/ruff_integration_constants.py +16 -0
- package/hooks/hooks_constants/test_bash_pre_tool_use_dispatcher_constants.py +24 -0
- package/hooks/hooks_constants/test_pre_tool_use_dispatcher_constants.py +6 -0
- package/hooks/hooks_constants/volatile_path_in_post_blocker_constants.py +8 -1
- package/hooks/lifecycle/enter_worktree_origin_prefetch.py +163 -146
- package/hooks/lifecycle/test_enter_worktree_origin_prefetch.py +185 -178
- package/hooks/pyproject.toml +1 -0
- package/hooks/validators/CLAUDE.md +2 -0
- package/hooks/validators/config/__init__.py +0 -0
- package/hooks/validators/config/directory_exemption_constants.py +183 -0
- package/hooks/validators/config/test_directory_exemption_constants.py +21 -0
- package/hooks/validators/conftest.py +4 -0
- package/hooks/validators/mypy_integration.py +63 -50
- package/hooks/validators/pyproject_config_discovery.py +101 -0
- package/hooks/validators/ruff_integration.py +257 -25
- package/hooks/validators/run_all_validators.py +223 -19
- package/hooks/validators/test_directory_exemption_constants.py +185 -0
- package/hooks/validators/test_mypy_integration.py +32 -0
- package/hooks/validators/test_pyproject_config_discovery.py +94 -0
- package/hooks/validators/test_python_antipattern_checks.py +110 -5
- package/hooks/validators/test_ruff_integration.py +160 -2
- package/hooks/validators/test_run_all_validators.py +140 -68
- package/hooks/validators/test_run_all_validators_config_discovery.py +123 -0
- package/hooks/validators/test_run_all_validators_pretooluse.py +159 -1
- package/package.json +10 -2
- package/rules/CLAUDE.md +1 -0
- package/rules/docstring-prose-matches-implementation.md +45 -67
- package/rules/durable-post-artifacts.md +7 -0
- package/rules/state-what-is.md +25 -0
- package/rules/verified-commit-gate-skip.md +1 -1
- package/scripts/CLAUDE.md +1 -0
- package/scripts/Capture-PoolHealth.ps1 +410 -0
- package/scripts/_code_review_test_support.py +404 -0
- package/scripts/claude_chain_runner.py +141 -1
- package/scripts/codec_forwarding_test_support.py +83 -0
- package/scripts/conftest.py +23 -0
- package/scripts/dev_env_scripts_constants/CLAUDE.md +2 -2
- package/scripts/dev_env_scripts_constants/claude_chain_constants.py +53 -1
- package/scripts/dev_env_scripts_constants/code_review_constants.py +129 -12
- package/scripts/dev_env_scripts_constants/test_code_review_constants.py +55 -0
- package/scripts/invoke_code_review.py +550 -38
- package/scripts/resolve_worker_spawn.py +626 -619
- package/scripts/spawn_grok_batch.py +672 -672
- package/scripts/test_claude_chain_runner.py +131 -0
- package/scripts/test_invoke_code_review_chain.py +70 -0
- package/scripts/test_invoke_code_review_cli.py +192 -0
- package/scripts/test_invoke_code_review_codec.py +77 -0
- package/scripts/test_invoke_code_review_contract.py +256 -0
- package/scripts/test_invoke_code_review_git.py +123 -0
- package/scripts/test_invoke_code_review_mode.py +99 -0
- package/scripts/test_resolve_worker_spawn.py +1014 -1014
- package/scripts/test_resolve_worker_spawn_codec.py +101 -0
- package/skills/CLAUDE.md +2 -0
- package/skills/auditing-claude-config/SKILL.md +114 -114
- package/skills/autoconverge/SKILL.md +427 -421
- package/skills/autoconverge/reference/convergence.md +26 -4
- package/skills/autoconverge/reference/multi-pr.md +6 -1
- package/skills/autoconverge/reference/stop-conditions.md +16 -10
- package/skills/autoconverge/workflow/CLAUDE.md +1 -0
- package/skills/autoconverge/workflow/converge.clean-audit.test.mjs +4 -4
- package/skills/autoconverge/workflow/converge.codex-gate.test.mjs +175 -3
- package/skills/autoconverge/workflow/converge.contract.test.mjs +1263 -1244
- package/skills/autoconverge/workflow/converge.mjs +191 -8
- package/skills/autoconverge/workflow/converge.p2-advance.test.mjs +202 -0
- package/skills/autoconverge/workflow/converge_multi.mjs +7 -3
- package/skills/autoconverge/workflow/converge_multi.run-input.test.mjs +5 -0
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a11d903476b803493.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a26213978adeef6fb.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a3def0d15ed9d9110.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a41f41b1b708ee3b7.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a758b880abecc3ff7.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a8897b89656b1bd16.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-abd463d744a1437bc.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-ad19d027ae8ee1816.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/workflows/wf_881252e6-700.json +265 -265
- package/skills/closeout/SKILL.md +33 -50
- package/skills/codex-review/scripts/codex_review_scripts_constants/run_constants.py +8 -0
- package/skills/codex-review/scripts/run_codex_review.py +233 -1
- package/skills/codex-review/scripts/test_run_codex_review.py +189 -0
- package/skills/condensing-instructions/SKILL.md +81 -0
- package/skills/copilot-review/SKILL.md +119 -119
- package/skills/e-code-review/SKILL.md +52 -0
- package/skills/e-code-review/reference/fix.md +54 -0
- package/skills/e-code-review/reference/loop.md +43 -0
- package/skills/e-code-review/reference/low.md +57 -0
- package/skills/e-code-review/reference/medium.md +153 -0
- package/skills/e-code-review/reference/xhigh.md +182 -0
- package/skills/e-simplify/SKILL.md +97 -0
- package/skills/fresh-branch/CLAUDE.md +2 -0
- package/skills/fresh-branch/SKILL.md +2 -0
- package/skills/fresh-branch/scripts/create_fresh_branch.py +78 -180
- package/skills/fresh-branch/scripts/fresh_branch_git_commands.py +285 -0
- package/skills/fresh-branch/scripts/fresh_branch_scripts_constants/fresh_branch_cli_constants.py +1 -0
- package/skills/fresh-branch/scripts/pytest.ini +4 -0
- package/skills/fresh-branch/scripts/test_create_fresh_branch.py +98 -0
- package/skills/fresh-branch/scripts/test_fresh_branch_git_commands.py +310 -0
- package/skills/issue-tracker/SKILL.md +92 -0
- package/skills/issue-tracker/reference/epic-and-sub-issue-model.md +55 -0
- package/skills/issue-tracker/reference/handoff-schema.md +64 -0
- package/skills/issue-tracker/reference/operation-matrix.md +41 -0
- package/skills/orchestrator/SKILL.md +162 -21
- package/skills/orchestrator/scripts/status_gate.py +625 -0
- package/skills/orchestrator/scripts/status_gate_constants/__init__.py +1 -0
- package/skills/orchestrator/scripts/status_gate_constants/config/__init__.py +1 -0
- package/skills/orchestrator/scripts/status_gate_constants/config/constants.py +47 -0
- package/skills/orchestrator/scripts/test_status_gate.py +439 -0
- package/skills/orchestrator-refresh/SKILL.md +110 -35
- package/skills/plan-to-pr/SKILL.md +155 -0
- package/skills/plan-to-pr/reference/final-validation-tasks.md +15 -0
- package/skills/plan-to-pr/reference/model-routing.md +36 -0
- package/skills/plan-to-pr/reference/packet-contract.md +43 -0
- package/skills/plan-to-pr/reference/packet-schema.json +57 -0
- package/skills/plan-to-pr/reference/process-inventory.md +22 -0
- package/skills/plan-to-pr/reference/review-loop.md +33 -0
- package/skills/plan-to-pr/reference/run-record.schema.json +27 -0
- package/skills/plan-to-pr/reference/self-audit-tasks.md +15 -0
- package/skills/plan-to-pr/reference/task-seeds.md +14 -0
- package/skills/plan-to-pr/reference/task-ticket.md +38 -0
- package/skills/plan-to-pr/scripts/config/__init__.py +1 -0
- package/skills/plan-to-pr/scripts/config/constants.py +193 -0
- package/skills/plan-to-pr/scripts/create_packet.py +173 -0
- package/skills/plan-to-pr/scripts/test_create_packet.py +102 -0
- package/skills/plan-to-pr/scripts/test_validate_packet.py +256 -0
- package/skills/plan-to-pr/scripts/test_validate_protocol.py +135 -0
- package/skills/plan-to-pr/scripts/test_validate_run.py +158 -0
- package/skills/plan-to-pr/scripts/validate_packet.py +655 -0
- package/skills/plan-to-pr/scripts/validate_protocol.py +622 -0
- package/skills/plan-to-pr/scripts/validate_run.py +173 -0
- package/skills/plan-to-pr/test_skill_contract.py +207 -0
- package/skills/plan-to-pr/test_task_ticket_contract.py +151 -0
- package/skills/pr-converge/SKILL.md +472 -469
- package/skills/pr-converge/reference/examples.md +3 -3
- package/skills/pr-converge/reference/fix-protocol.md +1 -1
- package/skills/pr-converge/reference/ground-rules.md +7 -4
- package/skills/pr-converge/reference/multi-pr-orchestration.md +4 -1
- package/skills/pr-converge/reference/per-tick.md +5 -5
- package/skills/pr-converge/reference/progress-checklist.md +1 -1
- package/skills/pr-converge/scripts/check_convergence_gates.py +279 -279
- package/skills/pr-converge/scripts/test_check_convergence_codex.py +507 -507
- package/skills/pr-converge/scripts/test_check_convergence_gates.py +84 -84
- package/skills/pr-converge/test_step5_host_branch.py +1 -1
- package/skills/pr-fix-protocol/SKILL.md +1 -1
- package/skills/privacy-hygiene/SKILL.md +68 -68
- package/skills/prototype/SKILL.md +86 -0
- package/skills/prototype/reference/honest-limitations.md +23 -0
- package/skills/prototype/reference/promotion-tasks.md +23 -0
- package/skills/prototype/scripts/build_sandbox_settings.py +249 -0
- package/skills/prototype/scripts/conftest.py +15 -0
- package/skills/prototype/scripts/launch_sandbox.py +205 -0
- package/skills/prototype/scripts/probe_sandbox_safety.py +311 -0
- package/skills/prototype/scripts/prototype_scripts_constants/__init__.py +1 -0
- package/skills/prototype/scripts/prototype_scripts_constants/config/__init__.py +0 -0
- package/skills/prototype/scripts/prototype_scripts_constants/config/build_sandbox_settings_constants.py +41 -0
- package/skills/prototype/scripts/prototype_scripts_constants/config/launch_sandbox_constants.py +23 -0
- package/skills/prototype/scripts/prototype_scripts_constants/config/probe_sandbox_safety_constants.py +45 -0
- package/skills/prototype/scripts/prototype_scripts_constants/config/prototype_common_constants.py +10 -0
- package/skills/prototype/scripts/test_build_sandbox_settings.py +275 -0
- package/skills/prototype/scripts/test_launch_sandbox.py +303 -0
- package/skills/prototype/scripts/test_probe_sandbox_safety.py +284 -0
- package/skills/prototype/workflows/promotion.md +27 -0
- package/skills/prototype/workflows/sandbox.md +35 -0
- package/skills/release-notes-html/SKILL.md +164 -0
- package/skills/skill-builder/CLAUDE.md +3 -3
- package/skills/skill-builder/SKILL.md +5 -5
- package/skills/skill-builder/references/CLAUDE.md +1 -1
- package/skills/skill-builder/references/delegation-map.md +3 -3
- package/skills/skill-builder/references/description-field.md +1 -1
- package/skills/skill-builder/references/skill-modularity.md +2 -3
- package/skills/skill-builder/workflows/CLAUDE.md +1 -1
- package/skills/skill-builder/workflows/improve-skill.md +1 -1
- package/skills/skill-builder/workflows/new-skill.md +2 -2
- package/skills/task-build/CLAUDE.md +8 -7
- package/skills/task-build/SKILL.md +16 -8
- package/skills/task-build/reference/tool-routing.md +19 -0
- package/skills/team-advisor/SKILL.md +2 -2
- package/scripts/test_invoke_code_review.py +0 -672
- package/skills/closeout/reference/issue-body-templates.md +0 -108
|
@@ -7,15 +7,22 @@ from pr_loop_shared_constants.preflight_constants import GIT_DIRECTORY_NAME
|
|
|
7
7
|
__all__ = (
|
|
8
8
|
"ALL_AGENT_CONFIG_DENY_TOOLS",
|
|
9
9
|
"ALL_AGENT_CONFIG_PATH_PATTERNS",
|
|
10
|
+
"ALL_INERT_FILE_PERMISSION_TOOLS",
|
|
11
|
+
"ALL_LEGACY_PERMISSION_REAP_TOOLS",
|
|
10
12
|
"ALL_PERMISSION_ALLOW_TOOLS",
|
|
11
13
|
"ALL_TRUST_ENTRY_PROJECT_PATH_BOUNDARY_QUOTE_CHARACTERS",
|
|
12
14
|
"AUTO_MODE_ENVIRONMENT_ENTRY_PREFIX",
|
|
13
15
|
"AUTO_MODE_ENVIRONMENT_ENTRY_TEMPLATE",
|
|
14
16
|
"CLAUDE_SETTINGS_DIRECTORY_NAME",
|
|
15
17
|
"CLAUDE_SETTINGS_FILENAME",
|
|
18
|
+
"CLAUDE_SETTINGS_LOCAL_FILENAME",
|
|
16
19
|
"GIT_DIRECTORY_NAME",
|
|
20
|
+
"HOME_PROJECT_PATH_ALIAS",
|
|
21
|
+
"INERT_RULES_REMOVED_LOG_PREFIX",
|
|
22
|
+
"PROJECT_LOCAL_INERT_RULES_REMOVED_LOG_PREFIX",
|
|
17
23
|
"TEXT_FILE_ENCODING",
|
|
18
24
|
"UNIQUE_TEMPORARY_SUFFIX_BYTE_LENGTH",
|
|
25
|
+
"get_claude_project_local_settings_path",
|
|
19
26
|
"get_claude_user_settings_path",
|
|
20
27
|
)
|
|
21
28
|
|
|
@@ -24,6 +31,20 @@ ALL_PERMISSION_ALLOW_TOOLS: tuple[str, ...] = ("Edit", "Read")
|
|
|
24
31
|
|
|
25
32
|
ALL_AGENT_CONFIG_DENY_TOOLS: tuple[str, ...] = ("Edit", "Read")
|
|
26
33
|
|
|
34
|
+
ALL_LEGACY_PERMISSION_REAP_TOOLS: tuple[str, ...] = ("Write", "Glob")
|
|
35
|
+
|
|
36
|
+
ALL_INERT_FILE_PERMISSION_TOOLS: tuple[str, ...] = ("Write", "Glob", "NotebookEdit")
|
|
37
|
+
|
|
38
|
+
HOME_PROJECT_PATH_ALIAS: str = "$HOME"
|
|
39
|
+
|
|
40
|
+
INERT_RULES_REMOVED_LOG_PREFIX: str = (
|
|
41
|
+
"Inert Write/Glob/NotebookEdit rules removed: "
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
PROJECT_LOCAL_INERT_RULES_REMOVED_LOG_PREFIX: str = (
|
|
45
|
+
"Project-local inert Write/Glob/NotebookEdit rules removed: "
|
|
46
|
+
)
|
|
47
|
+
|
|
27
48
|
ALL_AGENT_CONFIG_PATH_PATTERNS: tuple[str, ...] = (
|
|
28
49
|
"settings*.json",
|
|
29
50
|
"hooks/**",
|
|
@@ -81,6 +102,8 @@ CLAUDE_SETTINGS_DIRECTORY_NAME: str = ".claude"
|
|
|
81
102
|
|
|
82
103
|
CLAUDE_SETTINGS_FILENAME: str = "settings.json"
|
|
83
104
|
|
|
105
|
+
CLAUDE_SETTINGS_LOCAL_FILENAME: str = "settings.local.json"
|
|
106
|
+
|
|
84
107
|
TEXT_FILE_ENCODING: str = "utf-8"
|
|
85
108
|
|
|
86
109
|
UNIQUE_TEMPORARY_SUFFIX_BYTE_LENGTH: int = 8
|
|
@@ -88,3 +111,24 @@ UNIQUE_TEMPORARY_SUFFIX_BYTE_LENGTH: int = 8
|
|
|
88
111
|
|
|
89
112
|
def get_claude_user_settings_path() -> Path:
|
|
90
113
|
return Path.home() / CLAUDE_SETTINGS_DIRECTORY_NAME / CLAUDE_SETTINGS_FILENAME
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def get_claude_project_local_settings_path(
|
|
117
|
+
project_root_path: Path | None = None,
|
|
118
|
+
) -> Path:
|
|
119
|
+
"""Return ``<project>/.claude/settings.local.json`` for the project root.
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
project_root_path: Project root; defaults to the process cwd.
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
Path to the project-local Claude settings file (may not exist yet).
|
|
126
|
+
"""
|
|
127
|
+
resolved_project_root_path = (
|
|
128
|
+
project_root_path if project_root_path is not None else Path.cwd()
|
|
129
|
+
)
|
|
130
|
+
return (
|
|
131
|
+
resolved_project_root_path
|
|
132
|
+
/ CLAUDE_SETTINGS_DIRECTORY_NAME
|
|
133
|
+
/ CLAUDE_SETTINGS_LOCAL_FILENAME
|
|
134
|
+
)
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
"""Configuration constants for the Copilot premium-interaction quota pre-check."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from pathlib import Path
|
|
6
|
-
|
|
7
|
-
COPILOT_QUOTA_ACCOUNT_ENV_VAR_NAME: str = "COPILOT_QUOTA_ACCOUNT"
|
|
8
|
-
GH_TOKEN_ENV_VAR_NAME: str = "GH_TOKEN"
|
|
9
|
-
COPILOT_INTERNAL_USER_API_PATH: str = "copilot_internal/user"
|
|
10
|
-
|
|
11
|
-
QUOTA_SNAPSHOTS_FIELD_NAME: str = "quota_snapshots"
|
|
12
|
-
PREMIUM_INTERACTIONS_FIELD_NAME: str = "premium_interactions"
|
|
13
|
-
PREMIUM_UNLIMITED_FIELD_NAME: str = "unlimited"
|
|
14
|
-
PREMIUM_REMAINING_FIELD_NAME: str = "remaining"
|
|
15
|
-
PREMIUM_OVERAGE_PERMITTED_FIELD_NAME: str = "overage_permitted"
|
|
16
|
-
PREMIUM_ENTITLEMENT_FIELD_NAME: str = "entitlement"
|
|
17
|
-
PREMIUM_PERCENT_REMAINING_FIELD_NAME: str = "percent_remaining"
|
|
18
|
-
|
|
19
|
-
EXIT_CODE_QUOTA_AVAILABLE: int = 0
|
|
20
|
-
EXIT_CODE_OUT_OF_QUOTA: int = 1
|
|
21
|
-
EXIT_CODE_QUOTA_API_DOWN: int = 2
|
|
22
|
-
EXIT_CODE_NO_ACCOUNT_CONFIGURED: int = 3
|
|
23
|
-
|
|
24
|
-
COPILOT_QUOTA_DEFAULT_ENV_FILE_PATH: Path = Path(__file__).resolve().parents[4] / ".env"
|
|
1
|
+
"""Configuration constants for the Copilot premium-interaction quota pre-check."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
COPILOT_QUOTA_ACCOUNT_ENV_VAR_NAME: str = "COPILOT_QUOTA_ACCOUNT"
|
|
8
|
+
GH_TOKEN_ENV_VAR_NAME: str = "GH_TOKEN"
|
|
9
|
+
COPILOT_INTERNAL_USER_API_PATH: str = "copilot_internal/user"
|
|
10
|
+
|
|
11
|
+
QUOTA_SNAPSHOTS_FIELD_NAME: str = "quota_snapshots"
|
|
12
|
+
PREMIUM_INTERACTIONS_FIELD_NAME: str = "premium_interactions"
|
|
13
|
+
PREMIUM_UNLIMITED_FIELD_NAME: str = "unlimited"
|
|
14
|
+
PREMIUM_REMAINING_FIELD_NAME: str = "remaining"
|
|
15
|
+
PREMIUM_OVERAGE_PERMITTED_FIELD_NAME: str = "overage_permitted"
|
|
16
|
+
PREMIUM_ENTITLEMENT_FIELD_NAME: str = "entitlement"
|
|
17
|
+
PREMIUM_PERCENT_REMAINING_FIELD_NAME: str = "percent_remaining"
|
|
18
|
+
|
|
19
|
+
EXIT_CODE_QUOTA_AVAILABLE: int = 0
|
|
20
|
+
EXIT_CODE_OUT_OF_QUOTA: int = 1
|
|
21
|
+
EXIT_CODE_QUOTA_API_DOWN: int = 2
|
|
22
|
+
EXIT_CODE_NO_ACCOUNT_CONFIGURED: int = 3
|
|
23
|
+
|
|
24
|
+
COPILOT_QUOTA_DEFAULT_ENV_FILE_PATH: Path = Path(__file__).resolve().parents[4] / ".env"
|
package/_shared/pr-loop/scripts/pr_loop_shared_constants/stale_worktree_rule_sweep_constants.py
CHANGED
|
@@ -1,107 +1,107 @@
|
|
|
1
|
-
"""Constants and rule-format readers for stale_worktree_rule_sweep.
|
|
2
|
-
|
|
3
|
-
The worktrees root is derived from the same ~/.claude home the permission
|
|
4
|
-
grant script mints its rules under, so the location is named in exactly one
|
|
5
|
-
place. A worktree rule points at a directory one or more segments below that
|
|
6
|
-
root (flat or nested layouts)::
|
|
7
|
-
|
|
8
|
-
Edit(<claude home>/worktrees/<worktree name>/.claude/**)
|
|
9
|
-
^^^^^^^^^^^^^^^
|
|
10
|
-
segment 1 (flat)
|
|
11
|
-
|
|
12
|
-
Edit(<claude home>/worktrees/<repository>/<worktree name>/.claude/**)
|
|
13
|
-
^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
|
|
14
|
-
nested layout
|
|
15
|
-
|
|
16
|
-
worktree_directory_for_rule(rule, root) -> project directory under root
|
|
17
|
-
|
|
18
|
-
A rule whose target path lies outside the worktrees root reads back as None,
|
|
19
|
-
so the sweep leaves it untouched.
|
|
20
|
-
"""
|
|
21
|
-
|
|
22
|
-
from pathlib import Path
|
|
23
|
-
|
|
24
|
-
from pr_loop_shared_constants.claude_permissions_constants import (
|
|
25
|
-
get_claude_user_settings_path,
|
|
26
|
-
)
|
|
27
|
-
|
|
28
|
-
WORKTREES_SUBDIRECTORY_NAME: str = "worktrees"
|
|
29
|
-
|
|
30
|
-
MINIMUM_WORKTREE_PATH_SEGMENT_COUNT: int = 1
|
|
31
|
-
|
|
32
|
-
RULE_PATH_OPEN_DELIMITER: str = "("
|
|
33
|
-
|
|
34
|
-
RULE_PATH_CLOSE_DELIMITER: str = ")"
|
|
35
|
-
|
|
36
|
-
CLAUDE_HOME_PATH_MARKER: str = "/.claude"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def get_claude_worktrees_root() -> Path:
|
|
40
|
-
"""Return the ~/.claude/worktrees directory the grant rules point under.
|
|
41
|
-
|
|
42
|
-
Reuses get_claude_user_settings_path so the ~/.claude home is resolved
|
|
43
|
-
in one place: the settings file's parent directory is the home, and the
|
|
44
|
-
worktrees live directly beneath it.
|
|
45
|
-
|
|
46
|
-
Returns:
|
|
47
|
-
The absolute path to the user's worktrees root directory.
|
|
48
|
-
"""
|
|
49
|
-
claude_home_directory = get_claude_user_settings_path().parent
|
|
50
|
-
return claude_home_directory / WORKTREES_SUBDIRECTORY_NAME
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def extract_rule_target_path(rule: str) -> str | None:
|
|
54
|
-
"""Return the path a permission rule targets, or None when unparsable.
|
|
55
|
-
|
|
56
|
-
A rule reads `Tool(<path>)`; the target is the text between the first
|
|
57
|
-
open delimiter and the last close delimiter::
|
|
58
|
-
|
|
59
|
-
Edit(/repo/wt/.claude/**) -> /repo/wt/.claude/**
|
|
60
|
-
not a rule -> None
|
|
61
|
-
|
|
62
|
-
Args:
|
|
63
|
-
rule: The permission rule string to read.
|
|
64
|
-
|
|
65
|
-
Returns:
|
|
66
|
-
The target path string, or None when the delimiters are absent.
|
|
67
|
-
"""
|
|
68
|
-
open_index = rule.find(RULE_PATH_OPEN_DELIMITER)
|
|
69
|
-
close_index = rule.rfind(RULE_PATH_CLOSE_DELIMITER)
|
|
70
|
-
if open_index == -1 or close_index <= open_index:
|
|
71
|
-
return None
|
|
72
|
-
return rule[open_index + 1 : close_index]
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
def worktree_directory_for_rule(rule: str, worktrees_root: Path) -> Path | None:
|
|
76
|
-
"""Return the worktree directory a rule targets, or None when it is not one.
|
|
77
|
-
|
|
78
|
-
Keeps every path segment below the worktrees root so flat
|
|
79
|
-
(`worktrees/<name>`) and nested (`worktrees/<repo>/<name>`) layouts
|
|
80
|
-
both resolve to the on-disk project directory::
|
|
81
|
-
|
|
82
|
-
Edit(<root>/flat-wt/.claude/**) -> <root>/flat-wt
|
|
83
|
-
Edit(<root>/repo/wt/.claude/**) -> <root>/repo/wt
|
|
84
|
-
Edit(/elsewhere/project/.claude/**) -> None
|
|
85
|
-
|
|
86
|
-
Args:
|
|
87
|
-
rule: The permission rule string to read.
|
|
88
|
-
worktrees_root: The ~/.claude/worktrees directory rules live under.
|
|
89
|
-
|
|
90
|
-
Returns:
|
|
91
|
-
The worktree directory, or None when the target lies outside the
|
|
92
|
-
worktrees root or has no path segments under it.
|
|
93
|
-
"""
|
|
94
|
-
target_path = extract_rule_target_path(rule)
|
|
95
|
-
if target_path is None:
|
|
96
|
-
return None
|
|
97
|
-
project_portion = target_path.rsplit(CLAUDE_HOME_PATH_MARKER, 1)[0]
|
|
98
|
-
if not project_portion:
|
|
99
|
-
return None
|
|
100
|
-
try:
|
|
101
|
-
relative_path = Path(project_portion).relative_to(worktrees_root)
|
|
102
|
-
except ValueError:
|
|
103
|
-
return None
|
|
104
|
-
all_segments = relative_path.parts
|
|
105
|
-
if len(all_segments) < MINIMUM_WORKTREE_PATH_SEGMENT_COUNT:
|
|
106
|
-
return None
|
|
107
|
-
return worktrees_root.joinpath(*all_segments)
|
|
1
|
+
"""Constants and rule-format readers for stale_worktree_rule_sweep.
|
|
2
|
+
|
|
3
|
+
The worktrees root is derived from the same ~/.claude home the permission
|
|
4
|
+
grant script mints its rules under, so the location is named in exactly one
|
|
5
|
+
place. A worktree rule points at a directory one or more segments below that
|
|
6
|
+
root (flat or nested layouts)::
|
|
7
|
+
|
|
8
|
+
Edit(<claude home>/worktrees/<worktree name>/.claude/**)
|
|
9
|
+
^^^^^^^^^^^^^^^
|
|
10
|
+
segment 1 (flat)
|
|
11
|
+
|
|
12
|
+
Edit(<claude home>/worktrees/<repository>/<worktree name>/.claude/**)
|
|
13
|
+
^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
|
|
14
|
+
nested layout
|
|
15
|
+
|
|
16
|
+
worktree_directory_for_rule(rule, root) -> project directory under root
|
|
17
|
+
|
|
18
|
+
A rule whose target path lies outside the worktrees root reads back as None,
|
|
19
|
+
so the sweep leaves it untouched.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
|
|
24
|
+
from pr_loop_shared_constants.claude_permissions_constants import (
|
|
25
|
+
get_claude_user_settings_path,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
WORKTREES_SUBDIRECTORY_NAME: str = "worktrees"
|
|
29
|
+
|
|
30
|
+
MINIMUM_WORKTREE_PATH_SEGMENT_COUNT: int = 1
|
|
31
|
+
|
|
32
|
+
RULE_PATH_OPEN_DELIMITER: str = "("
|
|
33
|
+
|
|
34
|
+
RULE_PATH_CLOSE_DELIMITER: str = ")"
|
|
35
|
+
|
|
36
|
+
CLAUDE_HOME_PATH_MARKER: str = "/.claude"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_claude_worktrees_root() -> Path:
|
|
40
|
+
"""Return the ~/.claude/worktrees directory the grant rules point under.
|
|
41
|
+
|
|
42
|
+
Reuses get_claude_user_settings_path so the ~/.claude home is resolved
|
|
43
|
+
in one place: the settings file's parent directory is the home, and the
|
|
44
|
+
worktrees live directly beneath it.
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
The absolute path to the user's worktrees root directory.
|
|
48
|
+
"""
|
|
49
|
+
claude_home_directory = get_claude_user_settings_path().parent
|
|
50
|
+
return claude_home_directory / WORKTREES_SUBDIRECTORY_NAME
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def extract_rule_target_path(rule: str) -> str | None:
|
|
54
|
+
"""Return the path a permission rule targets, or None when unparsable.
|
|
55
|
+
|
|
56
|
+
A rule reads `Tool(<path>)`; the target is the text between the first
|
|
57
|
+
open delimiter and the last close delimiter::
|
|
58
|
+
|
|
59
|
+
Edit(/repo/wt/.claude/**) -> /repo/wt/.claude/**
|
|
60
|
+
not a rule -> None
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
rule: The permission rule string to read.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
The target path string, or None when the delimiters are absent.
|
|
67
|
+
"""
|
|
68
|
+
open_index = rule.find(RULE_PATH_OPEN_DELIMITER)
|
|
69
|
+
close_index = rule.rfind(RULE_PATH_CLOSE_DELIMITER)
|
|
70
|
+
if open_index == -1 or close_index <= open_index:
|
|
71
|
+
return None
|
|
72
|
+
return rule[open_index + 1 : close_index]
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def worktree_directory_for_rule(rule: str, worktrees_root: Path) -> Path | None:
|
|
76
|
+
"""Return the worktree directory a rule targets, or None when it is not one.
|
|
77
|
+
|
|
78
|
+
Keeps every path segment below the worktrees root so flat
|
|
79
|
+
(`worktrees/<name>`) and nested (`worktrees/<repo>/<name>`) layouts
|
|
80
|
+
both resolve to the on-disk project directory::
|
|
81
|
+
|
|
82
|
+
Edit(<root>/flat-wt/.claude/**) -> <root>/flat-wt
|
|
83
|
+
Edit(<root>/repo/wt/.claude/**) -> <root>/repo/wt
|
|
84
|
+
Edit(/elsewhere/project/.claude/**) -> None
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
rule: The permission rule string to read.
|
|
88
|
+
worktrees_root: The ~/.claude/worktrees directory rules live under.
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
The worktree directory, or None when the target lies outside the
|
|
92
|
+
worktrees root or has no path segments under it.
|
|
93
|
+
"""
|
|
94
|
+
target_path = extract_rule_target_path(rule)
|
|
95
|
+
if target_path is None:
|
|
96
|
+
return None
|
|
97
|
+
project_portion = target_path.rsplit(CLAUDE_HOME_PATH_MARKER, 1)[0]
|
|
98
|
+
if not project_portion:
|
|
99
|
+
return None
|
|
100
|
+
try:
|
|
101
|
+
relative_path = Path(project_portion).relative_to(worktrees_root)
|
|
102
|
+
except ValueError:
|
|
103
|
+
return None
|
|
104
|
+
all_segments = relative_path.parts
|
|
105
|
+
if len(all_segments) < MINIMUM_WORKTREE_PATH_SEGMENT_COUNT:
|
|
106
|
+
return None
|
|
107
|
+
return worktrees_root.joinpath(*all_segments)
|