* feat(computer): add computer commands with exec and ssh
* fix(computer): flush bridge writes and read gateway error bodies
* test(computer): drive exec and ssh end to end through fake servers
* chore(api): regenerate bindings from the current spec
* feat(computer): list exec and ssh in describe
* chore: bump version
Self-hosted Steel server returns `timeout: 0` (or `inactivityTimeout: 0`)
to mean 'session never expires'. `get_session_timeout` /
`get_session_inactivity_timeout` passed `Some(0)` through unchanged,
and `daemon/server.rs` then took that with `Option::or`:
let effective_timeout = get_session_timeout(&session).or(params.timeout_ms);
// Some(0).or(Some(...)) == Some(0)
`expires_at` was computed as `created_at + 0 - 30s`, i.e. already in
the past, so the first `tokio::select!` tick resolved `expiry_sleep`,
`break`ed the loop, dropped the `UnixListener`, and the CLI immediately
got ECONNRESET on `steel browser start`.
Fix: filter `0` at the parse site with `Some(n).filter(|&n| n > 0)`,
so every call site automatically gets the right semantics and
`params.timeout_ms` (user's explicit `--session-timeout` or
`--inactivity-timeout`) falls through correctly.
Added unit tests for integer 0, string "0", all three key names,
precedence unchanged, and a regression guard for nonzero values.
Ad-hoc verification (cargo not installable in sandbox; cross-language
port in /tmp/hermes-verify-zero-timeout-fix.py): 28/28 cases pass,
including before/after reproduction of the actual bug scenario.
Co-authored-by: Hermes Agent <hermes@nous.research>
Users had no way to tell which project (environment) their API key is
scoped to, or whether it is production. The API exposes this via
GET /projects (name, slug, isProduction), so:
- add src/api/projects.rs: /projects binding, response parsing, and
current-project resolution (single project wins; among several, a
sole default wins; ambiguity resolves to nothing rather than a guess)
- steel doctor: new "Project" check after auth, fetched concurrently
with the auth probe and silently skipped on error so doctor never
degrades because of an informational check
- steel config: print project name/slug and environment label, best
effort with a 2s timeout so the command stays usable offline
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Detect Pi via ~/.pi/ and install the Steel skill to the shared
~/.agents/skills/steel-browser/SKILL.md path Pi scans as a fallback.
Pi follows the same Agent Skills standard as Claude Code and Codex,
so SKILL_CONTENT is reused verbatim.