claude-dev-env 8.46.6 → 8.46.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/agents-archived/clean-coder.md +1 -1
- package/.agents/agents-archived/code-quality-agent.md +1 -1
- package/.agents/skills/grok-spawn/reference/worker-briefs.md +2 -2
- package/hooks/blocking/code_rules_comments.py +3 -3
- package/hooks/routing/subagent_model_pin_hook.py +3 -8
- package/hooks/routing/test_subagent_model_pin_hook.py +1 -1
- package/hooks/routing/test_thread_spawn_pace_hook.py +1 -1
- package/hooks/routing/thread_spawn_pace_hook.py +2 -6
- package/package.json +1 -1
|
@@ -22,7 +22,7 @@ Before writing a single line — **task-local discovery only** (no project-wide
|
|
|
22
22
|
1. **Load scoped repository instructions first.** Starting at the repository root, read every applicable `AGENTS.md` on the path to the task file. Then read the applicable `CLAUDE.md` files. Apply nearer instructions after broader ones; the closest file wins.
|
|
23
23
|
2. **Read the file you are about to edit** (when editing existing code). Note every existing comment so you can leave each one untouched on lines that remain otherwise unchanged.
|
|
24
24
|
3. **Discover config only next to the task files.** From each file you will write or edit, walk up to the nearest package or repo root and inspect the target package's existing constants layout — such as `config/` or a sibling `*_constants` package. Keep this task-local constants search. Do **not** force a generic `config/` layout. Do **not** glob the whole tree for every config file. Do **not** glob or open `.env`, `.env.*`, or other secret files.
|
|
25
|
-
4. **Reuse constants from that local table.** Reuse first: exact value match → import the existing name. Semantic match → reuse it. Add a shared constant only when the value is shared policy or has multiple consumers. When no match exists, use the target package's existing constants layout, and keep a one-use value in the scope that reads it
|
|
25
|
+
4. **Reuse constants from that local table.** Reuse first: exact value match → import the existing name. Semantic match → reuse it. Add a shared constant only when the value is shared policy or has multiple consumers. When no match exists, use the target package's existing constants layout, and keep a one-use value in the scope that reads it.
|
|
26
26
|
5. **Search callers.** When a symbol, name, or signature changes, search its full caller boundary and update every consumer. This search may be wider than the constants search.
|
|
27
27
|
|
|
28
28
|
## Generation mindset (9 laws)
|
|
@@ -210,7 +210,7 @@ Every Shape A finding cites a file path and a line number. The offending line is
|
|
|
210
210
|
Do not infer missing context. If the diff and allowed checks cannot confirm a
|
|
211
211
|
claim, use an open question or an evidence gap.
|
|
212
212
|
|
|
213
|
-
When the diff alone lacks the context to confirm a finding, list the item under an "Open questions" section
|
|
213
|
+
When the diff alone lacks the context to confirm a finding, list the item under an "Open questions" section and keep it out of the Shape A findings. Each open question names the file and line where uncertainty arose and states what additional context would resolve it.
|
|
214
214
|
|
|
215
215
|
```json
|
|
216
216
|
{
|
|
@@ -150,7 +150,7 @@ For each acceptance line from the brief:
|
|
|
150
150
|
1. Keep task-specific detail in its own part file so the brief templates stay
|
|
151
151
|
reusable.
|
|
152
152
|
2. Absolute paths only in `prompt_parts` — the launcher reads them as given.
|
|
153
|
-
3. One worker, one closed scope. Split large work into more workers
|
|
154
|
-
|
|
153
|
+
3. One worker, one closed scope. Split large work into more workers, each with a
|
|
154
|
+
short brief.
|
|
155
155
|
4. The lead session fills bracketed fields before launch; workers never see the
|
|
156
156
|
skill folder unless you copy text into their part files.
|
|
@@ -50,11 +50,11 @@ def check_comments_python(content: str) -> list[str]:
|
|
|
50
50
|
Hash characters that appear inside string literals (hex color codes,
|
|
51
51
|
URL fragments, and the hash inside an f-string interpolation pattern)
|
|
52
52
|
are correctly skipped because the tokenizer recognizes them as parts
|
|
53
|
-
of string tokens
|
|
53
|
+
of string tokens.
|
|
54
54
|
|
|
55
55
|
When the tokenizer cannot parse the file (partial content during
|
|
56
|
-
Edit, invalid syntax), the check returns no findings
|
|
57
|
-
|
|
56
|
+
Edit, invalid syntax), the check returns no findings and does not
|
|
57
|
+
fall back to a line-walker scan — false negatives on
|
|
58
58
|
syntactically-invalid drafts are preferable to false positives that
|
|
59
59
|
mis-classify string-interior hash characters as comments.
|
|
60
60
|
"""
|
|
@@ -6,8 +6,8 @@ pin holds at every level.
|
|
|
6
6
|
|
|
7
7
|
::
|
|
8
8
|
|
|
9
|
-
model omitted ->
|
|
10
|
-
model sonnet or haiku ->
|
|
9
|
+
model omitted -> updatedInput model "opus"
|
|
10
|
+
model sonnet or haiku -> updatedInput model "opus"
|
|
11
11
|
model opus or fable -> no output; the call runs unchanged
|
|
12
12
|
|
|
13
13
|
A model id counts by its family: ``claude-sonnet-5-5`` is sonnet. A fork
|
|
@@ -24,14 +24,10 @@ hooks_root_directory = str(Path(__file__).resolve().parent.parent)
|
|
|
24
24
|
if hooks_root_directory not in sys.path:
|
|
25
25
|
sys.path.insert(0, hooks_root_directory)
|
|
26
26
|
|
|
27
|
-
from hooks_constants.bash_pre_tool_use_dispatcher_constants import
|
|
28
|
-
ALLOW_DECISION,
|
|
29
|
-
HOOK_EVENT_NAME,
|
|
30
|
-
)
|
|
27
|
+
from hooks_constants.bash_pre_tool_use_dispatcher_constants import HOOK_EVENT_NAME
|
|
31
28
|
from hooks_constants.pre_tool_use_allow_output import (
|
|
32
29
|
HOOK_EVENT_NAME_KEY,
|
|
33
30
|
HOOK_SPECIFIC_OUTPUT_KEY,
|
|
34
|
-
PERMISSION_DECISION_KEY,
|
|
35
31
|
UPDATED_INPUT_KEY,
|
|
36
32
|
)
|
|
37
33
|
from hooks_constants.pre_tool_use_stdin import read_hook_input_dictionary_from_stdin
|
|
@@ -84,7 +80,6 @@ def decide_hook_output(tool_input: object) -> dict[str, object] | None:
|
|
|
84
80
|
return {
|
|
85
81
|
HOOK_SPECIFIC_OUTPUT_KEY: {
|
|
86
82
|
HOOK_EVENT_NAME_KEY: HOOK_EVENT_NAME,
|
|
87
|
-
PERMISSION_DECISION_KEY: ALLOW_DECISION,
|
|
88
83
|
UPDATED_INPUT_KEY: {**tool_input, MODEL_INPUT_KEY: SUBAGENT_MODEL_ALIAS},
|
|
89
84
|
ADDITIONAL_CONTEXT_KEY: f"{CONTEXT_PREFIX}{previous_model_text}{CONTEXT_SUFFIX}",
|
|
90
85
|
}
|
|
@@ -31,7 +31,7 @@ def test_should_move_the_spawn_to_opus(requested_model: object) -> None:
|
|
|
31
31
|
if requested_model is not None:
|
|
32
32
|
tool_input["model"] = requested_model
|
|
33
33
|
decision = json.loads(_run_hook(tool_input))["hookSpecificOutput"]
|
|
34
|
-
assert
|
|
34
|
+
assert "permissionDecision" not in decision
|
|
35
35
|
assert decision["updatedInput"] == {**SPAWN_INPUT, "model": "opus"}
|
|
36
36
|
|
|
37
37
|
|
|
@@ -51,7 +51,7 @@ def _hook_specific_output(stdout: str) -> dict[str, object]:
|
|
|
51
51
|
def _assert_reshaped(stdout: str) -> None:
|
|
52
52
|
decision = _hook_specific_output(stdout)
|
|
53
53
|
assert decision["hookEventName"] == "PreToolUse"
|
|
54
|
-
assert
|
|
54
|
+
assert "permissionDecision" not in decision
|
|
55
55
|
assert decision["updatedInput"] == {
|
|
56
56
|
**SPAWN_INPUT,
|
|
57
57
|
"model": "opus",
|
|
@@ -7,7 +7,7 @@ beside it, or the script ``COORDINATOR_USAGE_PACE_SCRIPT`` names.
|
|
|
7
7
|
::
|
|
8
8
|
|
|
9
9
|
usage under pace (exit 1) -> no output; the call runs unchanged
|
|
10
|
-
over pace (exit 0) or unreadable ->
|
|
10
|
+
over pace (exit 0) or unreadable -> updatedInput:
|
|
11
11
|
model "opus", effort "low"
|
|
12
12
|
input that cannot be reshaped -> deny with a one-line reason
|
|
13
13
|
|
|
@@ -27,10 +27,7 @@ hooks_root_directory = str(Path(__file__).resolve().parent.parent)
|
|
|
27
27
|
if hooks_root_directory not in sys.path:
|
|
28
28
|
sys.path.insert(0, hooks_root_directory)
|
|
29
29
|
|
|
30
|
-
from hooks_constants.bash_pre_tool_use_dispatcher_constants import
|
|
31
|
-
ALLOW_DECISION,
|
|
32
|
-
HOOK_EVENT_NAME,
|
|
33
|
-
)
|
|
30
|
+
from hooks_constants.bash_pre_tool_use_dispatcher_constants import HOOK_EVENT_NAME
|
|
34
31
|
from hooks_constants.pre_tool_use_allow_output import (
|
|
35
32
|
HOOK_EVENT_NAME_KEY,
|
|
36
33
|
HOOK_SPECIFIC_OUTPUT_KEY,
|
|
@@ -130,7 +127,6 @@ def decide_hook_output(
|
|
|
130
127
|
verdict_excerpt = pace_verdict_text.strip()[:PACE_VERDICT_CONTEXT_MAXIMUM_CHARACTERS]
|
|
131
128
|
return _hook_output(
|
|
132
129
|
{
|
|
133
|
-
PERMISSION_DECISION_KEY: ALLOW_DECISION,
|
|
134
130
|
UPDATED_INPUT_KEY: reshaped_input,
|
|
135
131
|
ADDITIONAL_CONTEXT_KEY: RESHAPE_CONTEXT_PREFIX + verdict_excerpt,
|
|
136
132
|
}
|