Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .claude/skills/e2e-node-management-test/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,28 @@ ant node daemon start --json

Re-run `ant node daemon info --json` and update the saved `api_base` URL (the port will have changed).

**Step 5.5 — Stale PID file recovery:**

A daemon that dies without cleaning up (a reboot, an OOM kill) leaves `daemon.pid` and
`daemon.port` behind, and its PID can be reused by an unrelated process. Simulate that by
recording the shell's own PID and a dead port as the daemon's. Run everything as **one** shell
command so the shell (the "unrelated process") is still alive while `ant` runs:

```bash
# Linux: DATA_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/ant"
# macOS: DATA_DIR="$HOME/Library/Application Support/ant"
# Windows: DATA_DIR="$APPDATA/ant", and write $(cat /proc/$$/winpid) instead of $$
ant node daemon stop --json
echo $$ > "$DATA_DIR/daemon.pid"; echo 1 > "$DATA_DIR/daemon.port"
ant node daemon info --json; ant node daemon status --json; ant node daemon start --json
```

Verify: `info` and `status` both report `running: false`, and `start` reports
`already_running: false` with a `port` that is present and not `1`. A stale port file must not be
read back as the new daemon's port.

Re-run `ant node daemon info --json` and update the saved `api_base` URL.

### Phase 6: Node management

**Step 6.1 — Add nodes:**
Expand Down Expand Up @@ -516,6 +538,7 @@ Phase 5: Daemon Lifecycle
[PASS] 5.2 Daemon status
[PASS] 5.3 Daemon info
[PASS] 5.4 Pinned-port flag round-trip
[PASS] 5.5 Stale PID file recovery

Phase 6: Node Management
[PASS] 6.1 Add 3 nodes
Expand Down
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
metadata describing a file that was no longer there, so the next `npm update` silently rolled
the user back.

### Fixed
- `ant node daemon info` and `ant node daemon start` no longer mistake a stale PID file for a
running daemon (V2-1655). A daemon that dies without cleaning up (a reboot, an OOM kill)
leaves its PID and port files behind, and once the PID is reused by an unrelated process,
`info` reported the dead daemon as running while `status` said it was not, and `start`
refused to start a new one. Both now require the process to be identifiable as the daemon,
the check `stop` already applied, and `start` removes the stale files before starting a new
daemon. On every platform the process must be `ant` running `ant node daemon run`, so another
`ant` command holding the reused PID is not taken for the daemon either. Where a process's
arguments or executable can't be read (another user's, an elevated or protected one on
Windows) or don't show that, it counts as the daemon only if the daemon's own API on the
recorded port reports its PID, on the configured listen address or either loopback (IPv4 or
IPv6), each asked with a one-second deadline. Otherwise `start` and `stop` say they can't tell
and leave the files alone, rather than risk orphaning a live daemon. Previously macOS trusted any
live PID and Windows checked only the executable's name, case-sensitively. `start` now fails
instead of carrying on when a stale file can't be removed, and it only spawns the daemon from
the `ant` binary. The `info` help text and README no longer claim its output is always JSON:
it is human-readable unless `--json` is passed, like every other command.

## [0.3.6] - 2026-09-01

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ Daemon is running

#### `ant node daemon info`

Output connection details as JSON (always JSON, regardless of `--json` flag). AI agents use this to discover the daemon's REST API.
Show connection details: PID, port, console URL and REST API base. AI agents use `ant node daemon info --json` to discover the daemon's REST API.

```json
{
Expand Down
2 changes: 1 addition & 1 deletion ant-cli/src/commands/node/daemon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub enum DaemonCommand {
Stop,
/// Show whether the daemon is running and summary stats
Status,
/// Output connection details for programmatic use (always JSON)
/// Show connection details: PID, port, console and API URLs (add --json for scripts)
Info,
/// Run the daemon in the foreground (used internally)
#[command(hide = true)]
Expand Down
Loading
Loading