Skip to content

fix(ui): delete what the cursor is on, and make a seeded removal stick - #193

Merged
sanil-23 merged 7 commits into
tinyhumansai:mainfrom
sanil-23:feat/hosts-pointer-delete
Aug 5, 2026
Merged

fix(ui): delete what the cursor is on, and make a seeded removal stick#193
sanil-23 merged 7 commits into
tinyhumansai:mainfrom
sanil-23:feat/hosts-pointer-delete

Conversation

@sanil-23

@sanil-23 sanil-23 commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Four fixes to the Hosts page and the Agents rail, found by using them.

d removed the wrong thing

remove_host_row never asked which kind of row the cursor was on. On a host
header selected_host_agent() is None, so the undeclare no-opped and it fell
through to selected_host() — which for a host row resolves to
host.detail_worker, whichever single entry happened to have probed the machine.
Pressing d on a host of three agents removed one of them and left the host
standing, with nothing on screen saying which.

The cursor already distinguishes them (HostsRow.agent is None on a header).
Asking first is the fix. A host row now removes the host — undeclaring every
agent this machine declared on it and dropping its roster entries — and refuses
on the primary local host, which is declared by [host] rather than by a
removable entry. Agent rows are unchanged.

Removing a host is several registry ops for one keypress, so they travel as one
new Cmd::WorkerOps and report one status instead of racing N.

Removing a seeded agent was not a removal

An install that has never declared anything advertises a seeded fleet — one
agent per coding-agent CLI on PATH (specs_for falls back to seed_for when
the declaration list is empty). On a fresh machine every row is one of those
and none has a declaration behind it, so undeclare_selected_agent — which
guards on agent.declared — wrote nothing. Only the roster entry went, and the
seed recomputed it from PATH at the next start.

The first removal now makes the list real: the host's survivors are written down
as declarations with the removed one absent, so the fleet becomes what the
operator declared rather than what happened to be installed. Later removals are
ordinary undeclares. Declarations on other hosts pass through untouched, and a
row this machine may not edit is never written down.

Add Host adds a machine, and only a machine

The wizard asked which kind first, and "local" meant a harness plus a directory
on this device — which is what an agent is now. Two flows wrote the same thing
from the same two answers and disagreed about what to call it. Adding capacity
here is declaring an agent (n on a local host row), so the page is remote-only.

That retires the kind picker, the harness list, the per-frame provider-detection
cache, the directory prompt, add_local_host, and Cmd::StartLocalHost — whose
only producer it was. Hosts declared in [[hosts]] are unaffected:
local_host::start_all starts those at launch and always did. The one capability
removed is adding a local host mid-session, which is the thing being replaced.

LocalHostSpawner outlived its purpose by one reader — a workflow's agent step
resolves custom-harness names against it — so it is now LocalHostHarnesses
holding the options it reads them from.

Reading the tree

Host rows draw as the tree they describe: ├─/└─ branches with id, harness and
workspace in columns measured across the whole tree — not per host, which restarts
the alignment under every header, and not per scroll window, which slides the text
sideways under a cursor that only moved down. Paths truncate from the left,
because the tail says which checkout it is.

On the Agents rail, the tree began immediately under the green + New agent
button, so the two read as one block. A dim ── agents ── now separates them,
matching the lane list's ── functions ──; it appears only when there is a tree
to head and the cursor skips it. And an idle declared agent was drawn wholly
DIM — name, harness and directory alike — leaving nothing to read the row by;
the name now carries it and only the qualifier recedes.

Validation

  • cargo fmt --all --check
  • cargo clippy --locked --all-targets -- -D warnings
  • cargo test --locked -p medulla-tui --lib ui::app — 394 pass

Six new tests: the two d branches, the declared-agent-by-host-row case, the
refusal on this device, the seeded-removal persistence, and the heading's
placement.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Simplified Add Host flow to remote joining and address entry.
    • Added batch worker actions with sequential processing and partial-failure reporting.
    • Added a clearer Agents section to the host list.
    • Added safer host and agent removal with seeded-agent declaration handling.
  • Bug Fixes

    • Host removal now targets the correct host and protects local hosts.
    • Improved alignment, truncation, styling, and selection behavior for agent lists.

sanil-23 and others added 4 commits August 5, 2026 19:46
`d` on the Hosts page resolved the row it was on through `selected_host()`,
which answers with the host's `detail_worker` when the cursor is on a host
header — whichever single roster entry happened to have probed the machine. So
pressing it on a host of three agents removed one of them and left the host
standing, with no way to tell from the screen which one went.

The cursor already distinguishes the two: `HostsRow.agent` is `None` on a host
header. Asking it first is the fix. A host row now removes the host — undeclaring
every agent this machine declared on it and dropping its roster entries — and
refuses on the primary local host, which is declared by [host] rather than by a
removable entry and would be back at the next launch anyway. Agent rows are
unchanged. Removing a host is several registry ops for one keypress, so they
travel as one `Cmd::WorkerOps` and report one status rather than racing N.

The rows are drawn as the tree they describe: branch glyphs, and id, harness and
workspace in columns measured across the whole tree — not per host, which would
restart the alignment under every header, and not per scroll window, which would
slide the text sideways under a cursor that only moved down. Paths truncate from
the left, because the tail is what says which checkout it is.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The wizard asked which kind first, and "local" meant a harness plus a directory
on this device — which is what an agent is now. Two flows wrote the same thing
and disagreed about what to call it: one produced a host row, the other an agent
under a host row, from the same two answers. Adding capacity to this device is
declaring an agent, and that is done where the agents are (n on a local host row
in the Hosts tab), so the page is remote-only and says so.

What that retires, in order: the kind picker and its two-step state; the harness
list and the detected-provider cache the page consulted every frame; the
directory prompt; `add_local_host`; and `Cmd::StartLocalHost`, whose only
producer it was. Hosts declared in [[hosts]] are unaffected — `local_host::start_all`
starts those at launch, and always did. The one capability actually removed is
adding a local host *mid-session*, which is the thing being replaced.

`LocalHostSpawner` outlived its purpose by one reader: a workflow's `agent` step
resolves a custom-harness name against it. Every other field existed for the
spawn it no longer does, so it is now `LocalHostHarnesses` holding the options
it reads them from — a type that spawns nothing should not be called a spawner.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Two rail fixes. The tree began immediately under the green `+ New agent`
button, so the button and the first agent read as one block — a list whose first
entry happened to be coloured. A dim `── agents ──` now sits between them,
matching the lane list's `── functions ──` so the rail's two headings read as
the same kind of thing. It is emitted only when there is a tree to head, and the
cursor skips it like a host header.

And an idle declared agent was drawn wholly DIM — name, harness and directory
alike — which left the row with nothing to read it by. The name now carries the
row in cyan and only the qualifier recedes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
An install that has never declared anything advertises a *seeded* fleet — one
agent per coding-agent CLI found on PATH (`specs_for` falls back to
`seed_for` when the declaration list is empty). Every row on a fresh machine is
one of those, and none of them has a declaration behind it.

So `d` could not remove one. `undeclare_selected_agent` guards on
`agent.declared`, which is false for a seed, and returned without writing
anything; all that was left was dropping the roster entry, which the seed
recomputes from PATH at the next start. The agent came back, which is what
"I deleted it and it is still there" was.

The first removal is now what makes the list real: the host's surviving agents
are written down as declarations and the removed one is not among them. From
then on the fleet is what the operator declared rather than what happened to be
installed, and the next removal is an ordinary undeclare. Declarations on other
hosts are carried through untouched, and a row this machine may not edit is
never written down — it belongs to the config that declares it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sanil-23 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

No new commits to review since the last review.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 64b8dc79-8e5c-491b-af34-29fb0b27e33e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The TUI replaces stateful local-host spawning with harness-only wiring and batch worker operations. Host removal now persists seeded-agent changes. Add Host supports remote hosts only. Agent rail rows and host-list rendering receive new headings, styling, alignment, and truncation behavior.

Changes

Host management and TUI routing

Layer / File(s) Summary
Local host wiring and worker operations
src/tui/src/local_host/mod.rs, src/tui/src/app_loop.rs, src/tui/src/event_loop/..., src/tui/src/ui/app/types.rs
LocalHostHarnesses replaces LocalHostSpawner. WorkerOps applies worker mutations in order and reports partial results.
Host and seeded-agent removal
src/tui/src/ui/app/hosts/..., src/tui/src/ui/app/keys/routing/mod.rs
Host deletion removes associated workers and declarations, protects the local host, and adopts remaining seeded agents before persistence.
Remote-only host addition
src/tui/src/ui/app/keys/routing/add_host.rs, src/tui/src/ui/app/render/routing/add_host.rs, src/tui/src/ui/app/state.rs, src/tui/src/ui/app/types.rs, src/tui/tests/...
The Add Host flow handles remote join commands and worker addresses without local provider, harness, workspace, or selection state.
Agent rail and host-list presentation
src/tui/src/ui/app/rail/..., src/tui/src/ui/app/render/agents/rail/..., src/tui/src/ui/app/render/routing/hosts/list.rs, src/tui/tests/feature_workers/roles.rs
The agent tree gains a non-selectable heading. Agent rows gain styled fields, tree branches, aligned columns, and Unicode-aware truncation.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant remove_host_row
  participant remove_selected_host
  participant Config
  participant WorkerOps
  User->>remove_host_row: Delete selected host
  remove_host_row->>remove_selected_host: Remove host and editable agents
  remove_selected_host->>Config: Persist seeded-agent declarations
  remove_selected_host-->>WorkerOps: Return worker removal operations
  WorkerOps-->>User: Report removal status
Loading

Possibly related PRs

Poem

A rabbit trims the host-tree rows,
And batches worker moves in flows.
Local spawners fade from sight,
Remote hosts now join just right.
Seeded agents stay in line—
Neat rails and columns shine!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the primary changes: deleting the item under the cursor and persisting seeded-agent removal.

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (2)
src/tui/src/ui/app/rail/mod.rs (1)

260-265: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Move behavior-heavy code out of directory mod.rs files.

These directory modules contain rail assembly and rendering behavior. Keep each mod.rs limited to module documentation and wiring. Move the implementation into named child modules.

  • src/tui/src/ui/app/rail/mod.rs#L260-L265: move flatten and its rail-tree assembly helpers into a dedicated child module.
  • src/tui/src/ui/app/render/agents/rail/mod.rs#L346-L351: move row rendering dispatch into a dedicated child module.
  • src/tui/src/ui/app/render/agents/rail/mod.rs#L399-L422: keep declared-agent row styling with that rendering implementation.

As per coding guidelines, “Keep mod.rs focused on module documentation, mod/pub use wiring, and glue that fits no more specific submodule.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/tui/src/ui/app/rail/mod.rs` around lines 260 - 265, Move the rail
assembly logic in `Rail::flatten` and its helper code out of
`src/tui/src/ui/app/rail/mod.rs` into a dedicated child module, leaving `mod.rs`
as wiring/documentation only. Do the same for the row rendering dispatch in
`src/tui/src/ui/app/render/agents/rail/mod.rs`, extracting the behavior from the
render entrypoint while keeping the declared-agent row styling with that
rendering implementation. Preserve the existing `flatten`, row-dispatch, and
styling behavior by re-exporting or wiring the new child modules from each
`mod.rs` rather than keeping the implementation inline.

Source: Coding guidelines

src/tui/src/ui/app/hosts/tests.rs (1)

654-669: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Assert the surviving declaration by id.

!declared.is_empty() passes for any non-empty list. Name the sibling instead, so the test fails if adoption writes the wrong agent or writes more than the survivors.

♻️ Proposed test tightening
-    assert!(
-        !declared.is_empty(),
-        "and its siblings now are, so the list stops being seeded: {declared:?}"
-    );
+    let survivor = if target == "medulla-claude" {
+        "medulla-codex"
+    } else {
+        "medulla-claude"
+    };
+    assert_eq!(
+        declared,
+        vec![survivor.to_string()],
+        "the sibling is declared and nothing else is: {declared:?}"
+    );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/tui/src/ui/app/hosts/tests.rs` around lines 654 - 669, Update the
assertions in the host adoption test around the declared agent list to verify
the specific surviving sibling agent ID rather than only checking that declared
is non-empty. Preserve the existing assertion that target is absent, and assert
the expected survivor by ID so incorrect or extra declarations fail the test.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/tui/src/event_loop/types.rs`:
- Around line 109-112: Update the doc comment for the local_hosts field to
describe LocalHostHarnesses as containing the primary host’s options for
workflow agent steps to resolve a declared custom harness; remove references to
starting hosts, bus bindings, and session managers. Renaming local_hosts to
local_host_harnesses is optional and should include its known app_loop and
run_cmd references if performed.

In `@src/tui/src/hub_relay/tests.rs`:
- Around line 356-360: Update the comments in
a_host_added_after_launch_is_not_remembered_as_a_remote_peer, including the “The
spawner binds a second host” comment, to describe a second host being created
during the session without attributing that action to LocalHostHarnesses. Keep
the test and its save-time filtering scenario unchanged.

In `@src/tui/src/ui/app/hosts/edit.rs`:
- Around line 225-243: Update remove_selected_host so non-primary host removal
adopts seeded-agent survivors into the declaration list, following
adopt_seeded_agents and the single-agent removal path. Continue passing all
applicable agent IDs through undeclare_agent_id, including seeded agents. Update
the status reporting to detect undeclared < declared.len() and clearly indicate
the undeclare shortfall instead of reporting removal as complete.
- Around line 263-282: Update adopt_seeded_agents so survivors reuse their
existing AgentDeclaration when one already exists, preserving custom name and
strategy fields; only call declaration_for for agents without a matching
declaration. Keep filtering out the removed agent and non-editable rows, and
retain declarations belonging to other hosts.

In `@src/tui/src/ui/app/keys/routing/add_host.rs`:
- Around line 29-31: Update the add_host_key routing test in routing.rs to
reflect that the first c key now copies REMOTE_JOIN_COMMAND immediately. Assert
one copy after c, remove the obsolete Down/selection steps, and retain coverage
for the resulting handled routing behavior.

In `@src/tui/src/ui/app/rail/tests.rs`:
- Around line 417-443: Extend the test coverage around the rail-row behavior by
adding a fixture with no agents in every HostGroup and asserting that
`RailRow::AgentsHeader` is absent from `app.rail_rows()`. Keep the existing
agent-present assertions in
`the_agents_heading_sits_under_the_create_action_and_only_over_a_tree`
unchanged.

---

Nitpick comments:
In `@src/tui/src/ui/app/hosts/tests.rs`:
- Around line 654-669: Update the assertions in the host adoption test around
the declared agent list to verify the specific surviving sibling agent ID rather
than only checking that declared is non-empty. Preserve the existing assertion
that target is absent, and assert the expected survivor by ID so incorrect or
extra declarations fail the test.

In `@src/tui/src/ui/app/rail/mod.rs`:
- Around line 260-265: Move the rail assembly logic in `Rail::flatten` and its
helper code out of `src/tui/src/ui/app/rail/mod.rs` into a dedicated child
module, leaving `mod.rs` as wiring/documentation only. Do the same for the row
rendering dispatch in `src/tui/src/ui/app/render/agents/rail/mod.rs`, extracting
the behavior from the render entrypoint while keeping the declared-agent row
styling with that rendering implementation. Preserve the existing `flatten`,
row-dispatch, and styling behavior by re-exporting or wiring the new child
modules from each `mod.rs` rather than keeping the implementation inline.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1a4a768d-7b33-4094-8ec5-939992667b08

📥 Commits

Reviewing files that changed from the base of the PR and between 1d52d1f and 10451a4.

📒 Files selected for processing (20)
  • src/tui/src/app_loop.rs
  • src/tui/src/event_loop/cmd_dispatch/mod.rs
  • src/tui/src/event_loop/cmd_dispatch/workflows.rs
  • src/tui/src/event_loop/types.rs
  • src/tui/src/hub_relay/tests.rs
  • src/tui/src/local_host/mod.rs
  • src/tui/src/ui/app/commands/dispatch.rs
  • src/tui/src/ui/app/hosts/edit.rs
  • src/tui/src/ui/app/hosts/tests.rs
  • src/tui/src/ui/app/keys/routing/add_host.rs
  • src/tui/src/ui/app/keys/routing/mod.rs
  • src/tui/src/ui/app/rail/mod.rs
  • src/tui/src/ui/app/rail/tests.rs
  • src/tui/src/ui/app/rail/types.rs
  • src/tui/src/ui/app/render/agents/rail/mod.rs
  • src/tui/src/ui/app/render/routing/add_host.rs
  • src/tui/src/ui/app/render/routing/hosts/list.rs
  • src/tui/src/ui/app/state.rs
  • src/tui/src/ui/app/types.rs
  • src/tui/src/ui/app/workspaces.rs
💤 Files with no reviewable changes (3)
  • src/tui/src/ui/app/workspaces.rs
  • src/tui/src/ui/app/commands/dispatch.rs
  • src/tui/src/ui/app/state.rs

Comment thread src/tui/src/event_loop/types.rs Outdated
Comment thread src/tui/src/hub_relay/tests.rs
Comment thread src/tui/src/ui/app/hosts/edit.rs Outdated
Comment thread src/tui/src/ui/app/hosts/edit.rs
Comment thread src/tui/src/ui/app/keys/routing/add_host.rs
Comment thread src/tui/src/ui/app/rail/tests.rs
…finds

Review follow-ups, and the CI failure behind them.

The Add Host tests still drove the retired kind picker — Down to pick Remote,
then two confirms. With one step the second 'a' was typed into the address
prompt instead, so an empty submit was no longer empty. Three tests, two of
which failed and one of which passed for that reason.

`adopt_seeded_agents` rebuilt every survivor through `declaration_for`, which
goes via `AgentDeclaration::new` and hardcodes `name: None` and the checkout
strategy. A host holds declared and seeded rows at once, so removing one seed
silently reset the operator's name (and any non-default strategy) on every
declared sibling. An existing declaration is now carried through as it is, and
only a row with none is built from the projection.

`remove_selected_host` skipped seeded rows, so removing a host this device runs
dropped roster entries that the seed recomputes from PATH at the next launch —
the same non-removal this branch fixes for a single agent. A running host cannot
be emptied for that exact reason: with no declarations left it seeds again. So it
is refused, and the message points at its agents, which are removable one by one.
The guard asks the *running* hosts rather than `host.kind`, because a row is
also Local when it exists only because agents are declared against its id — that
one has no config entry to come back from and is removable.

The status compares what was undeclared against what was attempted: a
declaration that would not write is an agent that returns at the next launch, and
reporting it as removed is how the operator finds out later instead of now.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sanil-23 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

Six more sites still drove the retired kind picker. The two that failed CI were
in `feature_paste` and `feature_workers`; the rest passed while asserting a
flow that no longer exists, which is worse.

Two tests went with the behaviour they covered: the local-host retry (that whole
save path is gone with the wizard's local kind) and the confirmed-kind arrowing
regression (there is no kind to confirm). Three assertions were rewritten rather
than deleted — the page's opening line changed with the page, `c` now always has
an install line to copy instead of copying nothing on the local branch, and the
roles test no longer pins which agent the cursor lands on: removing an
undeclared row writes the survivors down, and a newly declared agent sorts above
the roster-only rows, so the order after that keypress is legitimately different.
What that test is about — the arrows leaving the role list — is asserted instead.

Verified with the whole integration suite this time, not a truncated view of it:
36 targets pass. The remaining failures are the known macOS `launch_root` trio
and the two `daemon::providers` watchdog tests that pass in isolation.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sanil-23 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

coderabbitai[bot]
coderabbitai Bot previously requested changes Aug 5, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/tui/tests/feature_workers/roles.rs`:
- Around line 132-141: Strengthen the assertion after
app.on_event(key(KeyCode::Down)) in the role-navigation test so it verifies tree
focus rather than merely finding an “Agent · ” label in the rendered buffer. Use
the unique tree-focus marker produced by render, or inspect the app’s focus
state directly, and ensure the assertion fails when focus remains on the role
toggles.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 60d381d9-a6e4-4424-9616-ad9ad2f35d73

📥 Commits

Reviewing files that changed from the base of the PR and between 8eee69a and be5d36f.

📒 Files selected for processing (4)
  • src/tui/tests/feature_paste/composer.rs
  • src/tui/tests/feature_workers/list.rs
  • src/tui/tests/feature_workers/roles.rs
  • src/tui/tests/feature_workers/routing.rs

Comment thread src/tui/tests/feature_workers/roles.rs Outdated
Two review follow-ups, both about tests proving less than they read as proving.

The roles test asserted `out.contains("Agent · ")` after the removal, which only
says an agent label is somewhere in the terminal buffer — an agent preview is
drawn whether the arrows are on the tree or on the toggles, so it would have
passed with the focus still on the role list, which is the one thing the test
exists to catch. It now asks the focus directly, through a seam in the same shape
as `hosts_cursor_on_host` beside it.

And the heading test covered only the branch where a heading appears. The other
half is the one worth having: a hosting device with nothing declared and no
traffic offers the create action and no heading over it. Built on the empty
runtime rather than `hosting_app`, whose demo lanes are agents in their own
right — the first attempt asserted the empty case against a fixture that has a
tree, and failed for that reason rather than finding a bug.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sanil-23 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@sanil-23

sanil-23 commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Already reviewed.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@sanil-23
sanil-23 merged commit 09d6096 into tinyhumansai:main Aug 5, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant