claude-dev-env 1.42.0 → 1.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_shared/pr-loop/scripts/_claude_permissions_common.py +1 -5
- package/_shared/pr-loop/scripts/code_rules_gate.py +293 -8
- package/_shared/pr-loop/scripts/fix_hookspath.py +96 -5
- package/_shared/pr-loop/scripts/grant_project_claude_permissions.py +3 -16
- package/_shared/pr-loop/scripts/post_audit_thread.py +4 -4
- package/_shared/pr-loop/scripts/{config → pr_loop_shared_constants}/claude_permissions_constants.py +1 -1
- package/_shared/pr-loop/scripts/preflight.py +13 -31
- package/_shared/pr-loop/scripts/reviews_disabled.py +2 -16
- package/_shared/pr-loop/scripts/revoke_project_claude_permissions.py +3 -16
- package/_shared/pr-loop/scripts/tests/conftest.py +1 -51
- package/_shared/pr-loop/scripts/tests/test_agent_config_carveout.py +4 -4
- package/_shared/pr-loop/scripts/tests/test_claude_permissions_common.py +4 -2
- package/_shared/pr-loop/scripts/tests/test_claude_permissions_constants.py +4 -2
- package/_shared/pr-loop/scripts/tests/test_claude_settings_keys_constants.py +4 -2
- package/_shared/pr-loop/scripts/tests/test_code_rules_gate_constants.py +4 -2
- package/_shared/pr-loop/scripts/tests/test_fix_hookspath_constants.py +6 -2
- package/_shared/pr-loop/scripts/tests/test_grant_project_claude_permissions.py +2 -2
- package/_shared/pr-loop/scripts/tests/test_post_audit_thread.py +1 -2
- package/_shared/pr-loop/scripts/tests/test_post_audit_thread_constants.py +4 -2
- package/_shared/pr-loop/scripts/tests/test_preflight.py +17 -52
- package/_shared/pr-loop/scripts/tests/test_preflight_constants.py +6 -2
- package/_shared/pr-loop/scripts/tests/test_revoke_project_claude_permissions.py +2 -2
- package/agents/pr-description-writer.md +50 -140
- package/docs/PR_DESCRIPTION_GUIDE.md +101 -102
- package/hooks/_gh_pr_author_swap_utils.py +1 -1
- package/hooks/blocking/bot_mention_comment_blocker.py +4 -10
- package/hooks/blocking/code_rules_enforcer.py +217 -99
- package/hooks/blocking/code_rules_path_utils.py +8 -1
- package/hooks/blocking/destructive_command_blocker.py +1 -1
- package/hooks/blocking/es_exe_path_rewriter.py +7 -13
- package/hooks/blocking/gh_body_arg_blocker.py +6 -1
- package/hooks/blocking/gh_pr_author_enforcer.py +5 -5
- package/hooks/blocking/gh_pr_author_restore.py +5 -5
- package/hooks/blocking/hedging_language_blocker.py +4 -10
- package/hooks/blocking/md_path_exemptions.py +205 -0
- package/hooks/blocking/md_to_html_blocker.py +48 -20
- package/hooks/blocking/pr_converge_bugteam_enforcer.py +5 -11
- package/hooks/blocking/pr_description_enforcer.py +626 -41
- package/hooks/blocking/question_to_user_enforcer.py +4 -10
- package/hooks/blocking/state_description_blocker.py +6 -12
- package/hooks/blocking/tdd_enforcer.py +1 -1
- package/hooks/blocking/test_bot_mention_comment_blocker.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer.py +3 -3
- package/hooks/blocking/test_code_rules_enforcer_any_exempt_files.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_cap_meta.py +0 -2
- package/hooks/blocking/test_code_rules_enforcer_comment_string_awareness.py +184 -0
- package/hooks/blocking/test_code_rules_enforcer_type_checking_scope.py +82 -0
- package/hooks/blocking/test_code_rules_enforcer_unused_imports.py +29 -29
- package/hooks/blocking/test_gh_body_arg_blocker.py +7 -8
- package/hooks/blocking/test_gh_pr_author_enforcer.py +1 -1
- package/hooks/blocking/test_gh_pr_author_restore.py +1 -1
- package/hooks/blocking/test_hedging_language_blocker.py +2 -2
- package/hooks/blocking/test_md_to_html_blocker.py +463 -8
- package/hooks/blocking/test_pr_converge_bugteam_enforcer.py +1 -1
- package/hooks/blocking/test_pr_description_enforcer.py +1210 -13
- package/hooks/blocking/test_question_to_user_enforcer.py +1 -1
- package/hooks/blocking/windows_rmtree_blocker.py +5 -11
- package/hooks/diagnostic/hook_log_extractor.py +1 -1
- package/hooks/diagnostic/hook_log_init.py +1 -1
- package/hooks/diagnostic/hook_log_stop_wrapper.py +1 -1
- package/hooks/diagnostic/test_hook_log_extractor.py +1 -1
- package/hooks/diagnostic/test_hook_log_init.py +2 -2
- package/hooks/diagnostic/test_hook_log_stop_wrapper.py +1 -1
- package/hooks/git-hooks/gate_utils.py +1 -1
- package/hooks/git-hooks/pre_commit.py +1 -1
- package/hooks/git-hooks/pre_push.py +1 -1
- package/hooks/git-hooks/test_config.py +5 -5
- package/hooks/git-hooks/test_pre_push.py +6 -6
- package/hooks/{config → hooks_constants}/code_rules_enforcer_constants.py +37 -0
- package/hooks/hooks_constants/code_rules_path_utils_constants.py +28 -0
- package/hooks/hooks_constants/md_to_html_blocker_constants.py +82 -0
- package/hooks/{config → hooks_constants}/pr_converge_bugteam_enforcer_state.py +1 -1
- package/hooks/hooks_constants/pr_description_enforcer_constants.py +154 -0
- package/hooks/{config → hooks_constants}/pre_tool_use_stdin.py +1 -1
- package/hooks/{config → hooks_constants}/project_paths_reader.py +2 -2
- package/hooks/{config → hooks_constants}/test_banned_identifiers_constants.py +1 -1
- package/hooks/{config → hooks_constants}/test_dynamic_stderr_handler.py +1 -1
- package/hooks/{config → hooks_constants}/test_hardcoded_user_path_constants.py +1 -1
- package/hooks/{config → hooks_constants}/test_hook_log_extractor_constants.py +2 -2
- package/hooks/hooks_constants/test_md_to_html_blocker_constants.py +110 -0
- package/hooks/{config → hooks_constants}/test_messages.py +2 -6
- package/hooks/{config → hooks_constants}/test_path_rewriter_constants.py +1 -1
- package/hooks/hooks_constants/test_pr_description_enforcer_constants.py +292 -0
- package/hooks/{config → hooks_constants}/test_pre_tool_use_stdin.py +2 -2
- package/hooks/{config → hooks_constants}/test_project_paths_reader.py +3 -3
- package/hooks/{config → hooks_constants}/test_session_env_cleanup_constants.py +1 -1
- package/hooks/{config → hooks_constants}/test_setup_project_paths_constants.py +2 -2
- package/hooks/{config → hooks_constants}/test_unused_module_import_constants.py +1 -1
- package/hooks/lifecycle/pr_converge_bugteam_skill_tracker.py +5 -11
- package/hooks/lifecycle/test_pr_converge_bugteam_skill_tracker.py +1 -1
- package/hooks/session/gh_pr_author_session_cleanup.py +5 -6
- package/hooks/session/session_env_cleanup.py +4 -10
- package/hooks/session/test_gh_pr_author_session_cleanup.py +1 -1
- package/hooks/session/test_untracked_repo_detector.py +2 -2
- package/hooks/session/untracked_repo_detector.py +6 -12
- package/hooks/test__gh_pr_author_swap_utils.py +1 -1
- package/hooks/validators/run_all_validators.py +16 -5
- package/hooks/validators/test_output_formatter.py +46 -0
- package/hooks/workflow/doc_gist_auto_publish.py +1 -1
- package/hooks/workflow/md_to_html_companion.py +8 -15
- package/hooks/workflow/test_md_to_html_companion.py +184 -23
- package/package.json +1 -1
- package/rules/ask-user-question-required.md +1 -1
- package/rules/vault-context.md +1 -1
- package/scripts/{config → dev_env_scripts_constants}/timing.py +1 -1
- package/scripts/setup_project_paths.py +49 -11
- package/scripts/sweep_empty_dirs.py +10 -1
- package/scripts/test_setup_project_paths.py +2 -2
- package/scripts/test_sweep_empty_dirs.py +2 -6
- package/skills/_shared/pr-loop/scripts/_path_resolver.py +1 -1
- package/skills/_shared/pr-loop/scripts/build_audit_prompt.py +1 -1
- package/skills/_shared/pr-loop/scripts/build_fix_prompt.py +1 -1
- package/skills/_shared/pr-loop/scripts/init_loop_state.py +1 -1
- package/skills/_shared/pr-loop/scripts/teardown_worktrees.py +1 -1
- package/skills/_shared/pr-loop/scripts/write_audit_outcomes.py +2 -2
- package/skills/_shared/pr-loop/scripts/write_fix_outcomes.py +2 -2
- package/skills/bugteam/PROMPTS.md +1 -1
- package/skills/bugteam/SKILL.md +1 -1
- package/skills/bugteam/reference/github-pr-reviews.md +1 -1
- package/skills/bugteam/scripts/{_claude_permissions_common.py → _bugteam_permissions_common.py} +1 -13
- package/skills/bugteam/scripts/bugteam_code_rules_gate.py +1 -13
- package/skills/bugteam/scripts/bugteam_fix_hookspath.py +1 -16
- package/skills/bugteam/scripts/bugteam_preflight.py +1 -13
- package/skills/bugteam/scripts/grant_project_claude_permissions.py +2 -8
- package/skills/bugteam/scripts/probe_code_rules_enforcer_check.py +1 -1
- package/skills/bugteam/scripts/reflow_skill_md.py +1 -1
- package/skills/bugteam/scripts/revoke_project_claude_permissions.py +2 -8
- package/skills/bugteam/scripts/{test__claude_permissions_common.py → test__bugteam_permissions_common.py} +4 -4
- package/skills/bugteam/scripts/test_agent_config_carveout.py +2 -2
- package/skills/bugteam/scripts/test_bugteam_fix_hookspath.py +0 -26
- package/skills/bugteam/scripts/{test_claude_permissions_common.py → test_bugteam_permissions_common.py} +3 -66
- package/skills/bugteam/scripts/test_bugteam_preflight.py +2 -27
- package/skills/bugteam/scripts/windows_safe_rmtree.py +1 -1
- package/skills/doc-gist/SKILL.md +1 -1
- package/skills/doc-gist/scripts/gist_upload.py +1 -1
- package/skills/implement/SKILL.md +2 -2
- package/skills/implement/scripts/append_note.py +1 -1
- package/skills/pr-converge/pr_converge_skill_constants/__init__.py +0 -0
- package/skills/pr-converge/{config → pr_converge_skill_constants}/constants.py +1 -1
- package/skills/pr-converge/scripts/check_bugbot_ci.py +1 -1
- package/skills/pr-converge/scripts/check_convergence.py +11 -4
- package/skills/pr-converge/scripts/check_pending_reviews.py +1 -1
- package/skills/pr-converge/scripts/fetch_copilot_reviews.py +1 -1
- package/skills/pr-converge/scripts/post_fix_reply.py +1 -1
- package/skills/pr-converge/scripts/pr_converge_scripts_constants/__init__.py +0 -0
- package/skills/pr-converge/scripts/{config → pr_converge_scripts_constants}/pr_converge_constants.py +1 -1
- package/skills/pr-converge/scripts/reflow_skill_md.py +90 -16
- package/skills/pr-converge/scripts/test_check_convergence.py +18 -0
- package/skills/pr-converge/scripts/test_reflow_skill_md.py +0 -31
- package/skills/pre-compact/SKILL.md +114 -0
- package/skills/session-log/SKILL.md +98 -233
- package/hooks/config/pr_description_enforcer_constants.py +0 -19
- package/hooks/config/test_pr_description_enforcer_constants.py +0 -82
- package/skills/bugteam/scripts/test_grant_project_claude_permissions.py +0 -55
- package/skills/bugteam/scripts/test_revoke_project_claude_permissions.py +0 -55
- package/skills/pr-converge/scripts/conftest.py +0 -60
- package/skills/pr-converge/scripts/evict_cached_config_modules.py +0 -20
- package/skills/pr-converge/scripts/test_evict_cached_config_modules.py +0 -22
- /package/_shared/pr-loop/scripts/{config → pr_loop_shared_constants}/__init__.py +0 -0
- /package/_shared/pr-loop/scripts/{config → pr_loop_shared_constants}/claude_settings_keys_constants.py +0 -0
- /package/_shared/pr-loop/scripts/{config → pr_loop_shared_constants}/code_rules_gate_constants.py +0 -0
- /package/_shared/pr-loop/scripts/{config → pr_loop_shared_constants}/fix_hookspath_constants.py +0 -0
- /package/_shared/pr-loop/scripts/{config → pr_loop_shared_constants}/post_audit_thread_constants.py +0 -0
- /package/_shared/pr-loop/scripts/{config → pr_loop_shared_constants}/preflight_constants.py +0 -0
- /package/_shared/pr-loop/scripts/{config → pr_loop_shared_constants}/reviews_disabled_constants.py +0 -0
- /package/hooks/git-hooks/{config.py → git_hooks_constants/__init__.py} +0 -0
- /package/hooks/{config → hooks_constants}/__init__.py +0 -0
- /package/hooks/{config → hooks_constants}/any_type_config.py +0 -0
- /package/hooks/{config → hooks_constants}/banned_identifiers_constants.py +0 -0
- /package/hooks/{config → hooks_constants}/blocking_check_limits.py +0 -0
- /package/hooks/{config → hooks_constants}/bot_mention_comment_blocker_constants.py +0 -0
- /package/hooks/{config → hooks_constants}/convergence_branch_constants.py +0 -0
- /package/hooks/{config → hooks_constants}/doc_gist_auto_publish_constants.py +0 -0
- /package/hooks/{config → hooks_constants}/dynamic_stderr_handler.py +0 -0
- /package/hooks/{config → hooks_constants}/gh_pr_author_swap_constants.py +0 -0
- /package/hooks/{config → hooks_constants}/hardcoded_user_path_constants.py +0 -0
- /package/hooks/{config → hooks_constants}/hook_log_extractor_constants.py +0 -0
- /package/hooks/{config → hooks_constants}/html_companion_constants.py +0 -0
- /package/hooks/{config → hooks_constants}/inline_tuple_string_magic_constants.py +0 -0
- /package/hooks/{config → hooks_constants}/messages.py +0 -0
- /package/hooks/{config → hooks_constants}/path_rewriter_constants.py +0 -0
- /package/hooks/{config → hooks_constants}/pr_converge_bugteam_enforcer_constants.py +0 -0
- /package/hooks/{config → hooks_constants}/session_env_cleanup_constants.py +0 -0
- /package/hooks/{config → hooks_constants}/setup_project_paths_constants.py +0 -0
- /package/hooks/{config → hooks_constants}/state_description_blocker_constants.py +0 -0
- /package/hooks/{config → hooks_constants}/stuttering_check_config.py +0 -0
- /package/hooks/{config → hooks_constants}/stuttering_import_binding_constants.py +0 -0
- /package/hooks/{config → hooks_constants}/sys_path_insert_constants.py +0 -0
- /package/hooks/{config → hooks_constants}/unused_module_import_constants.py +0 -0
- /package/hooks/{config → hooks_constants}/windows_rmtree_blocker_constants.py +0 -0
- /package/{skills/_shared/pr-loop/scripts/config → hooks/lifecycle}/__init__.py +0 -0
- /package/{skills/bugteam/scripts/config → hooks/session}/__init__.py +0 -0
- /package/scripts/{config → dev_env_scripts_constants}/__init__.py +0 -0
- /package/skills/{doc-gist/scripts/config → _shared/pr-loop/scripts/skills_pr_loop_constants}/__init__.py +0 -0
- /package/skills/_shared/pr-loop/scripts/{config → skills_pr_loop_constants}/path_resolver_constants.py +0 -0
- /package/skills/{implement/scripts/config → bugteam/scripts/bugteam_scripts_constants}/__init__.py +0 -0
- /package/skills/bugteam/scripts/{config → bugteam_scripts_constants}/bugteam_code_rules_gate_constants.py +0 -0
- /package/skills/bugteam/scripts/{config → bugteam_scripts_constants}/bugteam_fix_hookspath_constants.py +0 -0
- /package/skills/bugteam/scripts/{config → bugteam_scripts_constants}/bugteam_preflight_constants.py +0 -0
- /package/skills/bugteam/scripts/{config → bugteam_scripts_constants}/claude_permissions_common_constants.py +0 -0
- /package/skills/bugteam/scripts/{config → bugteam_scripts_constants}/probe_code_rules_enforcer_check_constants.py +0 -0
- /package/skills/bugteam/scripts/{config → bugteam_scripts_constants}/reflow_skill_md_constants.py +0 -0
- /package/skills/bugteam/scripts/{config → bugteam_scripts_constants}/windows_safe_rmtree_constants.py +0 -0
- /package/skills/{pr-converge/config → doc-gist/scripts/doc_gist_scripts_constants}/__init__.py +0 -0
- /package/skills/doc-gist/scripts/{config → doc_gist_scripts_constants}/gist_upload_constants.py +0 -0
- /package/skills/{pr-converge/scripts/config → implement/scripts/implement_scripts_constants}/__init__.py +0 -0
- /package/skills/implement/scripts/{config → implement_scripts_constants}/notes_constants.py +0 -0
- /package/skills/pr-converge/scripts/{config → pr_converge_scripts_constants}/reflow_skill_md_constants.py +0 -0
|
@@ -9,23 +9,10 @@ the changes applied. No-op when the entries already exist.
|
|
|
9
9
|
import sys
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
|
|
12
|
-
parent_directory = str(Path(__file__).
|
|
13
|
-
try:
|
|
14
|
-
sys.path.remove(parent_directory)
|
|
15
|
-
except ValueError:
|
|
16
|
-
pass
|
|
12
|
+
parent_directory = str(Path(__file__).resolve().parent)
|
|
17
13
|
if parent_directory not in sys.path:
|
|
18
14
|
sys.path.insert(0, parent_directory)
|
|
19
15
|
|
|
20
|
-
for each_cached_module_name in [
|
|
21
|
-
each_module_key
|
|
22
|
-
for each_module_key in list(sys.modules)
|
|
23
|
-
if each_module_key == "config"
|
|
24
|
-
or each_module_key.startswith("config.")
|
|
25
|
-
or each_module_key == "_claude_permissions_common"
|
|
26
|
-
]:
|
|
27
|
-
sys.modules.pop(each_cached_module_name, None)
|
|
28
|
-
|
|
29
16
|
from _claude_permissions_common import ( # noqa: E402
|
|
30
17
|
append_if_missing,
|
|
31
18
|
build_agent_config_deny_rules,
|
|
@@ -40,7 +27,7 @@ from _claude_permissions_common import ( # noqa: E402
|
|
|
40
27
|
remove_matching_entries_from_list,
|
|
41
28
|
save_settings,
|
|
42
29
|
)
|
|
43
|
-
from
|
|
30
|
+
from pr_loop_shared_constants.claude_permissions_constants import (
|
|
44
31
|
ALL_AGENT_CONFIG_DENY_TOOLS,
|
|
45
32
|
ALL_AGENT_CONFIG_PATH_PATTERNS,
|
|
46
33
|
ALL_PERMISSION_ALLOW_TOOLS,
|
|
@@ -48,7 +35,7 @@ from config.claude_permissions_constants import ( # noqa: E402
|
|
|
48
35
|
AUTO_MODE_ENVIRONMENT_ENTRY_TEMPLATE,
|
|
49
36
|
get_claude_user_settings_path,
|
|
50
37
|
)
|
|
51
|
-
from
|
|
38
|
+
from pr_loop_shared_constants.claude_settings_keys_constants import (
|
|
52
39
|
CLAUDE_SETTINGS_ADDITIONAL_DIRECTORIES_KEY,
|
|
53
40
|
CLAUDE_SETTINGS_ALLOW_KEY,
|
|
54
41
|
CLAUDE_SETTINGS_AUTO_MODE_KEY,
|
|
@@ -32,11 +32,11 @@ import urllib.request
|
|
|
32
32
|
from pathlib import Path
|
|
33
33
|
from typing import NoReturn
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
if
|
|
37
|
-
sys.path.insert(0,
|
|
35
|
+
parent_directory = str(Path(__file__).resolve().parent)
|
|
36
|
+
if parent_directory not in sys.path:
|
|
37
|
+
sys.path.insert(0, parent_directory)
|
|
38
38
|
|
|
39
|
-
from
|
|
39
|
+
from pr_loop_shared_constants.post_audit_thread_constants import ( # noqa: E402
|
|
40
40
|
ALL_GH_API_COMMAND_PARTS,
|
|
41
41
|
ALL_GH_API_USER_COMMAND_PARTS,
|
|
42
42
|
ALL_GH_AUTH_STATUS_COMMAND_PARTS,
|
|
@@ -4,38 +4,20 @@ import subprocess
|
|
|
4
4
|
import sys
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
parent_directory = str(Path(__file__).resolve().parent)
|
|
8
|
+
sys.path[:] = [
|
|
9
|
+
each_existing_entry
|
|
10
|
+
for each_existing_entry in sys.path
|
|
11
|
+
if not (
|
|
12
|
+
os.path.exists(each_existing_entry)
|
|
13
|
+
and os.path.samefile(each_existing_entry, parent_directory)
|
|
14
|
+
)
|
|
15
|
+
]
|
|
16
|
+
if parent_directory not in sys.path:
|
|
17
|
+
sys.path.insert(0, parent_directory)
|
|
11
18
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
str(_script_directory_resolved),
|
|
15
|
-
str(_script_directory_absolute),
|
|
16
|
-
):
|
|
17
|
-
return True
|
|
18
|
-
try:
|
|
19
|
-
candidate_path = Path(each_path_entry)
|
|
20
|
-
except (OSError, ValueError):
|
|
21
|
-
return False
|
|
22
|
-
if candidate_path.exists():
|
|
23
|
-
try:
|
|
24
|
-
return os.path.samefile(candidate_path, _script_directory_resolved)
|
|
25
|
-
except OSError:
|
|
26
|
-
return False
|
|
27
|
-
return False
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
for each_index in range(len(sys.path) - 1, -1, -1):
|
|
31
|
-
if _entry_points_at_preflight_script_directory(sys.path[each_index]):
|
|
32
|
-
sys.path.pop(each_index)
|
|
33
|
-
_preflight_scripts_path_entry = str(_script_directory_absolute)
|
|
34
|
-
if _preflight_scripts_path_entry not in sys.path:
|
|
35
|
-
sys.path.insert(0, _preflight_scripts_path_entry)
|
|
36
|
-
|
|
37
|
-
from config.fix_hookspath_constants import HOOKS_PATH_VERIFICATION_SUFFIX
|
|
38
|
-
from config.preflight_constants import (
|
|
19
|
+
from pr_loop_shared_constants.fix_hookspath_constants import HOOKS_PATH_VERIFICATION_SUFFIX # noqa: E402
|
|
20
|
+
from pr_loop_shared_constants.preflight_constants import (
|
|
39
21
|
ALL_GIT_CONFIG_GET_CORE_HOOKS_PATH_SUBCOMMAND,
|
|
40
22
|
ALL_GIT_DIFF_NAME_ONLY_SUBCOMMAND,
|
|
41
23
|
ALL_GIT_LS_FILES_TEST_DISCOVERY_SUBCOMMAND,
|
|
@@ -8,22 +8,8 @@ rules and disabled-token taxonomy live in exactly one place.
|
|
|
8
8
|
from __future__ import annotations
|
|
9
9
|
|
|
10
10
|
import os
|
|
11
|
-
|
|
12
|
-
from
|
|
13
|
-
|
|
14
|
-
for each_cached_module_name in [
|
|
15
|
-
each_module_key
|
|
16
|
-
for each_module_key in list(sys.modules)
|
|
17
|
-
if each_module_key == "config" or each_module_key.startswith("config.")
|
|
18
|
-
]:
|
|
19
|
-
sys.modules.pop(each_cached_module_name, None)
|
|
20
|
-
_shared_pr_loop_scripts_directory = str(Path(__file__).absolute().parent)
|
|
21
|
-
while _shared_pr_loop_scripts_directory in sys.path:
|
|
22
|
-
sys.path.remove(_shared_pr_loop_scripts_directory)
|
|
23
|
-
if _shared_pr_loop_scripts_directory not in sys.path:
|
|
24
|
-
sys.path.insert(0, _shared_pr_loop_scripts_directory)
|
|
25
|
-
|
|
26
|
-
from config.reviews_disabled_constants import (
|
|
11
|
+
|
|
12
|
+
from pr_loop_shared_constants.reviews_disabled_constants import (
|
|
27
13
|
CLAUDE_REVIEWS_DISABLED_BUGTEAM_TOKEN,
|
|
28
14
|
CLAUDE_REVIEWS_DISABLED_ENV_VAR_NAME,
|
|
29
15
|
CLAUDE_REVIEWS_DISABLED_TOKEN_SEPARATOR,
|
|
@@ -10,23 +10,10 @@ autoMode sections so repeated grant/revoke cycles leave no dead structure.
|
|
|
10
10
|
import sys
|
|
11
11
|
from pathlib import Path
|
|
12
12
|
|
|
13
|
-
parent_directory = str(Path(__file__).
|
|
14
|
-
try:
|
|
15
|
-
sys.path.remove(parent_directory)
|
|
16
|
-
except ValueError:
|
|
17
|
-
pass
|
|
13
|
+
parent_directory = str(Path(__file__).resolve().parent)
|
|
18
14
|
if parent_directory not in sys.path:
|
|
19
15
|
sys.path.insert(0, parent_directory)
|
|
20
16
|
|
|
21
|
-
for each_cached_module_name in [
|
|
22
|
-
each_module_key
|
|
23
|
-
for each_module_key in list(sys.modules)
|
|
24
|
-
if each_module_key == "config"
|
|
25
|
-
or each_module_key.startswith("config.")
|
|
26
|
-
or each_module_key == "_claude_permissions_common"
|
|
27
|
-
]:
|
|
28
|
-
sys.modules.pop(each_cached_module_name, None)
|
|
29
|
-
|
|
30
17
|
from _claude_permissions_common import ( # noqa: E402
|
|
31
18
|
build_agent_config_deny_rules,
|
|
32
19
|
build_permission_rules,
|
|
@@ -39,14 +26,14 @@ from _claude_permissions_common import ( # noqa: E402
|
|
|
39
26
|
remove_matching_entries_from_list,
|
|
40
27
|
save_settings,
|
|
41
28
|
)
|
|
42
|
-
from
|
|
29
|
+
from pr_loop_shared_constants.claude_permissions_constants import (
|
|
43
30
|
ALL_AGENT_CONFIG_DENY_TOOLS,
|
|
44
31
|
ALL_AGENT_CONFIG_PATH_PATTERNS,
|
|
45
32
|
ALL_PERMISSION_ALLOW_TOOLS,
|
|
46
33
|
AUTO_MODE_ENVIRONMENT_ENTRY_PREFIX,
|
|
47
34
|
get_claude_user_settings_path,
|
|
48
35
|
)
|
|
49
|
-
from
|
|
36
|
+
from pr_loop_shared_constants.claude_settings_keys_constants import (
|
|
50
37
|
CLAUDE_SETTINGS_ADDITIONAL_DIRECTORIES_KEY,
|
|
51
38
|
CLAUDE_SETTINGS_ALLOW_KEY,
|
|
52
39
|
CLAUDE_SETTINGS_AUTO_MODE_KEY,
|
|
@@ -1,51 +1 @@
|
|
|
1
|
-
"""Test fixtures for _shared/pr-loop/scripts/.
|
|
2
|
-
|
|
3
|
-
Two unrelated Python packages live under the name ``config`` in this repo:
|
|
4
|
-
- ``_shared/pr-loop/scripts/config/`` (constants for grant/revoke/gate/preflight scripts)
|
|
5
|
-
- ``hooks/config/`` (constants for the code-rules enforcer and other hooks)
|
|
6
|
-
|
|
7
|
-
When tests under this directory exercise the gate (which loads
|
|
8
|
-
``hooks/blocking/code_rules_enforcer.py``) and also load the grant/revoke
|
|
9
|
-
scripts in the same pytest process, ``sys.modules['config']`` and
|
|
10
|
-
``sys.modules['config.<submodule>']`` cache entries from one package leak
|
|
11
|
-
into the other. The next ``from config.<submodule> import ...`` then fails
|
|
12
|
-
with ``ModuleNotFoundError`` because the cached parent package does not
|
|
13
|
-
expose that submodule.
|
|
14
|
-
|
|
15
|
-
Independently, several scripts in this folder do
|
|
16
|
-
``Path(__file__).resolve()`` then prepend the resulting directory to
|
|
17
|
-
``sys.path``. On Windows when the working tree lives under a mapped drive
|
|
18
|
-
backed by a UNC share (``Y:`` -> ``\\\\server\\share\\...``), ``.resolve()``
|
|
19
|
-
returns the UNC form, and Python's import machinery on this host cannot
|
|
20
|
-
locate ``config`` packages from a UNC ``sys.path`` entry. The Y:-form entry
|
|
21
|
-
gets pushed to a later index by subsequent inserts, making ``from
|
|
22
|
-
config.<submodule> import ...`` fail.
|
|
23
|
-
|
|
24
|
-
This autouse fixture restores both invariants before each test:
|
|
25
|
-
1. evict every ``config`` and ``config.*`` entry from ``sys.modules``
|
|
26
|
-
2. prepend the drive-letter (``.absolute()``) form of the scripts
|
|
27
|
-
directory to ``sys.path`` so package resolution always has a
|
|
28
|
-
non-UNC path to search first
|
|
29
|
-
"""
|
|
30
|
-
|
|
31
|
-
from __future__ import annotations
|
|
32
|
-
|
|
33
|
-
import sys
|
|
34
|
-
from pathlib import Path
|
|
35
|
-
|
|
36
|
-
import pytest
|
|
37
|
-
|
|
38
|
-
SCRIPTS_DIRECTORY_DRIVE_LETTER_FORM = str(Path(__file__).absolute().parent.parent)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
@pytest.fixture(autouse=True)
|
|
42
|
-
def _evict_config_namespace_between_tests() -> None:
|
|
43
|
-
for each_module_name in [
|
|
44
|
-
each_key
|
|
45
|
-
for each_key in list(sys.modules)
|
|
46
|
-
if each_key == "config" or each_key.startswith("config.")
|
|
47
|
-
]:
|
|
48
|
-
sys.modules.pop(each_module_name, None)
|
|
49
|
-
if SCRIPTS_DIRECTORY_DRIVE_LETTER_FORM in sys.path:
|
|
50
|
-
sys.path.remove(SCRIPTS_DIRECTORY_DRIVE_LETTER_FORM)
|
|
51
|
-
sys.path.insert(0, SCRIPTS_DIRECTORY_DRIVE_LETTER_FORM)
|
|
1
|
+
"""Test fixtures for _shared/pr-loop/scripts/tests/."""
|
|
@@ -49,7 +49,6 @@ def _load_grant_module() -> ModuleType:
|
|
|
49
49
|
scripts_directory_str = str(scripts_directory.resolve())
|
|
50
50
|
if scripts_directory_str not in sys.path:
|
|
51
51
|
sys.path.insert(0, scripts_directory_str)
|
|
52
|
-
sys.modules.pop("config", None)
|
|
53
52
|
return _load_module_from_path(
|
|
54
53
|
"grant_project_claude_permissions",
|
|
55
54
|
scripts_directory / "grant_project_claude_permissions.py",
|
|
@@ -61,7 +60,6 @@ def _load_revoke_module() -> ModuleType:
|
|
|
61
60
|
scripts_directory_str = str(scripts_directory.resolve())
|
|
62
61
|
if scripts_directory_str not in sys.path:
|
|
63
62
|
sys.path.insert(0, scripts_directory_str)
|
|
64
|
-
sys.modules.pop("config", None)
|
|
65
63
|
return _load_module_from_path(
|
|
66
64
|
"revoke_project_claude_permissions",
|
|
67
65
|
scripts_directory / "revoke_project_claude_permissions.py",
|
|
@@ -70,8 +68,10 @@ def _load_revoke_module() -> ModuleType:
|
|
|
70
68
|
|
|
71
69
|
def _load_constants_module() -> ModuleType:
|
|
72
70
|
return _load_module_from_path(
|
|
73
|
-
"
|
|
74
|
-
_scripts_directory()
|
|
71
|
+
"pr_loop_shared_constants.claude_permissions_constants",
|
|
72
|
+
_scripts_directory()
|
|
73
|
+
/ "pr_loop_shared_constants"
|
|
74
|
+
/ "claude_permissions_constants.py",
|
|
75
75
|
)
|
|
76
76
|
|
|
77
77
|
|
|
@@ -138,10 +138,12 @@ def test_save_settings_temp_suffix_includes_pid_and_random_token(
|
|
|
138
138
|
|
|
139
139
|
def test_text_file_encoding_sourced_from_config() -> None:
|
|
140
140
|
config_module_path = (
|
|
141
|
-
Path(__file__).parent.parent
|
|
141
|
+
Path(__file__).parent.parent
|
|
142
|
+
/ "pr_loop_shared_constants"
|
|
143
|
+
/ "claude_permissions_constants.py"
|
|
142
144
|
)
|
|
143
145
|
specification = importlib.util.spec_from_file_location(
|
|
144
|
-
"
|
|
146
|
+
"pr_loop_shared_constants.claude_permissions_constants", config_module_path
|
|
145
147
|
)
|
|
146
148
|
assert specification is not None
|
|
147
149
|
assert specification.loader is not None
|
|
@@ -7,10 +7,12 @@ from types import ModuleType
|
|
|
7
7
|
|
|
8
8
|
def _load_constants_module() -> ModuleType:
|
|
9
9
|
module_path = (
|
|
10
|
-
Path(__file__).parent.parent
|
|
10
|
+
Path(__file__).parent.parent
|
|
11
|
+
/ "pr_loop_shared_constants"
|
|
12
|
+
/ "claude_permissions_constants.py"
|
|
11
13
|
)
|
|
12
14
|
specification = importlib.util.spec_from_file_location(
|
|
13
|
-
"
|
|
15
|
+
"pr_loop_shared_constants.claude_permissions_constants", module_path
|
|
14
16
|
)
|
|
15
17
|
assert specification is not None
|
|
16
18
|
assert specification.loader is not None
|
|
@@ -7,10 +7,12 @@ from types import ModuleType
|
|
|
7
7
|
|
|
8
8
|
def _load_constants_module() -> ModuleType:
|
|
9
9
|
module_path = (
|
|
10
|
-
Path(__file__).parent.parent
|
|
10
|
+
Path(__file__).parent.parent
|
|
11
|
+
/ "pr_loop_shared_constants"
|
|
12
|
+
/ "claude_settings_keys_constants.py"
|
|
11
13
|
)
|
|
12
14
|
specification = importlib.util.spec_from_file_location(
|
|
13
|
-
"
|
|
15
|
+
"pr_loop_shared_constants.claude_settings_keys_constants", module_path
|
|
14
16
|
)
|
|
15
17
|
assert specification is not None
|
|
16
18
|
assert specification.loader is not None
|
|
@@ -7,10 +7,12 @@ from types import ModuleType
|
|
|
7
7
|
|
|
8
8
|
def _load_constants_module() -> ModuleType:
|
|
9
9
|
module_path = (
|
|
10
|
-
Path(__file__).parent.parent
|
|
10
|
+
Path(__file__).parent.parent
|
|
11
|
+
/ "pr_loop_shared_constants"
|
|
12
|
+
/ "code_rules_gate_constants.py"
|
|
11
13
|
)
|
|
12
14
|
specification = importlib.util.spec_from_file_location(
|
|
13
|
-
"
|
|
15
|
+
"pr_loop_shared_constants.code_rules_gate_constants", module_path
|
|
14
16
|
)
|
|
15
17
|
assert specification is not None
|
|
16
18
|
assert specification.loader is not None
|
|
@@ -11,9 +11,13 @@ from types import ModuleType
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def _load_constants_module() -> ModuleType:
|
|
14
|
-
module_path =
|
|
14
|
+
module_path = (
|
|
15
|
+
Path(__file__).parent.parent
|
|
16
|
+
/ "pr_loop_shared_constants"
|
|
17
|
+
/ "fix_hookspath_constants.py"
|
|
18
|
+
)
|
|
15
19
|
specification = importlib.util.spec_from_file_location(
|
|
16
|
-
"
|
|
20
|
+
"pr_loop_shared_constants.fix_hookspath_constants", module_path
|
|
17
21
|
)
|
|
18
22
|
assert specification is not None
|
|
19
23
|
assert specification.loader is not None
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"""Smoke tests for grant_project_claude_permissions wiring.
|
|
2
2
|
|
|
3
3
|
Confirms the module imports cleanly with the constants now sourced from
|
|
4
|
-
|
|
4
|
+
pr_loop_shared_constants/claude_permissions_constants.py and
|
|
5
|
+
pr_loop_shared_constants/claude_settings_keys_constants.py.
|
|
5
6
|
"""
|
|
6
7
|
|
|
7
8
|
from __future__ import annotations
|
|
@@ -17,7 +18,6 @@ def _load_grant_module() -> ModuleType:
|
|
|
17
18
|
parent_directory = str(scripts_directory.resolve())
|
|
18
19
|
if parent_directory not in sys.path:
|
|
19
20
|
sys.path.insert(0, parent_directory)
|
|
20
|
-
sys.modules.pop("config", None)
|
|
21
21
|
module_path = scripts_directory / "grant_project_claude_permissions.py"
|
|
22
22
|
specification = importlib.util.spec_from_file_location(
|
|
23
23
|
"grant_project_claude_permissions", module_path
|
|
@@ -36,11 +36,10 @@ from typing import Any
|
|
|
36
36
|
THIS_FILE_DIRECTORY = Path(__file__).resolve().parent
|
|
37
37
|
SCRIPT_DIRECTORY = THIS_FILE_DIRECTORY.parent
|
|
38
38
|
|
|
39
|
-
sys.modules.pop("config", None)
|
|
40
39
|
if str(SCRIPT_DIRECTORY) not in sys.path:
|
|
41
40
|
sys.path.insert(0, str(SCRIPT_DIRECTORY))
|
|
42
41
|
|
|
43
|
-
from
|
|
42
|
+
from pr_loop_shared_constants.post_audit_thread_constants import ( # noqa: E402
|
|
44
43
|
ALL_GH_AUTH_TOKEN_COMMAND_PARTS,
|
|
45
44
|
ALL_RETRY_BACKOFF_SECONDS,
|
|
46
45
|
BUGTEAM_REVIEWER_ACCOUNT_ENV_VAR_NAME,
|
|
@@ -7,10 +7,12 @@ from types import ModuleType
|
|
|
7
7
|
|
|
8
8
|
def _load_constants_module() -> ModuleType:
|
|
9
9
|
module_path = (
|
|
10
|
-
Path(__file__).parent.parent
|
|
10
|
+
Path(__file__).parent.parent
|
|
11
|
+
/ "pr_loop_shared_constants"
|
|
12
|
+
/ "post_audit_thread_constants.py"
|
|
11
13
|
)
|
|
12
14
|
specification = importlib.util.spec_from_file_location(
|
|
13
|
-
"
|
|
15
|
+
"pr_loop_shared_constants.post_audit_thread_constants", module_path
|
|
14
16
|
)
|
|
15
17
|
assert specification is not None
|
|
16
18
|
assert specification.loader is not None
|
|
@@ -31,7 +31,7 @@ def _load_preflight_module() -> ModuleType:
|
|
|
31
31
|
|
|
32
32
|
preflight = _load_preflight_module()
|
|
33
33
|
|
|
34
|
-
from
|
|
34
|
+
from pr_loop_shared_constants.preflight_constants import ( # noqa: E402
|
|
35
35
|
PYTEST_INI_FILENAME,
|
|
36
36
|
PYTEST_NO_TESTS_COLLECTED_EXIT_CODE,
|
|
37
37
|
)
|
|
@@ -204,16 +204,19 @@ def test_should_exit_nonzero_when_subprocess_run_raises_os_error(
|
|
|
204
204
|
|
|
205
205
|
|
|
206
206
|
def test_preflight_uses_shared_hooks_path_suffix_constant() -> None:
|
|
207
|
-
"""Preflight's expected suffix must come from
|
|
208
|
-
so the canonical hooks
|
|
207
|
+
"""Preflight's expected suffix must come from
|
|
208
|
+
pr_loop_shared_constants.fix_hookspath_constants so the canonical hooks
|
|
209
|
+
directory is defined in exactly one place."""
|
|
209
210
|
scripts_directory = str(Path(__file__).parent.parent.resolve())
|
|
210
211
|
if scripts_directory not in sys.path:
|
|
211
212
|
sys.path.insert(0, scripts_directory)
|
|
212
213
|
constants_module_path = (
|
|
213
|
-
Path(__file__).parent.parent
|
|
214
|
+
Path(__file__).parent.parent
|
|
215
|
+
/ "pr_loop_shared_constants"
|
|
216
|
+
/ "fix_hookspath_constants.py"
|
|
214
217
|
)
|
|
215
218
|
constants_specification = importlib.util.spec_from_file_location(
|
|
216
|
-
"
|
|
219
|
+
"pr_loop_shared_constants.fix_hookspath_constants",
|
|
217
220
|
constants_module_path,
|
|
218
221
|
)
|
|
219
222
|
assert constants_specification is not None
|
|
@@ -234,15 +237,18 @@ def test_preflight_skip_uses_shared_env_var_constant(
|
|
|
234
237
|
capsys: pytest.CaptureFixture[str],
|
|
235
238
|
monkeypatch: pytest.MonkeyPatch,
|
|
236
239
|
) -> None:
|
|
237
|
-
"""The preflight skip env-var name must come from
|
|
240
|
+
"""The preflight skip env-var name must come from
|
|
241
|
+
pr_loop_shared_constants/preflight_constants.py."""
|
|
238
242
|
scripts_directory = str(Path(__file__).parent.parent.resolve())
|
|
239
243
|
if scripts_directory not in sys.path:
|
|
240
244
|
sys.path.insert(0, scripts_directory)
|
|
241
245
|
constants_module_path = (
|
|
242
|
-
Path(__file__).parent.parent
|
|
246
|
+
Path(__file__).parent.parent
|
|
247
|
+
/ "pr_loop_shared_constants"
|
|
248
|
+
/ "preflight_constants.py"
|
|
243
249
|
)
|
|
244
250
|
constants_specification = importlib.util.spec_from_file_location(
|
|
245
|
-
"
|
|
251
|
+
"pr_loop_shared_constants.preflight_constants",
|
|
246
252
|
constants_module_path,
|
|
247
253
|
)
|
|
248
254
|
assert constants_specification is not None
|
|
@@ -306,8 +312,9 @@ def test_preflight_does_not_import_unused_repository_root_marker_constant() -> N
|
|
|
306
312
|
|
|
307
313
|
def test_pytest_no_tests_collected_helper_returns_named_constant() -> None:
|
|
308
314
|
"""The pytest "no tests collected" exit code must be sourced from the
|
|
309
|
-
named constant in
|
|
310
|
-
literal 5 inside the function body (CODE_RULES magic-values
|
|
315
|
+
named constant in pr_loop_shared_constants/preflight_constants.py rather
|
|
316
|
+
than the bare literal 5 inside the function body (CODE_RULES magic-values
|
|
317
|
+
rule)."""
|
|
311
318
|
assert preflight._pytest_exit_code_no_tests_collected() == (
|
|
312
319
|
PYTEST_NO_TESTS_COLLECTED_EXIT_CODE
|
|
313
320
|
)
|
|
@@ -317,30 +324,6 @@ def test_pytest_no_tests_collected_helper_returns_named_constant() -> None:
|
|
|
317
324
|
)
|
|
318
325
|
|
|
319
326
|
|
|
320
|
-
def test_preflight_bootstrap_moves_script_directory_to_front() -> None:
|
|
321
|
-
"""Import bootstrap keeps exactly one script directory entry at the front."""
|
|
322
|
-
module_path = Path(__file__).parent.parent / "preflight.py"
|
|
323
|
-
script_directory_resolved = str(module_path.parent.resolve())
|
|
324
|
-
script_directory_absolute = str(module_path.parent.absolute())
|
|
325
|
-
original_sys_path = list(sys.path)
|
|
326
|
-
try:
|
|
327
|
-
sys.path.insert(0, script_directory_resolved)
|
|
328
|
-
sys.path.insert(0, script_directory_resolved)
|
|
329
|
-
sys.path.insert(0, str(module_path.parents[4]))
|
|
330
|
-
_load_preflight_module()
|
|
331
|
-
assert os.path.samefile(sys.path[0], script_directory_resolved)
|
|
332
|
-
equivalent_count = sum(
|
|
333
|
-
1
|
|
334
|
-
for each_entry in sys.path
|
|
335
|
-
if os.path.exists(each_entry)
|
|
336
|
-
and os.path.samefile(each_entry, script_directory_resolved)
|
|
337
|
-
)
|
|
338
|
-
assert equivalent_count == 1
|
|
339
|
-
assert sys.path[0] == script_directory_absolute
|
|
340
|
-
finally:
|
|
341
|
-
sys.path[:] = original_sys_path
|
|
342
|
-
|
|
343
|
-
|
|
344
327
|
def test_main_uses_correct_changed_files_function_name() -> None:
|
|
345
328
|
"""main() must call get_changed_files, not the undefined get_all_changed_files."""
|
|
346
329
|
main_source = inspect.getsource(preflight.main)
|
|
@@ -528,24 +511,6 @@ def test_explicit_scope_all_with_base_ref_should_not_call_get_changed_files(
|
|
|
528
511
|
mock_get_changed.assert_not_called()
|
|
529
512
|
|
|
530
513
|
|
|
531
|
-
def test_preflight_bootstrap_matches_code_rules_sys_path_pattern() -> None:
|
|
532
|
-
"""Bootstrap must clear duplicate script_directory entries, then guard insert."""
|
|
533
|
-
module_path = Path(__file__).parent.parent / "preflight.py"
|
|
534
|
-
source = module_path.read_text(encoding="utf-8")
|
|
535
|
-
assert "_entry_points_at_preflight_script_directory" in source, (
|
|
536
|
-
"Bootstrap must remove script_directory entries using path equivalence"
|
|
537
|
-
)
|
|
538
|
-
assert "for each_index in range(len(sys.path) - 1, -1, -1):" in source, (
|
|
539
|
-
"Bootstrap must walk sys.path to drop duplicate script directory entries"
|
|
540
|
-
)
|
|
541
|
-
assert "_preflight_scripts_path_entry not in sys.path:" in source, (
|
|
542
|
-
"Bootstrap insert must be guarded for code_rules_gate compliance"
|
|
543
|
-
)
|
|
544
|
-
assert "sys.path.insert(0, _preflight_scripts_path_entry)" in source, (
|
|
545
|
-
"Bootstrap must insert the absolute script directory at index 0"
|
|
546
|
-
)
|
|
547
|
-
|
|
548
|
-
|
|
549
514
|
def test_has_discoverable_tests_should_include_untracked_test_files(
|
|
550
515
|
tmp_path: Path,
|
|
551
516
|
) -> None:
|
|
@@ -6,9 +6,13 @@ from types import ModuleType
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def _load_constants_module() -> ModuleType:
|
|
9
|
-
module_path =
|
|
9
|
+
module_path = (
|
|
10
|
+
Path(__file__).parent.parent
|
|
11
|
+
/ "pr_loop_shared_constants"
|
|
12
|
+
/ "preflight_constants.py"
|
|
13
|
+
)
|
|
10
14
|
specification = importlib.util.spec_from_file_location(
|
|
11
|
-
"
|
|
15
|
+
"pr_loop_shared_constants.preflight_constants", module_path
|
|
12
16
|
)
|
|
13
17
|
assert specification is not None
|
|
14
18
|
assert specification.loader is not None
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"""Smoke tests for revoke_project_claude_permissions wiring.
|
|
2
2
|
|
|
3
3
|
Confirms the module imports cleanly with the constants now sourced from
|
|
4
|
-
|
|
4
|
+
pr_loop_shared_constants/claude_permissions_constants.py and
|
|
5
|
+
pr_loop_shared_constants/claude_settings_keys_constants.py.
|
|
5
6
|
"""
|
|
6
7
|
|
|
7
8
|
from __future__ import annotations
|
|
@@ -17,7 +18,6 @@ def _load_revoke_module() -> ModuleType:
|
|
|
17
18
|
parent_directory = str(scripts_directory.resolve())
|
|
18
19
|
if parent_directory not in sys.path:
|
|
19
20
|
sys.path.insert(0, parent_directory)
|
|
20
|
-
sys.modules.pop("config", None)
|
|
21
21
|
module_path = scripts_directory / "revoke_project_claude_permissions.py"
|
|
22
22
|
specification = importlib.util.spec_from_file_location(
|
|
23
23
|
"revoke_project_claude_permissions", module_path
|