claude-dev-env 7.5.0 → 7.6.1

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.
Files changed (125) hide show
  1. package/.agents/skills/everything-search/scripts/everything_search.py +11 -0
  2. package/.agents/skills/everything-search/scripts/test_everything_search.py +1 -0
  3. package/.agents/skills/fresh-branch/SKILL.md +1 -0
  4. package/.agents/skills/fresh-branch/scripts/fresh_branch_git_commands.py +3 -0
  5. package/.agents/skills/fresh-branch/scripts/subprocess_window_access.py +43 -0
  6. package/.agents/skills/session-continuity/README.md +19 -9
  7. package/.agents/skills/syncing-submodules/SKILL.md +1 -0
  8. package/.agents/skills/syncing-submodules/scripts/submodule_sync.py +4 -0
  9. package/.agents/skills/syncing-submodules/scripts/subprocess_window_access.py +43 -0
  10. package/.agents/skills/test-runner/SKILL.md +1 -0
  11. package/.agents/skills/test-runner/scripts/preflight_checks.py +5 -0
  12. package/.agents/skills/test-runner/scripts/run_tests.py +11 -0
  13. package/.agents/skills/test-runner/scripts/subprocess_window_access.py +43 -0
  14. package/.agents/skills/test-runner/scripts/test_run_tests.py +9 -7
  15. package/_shared/pr-loop/scripts/check_bugbot_ci.py +3 -0
  16. package/_shared/pr-loop/scripts/check_convergence_gates.py +3 -0
  17. package/_shared/pr-loop/scripts/check_pending_reviews.py +3 -0
  18. package/_shared/pr-loop/scripts/code_rules_gate_parts/added_line_maps.py +3 -0
  19. package/_shared/pr-loop/scripts/code_rules_gate_parts/baseline_import_isolation.py +3 -0
  20. package/_shared/pr-loop/scripts/code_rules_gate_parts/git_blob_readers.py +5 -0
  21. package/_shared/pr-loop/scripts/code_rules_gate_parts/git_file_sets.py +4 -0
  22. package/_shared/pr-loop/scripts/code_rules_gate_parts/staged_test_regression.py +3 -0
  23. package/_shared/pr-loop/scripts/code_rules_gate_parts/staged_test_running.py +3 -0
  24. package/_shared/pr-loop/scripts/codex_usage_probe.py +3 -0
  25. package/_shared/pr-loop/scripts/copilot_quota.py +3 -0
  26. package/_shared/pr-loop/scripts/fetch_copilot_reviews.py +3 -0
  27. package/_shared/pr-loop/scripts/fix_hookspath.py +7 -0
  28. package/_shared/pr-loop/scripts/post_fix_reply.py +4 -0
  29. package/_shared/pr-loop/scripts/preflight.py +7 -0
  30. package/_shared/pr-loop/scripts/preflight_self_heal.py +5 -0
  31. package/_shared/pr-loop/scripts/run_codex_review.py +3 -0
  32. package/_shared/pr-loop/scripts/subprocess_window_access.py +41 -0
  33. package/_shared/pr-loop/scripts/terminology_sweep.py +5 -0
  34. package/_shared/process-tree/scripts/process_tree_kill.py +3 -0
  35. package/_shared/process-tree/scripts/subprocess_window_access.py +41 -0
  36. package/bin/install-constants.mjs +4 -2
  37. package/bin/install-session-continuity.mjs +73 -30
  38. package/bin/install-session-continuity.test.mjs +52 -1
  39. package/bin/install.cursor-rules.test.mjs +57 -15
  40. package/bin/install.mjs +80 -15
  41. package/bin/install.test.mjs +57 -0
  42. package/bin/pstack-model-preferences.claude.json +23 -0
  43. package/hooks/advisory/pr_done_reminder.py +7 -0
  44. package/hooks/advisory/refactor_guard.py +8 -0
  45. package/hooks/advisory/test_pr_done_reminder.py +21 -0
  46. package/hooks/advisory/test_refactor_guard.py +40 -0
  47. package/hooks/blocking/block_main_commit.py +4 -0
  48. package/hooks/blocking/code_rules_comments.py +39 -5
  49. package/hooks/blocking/pii_prevention_blocker_parts/repository_exemption.py +3 -0
  50. package/hooks/blocking/precommit_code_rules_gate.py +3 -0
  51. package/hooks/blocking/tdd_enforcer_parts/content_analysis.py +19 -3
  52. package/hooks/blocking/tdd_enforcer_parts/git_tracking.py +4 -0
  53. package/hooks/blocking/tdd_enforcer_parts/tests/test_content_analysis.py +25 -0
  54. package/hooks/blocking/test_code_rules_enforcer_comment_string_awareness.py +27 -0
  55. package/hooks/blocking/test_code_rules_enforcer_exempt_marker_chained.py +10 -0
  56. package/hooks/git-hooks/git_hooks_constants/verification_notice_constants.py +0 -2
  57. package/hooks/git-hooks/pull_request_handoff.py +3 -0
  58. package/hooks/git-hooks/subprocess_window_access.py +41 -0
  59. package/hooks/git-hooks/test_verification_start.py +4 -0
  60. package/hooks/git-hooks/verification_notice_context.py +3 -0
  61. package/hooks/git-hooks/verification_start.py +7 -8
  62. package/hooks/hooks_constants/code_rules_enforcer_constants.py +2 -0
  63. package/hooks/hooks_constants/subprocess_window.py +141 -0
  64. package/hooks/hooks_constants/subprocess_window_constants.py +9 -0
  65. package/hooks/hooks_constants/test_code_rules_enforcer_constants.py +6 -0
  66. package/hooks/hooks_constants/test_subprocess_window.py +128 -0
  67. package/hooks/lifecycle/enter_worktree_origin_prefetch.py +3 -0
  68. package/hooks/validation/mypy_validator.py +4 -0
  69. package/hooks/validators/README.md +1 -0
  70. package/hooks/validators/git_checks.py +4 -0
  71. package/hooks/validators/health_check.py +3 -0
  72. package/hooks/validators/hook_timing_harness.py +3 -0
  73. package/hooks/validators/mypy_integration.py +4 -0
  74. package/hooks/validators/ruff_integration.py +6 -0
  75. package/hooks/validators/run_all_validators.py +7 -0
  76. package/hooks/validators/subprocess_window_access.py +41 -0
  77. package/hooks/workflow/auto_formatter.py +8 -0
  78. package/hooks/workflow/test_auto_formatter.py +39 -0
  79. package/package.json +1 -1
  80. package/rules/pstack-models.md +4 -3
  81. package/scripts/automatic_advisory/checkout.py +8 -1
  82. package/scripts/automatic_advisory/cli.py +9 -3
  83. package/scripts/automatic_advisory/config/constants.py +0 -2
  84. package/scripts/automatic_advisory/execution.py +7 -1
  85. package/scripts/automatic_advisory/git.py +9 -1
  86. package/scripts/automatic_advisory/process_host.py +3 -0
  87. package/scripts/claude_chain_runner.py +3 -0
  88. package/scripts/gh_artifact_upload.py +3 -0
  89. package/scripts/grok_headless_runner.py +3 -0
  90. package/scripts/grok_patch_artifacts.py +4 -0
  91. package/scripts/grok_worker_preflight.py +3 -0
  92. package/scripts/invoke_code_review.py +3 -0
  93. package/scripts/local_verification/command_runner.py +3 -0
  94. package/scripts/local_verification/git_state.py +3 -0
  95. package/scripts/policy_lint/adapter_detectors.py +48 -2
  96. package/scripts/policy_lint/adapter_pairing.py +150 -2
  97. package/scripts/policy_lint/adapters.py +46 -4
  98. package/scripts/policy_lint/config/approved_test_pairs.py +25 -9
  99. package/scripts/policy_lint/config/constants.py +3 -0
  100. package/scripts/policy_lint/registry.py +1 -1
  101. package/scripts/policy_lint/selection_git.py +11 -0
  102. package/scripts/repository_checks/config/constants.py +5 -0
  103. package/scripts/repository_checks/config/policy_document.py +19 -0
  104. package/scripts/repository_checks/email_exemptions.py +14 -71
  105. package/scripts/repository_checks/path_exemptions.py +35 -0
  106. package/scripts/repository_checks/policy_document.py +120 -0
  107. package/scripts/repository_checks/tracked_secrets.py +27 -4
  108. package/scripts/setup_project_paths.py +3 -0
  109. package/scripts/spawn_grok_batch.py +3 -0
  110. package/scripts/subprocess_window_access.py +41 -0
  111. package/scripts/test_dispatcher_profile_import.py +4 -0
  112. package/scripts/tests/test_automatic_advisory_window_flags.py +17 -11
  113. package/scripts/tests/test_email_exemptions.py +37 -0
  114. package/scripts/tests/test_path_exemptions.py +164 -0
  115. package/scripts/tests/test_policy_document.py +104 -0
  116. package/scripts/tests/test_policy_lint_rules_function_length_scope.py +101 -0
  117. package/scripts/tests/test_policy_lint_rules_pairing.py +375 -0
  118. package/scripts/tests/test_policy_lint_rules_registry.py +116 -0
  119. package/scripts/tests/test_policy_lint_selection.py +34 -0
  120. package/scripts/tests/test_subprocess_window_access.py +118 -0
  121. package/scripts/tests/test_tracked_secrets.py +79 -0
  122. package/scripts/validate_instruction_pairs.py +3 -0
  123. package/scripts/verify_installable_package.py +5 -0
  124. package/scripts/automatic_advisory/window_flags.py +0 -41
  125. package/scripts/repository_checks/config/email_exemptions.py +0 -10
@@ -3,7 +3,9 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import hashlib
6
+ import json
6
7
  import sys
8
+ from collections.abc import Callable
7
9
  from pathlib import Path
8
10
 
9
11
  import pytest
@@ -12,6 +14,7 @@ from repository_checks.config.constants import (
12
14
  CHECK_ID_TRACKED_PERSONAL_DATA,
13
15
  FAILED_CHECK_EXIT_CODE,
14
16
  FINDINGS_EXIT_CODE,
17
+ SUCCESS_EXIT_CODE,
15
18
  )
16
19
  from repository_checks.hook_modules import load_hooks_module
17
20
  from repository_checks.tracked_secrets import collect_tracked_secret_findings
@@ -35,6 +38,8 @@ _OTHER_FIXTURE_EMAIL = "other-owner@company.io"
35
38
  _OTHER_FIXTURE_HOME_PATH = "C:/Users/realname/notes.txt"
36
39
  _FIXTURE_NOTES_RELATIVE_PATH = "src/notes.py"
37
40
  _OTHER_NOTES_RELATIVE_PATH = "src/other_notes.py"
41
+ _FROZEN_RELATIVE_PATH = "evidence/manifest.json"
42
+ _STALE_DIGEST = hashlib.sha256(b"different bytes").hexdigest()
38
43
  _PII_PREVENTION_CONSTANTS = load_hooks_module(
39
44
  "hooks_constants.pii_prevention_constants"
40
45
  )
@@ -151,6 +156,80 @@ def test_should_keep_owned_checker_modules_free_of_tracked_secret_findings() ->
151
156
  assert collect_tracked_secret_findings(_REPOSITORY_ROOT, all_relative_paths) == []
152
157
 
153
158
 
159
+ def test_should_skip_every_category_in_a_frozen_file_whose_digest_matches(
160
+ tmp_path: Path,
161
+ ) -> None:
162
+ """One recorded digest silences the whole file, not one matched value."""
163
+ repository_root = tmp_path / "repo"
164
+ initialize_repository(repository_root)
165
+ _write_frozen_path_exemption_fixture(repository_root, _matching_digest)
166
+ commit_tracked_files(repository_root)
167
+ exit_code, stdout_text, _stderr_text = run_policy(repository_root)
168
+ assert exit_code == SUCCESS_EXIT_CODE
169
+ assert _pii_categories_for_path(stdout_text, _FROZEN_RELATIVE_PATH) == []
170
+
171
+
172
+ def test_should_keep_reporting_a_frozen_file_whose_digest_is_stale(
173
+ tmp_path: Path,
174
+ ) -> None:
175
+ repository_root = tmp_path / "repo"
176
+ initialize_repository(repository_root)
177
+ _write_frozen_path_exemption_fixture(repository_root, _stale_digest)
178
+ commit_tracked_files(repository_root)
179
+ exit_code, stdout_text, _stderr_text = run_policy(repository_root)
180
+ assert exit_code == FINDINGS_EXIT_CODE
181
+ assert _pii_categories_for_path(stdout_text, _FROZEN_RELATIVE_PATH) == [
182
+ _PII_CATEGORY_HOME_PATH,
183
+ _PII_PREVENTION_CONSTANTS.CATEGORY_SECRET,
184
+ ]
185
+
186
+
187
+ def test_should_exempt_a_frozen_file_named_by_a_windows_tracked_path(
188
+ tmp_path: Path,
189
+ ) -> None:
190
+ """Git on Windows can hand back backslashes, and the entry records slashes."""
191
+ repository_root = tmp_path / "repo"
192
+ repository_root.mkdir()
193
+ _write_frozen_path_exemption_fixture(repository_root, _matching_digest)
194
+ windows_tracked_path = _FROZEN_RELATIVE_PATH.replace("/", "\\")
195
+ assert (
196
+ collect_tracked_secret_findings(repository_root, [windows_tracked_path]) == []
197
+ )
198
+
199
+
200
+ def _write_frozen_path_exemption_fixture(
201
+ repository_root: Path, choose_digest: Callable[[Path], str]
202
+ ) -> None:
203
+ frozen_path = repository_root / _FROZEN_RELATIVE_PATH
204
+ write_text(
205
+ frozen_path,
206
+ f"home = '{_OTHER_FIXTURE_HOME_PATH}'\ntoken = '{_SYNTHETIC_GITHUB_TOKEN}'\n",
207
+ )
208
+ write_text(
209
+ repository_root / "config" / "repository-policy.json",
210
+ json.dumps(
211
+ {
212
+ "version": 1,
213
+ "path_exemptions": [
214
+ {
215
+ "path": _FROZEN_RELATIVE_PATH,
216
+ "sha256": choose_digest(frozen_path),
217
+ "reason": "Frozen evidence file pinned by its consumers",
218
+ }
219
+ ],
220
+ }
221
+ ),
222
+ )
223
+
224
+
225
+ def _matching_digest(frozen_path: Path) -> str:
226
+ return hashlib.sha256(frozen_path.read_bytes()).hexdigest()
227
+
228
+
229
+ def _stale_digest(_frozen_path: Path) -> str:
230
+ return _STALE_DIGEST
231
+
232
+
154
233
  def _write_exact_exemption_fixture(repository_root: Path) -> None:
155
234
  write_text(
156
235
  repository_root / _FIXTURE_NOTES_RELATIVE_PATH,
@@ -9,6 +9,8 @@ import stat
9
9
  import subprocess
10
10
  from pathlib import Path
11
11
 
12
+ from subprocess_window_access import hidden_window_creation_flags
13
+
12
14
  git_directory_name = ".git"
13
15
  git_listing_commands = (
14
16
  (("git", "ls-files", "--stage", "-z"), True),
@@ -32,6 +34,7 @@ def _read_git_paths_and_modes(
32
34
  cwd=repository_root,
33
35
  capture_output=True,
34
36
  check=True,
37
+ creationflags=hidden_window_creation_flags(),
35
38
  )
36
39
  for each_record in completed_process.stdout.split(b"\0"):
37
40
  if not each_record:
@@ -68,6 +68,8 @@ from dev_env_scripts_constants.verify_installable_package_constants import (
68
68
  VERIFICATION_PASSED_MESSAGE,
69
69
  )
70
70
 
71
+ from subprocess_window_access import hidden_window_creation_flags
72
+
71
73
 
72
74
  def package_root_path() -> Path:
73
75
  """Return the claude-dev-env package root that holds package.json."""
@@ -303,6 +305,7 @@ def run_npm_pack(into_directory: Path, from_package_root: Path) -> Path:
303
305
  capture_output=True,
304
306
  text=True,
305
307
  encoding=UTF8_ENCODING,
308
+ creationflags=hidden_window_creation_flags(),
306
309
  )
307
310
  tarball_name = _npm_pack_filename_from_json(completed.stdout)
308
311
  return into_directory / tarball_name
@@ -439,6 +442,7 @@ def list_git_tracked_paths_under(
439
442
  capture_output=True,
440
443
  text=True,
441
444
  encoding=UTF8_ENCODING,
445
+ creationflags=hidden_window_creation_flags(),
442
446
  )
443
447
  return frozenset(
444
448
  each_line.replace("\\", "/")
@@ -520,6 +524,7 @@ def smoke_check_install_entrypoint(from_package_root: Path) -> str | None:
520
524
  capture_output=True,
521
525
  text=True,
522
526
  encoding=UTF8_ENCODING,
527
+ creationflags=hidden_window_creation_flags(),
523
528
  )
524
529
  if completed.returncode == 0:
525
530
  return None
@@ -1,41 +0,0 @@
1
- """Windows creation flags that hide the advisory poller and its children.
2
-
3
- A poller with no console makes each git call and each check open a fresh
4
- console window. A hidden console is inherited by descendants, so those
5
- children stay off the screen.
6
- """
7
-
8
- from __future__ import annotations
9
-
10
- import subprocess
11
- import sys
12
-
13
- from .config.constants import (
14
- CREATE_NEW_PROCESS_GROUP_ATTRIBUTE,
15
- CREATE_NO_WINDOW_ATTRIBUTE,
16
- WINDOWS_PLATFORM,
17
- )
18
-
19
-
20
- def hidden_window_creation_flags() -> int:
21
- """Return the flag that runs a Windows child without a visible console.
22
-
23
- Returns:
24
- The hidden-console flag on Windows, zero elsewhere.
25
- """
26
- if sys.platform != WINDOWS_PLATFORM:
27
- return 0
28
- return getattr(subprocess, CREATE_NO_WINDOW_ATTRIBUTE, 0)
29
-
30
-
31
- def detached_poller_creation_flags() -> int:
32
- """Return the flags for the long-running poller on Windows.
33
-
34
- Returns:
35
- A new process group plus a hidden console on Windows, zero elsewhere.
36
- """
37
- if sys.platform != WINDOWS_PLATFORM:
38
- return 0
39
- return getattr(subprocess, CREATE_NEW_PROCESS_GROUP_ATTRIBUTE, 0) | getattr(
40
- subprocess, CREATE_NO_WINDOW_ATTRIBUTE, 0
41
- )
@@ -1,10 +0,0 @@
1
- """Repository public-email exception schema."""
2
-
3
- import re
4
-
5
- CONFIG_RELATIVE_PATH = "config/repository-policy.json"
6
- DIGEST_PATTERN = re.compile(r"[0-9a-f]{64}")
7
- FORBIDDEN_PATH_CHARACTERS = frozenset("\\:*?[]")
8
- ALL_ENTRY_FIELDS = frozenset({"path", "sha256", "reason"})
9
- ALL_FORBIDDEN_PATH_SEGMENTS = frozenset({"", ".", ".."})
10
- FIRST_PRINTABLE_CODEPOINT = 32