Skip to content

fix(devkitd): parse ps rows with padded columns on Linux - #372

Merged
codeaholicguy merged 1 commit into
mainfrom
fix/devkitd-ps-parser
Oct 12, 2026
Merged

codeaholicguy merged 1 commit into
mainfrom
fix/devkitd-ps-parser

Conversation

@codeaholicguy

Copy link
Copy Markdown
Owner

Summary

Fixes #371 — ai-devkit agent list reported "No running agents detected." on Linux despite running agents.

Root cause. devkit-core's sweep parser split each ps -axo pid=,ppid=,tty=,command= row with splitn(4, char::is_whitespace), which splits on each whitespace character. Linux procps right-aligns/pads columns with runs of spaces (" 61524 60968 pts/1 claude"), producing empty fields that fail i64::parse — so every row was dropped and the daemon's agent.list was permanently empty. The CLI then treated that empty-but-non-null answer as authoritative and never ran its local adapters. The existing PS_FIXTURE test never caught this because its padding sits between tty and command (where the remainder absorbs it), not between the numeric columns.

Changes

  • rust/crates/devkit-core/src/discover.rs: new split_ps_row splits pid/ppid/tty on whitespace runs and keeps the remainder as command verbatim. sweep() now tracing::warn!s when it parses 0 processes from non-empty ps output (the issue's suggested tripwire).
  • packages/agent-manager/src/AgentManager.ts (defense in depth): only a non-empty daemon answer is authoritative. An empty answer falls through to local adapters; if local detection finds agents, the local result wins and a one-line stderr warning is emitted (a daemon whose sweep yields nothing while agents exist is broken, per fix(devkitd): ps parser drops all rows on Linux (padded columns), so agent list shows no agents #371). Daemon-absent/throw behavior is unchanged.
  • packages/daemon-client/src/__tests__/daemon-sweep.test.ts (new): end-to-end coverage at the daemon boundary — spawns the real devkitd with a stub ps on PATH printing padded procps rows (the issue's own repro technique) and asserts agent.list reports them.
  • .github/workflows/ci.yml: the rust job now runs cargo test --workspace (it previously ran only fmt + clippy — no Rust tests ran in CI at all), and the npm test job now builds devkitd so the daemon-client integration tests actually execute instead of skipping via describe.runIf(bin != null). Why CI never caught this: no Rust cargo test step, no devkitd binary in the JS test job, and no agent list e2e existed.

Issue test matrix — every row must yield procs=1

stub ps line before after
61524 60968 pts/1 claude 1 1
61524 60968 pts/1 claude 1 1
61524 60968 pts/1 claude 0 1
61524 60968 pts/1 claude 0 1
61524 60968 pts/1 claude 0 1

Validation

  • cargo fmt --all -- --check, cargo clippy --workspace --all-targets -- -D warnings, cargo test --workspace — all green (94 tests).
  • npm run lint — clean; npm test — 8 projects green incl. new daemon-sweep integration test (verified failing-then-passing TDD on both Rust and CLI sides); npm run test:e2e — 42 passed.

Test plan

  • Issue matrix unit test: all five rows parse to procs=1
  • Command remainder preserves inner spacing (claude --resume abc123)
  • CLI falls back to local adapters on empty-daemon/local-nonempty disagreement (+warning); silent when both empty
  • Real devkitd + stub ps e2e: agent.list returns the padded-row agents
  • CI: rust job runs cargo test; npm job builds devkitd so daemon tests don't skip

Closes #371

Generated with Devin

The sweep parser split each `ps -axo` row on single whitespace chars, so
procps-padded columns produced empty fields and every row was dropped —
`agent list` always reported "No running agents detected" on Linux. Split
pid/ppid/tty on whitespace runs and keep the remainder as the command,
warn when a sweep parses zero rows from non-empty output, and stop
treating an empty daemon answer as authoritative when local detection
finds agents.

Closes #371

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@codeaholicguy
codeaholicguy merged commit 86d46ac into main Oct 12, 2026
8 checks passed
@codeaholicguy
codeaholicguy deleted the fix/devkitd-ps-parser branch October 12, 2026 13:37
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.

fix(devkitd): ps parser drops all rows on Linux (padded columns), so agent list shows no agents

1 participant