Skip to content

Commit 967895c

Browse files
fix(ci): resolve nightly-install, CI test, and UAT failures
- doctor: change missing config from fail to warn (expected on fresh install) - test_harness_matrix: add integration marker so 42 agent tests are excluded from CI runs (they require tmux + mock agent spawning) - test_study_integration: pass --agent claude so detect_agents() guard is bypassed on runners with no AI agents installed - harness: capture subprocess/pexpect output in timeout errors for UAT diagnostic visibility - pyproject.toml: register e2e pytest marker at workspace root Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e776047 commit 967895c

7 files changed

Lines changed: 32 additions & 8 deletions

File tree

packages/studyctl/src/studyctl/doctor/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def check_config_file() -> list[CheckResult]:
9999
CheckResult(
100100
"core",
101101
"config_file",
102-
"fail",
102+
"warn",
103103
f"Config not found: {config_path}",
104104
"studyctl config init",
105105
fix_auto=True,

packages/studyctl/tests/harness/study.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def start(
110110
env.pop("TMUX", None)
111111
env.pop("TMUX_PANE", None)
112112

113-
subprocess.run(
113+
result = subprocess.run(
114114
[
115115
sys.executable,
116116
"-m",
@@ -136,7 +136,12 @@ def start(
136136
self.tmux.wait_for(
137137
lambda: self.state.get("study_session_id") is not None,
138138
timeout=10,
139-
msg="session state file not written",
139+
msg=(
140+
f"session state file not written"
141+
f" (exit={result.returncode},"
142+
f" stdout={result.stdout[-200:]!r},"
143+
f" stderr={result.stderr[-200:]!r})"
144+
),
140145
)
141146

142147
state = self.state

packages/studyctl/tests/harness/terminal.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,16 @@ def spawn_study(
7575
import time
7676

7777
time.sleep(0.5)
78-
raise TimeoutError("Session state file not created after spawn")
78+
79+
# Capture child output for diagnostics
80+
child_output = ""
81+
if self._child:
82+
before = self._child.before if isinstance(self._child.before, str) else ""
83+
after = self._child.after if isinstance(self._child.after, str) else ""
84+
child_output = before + after
85+
raise TimeoutError(
86+
f"Session state file not created after spawn (child output: {child_output[-300:]!r})"
87+
)
7988

8089
def attach_and_send_q(self, *, timeout: int = 15) -> bool:
8190
"""Attach to the tmux session and send Q to the sidebar pane.

packages/studyctl/tests/test_doctor_core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ def test_config_missing(self, tmp_path: Path):
7272
missing = tmp_path / "nope.yaml"
7373
with patch("studyctl.doctor.core._get_config_path", return_value=missing):
7474
results = check_config_file()
75-
assert results[0].status == "fail"
75+
assert results[0].status == "warn"
7676
assert "config init" in results[0].fix_hint
7777

7878
def test_config_invalid_yaml(self, tmp_path: Path):

packages/studyctl/tests/test_harness_matrix.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949

5050
pytestmark = [
5151
pytest.mark.skipif(not shutil.which("tmux"), reason="tmux not installed"),
52+
pytest.mark.integration,
5253
pytest.mark.e2e,
5354
]
5455

packages/studyctl/tests/test_study_integration.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,13 +235,21 @@ def _start_session(
235235
env_overrides = {
236236
"STUDYCTL_TEST_AGENT_CMD": f"bash {agent_script} {{persona_file}}",
237237
}
238-
args = ["study", topic, "--energy", str(energy)]
238+
args = ["study", topic, "--energy", str(energy), "--agent", "claude"]
239239
if extra_args:
240240
args.extend(extra_args)
241241

242-
_studyctl(*args, env_overrides=env_overrides)
242+
result = _studyctl(*args, env_overrides=env_overrides)
243243

244-
_wait_for(STATE_FILE.exists, desc="session-state.json created")
244+
_wait_for(
245+
STATE_FILE.exists,
246+
desc=(
247+
f"session-state.json created"
248+
f" (exit={result.returncode},"
249+
f" stdout={result.stdout[-200:]!r},"
250+
f" stderr={result.stderr[-200:]!r})"
251+
),
252+
)
245253
state = _read_state()
246254
session_name = state.get("tmux_session", "")
247255
_wait_for(lambda: _session_exists(session_name), desc=f"tmux session {session_name}")

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,5 @@ testpaths = ["packages/agent-session-tools/tests", "packages/studyctl/tests"]
5858
addopts = "--import-mode=importlib"
5959
markers = [
6060
"integration: requires external infrastructure (tmux, real DB, network)",
61+
"e2e: end-to-end browser tests requiring Playwright + web server",
6162
]

0 commit comments

Comments
 (0)