mirror of
https://github.com/0xWheatyz/handler.git
synced 2026-08-30 04:36:24 +00:00
fix(mise-init): unblock the bootstrap agent + surface live agent output
The mise-init agent wedged on launch and the UI reported it green. Three distinct problems, fixed together: 1. Onboarding wedge (the proximate bug). A freshly-installed claude opens interactive setup — theme picker, then a folder-trust prompt — before the REPL. A detached tmux agent has no one to answer it, so it sat on the theme picker forever while agents.status said 'working'. New control.claude_config.ensure_onboarded() marks onboarding complete and trusts the working dir in ~/.claude.json (merge-only, so the login flow's oauthAccount survives); spawn() calls it before launching. 2. Config-name gate. control/mise.py only recognized `.mise.toml`, so a repo shipping `mise.toml` (no dot) — or config under `.config/mise/` — failed the [tasks.test] gate even when healthy. It now accepts the filenames mise itself reads and scans them all for the test task. 3. "Done" != done (the design gap). A spawned agent's real state lives in its tmux pane, but the socket is control-container-only, so the API couldn't see it. The worker now snapshots each working agent's pane tail (last ~40 lines) into two new agents columns (last_output, output_at, migration 0007) on its existing poll loop; the API serializes them and AgentsSection renders a live-output <pre> under each running agent. A wedged agent now shows the theme picker instead of a misleading green badge. Tests: home-dir writes are isolated to tmp in conftest; added coverage for claude_config seeding/merge, the mise filename set, the worker capture (including dead-session skip), and the API serialization. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BxKY28XKCM6o4ag3nmaVsZ
This commit is contained in:
@@ -37,10 +37,22 @@ def test_spawn_refuses_without_mise_file(env, fake_tmux):
|
||||
root = env["tmp"] / "proj"
|
||||
root.mkdir(parents=True, exist_ok=True)
|
||||
_register_project(root)
|
||||
with pytest.raises(spawn.SpawnError, match="no .mise.toml"):
|
||||
with pytest.raises(spawn.SpawnError, match="no mise config"):
|
||||
spawn.spawn("proj", "api")
|
||||
|
||||
|
||||
def test_spawn_accepts_dotless_mise_toml(env, fake_tmux):
|
||||
# mise also reads `mise.toml` (no leading dot); the gate must honor it too.
|
||||
root = env["tmp"] / "proj"
|
||||
root.mkdir(parents=True, exist_ok=True)
|
||||
(root / "mise.toml").write_text("[tasks.test]\nrun = 'pytest'\n")
|
||||
_register_project(root)
|
||||
|
||||
agent = spawn.spawn("proj", "api")
|
||||
with get_engine().begin() as conn:
|
||||
assert repo.get_agent_by_name(conn, "proj", "api")["id"] == agent["id"]
|
||||
|
||||
|
||||
def test_spawn_creates_agent_settings_and_session(env, fake_tmux):
|
||||
root = env["tmp"] / "proj"
|
||||
_write_mise(root, with_test=True)
|
||||
@@ -89,7 +101,7 @@ def test_spawn_still_gates_without_mise_init_flag(env, fake_tmux):
|
||||
root.mkdir(parents=True, exist_ok=True)
|
||||
_register_project(root)
|
||||
# require_tests defaults on, so a normal spawn against a mise-less repo still refuses.
|
||||
with pytest.raises(spawn.SpawnError, match="no .mise.toml"):
|
||||
with pytest.raises(spawn.SpawnError, match="no mise config"):
|
||||
spawn.spawn("proj", "api")
|
||||
assert fake_tmux["calls"]["new_session"] == []
|
||||
|
||||
|
||||
Reference in New Issue
Block a user