claude-dev-env 8.43.5 → 8.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/advisor/advisor-protocol.md +2 -2
- package/_shared/advisor/reference/cli-chain.md +9 -12
- package/_shared/advisor/reference/lifecycle.md +1 -1
- package/_shared/advisor/reference/third-party-bind.md +3 -3
- package/bin/install.test.mjs +1 -1
- package/docs/second-claude-account.md +11 -13
- package/hooks/blocking/reply_length_gate.py +43 -11
- package/hooks/blocking/test_reply_length_gate.py +55 -0
- package/hooks/hooks.json +1 -1
- package/hooks/hooks_constants/reply_length_gate_constants.py +11 -0
- package/package.json +1 -1
- package/scripts/_code_review_test_support.py +29 -39
- package/scripts/claude_account_worker.py +46 -297
- package/scripts/claude_account_worker_process.py +18 -154
- package/scripts/claude_account_worker_report.py +8 -4
- package/scripts/claude_chain_usage.py +7 -271
- package/scripts/codec_forwarding_test_support.py +11 -65
- package/scripts/dev_env_scripts_constants/claude_account_worker_constants.py +6 -24
- package/scripts/invoke_code_review.py +34 -56
- package/scripts/resolve_worker_spawn.py +40 -72
- package/scripts/test_account_broker_guard.py +0 -4
- package/scripts/test_claude_account_worker.py +105 -350
- package/scripts/test_claude_chain_usage.py +50 -510
- package/scripts/test_dispatcher_profile_import.py +5 -9
- package/scripts/test_invoke_code_review.py +7 -6
- package/scripts/test_invoke_code_review_chain.py +26 -0
- package/scripts/test_invoke_code_review_cli.py +8 -8
- package/scripts/test_invoke_code_review_codec.py +3 -11
- package/scripts/test_invoke_code_review_contract.py +5 -1
- package/scripts/test_resolve_worker_spawn.py +118 -265
- package/scripts/test_resolve_worker_spawn_codec.py +9 -21
- package/scripts/tests/test_code_review_constants.py +2 -2
- package/scripts/claude_account_choice.py +0 -422
- package/scripts/claude_chain_runner.py +0 -1289
- package/scripts/test_claude_account_choice.py +0 -355
- package/scripts/test_claude_chain_runner.py +0 -1839
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
from datetime import datetime, timezone
|
|
5
6
|
from pathlib import Path
|
|
6
7
|
|
|
7
8
|
import pytest
|
|
@@ -22,6 +23,7 @@ from dev_env_scripts_constants.code_review_constants import (
|
|
|
22
23
|
REVIEW_PERMISSION_MODE as PERMISSION_MODE_BYPASS,
|
|
23
24
|
PERMISSION_MODE_FLAG,
|
|
24
25
|
)
|
|
26
|
+
from dev_env_scripts_constants.account_broker_constants import JobOutcome, WAIT_EXIT_CODE
|
|
25
27
|
from dev_env_scripts_constants.grok_worker_constants import (
|
|
26
28
|
MODEL_FLAG,
|
|
27
29
|
OUTPUT_FORMAT_FLAG,
|
|
@@ -68,3 +70,27 @@ def test_chain_redirects_empty_stdin_and_sets_cwd(
|
|
|
68
70
|
|
|
69
71
|
assert call_log.is_stdin_empty is True
|
|
70
72
|
assert call_log.claude_working_directory == working_directory
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def test_wait_reports_reset_without_running_git_status(
|
|
76
|
+
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
|
|
77
|
+
) -> None:
|
|
78
|
+
reset_at = datetime(2026, 10, 4, 12, tzinfo=timezone.utc)
|
|
79
|
+
call_log = install_seams(
|
|
80
|
+
monkeypatch,
|
|
81
|
+
host_profile=HOST_PROFILE_THIRD_PARTY,
|
|
82
|
+
claude_outcome=JobOutcome(WAIT_EXIT_CODE, "", "", None, (), "wait", None, reset_at),
|
|
83
|
+
)
|
|
84
|
+
monkeypatch.setattr(
|
|
85
|
+
invoker,
|
|
86
|
+
"review_git_status_runner",
|
|
87
|
+
lambda *args, **kwargs: pytest.fail("wait must not inspect the tree"),
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
outcome = run_review(tmp_path, session_model=FIXTURE_SESSION_SONNET)
|
|
91
|
+
|
|
92
|
+
assert call_log.claude_calls == 1
|
|
93
|
+
assert outcome.served_command is None
|
|
94
|
+
assert outcome.status == "wait"
|
|
95
|
+
assert outcome.wait_reset_at == reset_at.isoformat()
|
|
96
|
+
assert outcome.returncode == WAIT_EXIT_CODE
|
|
@@ -19,7 +19,7 @@ from _code_review_test_support import (
|
|
|
19
19
|
install_seams,
|
|
20
20
|
run_review_cli,
|
|
21
21
|
)
|
|
22
|
-
from
|
|
22
|
+
from dev_env_scripts_constants.account_broker_constants import BrokerConfigurationError
|
|
23
23
|
from dev_env_scripts_constants.claude_chain_constants import (
|
|
24
24
|
CHAIN_CONFIG_ERROR_EXIT_CODE,
|
|
25
25
|
)
|
|
@@ -62,6 +62,8 @@ def test_cli_prints_result_json_only(
|
|
|
62
62
|
RESULT_KEY_SERVED_COMMAND: None,
|
|
63
63
|
RESULT_KEY_RETURNCODE: IN_SESSION_RETURNCODE,
|
|
64
64
|
RESULT_KEY_DIRTY_TREE: False,
|
|
65
|
+
"status": None,
|
|
66
|
+
"wait_reset_at": None,
|
|
65
67
|
}
|
|
66
68
|
|
|
67
69
|
|
|
@@ -74,7 +76,7 @@ def test_cli_emits_json_on_chain_configuration_error(
|
|
|
74
76
|
install_seams(
|
|
75
77
|
monkeypatch,
|
|
76
78
|
host_profile=HOST_PROFILE_THIRD_PARTY,
|
|
77
|
-
claude_outcome=
|
|
79
|
+
claude_outcome=BrokerConfigurationError(FIXTURE_CHAIN_CONFIG_ERROR_MESSAGE),
|
|
78
80
|
working_directory=working_directory,
|
|
79
81
|
)
|
|
80
82
|
exit_code = run_review_cli(working_directory, session_model=FIXTURE_SESSION_OPUS)
|
|
@@ -87,13 +89,9 @@ def test_cli_emits_json_on_chain_configuration_error(
|
|
|
87
89
|
RESULT_KEY_SERVED_COMMAND: None,
|
|
88
90
|
RESULT_KEY_RETURNCODE: CHAIN_CONFIG_ERROR_EXIT_CODE,
|
|
89
91
|
RESULT_KEY_DIRTY_TREE: False,
|
|
92
|
+
"status": None,
|
|
93
|
+
"wait_reset_at": None,
|
|
90
94
|
}
|
|
91
|
-
config_error_outcome = invoker.CodeReviewOutcome(
|
|
92
|
-
mode=MODE_CHAIN,
|
|
93
|
-
served_command=None,
|
|
94
|
-
returncode=CHAIN_CONFIG_ERROR_EXIT_CODE,
|
|
95
|
-
is_dirty_tree=False,
|
|
96
|
-
)
|
|
97
95
|
|
|
98
96
|
|
|
99
97
|
def test_cli_emits_json_on_host_profile_value_error(
|
|
@@ -121,6 +119,8 @@ def test_cli_emits_json_on_host_profile_value_error(
|
|
|
121
119
|
RESULT_KEY_SERVED_COMMAND: None,
|
|
122
120
|
RESULT_KEY_RETURNCODE: HOST_PROFILE_ERROR_RETURNCODE,
|
|
123
121
|
RESULT_KEY_DIRTY_TREE: False,
|
|
122
|
+
"status": None,
|
|
123
|
+
"wait_reset_at": None,
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
|
|
@@ -20,12 +20,9 @@ FIXTURE_CHAIN_STDOUT = '{"result":"review done"}'
|
|
|
20
20
|
|
|
21
21
|
def _install_invoker_codec_seams(
|
|
22
22
|
monkeypatch: pytest.MonkeyPatch,
|
|
23
|
-
*,
|
|
24
|
-
all_chain_codec_keywords: dict[str, str],
|
|
25
23
|
) -> dict[str, object]:
|
|
26
24
|
return install_codec_seams(
|
|
27
25
|
monkeypatch,
|
|
28
|
-
all_chain_codec_keywords=all_chain_codec_keywords,
|
|
29
26
|
chain_stdout=FIXTURE_CHAIN_STDOUT,
|
|
30
27
|
runner_host=invoker,
|
|
31
28
|
runner_attribute_name="review_claude_runner",
|
|
@@ -37,10 +34,6 @@ def test_forwards_text_codec_keywords_to_subprocess_runner(
|
|
|
37
34
|
) -> None:
|
|
38
35
|
all_observed_runner_keywords = _install_invoker_codec_seams(
|
|
39
36
|
monkeypatch,
|
|
40
|
-
all_chain_codec_keywords={
|
|
41
|
-
FIXTURE_ENCODING_KEYWORD_NAME: FIXTURE_CHAIN_ENCODING,
|
|
42
|
-
FIXTURE_ERRORS_KEYWORD_NAME: FIXTURE_CHAIN_ERRORS,
|
|
43
|
-
},
|
|
44
37
|
)
|
|
45
38
|
|
|
46
39
|
invoker._run_claude_with_empty_stdin(
|
|
@@ -59,12 +52,11 @@ def test_forwards_text_codec_keywords_to_subprocess_runner(
|
|
|
59
52
|
)
|
|
60
53
|
|
|
61
54
|
|
|
62
|
-
def
|
|
55
|
+
def test_empty_stdin_and_cwd_reach_broker(
|
|
63
56
|
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
|
|
64
57
|
) -> None:
|
|
65
58
|
all_observed_runner_keywords = _install_invoker_codec_seams(
|
|
66
59
|
monkeypatch,
|
|
67
|
-
all_chain_codec_keywords={},
|
|
68
60
|
)
|
|
69
61
|
|
|
70
62
|
invoker._run_claude_with_empty_stdin(
|
|
@@ -73,5 +65,5 @@ def test_absent_text_codec_keywords_are_not_invented(
|
|
|
73
65
|
working_directory=tmp_path,
|
|
74
66
|
)
|
|
75
67
|
|
|
76
|
-
assert
|
|
77
|
-
assert
|
|
68
|
+
assert all_observed_runner_keywords["stdin_text"] == ""
|
|
69
|
+
assert all_observed_runner_keywords["cwd"] == tmp_path
|
|
@@ -20,6 +20,7 @@ from _code_review_test_support import (
|
|
|
20
20
|
install_seams,
|
|
21
21
|
run_review,
|
|
22
22
|
)
|
|
23
|
+
from dev_env_scripts_constants.account_broker_constants import WAIT_EXIT_CODE
|
|
23
24
|
from dev_env_scripts_constants.code_review_constants import (
|
|
24
25
|
CODE_REVIEW_MODEL_ALIAS,
|
|
25
26
|
DEFAULT_CODE_REVIEW_EFFORT,
|
|
@@ -96,8 +97,9 @@ def test_chain_failure_preserves_returncode(
|
|
|
96
97
|
|
|
97
98
|
assert review_outcome.mode == MODE_CHAIN
|
|
98
99
|
assert review_outcome.served_command is None
|
|
99
|
-
assert review_outcome.returncode ==
|
|
100
|
+
assert review_outcome.returncode == WAIT_EXIT_CODE
|
|
100
101
|
assert review_outcome.is_dirty_tree is False
|
|
102
|
+
assert review_outcome.status == "exhausted"
|
|
101
103
|
assert invoker.is_successful_code_review(review_outcome) is False
|
|
102
104
|
|
|
103
105
|
|
|
@@ -114,6 +116,8 @@ def test_encode_code_review_outcome_shape() -> None:
|
|
|
114
116
|
RESULT_KEY_SERVED_COMMAND: FIXTURE_SERVED_COMMAND,
|
|
115
117
|
RESULT_KEY_RETURNCODE: FIXTURE_CHAIN_RETURNCODE,
|
|
116
118
|
RESULT_KEY_DIRTY_TREE: True,
|
|
119
|
+
"status": None,
|
|
120
|
+
"wait_reset_at": None,
|
|
117
121
|
}
|
|
118
122
|
|
|
119
123
|
|