Commit Graph
55 Commits
Author SHA1 Message Date
m11yandClaude Fable 5 4c78440f70 Fix Codex hook trust hash for matcherless events (UserPromptSubmit/Stop) (#7110)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 17:07:42 -07:00
Soichi Sumi 5e9db83c48 fix: add 'hooks' to CODEX_SYSTEM_RESOURCE_ENTRIES (#7120) 2026-07-03 17:06:09 -07:00
4797cf81a4 fix(agent-hooks): stream hook payload to a temp file instead of inlining it on the curl command line (#4475)
The POSIX agent-hook script for every curl-based agent inlined the full
event payload via `curl --data-urlencode "payload=${payload}"`. Tool
output can be tens of KB, so the resulting process command line could be
multi-KB — which endpoint security tools (e.g. Microsoft Defender for
Endpoint) flag as an oversized/suspicious command line. That produced a
false-positive detection on Orca's own loopback (127.0.0.1) telemetry POST.

Stream the payload to an mktemp file and post it with
`--data-urlencode "payload@$payload_file"` instead. The urlencoded body on
the wire is byte-identical, so the agent-hook receiver is unchanged; the
payload simply never appears on a process command line. `trap ... EXIT`
removes the temp file on every exit path. Small bounded metadata fields
(paneKey/tabId/worktreeId/env/version) stay inline.

Applied to all curl-based agents: claude, codex, command-code, copilot,
cursor, droid, gemini, grok, antigravity. (amp/hermes/opencode post via
the HTTP request body and were never affected.) The Windows post-command
shares the same latent pattern and is flagged as follow-up.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
Co-authored-by: Orca <help@stably.ai>
2026-07-03 16:26:53 -07:00
Brennan BensonandNeil 99bc693cd5 Fix Codex config paths in managed runtime home (#7157)
* Fix mirrored Codex relative config paths

Orca mirrors ~/.codex/config.toml into a managed CODEX_HOME before launching Codex. Relative path-valued Codex settings were then resolved from the runtime home instead of the user's real Codex home, which made config loading fail in Orca while the same CLI worked in a normal terminal. Rewrite known relative path settings to absolute paths rooted at the system Codex home while preserving runtime-owned trust sections.

* Dedupe Codex TOML line scanner and include path rewrite in CLI tsconfig

* Harden Codex config path rewrite and cover managed account homes

- Track multiline arrays in the shared TOML line scanner so array lines
  are never mistaken for table headers or path keys
- Escape control characters and reject lone-surrogate unicode escapes so
  the rewritten runtime config always stays valid TOML
- Extend the rewrite allowlist with profiles.* file settings and
  debug.config_lockfile.* (both can abort Codex config loading)
- Rewrite relative paths when mirroring the canonical config into
  managed account homes (codex login CODEX_HOMEs), anchoring WSL
  accounts to the Linux-side ~/.codex with posix join semantics

---------

Co-authored-by: Neil <neil@stably.ai>
2026-07-02 17:01:41 -07:00
Eren Çakar 801effa68e fix(claude): use Git Bash-safe hook fast path
Fixes #7116.

Use a forward-slash bare .cmd path for Claude/OpenClaude Windows hooks when the managed script path is Git-Bash-safe, avoiding the per-hook PowerShell startup overhead in the common case. Unsafe paths with spaces or shell metacharacters continue to use the encoded PowerShell launcher from #6078.

Keep Codex on its cmd.exe-safe fast path and leave the other agent integrations on the hardened encoded launcher.

Co-authored-by: Eren Çakar <hey@erencakar.com>
2026-07-02 15:42:01 -07:00
NeilandOrca 46646d7ff1 chore(lint): upgrade oxlint to 1.71 + enable 7 new rules (autofixed backlog) (#6841)
* chore(lint): upgrade oxlint to 1.71 and enable 7 new rules

Upgrade oxlint 1.67.0 -> 1.71.0 (1.72 was blocked by the repo's 3-day
minimum-release-age supply-chain guard; nothing here needs it). The
bump is a no-op on the existing config.

Enable 3 error rules (backlog autofixed to zero in this commit) and
4 warn rules (surface signal without gating CI):

error (autofixed, behavior-preserving):
- unicorn/prefer-node-protocol        (~1531 sites: bare builtin -> node:)
- typescript/no-import-type-side-effects (~36: all-inline-type -> import type)
- unicorn/no-array-reverse            (19: copy-then-reverse -> toReversed)

warn (real signal, current fires are test-only/correct):
- unicorn/no-array-fill-with-reference-type  (aliasing footgun guard)
- typescript/no-unsafe-function-type         (bans bare Function type)
- unicorn/prefer-array-flat-map              (map().flat() -> flatMap())
- unicorn/prefer-regexp-test                 (.match() in bool ctx -> .test())

mobile/.oxlintrc.json extends root, so it inherits all 7; the autofix
ran from root and covered mobile/ too.

Verification (all green): oxlint 0 errors (root+mobile+aux configs),
oxfmt clean, typecheck (node+cli+web), vitest 22795 passed / 0 failed,
builds (electron-vite + web + cli) succeed. node: rewrites confirmed to
skip embedded SSH/CLI string payloads (AST-only); all toReversed sites
verified to operate on fresh copies or write-once locals.

* chore(lint): bump mobile oxlint to 1.71 so inherited rules parse

mobile/ is a standalone pnpm project pinning its own oxlint@1.67, which
lacks unicorn/no-array-fill-with-reference-type (needs >=1.70). Since
mobile/.oxlintrc.json extends the root config, mobile CI's 'cd mobile &&
oxlint' failed to parse the new rule. Bump mobile to match root (1.71).

Verified in mobile/: oxlint 0 errors, oxfmt --check clean, tsc --noEmit
pass, vitest 978 passed / 0 failed.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-06-29 22:38:29 -07:00
Brennan BensonandNeil b6ac7b9c92 Harden Windows hook command resolution (#6409)
* Keep spaced Windows Codex hook paths fast

* Harden Windows hook command resolution

---------

Co-authored-by: Neil <neil@stably.ai>
2026-06-25 22:43:25 -07:00
Brennan BensonandNeil 6a23099594 Fix Windows agent hook regressions (#6407)
Co-authored-by: Neil <neil@stably.ai>
2026-06-25 21:59:19 -07:00
d0d257189c Speed up Windows Codex/Claude hooks without dropping events (#6402)
Windows runs managed hooks through a shell, and #6078 wrapped the
launcher in `powershell -EncodedCommand` to survive spaces in profile
paths. Combined with the inner PowerShell Invoke-WebRequest post, every
hook spawned two PowerShell processes (~300ms startup each), so a hook
took ~650ms+ and fired up to 6x per turn. Codex 0.140 renders that as
lingering "Running <event> hook" rows. The earlier RC worked around it
by deleting SessionStart/UserPromptSubmit/Stop, which loses lifecycle
status fidelity.

Keep all six Codex events and make them fast instead:

- Codex runs hooks as `cmd.exe /C <command>` and forwards our string
  verbatim when it has no spaces/quotes, so emit the bare .cmd path for
  cmd-safe profiles (zero shell startup) and fall back to the encoded
  PowerShell launcher only for spaced/metachar paths (#6078 robustness).
- Replace the inner PowerShell post with curl.exe (Windows 10 1803+),
  posting the same form fields as the POSIX hook and reading the raw
  payload from stdin via `--data-urlencode payload@-` so UTF-8 (e.g. CJK)
  survives without code-page translation.

Result: the common Codex case is 0 PowerShell (~70-150ms vs ~650ms);
spaced-path profiles drop to 1.

Claude runs hooks through Git Bash, so its launcher must stay
PowerShell-encoded (a bare path is what breaks it), but its inner post
moves to curl.exe too, cutting Claude from two PowerShell startups to
one.

Validated against the real Codex 0.140 binary (interactive TUI + exec):
all managed hooks fire, render briefly, and clear with no lingering
rows; the listener receives every post in 1-6ms.

Co-authored-by: Neil <neil@stably.ai>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 20:53:58 -07:00
Brennan BensonandNeil fa3fd3ae02 Fix slow Codex hook statuses on Windows (#6398)
Co-authored-by: Neil <neil@stably.ai>
2026-06-25 19:24:04 -07:00
Brennan BensonandNeil e257d79294 Prevent Codex hook trust prompts on Windows upgrades (#6388)
Co-authored-by: Neil <neil@stably.ai>
2026-06-25 17:24:09 -07:00
Rod BoevandJinwoo Hong 1732648928 fix(codex): prevent duplicate config.toml hook trust key on Windows (#6318)
* fix(codex): prevent duplicate config.toml hook trust key on Windows (#6163)

* fix codex hook trust key normalization

---------

Co-authored-by: Jinwoo Hong <73622457+Jinwoo-H@users.noreply.github.com>
2026-06-24 20:29:24 -07:00
e65306cb2f fix(codex): sanitize hooks config writes (#6247)
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: brennanb2025 <brennankbenson@gmail.com>
2026-06-24 19:12:21 -07:00
Brennan Benson e03a1cf769 Prevent managed agent hooks from hanging (#6148) 2026-06-23 17:22:10 -07:00
Jorge SilvaandJinwoo Hong 1fde7f553c fix(agent-hooks): wrap Windows hook commands in cmd.exe to survive spaces in profile path (#6078) (#6083)
* fix(codex): wrap Windows hook command in cmd.exe to survive spaces in profile path (#6078)

Windows splits raw hook commands on whitespace, so a user profile path
like `C:\Users\Jane Doe` made Codex hooks exit with code 1. Add a
wrapWindowsHookCommand helper that invokes the .cmd through
`cmd.exe /d /c call "..."` and use it in getManagedCommand.

* fix(agent-hooks): wrap Windows hook command in cmd.exe for all agents with raw .cmd path (#6078)

Apply the wrapWindowsHookCommand helper to cursor, command-code, gemini,
grok, and droid, which shared the same raw-scriptPath-on-Windows pattern
as codex. A user profile path with a space (e.g. `C:\Users\Jane Doe`)
used to split at the space and fail with exit code 1.

Agents that already handle spaces correctly are left untouched:
- claude/openclaude (Git Bash + forward slashes)
- copilot (PowerShell with quoted path)
- kimi (Git Bash + forward slashes)
- antigravity (event-specific wrapper .cmd files)
- devin (already wraps via `cmd /d /s /c ""...""`)

Each fixed agent gets a Windows-only test asserting the cmd.exe wrapping
survives spaces in the profile path.

* fix(claude): wrap Windows hook command in cmd.exe to survive spaces in profile path (#6078)

Claude Code runs hooks through Git Bash on Windows. The previous
forward-slash trick only works when the path has no spaces — Git Bash
splits `C:/Users/Jane Doe/...` at the space and tries to execute
`C:/Users/Jane` as a command. Use wrapWindowsHookCommand so the .cmd is
invoked through `cmd.exe /d /c call "..."`, which Git Bash treats as one
argument. Applies to both Claude and OpenClaude (shared getManagedCommand).

* Harden Windows agent hook launcher

---------

Co-authored-by: Jinwoo Hong <73622457+Jinwoo-H@users.noreply.github.com>
2026-06-22 16:04:01 -07:00
Jinwoo Hong 52f45b3559 Handle literal Codex hook trust keys (#5872) 2026-06-21 23:33:57 -07:00
Brennan BensonandOrca fe8fe16c83 Preserve agent settings when sleeping sessions resume (#5916)
Co-authored-by: Orca <help@stably.ai>
2026-06-21 16:44:58 -07:00
slashdevcorpse f80704cc60 [perf] Speed up CLI launch through Orca
Speed up Windows CLI launch by delivering short startup commands through shell args, falling back to stdin for oversized commands, and moving Codex historical session bridging into an incremental background task. Includes review fixes for Windows symlink and WSL test reliability.
2026-06-18 22:21:48 -07:00
0ec3882cb8 Add project Windows runtime selection (#5519)
* Add project Windows runtime selection

* Fix project Windows runtime selection

Co-authored-by: Orca <help@stably.ai>

* fix: preserve WSL shell variables

---------

Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Neil <neil@stably.ai>
2026-06-17 16:08:14 -07:00
Jinwoo Hong f0ea7a39a7 Retry Codex trust config writes on Windows locks (#4710) 2026-06-05 15:43:13 -04:00
Jinwoo HongandOrca f888acdb65 Revert Codex launch homes to shared runtime (#4400)
Co-authored-by: Orca <help@stably.ai>
2026-06-01 12:36:16 -07:00
Neil a278fd33ea Fix Codex launch-home sqlite materialization latency (#4377) 2026-06-01 01:51:32 -07:00
Jinwoo Hong 57ac2ef08e Hot-swap Codex homes via active pointer
Route Codex terminal launches through stable active CODEX_HOME pointers for host and WSL launch homes, with account-switch repointing and validated Windows/WSL behavior.
2026-06-01 03:09:11 -04:00
Jinwoo Hong d900bf2eea Fix Windows Codex launch-home file links
Fix Windows launch-home file linking by using hard links for shared Codex files, handling EEXIST/idempotency, and covering the Windows SQLite sidecar behavior.
2026-06-01 02:59:16 -04:00
Brennan BensonandOrca e0502a8d8e Fix Codex launch-home hook trust repair (#4348)
Co-authored-by: Orca <help@stably.ai>
2026-05-31 21:30:11 -07:00
Jinwoo HongandOrca be75b94db7 Trust Codex launch-home hooks (#4324)
Co-authored-by: Orca <help@stably.ai>
2026-05-31 15:48:12 -07:00
Jinwoo HongandOrca c1ad123c7d Share Codex SQLite state across launch homes (#4323)
Co-authored-by: Orca <help@stably.ai>
2026-05-31 15:43:40 -07:00
Jinwoo Hong c05cc3150a Support WSL Codex launch homes (#4318) 2026-05-31 17:29:37 -04:00
Jinwoo Hong ec01ffb986 Preserve Codex runtime config preferences (#3944) 2026-05-31 16:40:39 -04:00
Neil d1b9392b49 perf: cap generated hook posts (#4166)
Generated agent hook POSTs now use short curl and PowerShell request timeouts so best-effort status hooks cannot hold agent subprocesses open on a stalled local listener.
2026-05-31 06:40:02 -07:00
Neil 2345ca8d48 fix: install Codex status hooks before mirrored user hooks 2026-05-31 02:27:08 -07:00
Jinwoo-HandOrca 61cee02438 test: restore codex hook cleanup warn spy
Co-authored-by: Orca <help@stably.ai>
2026-05-31 01:53:24 -07:00
Neil cb136952c9 fix: clean large legacy codex hook lists 2026-05-31 01:53:24 -07:00
Neil 3191550fa5 perf: avoid codex legacy trust spread (#3870) 2026-05-30 12:45:29 -07:00
Brennan BensonandOrca d3b56a5922 Add one-click setup script generation (#3370)
Co-authored-by: Orca <help@stably.ai>
2026-05-30 11:57:55 -07:00
bcc9c0d9e1 Deduplicate Codex hook trust blocks (#3196)
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: brennanb2025 <brennankbenson@gmail.com>
2026-05-30 11:19:12 -07:00
Neil f79977ac5a fix: avoid spread limit in usage session scans (#3640) 2026-05-30 04:36:45 -07:00
Jinwoo HongandOrca ddd08be1e6 Handle stale Codex hook trust indices (#2968)
Co-authored-by: Orca <help@stably.ai>
2026-05-27 21:16:04 -07:00
Brennan BensonandOrca b84819c2e1 Filter plugin-only Codex hooks from runtime mirror (#2921)
Co-authored-by: Orca <help@stably.ai>
2026-05-27 16:10:15 -07:00
ddda84f529 fix(shell-ready): honor user's ZDOTDIR (XDG-layout fix, redo of #1737) (#1947)
* fix(shell-ready): honor ZDOTDIR without breaking zsh scoping

Fixes #1866

This reimplements PR #1737 (reverted in #1864) with a safer approach
that preserves normal zsh startup semantics.

**Core fix**: Discover ZDOTDIR by sourcing user ~/.zshenv in a subshell
instead of inside a wrapper function. This preserves top-level zsh
scoping for common patterns like `typeset -U path` that broke in the
original implementation.

**Shell safety improvements**:
- Use `printf '%s\n'` instead of `echo` for capturing ZDOTDIR (handles
  special characters in paths safely)
- Subshell isolates early returns and side effects from wrapper

**Code quality**:
- Extract duplicated zsh wrapper template to `src/main/shell-templates.ts`
- Both local-pty and daemon paths now share identical wrapper logic

**Test coverage**:
- Add live zsh subprocess tests that spawn real zsh to verify:
  - XDG ZDOTDIR discovery works
  - `typeset -U path` in .zshrc preserves top-level scoping
  - Early returns in .zshenv don't crash the wrapper
  - Vanilla (non-XDG) configs fall back to HOME correctly
- Template structure tests validate subshell discovery logic

Before (broken):
```zsh
__orca_source_user_zshenv() {
  source "$HOME/.zshenv"  # typeset becomes function-scoped
}
```

After (fixed):
```zsh
_orca_discovered_zdotdir=$(
  unset ZDOTDIR
  [[ -f "$HOME/.zshenv" ]] && source "$HOME/.zshenv" 2>/dev/null
  printf '%s\n' "${ZDOTDIR}"
)
export ORCA_ORIG_ZDOTDIR="${_orca_discovered_zdotdir:-${_orca_spawn_orig_zdotdir:-$HOME}}"
```

The subshell sources .zshenv at top-level (preserving normal scoping),
captures only the ZDOTDIR value, then exits. User rcfiles (.zshrc, etc.)
are still sourced at the wrapper's top level, so all scoping works normally.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* Add shell-script-literal test framework and improvements

Adds a new declarative test framework for shell-ready tests that uses
literal shell scripts (copy-pastable into terminals) with inline snapshots.

Framework features:
- Shell scripts as string literals with # Run: marker to split setup/test
- Direct script execution (no brittle parsing) via temp files
- Path normalization for reproducible snapshots (<HOME>, <WRAPPER_DIR>)
- Auto-detects shell from command, supports bash/zsh/sh
- Inline snapshot testing with vitest toMatchInlineSnapshot()

Code quality improvements:
- Extract escapeRegex to shared string-utils.ts (deduplicates 2 copies)
- Refactor shell-templates.ts for readability (condense comments, add structure)
- Pre-compile regex patterns to avoid hot-path allocation
- Fix path normalization to sort by length (prevent nested path corruption)
- Fix actualUserHome handling to skip empty values

All tests passing (64/64 shell-ready tests, 55/55 affected tests).

Files added:
- src/main/providers/__tests__/shell-ready-framework/shell-script-test.ts
- src/main/providers/__tests__/shell-ready-framework/README.md
- src/main/providers/__tests__/shell-ready-framework-example.test.ts
- src/shared/string-utils.ts

Files modified:
- src/main/shell-templates.ts (readability cleanup)
- src/main/codex/config-toml-trust.ts (use shared escapeRegex)
- src/main/daemon/shell-ready.test.ts (updated for new framework)
- src/main/providers/local-pty-shell-ready.test.ts (updated for new framework)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(shell-ready): preserve zshenv semantics

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
2026-05-26 00:24:45 -07:00
Brennan BensonandOrca 0bfd9622e2 Prefer hardlinks for Codex session bridge (#2819)
Co-authored-by: Orca <help@stably.ai>
2026-05-25 20:54:43 -07:00
Brennan BensonandOrca 6f939896c0 Bridge legacy Codex sessions into runtime home (#2816)
Co-authored-by: Orca <help@stably.ai>
2026-05-25 19:56:48 -07:00
Brennan BensonandOrca a2c71461b4 Isolate Codex hooks in Orca runtime home (#2350)
Co-authored-by: Orca <help@stably.ai>
2026-05-25 15:07:40 -07:00
Neil d4703bd1ab Restore agent hook opt-out controls (#2778) 2026-05-25 10:37:22 -07:00
Neil 28ba9151a5 Revert "Add agent hook opt-out controls" (#2739) 2026-05-23 23:04:57 -07:00
Neil 4f81953d10 feat: add agent hook opt-out controls (#2714) 2026-05-23 21:16:49 -07:00
Neil 312677132e fix: speed up Codex draft prefill (#2105) 2026-05-16 13:58:17 -07:00
Neil 675b1b0cb6 Fix Windows agent hook Unicode prompts (#2100) 2026-05-16 13:32:23 -07:00
Brennan BensonandOrca 2cadcbc4e1 Support agent status hooks over SSH (#1865)
Co-authored-by: Orca <help@stably.ai>
2026-05-14 16:06:23 -07:00
Brennan BensonandOrca 727226fed9 fix(agent-hooks): write managed hook script to shared ~/.orca path (#1546)
Co-authored-by: Orca <help@stably.ai>
2026-05-14 11:57:48 -07:00