claude-dev-env 8.35.3 → 8.36.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.
@@ -52,6 +52,7 @@ For Claude Projects facts or reported coordinator mechanisms, read [platform evi
52
52
  ### Orient and retain the goals
53
53
 
54
54
  Read the current user message and applicable project instructions.
55
+ Read `~/.claude/rules/long-horizon-autonomy.md` and `~/.claude/rules/workers-done-before-complete.md` before the first dispatch. Invoking this skill does not load those two rules, so this read does.
55
56
  At startup or after context loss, inspect `.orchestrator/active-runs/` under the supplied project directory.
56
57
  Use an alternate registry only when loaded instructions or the runtime provide its exact locator.
57
58
  Verify the startup loader pointer described in run state before claiming recovery from a cold session.
@@ -28,7 +28,7 @@ Keep current authorization and configured model routing when restoring work.
28
28
  ## Process
29
29
 
30
30
  1. Read the current message and loaded instructions. Load the orchestrator entrypoint.
31
- 2. Resolve the run from its supplied locator or `.orchestrator/active-runs/` under the project directory.
31
+ Read `~/.claude/rules/long-horizon-autonomy.md` and `~/.claude/rules/workers-done-before-complete.md`. Invoking this skill does not load those two rules, so this read does.2. Resolve the run from its supplied locator or `.orchestrator/active-runs/` under the project directory.
32
32
  Read the run record's owner and optional wake metadata first.
33
33
  For a recorded one-shot firing, confirm both the invocation's wake identity and current root ownership.
34
34
  Immediately run `begin-firing` with its explicit `--status-file` and `--run-slug` through [optional scheduling](../orchestrator/reference/scheduling.md).
@@ -0,0 +1,14 @@
1
+ from hooks_constants import piped_pytest_blocker_constants as constants
2
+
3
+
4
+ def test_pytest_programs_and_interpreters_cover_supported_invocations() -> None:
5
+ assert {"pytest", "pytest.exe", "py.test"} <= constants.ALL_PYTEST_PROGRAM_BASENAMES
6
+ assert constants.PYTHON_INTERPRETER_BASENAME_PATTERN.fullmatch("python3.12.exe")
7
+ assert (constants.MODULE_RUN_FLAG, constants.PYTEST_MODULE_NAME) == ("-m", "pytest")
8
+
9
+
10
+ def test_pipe_and_wrapper_tokens_preserve_command_boundaries() -> None:
11
+ assert {"|", "|&"} <= constants.ALL_PIPE_OPERATOR_TOKENS
12
+ assert ";;" in constants.ALL_SEGMENT_RESET_OPERATOR_TOKENS
13
+ assert "-u" in constants.ALL_WRAPPER_OPTION_GRAMMARS_BY_NAME["sudo"].all_value_taking_options
14
+ assert constants.ALL_WRAPPER_OPTION_GRAMMARS_BY_NAME["timeout"].leading_operand_count == 1
@@ -0,0 +1,18 @@
1
+ from hooks_constants import verify_before_acting_constants as constants
2
+
3
+
4
+ def test_mutating_tool_and_mcp_names_are_classified() -> None:
5
+ assert {"Write", "Edit"} <= constants.ALL_ALWAYS_MUTATING_TOOL_NAMES
6
+ assert {"Bash", "PowerShell"} == constants.ALL_SHELL_TOOL_NAMES
7
+ assert constants.MCP_ACTION_WORD_SPLIT_PATTERN.split("create_pull_request") == [
8
+ "create",
9
+ "pull",
10
+ "request",
11
+ ]
12
+ assert "create" in constants.ALL_MCP_MUTATING_VERBS
13
+
14
+
15
+ def test_hedge_pattern_matches_a_hedged_claim_only() -> None:
16
+ assert constants.HEDGE_PATTERN.search("Perhaps the command writes a file.")
17
+ assert constants.HEDGE_PATTERN.search("I might be mistaken.")
18
+ assert constants.HEDGE_PATTERN.search("I checked the command output.") is None
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-dev-env",
3
- "version": "8.35.3",
3
+ "version": "8.36.1",
4
4
  "description": "Claude Code development standards — rules, hooks, agents, commands, and skills",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,3 +1,14 @@
1
+ ---
2
+ paths:
3
+ - "**/rules/**"
4
+ - "**/rules-archived/**"
5
+ - "**/skills/**"
6
+ - "**/skills-archived/**"
7
+ - "**/agents/**"
8
+ - "**/commands/**"
9
+ - "**/ever-shipped-skills.mjs"
10
+ ---
11
+
1
12
  # Archiving a Rule, Skill, Agent, or Command
2
13
 
3
14
  **When this applies:** Pruning agent configuration in this package — moving a
package/rules/bdd.md CHANGED
@@ -1,3 +1,12 @@
1
+ ---
2
+ paths:
3
+ - "**/*.py"
4
+ - "**/*.mjs"
5
+ - "**/*.js"
6
+ - "**/*.ts"
7
+ - "**/*.tsx"
8
+ ---
9
+
1
10
  # BDD (discovery-driven development)
2
11
 
3
12
  **Canonical detail:** `~/.claude/system-prompts/software-engineer.xml` → `<behavior_protocol>`.
@@ -1,3 +1,14 @@
1
+ ---
2
+ paths:
3
+ - "**/scripts/**"
4
+ - "**/hooks/**"
5
+ - "**/bin/**"
6
+ - "**/ci/**"
7
+ - "**/tools/**"
8
+ - "**/skills/**"
9
+ - "**/commands/**"
10
+ ---
11
+
1
12
  # Build Needs a User
2
13
 
3
14
  **When this applies:** Before you build a new tool, script, hook, gate, skill,
@@ -1,3 +1,13 @@
1
+ ---
2
+ paths:
3
+ - "**/*.py"
4
+ - "**/*.mjs"
5
+ - "**/*.js"
6
+ - "**/*.ts"
7
+ - "**/*.tsx"
8
+ - "**/*.ps1"
9
+ ---
10
+
1
11
  # Code Standards
2
12
 
3
13
  > **Canonical review contract:** [`CODE_RULES.md`](../docs/CODE_RULES.md) — the human and AI review contract for code quality, loaded on demand.
@@ -1,3 +1,12 @@
1
+ ---
2
+ paths:
3
+ - "**/*.py"
4
+ - "**/*.mjs"
5
+ - "**/*.js"
6
+ - "**/*.ts"
7
+ - "**/*.ps1"
8
+ ---
9
+
1
10
  # Failure Blast Radius
2
11
 
3
12
  **When this applies:** Batch code that processes assets, rows, accounts, messages, or files where one member can fail while the others are fine.
@@ -1,3 +1,14 @@
1
+ ---
2
+ paths:
3
+ - "**/hooks/**"
4
+ - "**/policy_lint/**"
5
+ - "**/repository_checks/**"
6
+ - "**/.pre-commit-config.yaml"
7
+ - "**/.githooks/**"
8
+ - "**/.husky/**"
9
+ - "**/.github/workflows/**"
10
+ ---
11
+
1
12
  # Flag Non-Breaking Findings
2
13
 
3
14
  **When this applies:** Writing or changing a local gate — a git hook, a
@@ -1,3 +1,9 @@
1
+ ---
2
+ paths:
3
+ - "**/skills/orchestrator/**"
4
+ - "**/skills/orchestrator-refresh/**"
5
+ ---
6
+
1
7
  # Long-Horizon Autonomy
2
8
 
3
9
  Source: [Anthropic - Prompting Claude Fable 5](https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/prompting-claude-fable-5)
@@ -1,3 +1,16 @@
1
+ ---
2
+ paths:
3
+ - "**/scripts/**"
4
+ - "**/hooks/**"
5
+ - "**/bin/**"
6
+ - "**/ci/**"
7
+ - "**/tools/**"
8
+ - "**/skills/**"
9
+ - "**/package.json"
10
+ - "**/pyproject.toml"
11
+ - "**/requirements*.txt"
12
+ ---
13
+
1
14
  # Prefer Existing Tools
2
15
 
3
16
  **When this applies:** Before you build a tool, check, scanner, script, or library of your own.
@@ -1,3 +1,9 @@
1
+ ---
2
+ paths:
3
+ - "**/skills/orchestrator/**"
4
+ - "**/skills/orchestrator-refresh/**"
5
+ ---
6
+
1
7
  # Workers Done Before Complete
2
8
 
3
9
  Before marking a task `completed` that spawned workers — subagents, workflow agents, or background shells — confirm both: every worker has finished, and each worker's result is merged into run state (`state.json`, `pr-converge-state.json`, the task list, or whatever record the task keeps). A worker still running, or one whose output never landed in run state, keeps the task `in_progress`: list the live workers, report any dead or hung one as a finding rather than dropping it in silence, and schedule a wakeup so the run picks the workers back up before the task closes.
@@ -0,0 +1,77 @@
1
+ """Which rules load in every session, and how skill-scoped rules still reach their skill."""
2
+
3
+ from pathlib import Path
4
+
5
+ PACKAGE_ROOT = Path(__file__).resolve().parents[2]
6
+ RULES_DIRECTORY = PACKAGE_ROOT / "rules"
7
+ SKILLS_DIRECTORY = PACKAGE_ROOT / ".agents" / "skills"
8
+
9
+ ALWAYS_ON_RULE_NAMES = frozenset(
10
+ {
11
+ "AGENTS.md",
12
+ "CLAUDE.md",
13
+ "agent-merges-its-own-green-pull-request.md",
14
+ "asd-ste100-language.md",
15
+ "ci-owns-the-gate.md",
16
+ "cleanup-temp-files.md",
17
+ "correction-lens.md",
18
+ "destructive-commands.md",
19
+ "durable-post-artifacts.md",
20
+ "explore-thoroughly.md",
21
+ "filesystem-search.md",
22
+ "gh-cli-conventions.md",
23
+ "git-workflow.md",
24
+ "memory-stores-durable-facts.md",
25
+ "no-contrast-framing.md",
26
+ "question-presentation.md",
27
+ "re-stage-before-commit.md",
28
+ "research-mode.md",
29
+ "review-closure-is-a-check.md",
30
+ "shell-invocation.md",
31
+ "verify-before-asking.md",
32
+ "verify-runtime-state.md",
33
+ }
34
+ )
35
+
36
+ SKILL_SCOPED_RULES = {
37
+ "long-horizon-autonomy.md": ("orchestrator", "orchestrator-refresh"),
38
+ "workers-done-before-complete.md": ("orchestrator", "orchestrator-refresh"),
39
+ }
40
+
41
+
42
+ def _declares_paths(rule_path: Path) -> bool:
43
+ lines = rule_path.read_text(encoding="utf-8").splitlines()
44
+ if not lines or lines[0] != "---":
45
+ return False
46
+ for each_line in lines[1:]:
47
+ if each_line == "---":
48
+ return False
49
+ if each_line.startswith("paths:"):
50
+ return True
51
+ return False
52
+
53
+
54
+ def test_only_allowlisted_rules_load_in_every_session() -> None:
55
+ unscoped_rule_names = {
56
+ each_rule.name
57
+ for each_rule in RULES_DIRECTORY.glob("*.md")
58
+ if not _declares_paths(each_rule)
59
+ }
60
+ assert unscoped_rule_names == ALWAYS_ON_RULE_NAMES
61
+
62
+
63
+ def test_skill_scoped_rules_carry_paths_on_their_skill_directories() -> None:
64
+ for each_rule_name, all_skill_names in SKILL_SCOPED_RULES.items():
65
+ rule_text = (RULES_DIRECTORY / each_rule_name).read_text(encoding="utf-8")
66
+ assert _declares_paths(RULES_DIRECTORY / each_rule_name)
67
+ for each_skill_name in all_skill_names:
68
+ assert f'"**/skills/{each_skill_name}/**"' in rule_text
69
+
70
+
71
+ def test_each_scoping_skill_tells_the_agent_to_read_its_rules() -> None:
72
+ for each_rule_name, all_skill_names in SKILL_SCOPED_RULES.items():
73
+ for each_skill_name in all_skill_names:
74
+ skill_text = (SKILLS_DIRECTORY / each_skill_name / "SKILL.md").read_text(
75
+ encoding="utf-8"
76
+ )
77
+ assert f"~/.claude/rules/{each_rule_name}" in skill_text