Commit Graph

8634 Commits

Author SHA1 Message Date
Ahmed Ibrahim
b6ab2214e3 Add TUI realtime conversation mode (#12687)
- Add a hidden `realtime_conversation` feature flag and `/realtime`
slash command for start/stop live voice sessions.
- Reuse transcription composer/footer UI for live metering, stream mic
audio, play assistant audio, render realtime user text events, and
force-close on feature disable.

---------

Co-authored-by: Codex <noreply@openai.com>
2026-02-24 12:54:30 -08:00
Michael Bolin
3b5fc7547e refactor: remove unused seatbelt unix socket arg (#12707)
https://github.com/openai/codex/pull/12052 introduced an
`allowed_unix_socket_paths` parameter to
`create_seatbelt_command_args()`, but
https://github.com/openai/codex/pull/12649 removed the abstraction that
#12052 introduced, so this parameter is no longer necessary as it is
always an empty slice.
2026-02-24 12:30:26 -08:00
pakrym-oai
daf0f03ac8 Ensure shell command skills trigger approval (#12697)
Summary
- detect skill-invoking shell commands based on the original command
string, request approvals when needed, and cache positive decisions per
session
- keep implicit skill invocation emitted after approval and keep skill
approval decline messaging centralized to the shell handler
- expand and adjust skill approval tests to cover shell-based skill
scripts while matching the new detection expectations

Testing
- Not run (not requested)
2026-02-24 12:13:20 -08:00
Michael Bolin
09c71c845e merge commit for archive created by Sapling 2026-02-24 11:58:59 -08:00
Michael Bolin
88c767093b refactor: remove unused seatbelt unix socket arg 2026-02-24 11:58:40 -08:00
Felipe Coury
061d1d3b5e feat(tui): add theme-aware diff backgrounds with capability-graded palettes (#12581)
## Problem

Diff lines used only foreground colors (green/red) with no background
tinting, making them hard to scan. The gutter (line numbers) also had no
theme awareness — dimmed text was fine on dark terminals but unreadable
on light ones.

## Mental model

Each diff line now has four styled layers: **gutter** (line number),
**sign** (`+`/`-`), **content** (text), and **line background** (full
terminal width). A `DiffTheme` enum (`Dark` / `Light`) is selected once
per render by probing the terminal's queried background via
`default_bg()`. A companion `DiffColorLevel` enum (`TrueColor` /
`Ansi256` / `Ansi16`) is derived from `stdout_color_level()` and gates
which palette is used. All style helpers dispatch on `(theme,
DiffLineType, color_level)` to pick the right colors.

| Theme Picker Wide | Theme Picker Narrow |
|---|---|
| <img width="1552" height="1012" alt="image"
src="https://github.com/user-attachments/assets/231b21b7-32d4-4727-80ed-7d01924954be"
/> | <img width="795" height="1012" alt="image"
src="https://github.com/user-attachments/assets/549cacdf-daec-43c9-ad64-2a28d16d140e"
/> |

| Dark BG - 16 colors | Dark BG - 256 colors | Dark BG - True Colors |
|---|---|---|
| <img width="1552" height="1012" alt="dark-16colors"
src="https://github.com/user-attachments/assets/fba36de3-c101-47d4-9e63-88cdd00410d0"
/> | <img width="1552" height="1012" alt="dark-256colors"
src="https://github.com/user-attachments/assets/f39e4307-c6b0-49c4-b4fe-bd26d3d8e41c"
/> | <img width="1552" height="1012" alt="dark-truecolor"
src="https://github.com/user-attachments/assets/1af4ec57-04bf-4dfb-8a44-0ab5e5aaaf18"
/> |

| Light BG - 16 colors | Light BG - 256 colors | Light BG - True Colors
|
|---|---|---|
| <img width="1552" height="1012" alt="light-16colors"
src="https://github.com/user-attachments/assets/2b5423d1-74b4-4b1e-8123-7c2488ff436b"
/> | <img width="1552" height="1012" alt="light-256colors"
src="https://github.com/user-attachments/assets/c94cff9a-8d3e-42c9-bbe7-079da39953a8"
/> | <img width="1552" height="1012" alt="light-truecolor"
src="https://github.com/user-attachments/assets/f73da626-725f-4452-99ee-69ef706df2c6"
/> |

## Non-goals

- No runtime theme switching beyond what `default_bg()` already
provides.
- No change to syntax highlighting theme selection or the highlight
module.

## Tradeoffs

- Three fixed palettes (truecolor RGB, 256-color indexed, 16-color
named) are maintained rather than using `best_color` nearest-match. This
is deliberate: `supports_color::on_cached(Stream::Stdout)` can misreport
capabilities once crossterm enters the alternate screen, so hand-picked
palette entries give better visual results than automatic quantization.
- Delete lines in the syntax-highlighted path get `Modifier::DIM` to
visually recede compared to insert lines. This trades some readability
of deleted code for scan-ability of additions.
- The theme picker's diff preview sets `preserve_side_content_bg: true`
on `ListSelectionView` so diff background tints survive into the side
panel. Other popups keep the default (`false`) to preserve their
reset-background look.

## Architecture

- **Color constants** are module-level `const` items grouped by palette
tier: `DARK_TC_*` / `LIGHT_TC_*` (truecolor RGB tuples), `DARK_256_*` /
`LIGHT_256_*` (xterm indexed), with named `Color` variants used for the
16-color tier.
- **`DiffTheme`** is a private enum; `diff_theme()` probes the terminal
and `diff_theme_for_bg()` is the testable pure-function version.
- **`DiffColorLevel`** is a private enum derived from `StdoutColorLevel`
via `diff_color_level()`.
- **Palette helpers** (`add_line_bg`, `del_line_bg`, `light_gutter_fg`,
`light_add_num_bg`, `light_del_num_bg`) each take `(DiffTheme,
DiffColorLevel)` or just `DiffColorLevel` and return a `Color`.
- **Style helpers** (`style_line_bg_for`, `style_gutter_for`,
`style_sign_add`, `style_sign_del`, `style_add`, `style_del`) each take
`(DiffLineType, DiffTheme, DiffColorLevel)` or `(DiffTheme,
DiffColorLevel)` and return a `Style`.
- **`push_wrapped_diff_line_inner_with_theme_and_color_level`** is the
innermost renderer, accepting both theme and color level so tests can
exercise any combination without depending on the terminal.
- **Line-level background** is applied via
`RtLine::from(...).style(line_bg)` so the tint extends across the full
terminal width, not just the text content.
- **Theme picker integration**: `ListSelectionView` gained a
`preserve_side_content_bg` flag. When `true`, the side panel skips
`force_bg_to_terminal_bg`, letting diff preview backgrounds render
faithfully.

## Observability

No new logging. Theme selection is deterministic from `default_bg()`,
which is already queried and cached at TUI startup.

## Tests

1. **`DiffTheme` is determined per `render_change` call** — if
`default_bg()` changes mid-render (e.g. `requery_default_colors()`
fires), different file chunks could render with different themes. Low
risk in practice since re-query only happens on explicit user action.
2. **16-color tier uses named `Color` variants** (`Color::Green`,
`Color::Red`, etc.) which the terminal maps to its own palette. On
unusual terminal themes these could clash with the background.
Acceptable since 16-color terminals already have unpredictable color
rendering.
3. **Light-theme `style_add` / `style_del` set bg but no fg** — on light
terminals, non-syntax-highlighted content uses the terminal's default
foreground against a pastel background. If the terminal's default fg
happens to be very light, contrast could suffer. This is an edge case
since light-terminal users typically have dark default fg.
4. **`preserve_side_content_bg` is a general-purpose flag but only used
by the theme picker** — if other popups start using side content with
intentional backgrounds they'll need to opt in explicitly. Not a real
risk today, just a note for future callers.
2026-02-24 11:55:01 -08:00
Yaroslav Volovich
67d9261e2c feat(sleep-inhibitor): add Linux and Windows idle-sleep prevention (#11766)
## Background
- follow-up to previous macOS-only PR:
https://github.com/openai/codex/pull/11711
- follow-up macOS refactor PR (current structural approach used here):
https://github.com/openai/codex/pull/12340

## Summary
- extend `codex-utils-sleep-inhibitor` with Linux and Windows backends
while preserving existing macOS behavior
- Linux backend:
  - use `systemd-inhibit` (`--what=idle --mode=block`) when available
- fall back to `gnome-session-inhibit` (`--inhibit idle`) when available
  - keep no-op behavior if neither backend exists on host
- Windows backend:
- use Win32 power request handles (`PowerCreateRequest` +
`PowerSetRequest` / `PowerClearRequest`) with
`PowerRequestSystemRequired`
- make `prevent_idle_sleep` Experimental on macOS/Linux/Windows; keep
under development on other targets

## Testing
- `just fmt`
- `cargo test -p codex-utils-sleep-inhibitor`
- `cargo test -p codex-core features::tests::`
- `cargo test -p codex-tui chatwidget::tests::`
- `just fix -p codex-utils-sleep-inhibitor`
- `just fix -p codex-core`

## Semantics and API references
- Goal remains: prevent idle system sleep while a turn is running.
- Linux:
  - `systemd-inhibit` / login1 inhibitor model:
-
https://www.freedesktop.org/software/systemd/man/latest/systemd-inhibit.html
-
https://www.freedesktop.org/software/systemd/man/org.freedesktop.login1.html
    - https://systemd.io/INHIBITOR_LOCKS/
  - xdg-desktop-portal Inhibit (relevant for sandboxed apps):
-
https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.Inhibit.html
- Windows:
  - `PowerCreateRequest`:
-
https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-powercreaterequest
  - `PowerSetRequest`:
-
https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-powersetrequest
  - `PowerClearRequest`:
-
https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-powerclearrequest
  - `SetThreadExecutionState` (alternative baseline API):
-
https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setthreadexecutionstate

## Chromium vs this PR
- Chromium Linux backend:
-
https://github.com/chromium/chromium/blob/main/services/device/wake_lock/power_save_blocker/power_save_blocker_linux.cc
- Chromium Windows backend:
-
https://github.com/chromium/chromium/blob/main/services/device/wake_lock/power_save_blocker/power_save_blocker_win.cc
- Electron powerSaveBlocker entry point:
-
https://github.com/electron/electron/blob/main/shell/browser/api/electron_api_power_save_blocker.cc

## Why we differ from Chromium
- Linux implementation mechanism:
- Chromium uses in-process D-Bus APIs plus UI-integrated screen-saver
suspension.
- This PR uses command-based inhibitor backends (`systemd-inhibit`,
`gnome-session-inhibit`) instead of linking a Linux D-Bus client in this
crate.
- Reason: keep `codex-utils-sleep-inhibitor` dependency-light and avoid
Linux CI/toolchain fragility from new native D-Bus linkage, while
preserving the same runtime intent (hold an inhibitor while a turn
runs).
- Linux UI integration scope:
- Chromium also uses `display::Screen::SuspendScreenSaver()` in its UI
stack.
- Codex `codex-rs` does not have that display abstraction in this crate,
so this PR scopes Linux behavior to process-level sleep inhibition only.
- Windows wake-lock type breadth:
- Chromium supports both display/system wake-lock types and extra
display-specific handling for some pre-Win11 scenarios.
- Codex’s feature is scoped to turn execution continuity (not forcing
display on), so this PR uses `PowerRequestSystemRequired` only.
2026-02-24 11:51:44 -08:00
sayan-oai
0b6c2e5652 fix: also try matching namespaced prefix for modelinfo candidate (#12658)
#### What
Try matching `\w+`-namespaced model after `longest prefix` as heuristic
to match `ModelInfo` from list of candidates.

This shouldn't regress existing behavior:
- `gpt-5.2-codex` -> `gpt-5.2` if `gpt-5.2-codex` not present
- `gpt-5.3` -> `gpt-5` if `gpt-5.3` not present
- `gpt-9` still doesn't match anything

while being more forgiving for custom prefixes:
- `oai/gpt-5.3-codex` -> `gpt-5.3-codex`

#### Tests
Added unit test.
2026-02-24 10:57:26 -08:00
Eric Traut
74cebceed7 Fix @mention token parsing in chat composer (#12643)
Fixes #12175

If a user types an npm package name with multiple `@` symbols like `npx
-y @foo/bar@latest`, the TUI currently treats this as though it's
attempting to invoke the file picker.

### What changed

- **Generalized `@` token parsing**
- `current_prefixed_token(...)` now treats `@` as a token start **only
at a whitespace boundary** (or start-of-line).
- If the cursor is on a nested `@` inside an existing
whitespace-delimited token (for example `@scope/pkg@latest`), it keeps
the surrounding token active instead of starting a new token at the
second `@`.
- It also avoids misclassifying mid-word usages like `foo@bar` as an `@`
file token.

- **Enter behavior with file popup**
- If the file-search popup is open but has **no selected match**,
pressing `Enter` now closes the popup and falls through to normal submit
behavior.
- This prevents pasted strings containing `@...` from blocking
submission just because file-search was active with no actionable
selection.

### Testing
I manually built and tested the scenarios involved with the bug report
and related use of `@` mentions to verify no regressions
2026-02-24 10:50:00 -08:00
Michael Bolin
3ca0e7673b feat: run zsh fork shell tool via shell-escalation (#12649)
## Why

This PR switches the `shell_command` zsh-fork path over to
`codex-shell-escalation` so the new shell tool can use the shared
exec-wrapper/escalation protocol instead of the `zsh_exec_bridge`
implementation that was introduced in
https://github.com/openai/codex/pull/12052. `zsh_exec_bridge` relied on
UNIX domain sockets, which is not as tamper-proof as the FD-based
approach in `codex-shell-escalation`.

## What Changed

- Added a Unix zsh-fork runtime adapter in `core`
(`core/src/tools/runtimes/shell/unix_escalation.rs`) that:
- runs zsh-fork commands through
`codex_shell_escalation::run_escalate_server`
  - bridges exec-policy / approval decisions into `ShellActionProvider`
- executes escalated commands via a `ShellCommandExecutor` that calls
`process_exec_tool_call`
- Updated `ShellRuntime` / `ShellCommandHandler` / tool spec wiring to
select a `shell_command` backend (`classic` vs `zsh-fork`) while leaving
the generic `shell` tool path unchanged.
- Removed the `zsh_exec_bridge`-based session service and deleted
`core/src/zsh_exec_bridge/mod.rs`.
- Moved exec-wrapper entrypoint dispatch to `arg0` by handling the
`codex-execve-wrapper` arg0 alias there, and removed the old
`codex_core::maybe_run_zsh_exec_wrapper_mode()` hooks from `cli` and
`app-server` mains.
- Added the needed `codex-shell-escalation` dependencies for `core` and
`arg0`.

## Tests

- `cargo test -p codex-core
shell_zsh_fork_prefers_shell_command_over_unified_exec`
- `cargo test -p codex-app-server turn_start_shell_zsh_fork --
--nocapture`
- verifies zsh-fork command execution and approval flows through the new
backend
- includes subcommand approve/decline coverage using the shared zsh
DotSlash fixture in `app-server/tests/suite/zsh`
- To test manually, I added the following to `~/.codex/config.toml`:

```toml
zsh_path = "/Users/mbolin/code/codex3/codex-rs/app-server/tests/suite/zsh"

[features]
shell_zsh_fork = true
```

Then I ran `just c` to run the dev build of Codex with these changes and
sent it the message:

```
run `echo $0`
```

And it replied with:

```
  echo $0 printed:

  /Users/mbolin/code/codex3/codex-rs/app-server/tests/suite/zsh

  In this tool context, $0 reflects the script path used to invoke the shell, not just zsh.
```

so the tool appears to be wired up correctly.

## Notes

- The zsh subcommand-decline integration test now uses `rm` under a
`WorkspaceWrite` sandbox. The previous `/usr/bin/true` scenario is
auto-allowed by the new `shell-escalation` policy path, which no longer
produces subcommand approval prompts.
2026-02-24 10:31:08 -08:00
viyatb-oai
8d3d58f992 feat(network-proxy): add MITM support and gate limited-mode CONNECT (#9859)
## Description
- Adds MITM support (CA load/issue, TLS termination, optional body
inspection).
- Adds `codex-network-proxy init` to create
`CODEX_HOME/network_proxy/mitm`.
- Enforces limited-mode HTTPS correctly: `CONNECT` requires MITM,
otherwise blocked with `mitm_required`.
- Keeps `origin/main` layering/reload semantics (managed layers included
in reload checks).
- Centralizes block reasons (`REASON_MITM_REQUIRED`) and removes
`println!`.
- Scope is MITM-only (no SOCKS changes).

gated by `mitm=false` (default)
2026-02-24 18:15:15 +00:00
Michael Bolin
1e0ae305ba Merge 3f7fbdd3a3 into sapling-pr-archive-bolinfest 2026-02-24 10:10:23 -08:00
Michael Bolin
3f7fbdd3a3 feat: run zsh fork shell tool via shell-escalation 2026-02-24 10:10:16 -08:00
Michael Bolin
8a36538299 merge commit for archive created by Sapling 2026-02-24 10:05:25 -08:00
Michael Bolin
66ab6474ba feat: run zsh fork shell tool via shell-escalation 2026-02-24 10:04:46 -08:00
Won Park
ca556fa313 ctrl-L (clears terminal but does not start a new chat) (#12628)
# ctrl-L

- Clears your terminal window
- Does not start a new chat
2026-02-24 10:03:42 -08:00
Dylan Hurd
f6053fdfb3 feat(core) Introduce Feature::RequestPermissions (#11871)
## Summary
Introduces the initial implementation of Feature::RequestPermissions.
RequestPermissions allows the model to request that a command be run
inside the sandbox, with additional permissions, like writing to a
specific folder. Eventually this will include other rules as well, and
the ability to persist these permissions, but this PR is already quite
large - let's get the core flow working and go from there!

<img width="1279" height="541" alt="Screenshot 2026-02-15 at 2 26 22 PM"
src="https://github.com/user-attachments/assets/0ee3ec0f-02ec-4509-91a2-809ac80be368"
/>

## Testing
- [x] Added tests
- [x] Tested locally
- [x] Feature
2026-02-24 09:48:57 -08:00
Michael Bolin
594ac583ee merge commit for archive created by Sapling 2026-02-24 09:48:39 -08:00
Michael Bolin
13ef9f1130 feat: run zsh fork shell tool via shell-escalation 2026-02-24 09:48:30 -08:00
Michael Bolin
806c05b691 Merge 4aeb9b4c19 into sapling-pr-archive-bolinfest 2026-02-24 09:46:24 -08:00
Michael Bolin
4aeb9b4c19 feat: run zsh fork shell tool via shell-escalation 2026-02-24 09:46:17 -08:00
jif-oai
9a8adbf6e5 feat: use process group to kill the PTY (#12688)
Use the process group kill logic to kill the PTY
2026-02-24 16:55:23 +00:00
pakrym-oai
97d0068658 Send warmup request (#11258)
Send a request with `generate: falls` but a full set of tools and
instructions to pre-warm inference.

---------

Co-authored-by: Codex <noreply@openai.com>
2026-02-24 08:15:47 -08:00
jif-oai
0679e70bfc fix: replay after /agent (#12663)
Filter the events after a`/agent` replay to prevent replaying decision
events
2026-02-24 12:08:38 +00:00
zuxin-oai
3fe365ad8a memories: tighten memory lookup guidance and citation requirements (#12635)
## Summary
- tighten the memory-use decision boundary so agents skip memory only
for clearly self-contained asks
- make the quick memory pass more explicit and bounded (including a
lightweight search budget)
- add structured `<memory_citation>` requirements and examples for final
replies
- clarify memory update guidance and end-state wording for memory lookup

## Why
The previous template was directionally correct, but still left room for
inconsistent memory lookup behavior and citation formatting. This change
makes the default behavior, quick-pass scope, and citation output
contract much more explicit.

## Testing
- not run (prompt/template text change only)

Co-authored-by: jif-oai <jif@openai.com>
2026-02-24 11:46:28 +00:00
jif-oai
8758db5d5b feat: mutli agents persist config overrides (#12667)
Fix propagation of runtime config changes and `--yolo`
2026-02-24 11:33:00 +00:00
zuxin-oai
15f6cfb047 memories: tighten consolidation prompt schema and indexing guidance (#12653)
## Summary
- tighten the Phase 2 consolidation prompt for task-oriented `MEMORY.md`
generation
- address Phase 2 under-coverage / "laziness" with stronger workflow +
final-pass checks
- improve recency/ordering behavior for `MEMORY.md` and
`memory_summary.md`
- rewrite `## What's in Memory` as a clearer routing index with explicit
recent-3-day structure

## Key Changes
- `MEMORY.md` schema cleanup:
- align on `## Task <n>` task sections (remove stale `task:`
rule/example references)
  - include `thread_id` in rollout provenance examples
  - compact comma-separated `### keywords` format
- Phase 2 completeness guardrails:
  - chunked INIT coverage pass over `raw_memories.md`
  - incremental net-new indexing / routing steps
- stronger final checks (day ordering, topic coverage, keyword
searchability, accidental duplication)
- Recency / ordering rules:
- clearer scan-order guidance for raw memories (newest-first bias in
incremental mode)
- utility+recency ordering guidance for `MEMORY.md` task groups and
summary topics
  - rebuild recent active window from current `updated_at` coverage
- `## What's in Memory` rewrite:
  - index/routing-layer framing (not a mini-handbook)
  - explicit recent 3 distinct memory-day layout
  - richer recent-topic entries + compact lower-priority routing entries
- clearer `desc` / `learnings` expectations and separation from `##
General Tips`
- Explicitly allow rollout-summary reuse across multiple tasks/blocks
when it supports distinct task angles (with distinct task-local value)

## Notes
- Prompt-template only:
`codex-rs/core/templates/memories/consolidation.md`
- No runtime/code changes

## Validation
- Manual diff review only
2026-02-24 09:41:20 +00:00
Michael Bolin
c1c4ff98fc merge commit for archive created by Sapling 2026-02-24 00:06:19 -08:00
Michael Bolin
f0c539421c feat: run zsh fork shell tool via shell-escalation 2026-02-24 00:06:12 -08:00
Michael Bolin
2c9937aae5 merge commit for archive created by Sapling 2026-02-24 00:02:20 -08:00
Michael Bolin
90b29d6662 feat: run zsh fork shell tool via shell-escalation 2026-02-24 00:02:13 -08:00
Michael Bolin
702a42c214 merge commit for archive created by Sapling 2026-02-23 23:41:13 -08:00
Michael Bolin
fddbb911f9 feat: run zsh fork shell tool via shell-escalation 2026-02-23 23:41:06 -08:00
Michael Bolin
42cc0afa11 merge commit for archive created by Sapling 2026-02-23 23:00:27 -08:00
Michael Bolin
47a0c16469 feat: run zsh fork shell tool via shell-escalation 2026-02-23 23:00:19 -08:00
pakrym-oai
68a7d98363 Simplify skill tracking (#12652)
Remove a few layers of structs and store SkillMetadata.

---------

Co-authored-by: alexsong-oai <alexsong@openai.com>
2026-02-23 22:47:39 -08:00
Michael Bolin
89b8b870a9 merge commit for archive created by Sapling 2026-02-23 22:47:11 -08:00
Michael Bolin
3b3a260533 feat: run zsh fork shell tool via shell-escalation 2026-02-23 22:47:04 -08:00
Michael Bolin
5eed633e31 merge commit for archive created by Sapling 2026-02-23 22:41:42 -08:00
Michael Bolin
65c66db428 feat: run zsh fork shell tool via shell-escalation 2026-02-23 22:41:36 -08:00
Michael Bolin
e129898c4a merge commit for archive created by Sapling 2026-02-23 22:39:27 -08:00
Michael Bolin
304dcae06c feat: run zsh fork shell tool via shell-escalation 2026-02-23 22:39:17 -08:00
sayan-oai
7e46e5b9c2 chore: rm hardcoded PRESETS list (#12650)
rm `PRESETS` list harcoded in `model_presets` as we now have bundled
`models.json` with equivalent info.

update logic to rely on bundled models instead, update tests.
2026-02-23 22:35:51 -08:00
pakrym-oai
58763afa0f Add skill approval event/response (#12633)
Set the stage for skill-level permission approval in addition to
command-level.

Behind a feature flag.
2026-02-23 22:28:58 -08:00
Eric Traut
a4076ab4b1 Avoid AbsolutePathBuf::parent() panic under EMFILE by skipping re-absolutization (#12647)
Fixes #12216

Fixes a panic in `AbsolutePathBuf::parent()` when the process hits file
descriptor exhaustion (`EMFILE` / "Too many open files").

### Root cause

`AbsolutePathBuf::parent()` was re-validating the parent path via
`from_absolute_path(...).expect(...)`.

`from_absolute_path()` calls `path_absolutize::absolutize()`, which can
depend on `std::env::current_dir()`. Under `EMFILE`, that can fail,
causing `parent()` to panic even though the parent of an absolute path
is already known.

### Change

- Stop re-absolutizing the result of `self.0.parent()`
- Construct `AbsolutePathBuf` directly from the known parent path
- Keep an invariant check with `debug_assert!(p.is_absolute())`

### Why this is safe

`self` is already an `AbsolutePathBuf`, so `self.0` is
absolute/normalized. The parent of an absolute path is expected to be
absolute, so re-running fallible normalization here is unnecessary and
can introduce unrelated panics.
2026-02-23 21:59:33 -08:00
Michael Bolin
6418bcf909 merge commit for archive created by Sapling 2026-02-23 21:59:24 -08:00
Michael Bolin
349b4fd902 feat: run zsh fork shell tool via shell-escalation 2026-02-23 21:59:13 -08:00
alexsong-oai
09a82f364f Support implicit skill invocation analytics events (#12049)
- use `skills_for_cwd` lookup to scope allowed skills and build
invocation context for downstream processing
- add detection in `stream_events_utils` to classify tool calls as
implicit skill invocations per the proposal (script runners, extensions,
`scripts` dirs, and SKILL.md reads)
- deduplicate invocations per turn and emit analytics/OTEL events on the
same background queue as explicit invokes
2026-02-23 21:55:49 -08:00
Dylan Hurd
fbeda61cc3 fix(exec) Patch resume test race condition (#12648)
## Summary
The test exec_resume_last_respects_cwd_filter_and_all_flag makes one
session “newest” by resuming it, but rollout updated_at is stored/sorted
at second precision. On fast CI (especially Windows), the touch could
land in the same second as initial session creation, making ordering
nondeterministic.

This change adds a short sleep before the recency-touch step so the
resumed session is guaranteed to have a later updated_at, preserving the
intended assertion without changing product behavior.
2026-02-23 21:54:25 -08:00
Michael Bolin
87ac014c3b merge commit for archive created by Sapling 2026-02-23 21:48:09 -08:00