Skip to content
Merged
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
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ pilotty snapshot --format text # Plain text with cursor indicator
# Wait for screen to change before returning (no more manual sleep!)
pilotty snapshot --await-change $HASH # Block until hash differs
pilotty snapshot --await-change $HASH --settle 100 # Then wait for stability
pilotty snapshot --settle 100 --strict # Fail on deadline or session exit
```

### Input
Expand Down Expand Up @@ -207,6 +208,7 @@ The `snapshot` command returns structured data about the terminal screen:

```json
{
"outcome": "immediate",
"snapshot_id": 42,
"size": { "cols": 80, "rows": 24 },
"cursor": { "row": 5, "col": 10, "visible": true },
Expand All @@ -221,6 +223,11 @@ The `snapshot` command returns structured data about the terminal screen:
}
```

JSON snapshots always include an `outcome`: `immediate`, `changed`, `settled`,
`deadline`, or `exited`. Deadline and exit outcomes return the latest available screen evidence
instead of replacing it with an error. Exited captures include process exit metadata and
whether the final output was completely drained.

## UI Elements (Contextual)

pilotty automatically detects interactive UI elements in terminal applications. Elements provide **read-only context** to help understand UI structure, with position data (row, col) for use with the click command.
Expand Down Expand Up @@ -272,6 +279,12 @@ pilotty snapshot --await-change $HASH --settle 100 # Wait 100ms after last chan
- `--await-change <HASH>`: Block until `content_hash` differs from this value
- `--settle <MS>`: After change detected, wait for screen to be stable for this many ms
- `-t, --timeout <MS>`: Maximum wait time (default: 30000)
- `--strict`: Preserve printed evidence but exit 3 on deadline or 4 on session exit

Without `--strict`, every capture outcome exits 0. CLI exit categories are: 0
success, 1 generic/API error, 2 command-line usage, 3 timing deadline, and 4 session
lifecycle. Commands that require a live process also exit 4 when they receive
`SESSION_EXITED`.

**Why this matters:**
- No more flaky automation due to race conditions
Expand Down
20 changes: 18 additions & 2 deletions crates/pilotty-cli/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ Wait for change:
HASH=$(pilotty snapshot | jq -r '.content_hash')
pilotty key Enter
pilotty snapshot --await-change $HASH # Block until screen changes
pilotty snapshot --await-change $HASH --settle 100 # Wait for 100ms stability")]
pilotty snapshot --await-change $HASH --settle 100 # Wait for 100ms stability
pilotty snapshot --settle 100 --strict # Exit nonzero on deadline/exit")]
Snapshot(SnapshotArgs),

/// Type text at the current cursor position
Expand Down Expand Up @@ -192,6 +193,10 @@ pub struct SnapshotArgs {
/// Total timeout in milliseconds for await-change and settle combined (default: 30s)
#[arg(short, long, default_value_t = 30000)]
pub timeout: u64,

/// Exit 3 on deadline or 4 on session exit, after printing capture evidence
#[arg(long)]
pub strict: bool,
}

#[derive(Debug, Clone, Copy, ValueEnum)]
Expand Down Expand Up @@ -319,9 +324,10 @@ pilotty list-sessions

#[cfg(test)]
mod tests {
use super::{Cli, Commands};
use clap::Parser;

use crate::args::{Cli, Commands};

#[test]
fn test_spawn_parses_hyphenated_args() {
let cli = Cli::parse_from(["pilotty", "spawn", "bash", "-c", "echo hello"]);
Expand Down Expand Up @@ -353,4 +359,14 @@ mod tests {
_ => panic!("Expected logs command"),
}
}

#[test]
fn snapshot_parses_strict_mode() {
let cli = Cli::parse_from(["pilotty", "snapshot", "--settle", "100", "--strict"]);

match cli.command {
Commands::Snapshot(args) => assert!(args.strict),
_ => panic!("Expected snapshot command"),
}
}
}
Loading
Loading