Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds a host-capability probe (home-fs, keychain) with per-session caching and gated warnings for non-interactive runs; emits reactive keychain-failure observations from credential/config stores and calls a proactive sandbox warning at authentication start. Includes Vitest tests for probe and warning semantics. ChangesSandbox & Host-Capability Detection
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Comment |
Greptile SummaryThis PR introduces host-capability diagnostics for sandboxed agent runs, a new
Confidence Score: 5/5Safe to merge. All previously flagged issues with the host probe are addressed and the new interaction-mode system is well-tested. The core host-probing logic correctly gates on isPermissionError for both home-fs and keychain paths. The interaction-mode abstraction cleanly replaces the old ad-hoc env-var checks and is covered by 135+ new tests. src/lib/host-probe.ts — the isLikelyHostFailure function's unconditional true return for browser-launch and localhost-bind is worth a second look if false-positive sandbox warnings surface on headless Linux hosts in agent mode. Important Files Changed
Reviews (9): Last reviewed commit: "Add first-class CLI interaction modes" | Re-trigger Greptile |
| } catch (error) { | ||
| const detail = error instanceof Error ? error.message : String(error); | ||
| return { capability: 'home-fs', detail }; | ||
| } |
There was a problem hiding this comment.
probeHomeFs catches every exception and converts it to a ProbeFailure, so non-permission errors like ENOSPC (disk full) or EIO (I/O error on a network drive) will cause warnIfSandboxed to print "This may be a sandboxed environment." — which is wrong and confusing. observeHostFailure correctly gates on isPermissionError; probeHomeFs should do the same so the two paths stay consistent.
| } catch (error) { | |
| const detail = error instanceof Error ? error.message : String(error); | |
| return { capability: 'home-fs', detail }; | |
| } | |
| } catch (error) { | |
| if (!isPermissionError(error)) return null; | |
| const detail = error instanceof Error ? error.message : String(error); | |
| return { capability: 'home-fs', detail }; | |
| } |
There was a problem hiding this comment.
Good catch — fixed in 7f9e0e6. probeHomeFs now mirrors observeHostFailure and only treats permission-class errors (isPermissionError) as sandbox indicators, so ENOSPC/EIO no longer produce misleading "sandboxed environment" warnings. Added a regression test (does not flag non-permission home-fs errors as sandbox failures).
When the CLI runs inside an AI agent sandbox (Claude Code, Codex, Cursor), the keyring and home directory may be unavailable. Instead of letting opaque EPERM errors confuse the agent, we now: 1. Proactively probe home-fs and keychain on first auth check in non-interactive mode (warnIfSandboxed in ensure-auth) 2. Reactively observe permission errors in keyring read/write calls in both credential-store and config-store (observeHostFailure) 3. Emit a single actionable warning per session pointing the user to re-run on the host shell
- probeKeychain() no longer reports the keychain as failed when the
probe entry is simply absent. A 'not found' / 'No such' error from
@napi-rs/keyring now indicates a healthy keychain (matches the
existing pattern in deleteFromKeyring in config-store and
credential-store), so non-interactive runs on healthy hosts no longer
emit false-positive sandbox warnings.
- Replace require('@napi-rs/keyring') with a static ES import. The
package has 'type: module', so the previous require() threw
ReferenceError at runtime and caused probeKeychain to always fail.
- Switch probeHomeFs to node:fs/promises and make runHostProbe and
warnIfSandboxed async, per the project's no-sync-fs guideline.
- Tighten the /sandbox/i permission pattern to /\bsandboxd?\b/i so
unrelated error messages containing 'sandbox' as a substring don't
trigger sandbox warnings.
Updates the spec to drive the async API and adds coverage for the
healthy-keychain (entry-absent) and substring-collision cases.
Co-Authored-By: nick.nisi@workos.com <nick.nisi@workos.com>
Co-Authored-By: nick.nisi@workos.com <nick.nisi@workos.com>
probeHomeFs previously treated every fs error as a sandbox indicator, so transient errors like ENOSPC or EIO would emit a misleading "sandboxed environment" warning. Gate the catch block on isPermissionError so it stays consistent with observeHostFailure. Co-Authored-By: nick.nisi@workos.com <nick.nisi@workos.com>
probeKeychain previously treated any non-missing-entry keychain error as a sandbox indicator. A user-canceled macOS keychain prompt or a transient keyring daemon error would therefore produce a misleading "sandboxed environment" warning on healthy hosts. Mirror probeHomeFs and observeHostFailure by ignoring non-permission errors. Co-Authored-By: nick.nisi@workos.com <nick.nisi@workos.com>
1046ad3 to
a9b122a
Compare
Move fs.unlink into a finally block with best-effort error handling so a successful writeFile never leaves an orphan probe file in ~/.workos when unlink itself fails. The probe is checking write access; cleanup should not affect the result. Co-Authored-By: nick.nisi@workos.com <nick.nisi@workos.com>
Summary
--mode human|agent|ciandWORKOS_MODE, while keeping--jsonscoped to output formatting.WORKOS_NO_PROMPT, non-TTY JSON defaults, andWORKOS_FORCE_TTYas an output-only override.interactionModeinworkos doctorand runs host-execution probing for agent/CI mode so sandboxed runs are visible.Why
Coding agents and CI need deterministic non-prompt behavior, but
--jsonis only an output contract. Before this, output formatting, TTY detection, prompts, browser launches, and sandbox trust were coupled. That made pseudo-TTY agents and scripts hard to reason about and made host-sandbox failures look like real WorkOS configuration or auth failures.This PR separates the two axes: output mode controls formatting; interaction mode controls who is driving the CLI and which behaviors are allowed.
Risk
WORKOS_FORCE_TTYnow only forces human output, not human interaction. UseWORKOS_MODE=humanfor that.Validation
pnpm test(138 files, 1776 tests)pnpm typecheckpnpm lintpnpm format:checkpnpm buildpnpm exec tsx src/bin.ts doctor --json --skip-ai --skip-api --install-dir "$PWD"-> inferredagent / non_ttyreport; exits 1 here because this repo intentionally lacks WorkOS env varsWORKOS_MODE=agent pnpm exec tsx src/bin.ts doctor --json --skip-ai --skip-api --install-dir "$PWD"->agent / envpnpm exec tsx src/bin.ts --mode agent doctor --json --skip-ai --skip-api --install-dir "$PWD"->agent / flagWORKOS_MODE=ci pnpm exec tsx src/bin.ts doctor --json --skip-ai --skip-api --install-dir "$PWD"->ci / envWORKOS_MODE=human pnpm exec tsx src/bin.ts doctor --json --skip-ai --skip-api --install-dir "$PWD"->human / env, proving JSON output and interaction mode are separatepnpm exec tsx src/bin.ts --mode agent doctor --help --json-> doctor command subtree