diff --git a/.codewith/skills/codewith-e2b-build/SKILL.md b/.codewith/skills/codewith-e2b-build/SKILL.md new file mode 100644 index 0000000000..fb0f9da0b3 --- /dev/null +++ b/.codewith/skills/codewith-e2b-build/SKILL.md @@ -0,0 +1,151 @@ +--- +name: codewith-e2b-build +description: Build and test Codewith Rust crates on remote compute (E2B, AWS Fargate, or Daytona) instead of this machine. Use when a worktree worker must offload heavy codex-rs builds/tests, run the FULL suite (codex-core) that needs big RAM/disk, run many builds in parallel, or avoid loading the local box. Not for local inner-loop edits. +user_invocable: true +--- + +# Codewith Remote Build (E2B / AWS / Daytona) + +Offload heavy Codewith Rust builds/tests from this machine to **remote compute**. +One CLI, three interchangeable backends (`--backend`): + +| Backend | Per-box vCPU / RAM / usable disk | Cap? | Best for | +|---|---|---|---| +| **`aws`** (Fargate) | up to **16 / 120 GB / 200 GB** (default 8 / 32 GB / 150 GB) | **none** — we own it | **the FULL suite** (codex-core), anything that OOM/disk-fills on E2B | +| `e2b` (default) | 8 / 8 GB / ~9 GB free | tier: 8 GB RAM, no volumes | fast scoped `test-fast`/`check`, warm-reuse builds | +| `daytona` | 4 / 8 GB / 10 GB | tier: per-sandbox 4/8/10 | small scoped checks only (too small for full suites) | + +**Why AWS exists here:** E2B (Pro) hard-caps templates at **8 GB RAM** ("Memory can't be +higher than 8192 MiB — contact support"), disk is **not a build knob** (rootfs ~21 GB, only +~9 GB free), and **Volumes are disabled** ("use of volumes is not enabled"). Daytona Tier 2 +raised the org pool but per-sandbox is still **4 vCPU / 8 GB / 10 GB** (contact support to +raise). Both need a support ticket to go bigger. **AWS Fargate has none of these caps** and +is our canonical self-hosted stack — so full-suite builds (e.g. `codex-core`, which needs +15-40 GB of target/artifacts and links large binaries) run there without OOM or +"No space left on device". The linker "Bus error" seen on E2B was **SIGBUS-on-full-disk** +(lld mmaps its output), i.e. a disk problem, not RAM — AWS's 150 GB disk fixes it. + +Entry point: **`scripts/codewith-remote-build.mjs`** (multi-backend). The legacy +`scripts/codewith-e2b-build.mjs` remains as an E2B-only alias for existing callers. + +Read the root `CODEWITH.md` and the `codewith-rust-build` skill for the Rust +workflow itself; this skill is only the remote-execution wrapper. Template/env +details discovered during setup live in [references/e2b-template-notes.md](references/e2b-template-notes.md) +and [references/backends.md](references/backends.md). + +## Source of truth = git (nothing is lost when a box expires) + +The sandbox is **ephemeral compute only**. Your code lives in the pushed git +branch. The box always does `git fetch origin ` + `git reset --hard` +(or fetches an exact `--sha`) before building. If a box expires, dies, or is +killed, **nothing is lost** — re-run against the same branch on a new box. +Push your branch before invoking. Uncommitted local changes can be layered on +with `--worktree ` (a `git diff HEAD` patch), but pushing is preferred. + +## Quick start + +```bash +# Installed skill location (invoke by absolute path; the script self-locates, so cwd doesn't matter): +cd ~/.claude/skills/codewith-e2b-build/scripts # (or .codewith/skills/codewith-e2b-build/scripts in the repo) +bun install # once: installs the e2b SDK locally (auto-runs if missing) + +# FULL suite (codex-core) on AWS Fargate — big RAM + 150 GB disk, no cap: +bun codewith-remote-build.mjs --backend aws --branch --crate codex-core --full + +# Fast scoped test on E2B (default backend), fresh box, auto-killed: +bun codewith-remote-build.mjs --branch --crate codex-core + +# Compile-only signal (any backend): +bun codewith-remote-build.mjs --backend aws --branch --crate codex-core --check +``` + +Auth per backend (never print secrets — reference by vault name only): +- **e2b:** `E2B_API_KEY` else `secrets get hasnaxyz/e2b/live/api_key --raw`. +- **daytona:** `secrets get hasnaxyz/daytona/live/{api_key,api_url} --raw`. +- **aws:** the named profile's creds (`--aws-profile`, default `hasna-tools`) — no key printed. + +## Invocation + +``` +codewith-e2b-build --branch --crate [--crate ...] [opts] +``` + +Required: +- `--branch ` — branch pushed to origin (source of truth). +- `--crate ` / `-p ` — crate(s) to build/test, e.g. `codex-core`. Repeatable. + Runs are **scoped**: never a full-workspace build unless you pass `--all`. + +Build mode (default `test` = `just test-fast-target`): +- `--check` — compile-only (`just check-fast`), fastest signal. +- `--full` — official gate (`just test`, includes bench-smoke). Use only when asked. +- `-- ` — pass extra args to the just recipe, e.g. `-- --test `. + +Sandbox lifecycle: +- `--sandbox ` — **reuse a running box** (keeps its target-dir cache warm → fast rebuilds). +- `--keep` — leave a fresh box running after the build (prints the reuse command). +- `--pause` — snapshot + pause the box after the build (resume later with a warm cache). +- `--kill` — force-kill even a reused box. +- `--timeout-min ` — box lifetime / keepalive window (default 90). +- `--template ` — E2B template (default `codewith-pr-drain`). + +Other: +- `--sha ` — build an exact commit instead of the branch tip. +- `--worktree ` — apply local `git diff HEAD` from this checkout over the branch. +- `--json` — print a final machine-readable `JSON {...}` result line. + +## What it returns + +Streams the live build log to stdout and to a log file, then prints a RESULT +block: `verdict` (PASS/FAIL), crates, branch, the nextest summary +(`N tests run: X passed, Y failed`), `exit` code, wall-clock, the `sandbox` id + +disposition, and the `log:` path. Exit code is 0 on PASS, 1 on FAIL. With +`--json` it also emits one JSON line for machines to parse. + +## Default template + toolchain env (the exit-127 fix) + +Default template `codewith-pr-drain` (8 vCPU / 8 GB). It carries the toolchain +under `/opt/rust`, a codewith checkout at `/opt/codewith` (with a warm cargo +registry cache — no crate re-downloads), and a persistent target at +`/opt/codewith-target`. + +The E2B command runner executes as the unprivileged `user` with a minimal PATH +and never inherits the Docker image ENV or rustup's default toolchain — that is +why a bare `rustc --version` returns exit 127. The wrapper fixes this by running +as `user: 'root'` with the toolchain env passed explicitly: + +``` +CARGO_HOME=/opt/rust/cargo RUSTUP_HOME=/opt/rust/rustup +CARGO_TARGET_DIR=/opt/codewith-target RUST_MIN_STACK=8388608 +PATH=/opt/rust/cargo/bin:/root/.bun/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +``` + +Running as root also fixes git "dubious ownership" (root owns `/opt/codewith`); +the wrapper adds `safe.directory` and does the fetch/checkout in place. + +## Longevity, reuse & speed + +- **Keepalive**: the box is created with a long `--timeout-min` (default 90) and + the wrapper refreshes the timeout every 30s (`Sandbox.setTimeout`) so long + builds never expire mid-run. Extend at any time by re-running with a larger + `--timeout-min` against `--sandbox `. +- **Reuse for speed**: the first build on a fresh box is a cold dev-profile + compile (~9 min for a `codex-core`-adjacent crate). Keep the box (`--keep`) + and pass `--sandbox ` to later builds — the warm `CARGO_TARGET_DIR` means + only changed crates recompile, so reruns are far faster. +- **Pause/resume**: `--pause` snapshots the box; resume later with `--sandbox ` + to get the warm cache back without paying to keep it running. + +## Parallel workers + +Each worker runs its own invocation (its own box, or its own reused box id) → +N concurrent remote builds, zero local Rust load. Mind E2B concurrent-sandbox +limits: **Hobby ≈ 20, Pro ≈ 100** concurrent sandboxes (add-on up to ~1,100). +Keep parallel worker count under the account cap; check current usage with +`Sandbox.list()` or `bunx @e2b/cli@latest sandbox list`. + +## Cleanup policy + +- Fresh box, no flag → **killed** after the build (safe default, no orphan cost). +- `--keep` / `--pause` → box survives for reuse. +- `--sandbox ` (reuse) → **left running** unless you pass `--kill`. +Kill a stray box any time: `bunx @e2b/cli@latest sandbox kill `. diff --git a/.codewith/skills/codewith-e2b-build/agents/openai.yaml b/.codewith/skills/codewith-e2b-build/agents/openai.yaml new file mode 100644 index 0000000000..492a20ce45 --- /dev/null +++ b/.codewith/skills/codewith-e2b-build/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Codewith E2B Build" + short_description: "Build and test Codewith Rust crates on a remote E2B sandbox (offload heavy builds)." + default_prompt: "Offload the Codewith Rust build/test to a remote E2B sandbox: fetch the pushed branch, run a scoped just test-fast for the changed crate(s), and report the verified pass/fail with the log path." diff --git a/.codewith/skills/codewith-e2b-build/references/e2b-template-notes.md b/.codewith/skills/codewith-e2b-build/references/e2b-template-notes.md new file mode 100644 index 0000000000..152c8d11f7 --- /dev/null +++ b/.codewith/skills/codewith-e2b-build/references/e2b-template-notes.md @@ -0,0 +1,76 @@ +# E2B template notes for Codewith Rust builds + +Facts discovered while building this skill. Update if templates change. + +## Templates evaluated + +| Template | vCPU/RAM | Toolchain visible to command runner | Codewith checkout | Warm target | Verdict | +|---|---|---|---|---|---| +| `codewith-pr-drain` | 8 / 8 GB | yes — `/opt/rust` (cargo, rustup, just, cargo-nextest) | `/opt/codewith` (+ warm cargo registry cache) | `/opt/codewith-target` (~1.3 GB, release profile) | **DEFAULT — chosen** | +| `open-pr-rust-8g` | 8 / 8 GB | no — nothing under `/opt` for the `user` account; toolchain/checkout not reachable by the command runner | not found by runner | none found | not usable as-is | +| `codewith-rust-validation-4g` | 4 / 4 GB | not probed in depth; only 4 vCPU (slower) | — | — | fallback / lower quota | + +`codewith-pr-drain` won because it is the only template that exposes a working +toolchain **and** a warm codewith checkout to the E2B command runner under `/opt`. + +## The exit-127 root cause and fix + +`sbx.commands.run('rustc --version')` returns **exit 127** because the E2B +command runner runs as the unprivileged user `user` with: + +- `PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin` (no `/opt/rust/cargo/bin`) +- `HOME=/home/user` (no rustup config; `RUSTUP_HOME`/`CARGO_HOME` unset) + +It does **not** inherit the Docker image `ENV`, and even a login shell +(`bash -lc`) doesn't help — rustup's default toolchain lives in +`/opt/rust/rustup/settings.toml`, invisible without `RUSTUP_HOME`. + +Fix: run commands as **root** with the toolchain env passed explicitly: + +``` +user: 'root' +CARGO_HOME=/opt/rust/cargo +RUSTUP_HOME=/opt/rust/rustup +CARGO_TARGET_DIR=/opt/codewith-target +RUST_MIN_STACK=8388608 +PATH=/opt/rust/cargo/bin:/root/.bun/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +``` + +With this env: `rustc 1.97.0`, `cargo 1.97.0`, `just 1.56.0`, +`cargo-nextest 0.9.140`, default toolchain `stable-x86_64-unknown-linux-gnu`. + +## Filesystem / permissions + +- `/opt/codewith` is **root-owned**; the `user` account cannot write it, and git + reports "dubious ownership". Running as root + `git config --global --add + safe.directory /opt/codewith` lets the box fetch/checkout in place. +- `/opt/codewith-target` is writable and is the persistent `CARGO_TARGET_DIR`. +- `/tmp` is user-writable — use it for uploaded patches (`--worktree`), then + `git apply` as root. + +## Build timing observed (small touched crate) + +- Crate `codex-image-generation-extension` via `just test-fast-target + /opt/codewith-target -p codex-image-generation-extension`. +- **Cold** dev-profile compile (warm cache was release-only, so debug rebuilt + the dep graph): ~9m14s compile, then 11 tests all PASS, ~9.4 min wall total. +- The cargo registry cache under `CARGO_HOME` is warm, so **no crate downloads**. +- Reusing the same box (`--sandbox `) keeps the debug target warm → later + rebuilds recompile only changed crates and are far faster. + +## E2B SDK primitives used + +- `Sandbox.create(template, { apiKey, timeoutMs })` — spin a box. +- `Sandbox.connect(id, { apiKey })` — reuse a running/paused box. +- `Sandbox.list({ apiKey })` — discover running/paused boxes. +- `sbx.commands.run(cmd, { user, envs, cwd, timeoutMs, onStdout, onStderr })`. +- `sbx.setTimeout(ms)` — keepalive / extend lifetime. +- `sbx.betaPause()` — snapshot+pause (warm resume via connect). +- `sbx.files.write(path, data)` — upload the `--worktree` patch (runs as `user`). +- `sbx.kill()` — destroy the box. + +## Concurrency limits + +E2B concurrent-sandbox caps: **Hobby ≈ 20, Pro ≈ 100** (add-on up to ~1,100). +Keep the number of parallel workers under the account cap. The Hasna `sandboxes` +CLI wrapper is broken (Hasna-cloud 400, bug 8da65aca) — use the E2B SDK directly. diff --git a/.codewith/skills/codewith-e2b-build/scripts/.gitignore b/.codewith/skills/codewith-e2b-build/scripts/.gitignore new file mode 100644 index 0000000000..a579b30a4d --- /dev/null +++ b/.codewith/skills/codewith-e2b-build/scripts/.gitignore @@ -0,0 +1,4 @@ +node_modules/ +bun.lock +bun.lockb +*.log diff --git a/.codewith/skills/codewith-e2b-build/scripts/codewith-e2b-build.mjs b/.codewith/skills/codewith-e2b-build/scripts/codewith-e2b-build.mjs new file mode 100644 index 0000000000..66bd77457c --- /dev/null +++ b/.codewith/skills/codewith-e2b-build/scripts/codewith-e2b-build.mjs @@ -0,0 +1,232 @@ +#!/usr/bin/env bun +// codewith-e2b-build: build/test a Codewith Rust crate on a remote E2B sandbox. +// +// Source of truth is git: the box does `git fetch origin && checkout`, +// so nothing is lost when a box expires. The box is ephemeral compute only. +// +// Usage: +// codewith-e2b-build --branch --crate [--crate ...] [opts] +// +// See ../SKILL.md for full docs. Run with --help for flags. + +import { spawnSync } from 'node:child_process'; +import { mkdirSync, createWriteStream } from 'node:fs'; +import { homedir } from 'node:os'; +import { join, dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const HERE = dirname(fileURLToPath(import.meta.url)); + +// --- Per-template environment (only codewith-pr-drain is validated end-to-end) --- +// The E2B command runner executes as unprivileged `user` with a minimal PATH and +// never inherits the Docker image ENV or rustup's default toolchain, so we pass the +// toolchain env explicitly and run as root (root also owns /opt/codewith for git). +const TEMPLATES = { + 'codewith-pr-drain': { + repo: '/opt/codewith', + target: '/opt/codewith-target', + envs: { + CARGO_HOME: '/opt/rust/cargo', + RUSTUP_HOME: '/opt/rust/rustup', + PATH: '/opt/rust/cargo/bin:/root/.bun/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', + RUST_MIN_STACK: '8388608', + }, + }, +}; +const DEFAULT_TEMPLATE = 'codewith-pr-drain'; + +function parseArgs(argv) { + const a = { + crates: [], template: DEFAULT_TEMPLATE, timeoutMin: 90, extra: [], + mode: 'test', // test | check | full + keep: false, kill: false, pause: false, all: false, json: false, + }; + for (let i = 0; i < argv.length; i++) { + const v = argv[i]; + const next = () => argv[++i]; + if (v === '--branch') a.branch = next(); + else if (v === '--sha') a.sha = next(); + else if (v === '--crate' || v === '-p') a.crates.push(next()); + else if (v === '--all') a.all = true; + else if (v === '--check') a.mode = 'check'; + else if (v === '--full') a.mode = 'full'; + else if (v === '--template') a.template = next(); + else if (v === '--sandbox') a.sandbox = next(); + else if (v === '--worktree') a.worktree = next(); + else if (v === '--repo') a.repo = next(); + else if (v === '--target') a.target = next(); + else if (v === '--timeout-min') a.timeoutMin = parseInt(next(), 10); + else if (v === '--keep') a.keep = true; + else if (v === '--kill') a.kill = true; + else if (v === '--pause') a.pause = true; + else if (v === '--json') a.json = true; + else if (v === '-h' || v === '--help') a.help = true; + else if (v === '--') { a.extra.push(...argv.slice(i + 1)); break; } + else a.extra.push(v); + } + return a; +} + +const HELP = `codewith-e2b-build — remote Codewith Rust build/test on E2B + +Required: + --branch git branch pushed to origin (source of truth) + --crate crate to build/test, e.g. codex-core (repeatable; or -p) + +Build mode (default: test): + --check compile-only (just check-fast), fastest signal + --full official gate (just test, includes bench-smoke) + -- extra args passed to the just recipe (e.g. --test ) + +Sandbox lifecycle: + --sandbox reuse a running box (keeps target-dir cache warm) + --keep leave a fresh box running after build (prints reuse cmd) + --pause snapshot+pause the box after build (warm resume later) + --kill force-kill even a reused box + --timeout-min box lifetime / keepalive window (default 90) + --template E2B template (default codewith-pr-drain) + +Other: + --sha build an exact commit instead of branch tip + --worktree apply local 'git diff HEAD' from this checkout over the branch + --json print a final machine-readable JSON result line + +Auth: reads E2B_API_KEY, else 'secrets get hasnaxyz/e2b/live/api_key --raw'. +Default cleanup: a fresh box is killed after the build unless --keep/--pause. +A reused (--sandbox) box is left running unless --kill.`; + +function getApiKey() { + if (process.env.E2B_API_KEY) return process.env.E2B_API_KEY; + const r = spawnSync('secrets', ['get', 'hasnaxyz/e2b/live/api_key', '--raw'], { encoding: 'utf8' }); + if (r.status === 0 && r.stdout.trim()) return r.stdout.trim(); + console.error('ERROR: no E2B_API_KEY and `secrets get` failed. Export E2B_API_KEY.'); + process.exit(2); +} + +async function main() { + const args = parseArgs(process.argv.slice(2)); + if (args.help) { console.log(HELP); return 0; } + if (!args.branch) { console.error('ERROR: --branch is required (source of truth = git).\n'); console.log(HELP); return 2; } + if (!args.crates.length && !args.all) { console.error('ERROR: pass at least one --crate (or --all to build the whole workspace).\n'); console.log(HELP); return 2; } + + const tpl = TEMPLATES[args.template] || TEMPLATES[DEFAULT_TEMPLATE]; + const repo = args.repo || tpl.repo; + const target = args.target || tpl.target; + const envs = { ...tpl.envs, CARGO_TARGET_DIR: target }; + const apiKey = getApiKey(); + const timeoutMs = args.timeoutMin * 60 * 1000; + + const { Sandbox } = await import('e2b').catch(async (e) => { + console.error('e2b SDK not found; installing into skill scripts dir…'); + const r = spawnSync('bun', ['install'], { cwd: HERE, stdio: 'inherit' }); + if (r.status !== 0) { console.error('bun install failed', String(e)); process.exit(2); } + return import('e2b'); + }); + + // log file + const logDir = join(homedir(), '.cache', 'codewith-e2b-build', 'logs'); + mkdirSync(logDir, { recursive: true }); + const stamp = new Date().toISOString().replace(/[:.]/g, '-'); + const logPath = join(logDir, `${stamp}-${args.branch.replace(/[\/]/g, '_')}.log`); + const logStream = createWriteStream(logPath); + const tail = []; + const sink = (d) => { process.stdout.write(d); logStream.write(d); tail.push(d); if (tail.length > 400) tail.shift(); }; + + const t0 = Date.now(); + let sbx, reused = false; + if (args.sandbox) { + sbx = await Sandbox.connect(args.sandbox, { apiKey }); + reused = true; + console.log(`## reusing sandbox ${sbx.sandboxId} (${args.template})`); + } else { + sbx = await Sandbox.create(args.template, { apiKey, timeoutMs }); + console.log(`## created sandbox ${sbx.sandboxId} (${args.template}) in ${((Date.now() - t0) / 1000).toFixed(1)}s`); + } + + // keepalive: keep extending the box lifetime so long builds never expire mid-run + const keepalive = setInterval(() => { sbx.setTimeout(timeoutMs).catch(() => {}); }, 30_000); + + const runOpts = { user: 'root', envs, cwd: repo, timeoutMs, onStdout: sink, onStderr: sink }; + const run = async (label, cmd, o = {}) => { + console.log(`\n=== ${label} ===`); + const s = Date.now(); + const r = await sbx.commands.run(cmd, { ...runOpts, ...o }).catch((e) => e.result || { exitCode: 1, error: String(e) }); + console.log(`\n-- ${label}: exit=${r.exitCode} (${((Date.now() - s) / 1000).toFixed(1)}s)`); + return r; + }; + + let result = { ok: false, exit: 1 }; + try { + // 1. Sync source of truth from git (branch or exact SHA). reset --hard makes it reproducible. + const ref = args.sha || `origin/${args.branch}`; + const fetchRef = args.sha ? args.sha : args.branch; + const gitCmd = + `git config --global --add safe.directory ${repo} && ` + + `git fetch origin ${fetchRef} && ` + + `git checkout -B ci-e2b ${args.sha ? args.sha : 'FETCH_HEAD'} && ` + + `git reset --hard ${args.sha ? args.sha : 'FETCH_HEAD'} && git log -1 --oneline`; + const g = await run('git sync', gitCmd); + if (g.exitCode !== 0) throw new Error('git sync failed'); + + // 2. Optional: apply an uncommitted local diff on top (branch push remains preferred). + if (args.worktree) { + const diff = spawnSync('git', ['-C', args.worktree, 'diff', 'HEAD'], { encoding: 'utf8', maxBuffer: 1 << 28 }); + if (diff.stdout && diff.stdout.trim()) { + await sbx.files.write('/tmp/e2b-local.patch', diff.stdout); // /tmp is user-writable; repo is root-owned + const ap = await run('apply worktree diff', `git apply --whitespace=nowarn /tmp/e2b-local.patch && echo applied`); + if (ap.exitCode !== 0) throw new Error('worktree diff failed to apply'); + } else { + console.log('## --worktree given but no local diff vs HEAD; using pushed branch as-is'); + } + } + + // 3. Scoped build/test. + const crateArgs = args.crates.map((c) => `-p ${c}`).join(' '); + let recipe; + if (args.mode === 'check') recipe = `just check-fast ${crateArgs}`; + else if (args.mode === 'full') recipe = `just test ${crateArgs}`; + else recipe = `just test-fast-target ${target} ${crateArgs}`; // default: fast + persistent warm target + const cmd = `${recipe} ${args.extra.join(' ')}`.trim(); + const b = await run(`build (${args.mode})`, cmd); + result = { ok: b.exitCode === 0, exit: b.exitCode }; + } catch (e) { + console.error('## error:', String(e)); + } finally { + clearInterval(keepalive); + logStream.end(); + } + + // Summarize + const joined = tail.join(''); + const m = joined.match(/Summary\s*\[[^\]]*\]\s*(\d+ tests? run:[^\n]*)/); + const summary = m ? m[1].trim() : (result.ok ? 'build/check passed' : 'no nextest summary (compile or test failure)'); + const verdict = result.ok ? 'PASS' : 'FAIL'; + const wall = ((Date.now() - t0) / 1000).toFixed(1); + + // Cleanup policy + let disposition; + if (args.pause) { await sbx.betaPause().catch(() => {}); disposition = `paused (resume: --sandbox ${sbx.sandboxId})`; } + else if (args.kill) { await sbx.kill(); disposition = 'killed'; } + else if (reused || args.keep) { await sbx.setTimeout(timeoutMs).catch(() => {}); disposition = `kept running (reuse: --sandbox ${sbx.sandboxId})`; } + else { await sbx.kill(); disposition = 'killed'; } + + console.log(`\n================ RESULT ================`); + console.log(`verdict: ${verdict}`); + console.log(`crates: ${args.crates.join(', ') || '(workspace)'}`); + console.log(`branch: ${args.branch}${args.sha ? ` @ ${args.sha}` : ''}`); + console.log(`summary: ${summary}`); + console.log(`exit: ${result.exit}`); + console.log(`wall: ${wall}s`); + console.log(`sandbox: ${sbx.sandboxId} (${disposition})`); + console.log(`log: ${logPath}`); + console.log(`=======================================`); + if (args.json) { + console.log('JSON ' + JSON.stringify({ + verdict, exit: result.exit, crates: args.crates, branch: args.branch, sha: args.sha || null, + summary, wallSeconds: Number(wall), sandboxId: sbx.sandboxId, disposition, logPath, template: args.template, + })); + } + return result.ok ? 0 : 1; +} + +main().then((c) => process.exit(c)).catch((e) => { console.error(e); process.exit(1); }); diff --git a/.codewith/skills/codewith-e2b-build/scripts/package.json b/.codewith/skills/codewith-e2b-build/scripts/package.json new file mode 100644 index 0000000000..f9af65f8e5 --- /dev/null +++ b/.codewith/skills/codewith-e2b-build/scripts/package.json @@ -0,0 +1,10 @@ +{ + "name": "codewith-e2b-build", + "private": true, + "type": "module", + "description": "Remote Codewith Rust build/test on an E2B sandbox (offload heavy Rust builds).", + "bin": { "codewith-e2b-build": "./codewith-e2b-build.mjs" }, + "dependencies": { + "e2b": "^2.32.0" + } +} diff --git a/CHANGELOG.md b/CHANGELOG.md index cb63f94d5f..58867ed3cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,29 @@ Known evidence gaps: ## [Unreleased] +## [0.1.81] - 2026-08-01 + +Tag: `rust-v0.1.81` +npm: +Compare: + +This release repairs durable background agents, which failed at spawn on every +new run in `0.1.80` and earlier. Any deployment that relies on background +agents outliving a single turn should upgrade directly to this version. + +### Fixed + +- Background agents: clamp the durable spawn-receipt lookback cursor to a floor + of `0`. `i64::saturating_sub` bounds the _type's_ range rather than clamping + toward zero, so subtracting the 20-event lookback window from a freshly + admitted run — which has only about four events at that point in its + lifecycle — produced a negative cursor. The event-cursor retention guard then + rejected that cursor as "compacted" even though nothing had been compacted, + and aborted the worker before it could start. Observed failures reported + `requested after seq -15, earliest retained seq is 1`. (#463) +- Auth: exit non-zero when an auth profile cannot be verified, so a failed + profile check is not mistaken for a successful one. (#462) + ## [0.1.80] - 2026-07-30 Tag: `rust-v0.1.80` diff --git a/codex-cli/package.json b/codex-cli/package.json index 06ad01ad7c..219fdc0f7d 100644 --- a/codex-cli/package.json +++ b/codex-cli/package.json @@ -1,6 +1,6 @@ { "name": "@hasna/codewith", - "version": "0.1.80", + "version": "0.1.81", "description": "Codewith command-line coding agent from Hasna.", "license": "Apache-2.0", "bin": { diff --git a/codex-rs/Cargo.lock b/codex-rs/Cargo.lock index 2c276e54f1..7c776ea844 100644 --- a/codex-rs/Cargo.lock +++ b/codex-rs/Cargo.lock @@ -276,7 +276,7 @@ checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" [[package]] name = "app_test_support" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "base64 0.22.1", @@ -1727,7 +1727,7 @@ dependencies = [ [[package]] name = "codex-agent-graph-store" -version = "0.1.80" +version = "0.1.81" dependencies = [ "async-trait", "codex-protocol", @@ -1742,7 +1742,7 @@ dependencies = [ [[package]] name = "codex-agent-identity" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "base64 0.22.1", @@ -1761,7 +1761,7 @@ dependencies = [ [[package]] name = "codex-analytics" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-app-server-protocol", "codex-git-utils", @@ -1781,7 +1781,7 @@ dependencies = [ [[package]] name = "codex-ansi-escape" -version = "0.1.80" +version = "0.1.81" dependencies = [ "ansi-to-tui", "ratatui", @@ -1790,7 +1790,7 @@ dependencies = [ [[package]] name = "codex-api" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "assert_matches", @@ -1827,7 +1827,7 @@ dependencies = [ [[package]] name = "codex-app-server" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "app_test_support", @@ -1925,7 +1925,7 @@ dependencies = [ [[package]] name = "codex-app-server-client" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-app-server", "codex-app-server-protocol", @@ -1952,7 +1952,7 @@ dependencies = [ [[package]] name = "codex-app-server-daemon" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "codex-app-server-protocol", @@ -1973,7 +1973,7 @@ dependencies = [ [[package]] name = "codex-app-server-protocol" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "clap", @@ -2000,7 +2000,7 @@ dependencies = [ [[package]] name = "codex-app-server-test-client" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "clap", @@ -2021,7 +2021,7 @@ dependencies = [ [[package]] name = "codex-app-server-transport" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "axum", @@ -2061,7 +2061,7 @@ dependencies = [ [[package]] name = "codex-apply-patch" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "assert_cmd", @@ -2080,7 +2080,7 @@ dependencies = [ [[package]] name = "codex-arg0" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "codex-apply-patch", @@ -2099,7 +2099,7 @@ dependencies = [ [[package]] name = "codex-async-utils" -version = "0.1.80" +version = "0.1.81" dependencies = [ "async-trait", "pretty_assertions", @@ -2109,7 +2109,7 @@ dependencies = [ [[package]] name = "codex-aws-auth" -version = "0.1.80" +version = "0.1.81" dependencies = [ "aws-config", "aws-credential-types", @@ -2124,7 +2124,7 @@ dependencies = [ [[package]] name = "codex-backend-client" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "codex-api", @@ -2141,7 +2141,7 @@ dependencies = [ [[package]] name = "codex-backend-openapi-models" -version = "0.1.80" +version = "0.1.81" dependencies = [ "serde", "serde_json", @@ -2150,7 +2150,7 @@ dependencies = [ [[package]] name = "codex-background-agent" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "codex-state", @@ -2165,7 +2165,7 @@ dependencies = [ [[package]] name = "codex-bwrap" -version = "0.1.80" +version = "0.1.81" dependencies = [ "cc", "libc", @@ -2174,7 +2174,7 @@ dependencies = [ [[package]] name = "codex-chatgpt" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "clap", @@ -2197,7 +2197,7 @@ dependencies = [ [[package]] name = "codex-cli" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "assert_cmd", @@ -2273,7 +2273,7 @@ dependencies = [ [[package]] name = "codex-client" -version = "0.1.80" +version = "0.1.81" dependencies = [ "async-trait", "bytes", @@ -2304,7 +2304,7 @@ dependencies = [ [[package]] name = "codex-cloud-config" -version = "0.1.80" +version = "0.1.81" dependencies = [ "base64 0.22.1", "chrono", @@ -2327,7 +2327,7 @@ dependencies = [ [[package]] name = "codex-cloud-tasks" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "async-trait", @@ -2360,7 +2360,7 @@ dependencies = [ [[package]] name = "codex-cloud-tasks-client" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "async-trait", @@ -2375,7 +2375,7 @@ dependencies = [ [[package]] name = "codex-cloud-tasks-mock-client" -version = "0.1.80" +version = "0.1.81" dependencies = [ "async-trait", "chrono", @@ -2385,7 +2385,7 @@ dependencies = [ [[package]] name = "codex-code-mode" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-protocol", "deno_core_icudata", @@ -2400,11 +2400,11 @@ dependencies = [ [[package]] name = "codex-collaboration-mode-templates" -version = "0.1.80" +version = "0.1.81" [[package]] name = "codex-config" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "async-trait", @@ -2452,7 +2452,7 @@ dependencies = [ [[package]] name = "codex-connectors" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "codex-app-server-protocol", @@ -2468,7 +2468,7 @@ dependencies = [ [[package]] name = "codex-context-fragments" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-protocol", "codex-utils-string", @@ -2476,7 +2476,7 @@ dependencies = [ [[package]] name = "codex-core" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "arc-swap", @@ -2606,7 +2606,7 @@ dependencies = [ [[package]] name = "codex-core-api" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-analytics", "codex-app-server-protocol", @@ -2625,7 +2625,7 @@ dependencies = [ [[package]] name = "codex-core-plugins" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "chrono", @@ -2665,7 +2665,7 @@ dependencies = [ [[package]] name = "codex-core-skills" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "codex-analytics", @@ -2697,7 +2697,7 @@ dependencies = [ [[package]] name = "codex-exec" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "assert_cmd", @@ -2743,7 +2743,7 @@ dependencies = [ [[package]] name = "codex-exec-server" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "arc-swap", @@ -2786,7 +2786,7 @@ dependencies = [ [[package]] name = "codex-execpolicy" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "clap", @@ -2804,7 +2804,7 @@ dependencies = [ [[package]] name = "codex-execpolicy-legacy" -version = "0.1.80" +version = "0.1.81" dependencies = [ "allocative", "anyhow", @@ -2824,7 +2824,7 @@ dependencies = [ [[package]] name = "codex-experimental-api-macros" -version = "0.1.80" +version = "0.1.81" dependencies = [ "proc-macro2", "quote", @@ -2833,7 +2833,7 @@ dependencies = [ [[package]] name = "codex-extension-api" -version = "0.1.80" +version = "0.1.81" dependencies = [ "async-trait", "codex-context-fragments", @@ -2843,7 +2843,7 @@ dependencies = [ [[package]] name = "codex-external-agent" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-protocol", "codex-sandboxing", @@ -2860,7 +2860,7 @@ dependencies = [ [[package]] name = "codex-external-agent-migration" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-hooks", "pretty_assertions", @@ -2872,7 +2872,7 @@ dependencies = [ [[package]] name = "codex-external-agent-sessions" -version = "0.1.80" +version = "0.1.81" dependencies = [ "chrono", "codex-app-server-protocol", @@ -2886,7 +2886,7 @@ dependencies = [ [[package]] name = "codex-features" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-otel", "codex-protocol", @@ -2899,7 +2899,7 @@ dependencies = [ [[package]] name = "codex-feedback" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "codex-login", @@ -2911,7 +2911,7 @@ dependencies = [ [[package]] name = "codex-file-search" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "clap", @@ -2927,7 +2927,7 @@ dependencies = [ [[package]] name = "codex-file-system" -version = "0.1.80" +version = "0.1.81" dependencies = [ "async-trait", "codex-protocol", @@ -2937,7 +2937,7 @@ dependencies = [ [[package]] name = "codex-file-watcher" -version = "0.1.80" +version = "0.1.81" dependencies = [ "notify", "pretty_assertions", @@ -2948,7 +2948,7 @@ dependencies = [ [[package]] name = "codex-git-utils" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "chrono", @@ -2972,7 +2972,7 @@ dependencies = [ [[package]] name = "codex-goal-extension" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "async-trait", @@ -2996,7 +2996,7 @@ dependencies = [ [[package]] name = "codex-guardian" -version = "0.1.80" +version = "0.1.81" dependencies = [ "async-trait", "codex-core", @@ -3006,7 +3006,7 @@ dependencies = [ [[package]] name = "codex-hooks" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "chrono", @@ -3030,7 +3030,7 @@ dependencies = [ [[package]] name = "codex-image-generation-extension" -version = "0.1.80" +version = "0.1.81" dependencies = [ "async-trait", "codex-api", @@ -3050,7 +3050,7 @@ dependencies = [ [[package]] name = "codex-install-context" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-utils-absolute-path", "codex-utils-home-dir", @@ -3060,7 +3060,7 @@ dependencies = [ [[package]] name = "codex-keyring-store" -version = "0.1.80" +version = "0.1.81" dependencies = [ "keyring", "tracing", @@ -3068,14 +3068,14 @@ dependencies = [ [[package]] name = "codex-known-provider-models" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-protocol", ] [[package]] name = "codex-linux-sandbox" -version = "0.1.80" +version = "0.1.81" dependencies = [ "clap", "codex-core", @@ -3100,7 +3100,7 @@ dependencies = [ [[package]] name = "codex-lmstudio" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-core", "codex-model-provider-info", @@ -3114,7 +3114,7 @@ dependencies = [ [[package]] name = "codex-login" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "async-trait", @@ -3156,7 +3156,7 @@ dependencies = [ [[package]] name = "codex-mcp" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "async-channel", @@ -3188,7 +3188,7 @@ dependencies = [ [[package]] name = "codex-mcp-server" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "codex-arg0", @@ -3221,7 +3221,7 @@ dependencies = [ [[package]] name = "codex-memories-extension" -version = "0.1.80" +version = "0.1.81" dependencies = [ "async-trait", "codex-core", @@ -3243,7 +3243,7 @@ dependencies = [ [[package]] name = "codex-memories-read" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-protocol", "codex-shell-command", @@ -3253,7 +3253,7 @@ dependencies = [ [[package]] name = "codex-memories-write" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "chrono", @@ -3288,7 +3288,7 @@ dependencies = [ [[package]] name = "codex-message-history" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-config", "memchr", @@ -3302,7 +3302,7 @@ dependencies = [ [[package]] name = "codex-model-provider" -version = "0.1.80" +version = "0.1.81" dependencies = [ "async-trait", "codex-agent-identity", @@ -3328,7 +3328,7 @@ dependencies = [ [[package]] name = "codex-model-provider-info" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-api", "codex-app-server-protocol", @@ -3345,7 +3345,7 @@ dependencies = [ [[package]] name = "codex-models-manager" -version = "0.1.80" +version = "0.1.81" dependencies = [ "async-trait", "chrono", @@ -3367,7 +3367,7 @@ dependencies = [ [[package]] name = "codex-network-proxy" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "async-trait", @@ -3401,7 +3401,7 @@ dependencies = [ [[package]] name = "codex-ollama" -version = "0.1.80" +version = "0.1.81" dependencies = [ "assert_matches", "async-stream", @@ -3421,7 +3421,7 @@ dependencies = [ [[package]] name = "codex-otel" -version = "0.1.80" +version = "0.1.81" dependencies = [ "chrono", "codex-api", @@ -3453,7 +3453,7 @@ dependencies = [ [[package]] name = "codex-plugin" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-config", "codex-utils-absolute-path", @@ -3463,7 +3463,7 @@ dependencies = [ [[package]] name = "codex-privacy-filter" -version = "0.1.80" +version = "0.1.81" dependencies = [ "pretty_assertions", "serde", @@ -3473,7 +3473,7 @@ dependencies = [ [[package]] name = "codex-process-hardening" -version = "0.1.80" +version = "0.1.81" dependencies = [ "libc", "pretty_assertions", @@ -3481,7 +3481,7 @@ dependencies = [ [[package]] name = "codex-prompts" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "codex-context-fragments", @@ -3495,7 +3495,7 @@ dependencies = [ [[package]] name = "codex-protocol" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "chardetng", @@ -3535,7 +3535,7 @@ dependencies = [ [[package]] name = "codex-realtime-webrtc" -version = "0.1.80" +version = "0.1.81" dependencies = [ "libwebrtc", "thiserror 2.0.18", @@ -3544,7 +3544,7 @@ dependencies = [ [[package]] name = "codex-response-debug-context" -version = "0.1.80" +version = "0.1.81" dependencies = [ "base64 0.22.1", "codex-api", @@ -3555,7 +3555,7 @@ dependencies = [ [[package]] name = "codex-responses-api-proxy" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "clap", @@ -3572,7 +3572,7 @@ dependencies = [ [[package]] name = "codex-rmcp-client" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "async-trait", @@ -3613,7 +3613,7 @@ dependencies = [ [[package]] name = "codex-rollout" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "async-trait", @@ -3639,7 +3639,7 @@ dependencies = [ [[package]] name = "codex-rollout-trace" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "codex-code-mode", @@ -3655,7 +3655,7 @@ dependencies = [ [[package]] name = "codex-sandboxing" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "async-trait", @@ -3676,7 +3676,7 @@ dependencies = [ [[package]] name = "codex-secrets" -version = "0.1.80" +version = "0.1.81" dependencies = [ "age", "anyhow", @@ -3697,7 +3697,7 @@ dependencies = [ [[package]] name = "codex-shell-command" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "base64 0.22.1", @@ -3718,7 +3718,7 @@ dependencies = [ [[package]] name = "codex-shell-escalation" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "async-trait", @@ -3739,7 +3739,7 @@ dependencies = [ [[package]] name = "codex-skills" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-utils-absolute-path", "include_dir", @@ -3748,7 +3748,7 @@ dependencies = [ [[package]] name = "codex-skills-extension" -version = "0.1.80" +version = "0.1.81" dependencies = [ "async-trait", "codex-core", @@ -3767,7 +3767,7 @@ dependencies = [ [[package]] name = "codex-state" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "chrono", @@ -3796,7 +3796,7 @@ dependencies = [ [[package]] name = "codex-stdio-to-uds" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "codex-uds", @@ -3808,7 +3808,7 @@ dependencies = [ [[package]] name = "codex-terminal-detection" -version = "0.1.80" +version = "0.1.81" dependencies = [ "pretty_assertions", "tracing", @@ -3816,7 +3816,7 @@ dependencies = [ [[package]] name = "codex-test-binary-support" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-arg0", "tempfile", @@ -3824,7 +3824,7 @@ dependencies = [ [[package]] name = "codex-thread-manager-sample" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "clap", @@ -3835,7 +3835,7 @@ dependencies = [ [[package]] name = "codex-thread-store" -version = "0.1.80" +version = "0.1.81" dependencies = [ "async-trait", "chrono", @@ -3859,11 +3859,11 @@ dependencies = [ [[package]] name = "codex-tool-contracts" -version = "0.1.80" +version = "0.1.81" [[package]] name = "codex-tools" -version = "0.1.80" +version = "0.1.81" dependencies = [ "async-trait", "codex-app-server-protocol", @@ -3888,7 +3888,7 @@ dependencies = [ [[package]] name = "codex-tui" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "arboard", @@ -4001,7 +4001,7 @@ dependencies = [ [[package]] name = "codex-uds" -version = "0.1.80" +version = "0.1.81" dependencies = [ "async-io", "pretty_assertions", @@ -4013,7 +4013,7 @@ dependencies = [ [[package]] name = "codex-utils-absolute-path" -version = "0.1.80" +version = "0.1.81" dependencies = [ "dirs", "dunce", @@ -4027,14 +4027,14 @@ dependencies = [ [[package]] name = "codex-utils-approval-presets" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-protocol", ] [[package]] name = "codex-utils-cache" -version = "0.1.80" +version = "0.1.81" dependencies = [ "lru 0.16.3", "sha1 0.11.0", @@ -4043,7 +4043,7 @@ dependencies = [ [[package]] name = "codex-utils-cargo-bin" -version = "0.1.80" +version = "0.1.81" dependencies = [ "assert_cmd", "runfiles", @@ -4052,7 +4052,7 @@ dependencies = [ [[package]] name = "codex-utils-cli" -version = "0.1.80" +version = "0.1.81" dependencies = [ "clap", "codex-protocol", @@ -4064,15 +4064,15 @@ dependencies = [ [[package]] name = "codex-utils-elapsed" -version = "0.1.80" +version = "0.1.81" [[package]] name = "codex-utils-fuzzy-match" -version = "0.1.80" +version = "0.1.81" [[package]] name = "codex-utils-home-dir" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-utils-absolute-path", "dirs", @@ -4082,7 +4082,7 @@ dependencies = [ [[package]] name = "codex-utils-image" -version = "0.1.80" +version = "0.1.81" dependencies = [ "base64 0.22.1", "codex-utils-cache", @@ -4095,7 +4095,7 @@ dependencies = [ [[package]] name = "codex-utils-json-to-toml" -version = "0.1.80" +version = "0.1.81" dependencies = [ "pretty_assertions", "serde_json", @@ -4104,7 +4104,7 @@ dependencies = [ [[package]] name = "codex-utils-oss" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-core", "codex-lmstudio", @@ -4114,7 +4114,7 @@ dependencies = [ [[package]] name = "codex-utils-output-truncation" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-protocol", "codex-utils-string", @@ -4123,7 +4123,7 @@ dependencies = [ [[package]] name = "codex-utils-path" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-utils-absolute-path", "dunce", @@ -4133,7 +4133,7 @@ dependencies = [ [[package]] name = "codex-utils-plugins" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-exec-server", "codex-login", @@ -4146,7 +4146,7 @@ dependencies = [ [[package]] name = "codex-utils-pty" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "filedescriptor", @@ -4162,7 +4162,7 @@ dependencies = [ [[package]] name = "codex-utils-readiness" -version = "0.1.80" +version = "0.1.81" dependencies = [ "assert_matches", "async-trait", @@ -4173,14 +4173,14 @@ dependencies = [ [[package]] name = "codex-utils-rustls-provider" -version = "0.1.80" +version = "0.1.81" dependencies = [ "rustls", ] [[package]] name = "codex-utils-sandbox-summary" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-core", "codex-model-provider-info", @@ -4191,7 +4191,7 @@ dependencies = [ [[package]] name = "codex-utils-sleep-inhibitor" -version = "0.1.80" +version = "0.1.81" dependencies = [ "core-foundation 0.9.4", "libc", @@ -4201,14 +4201,14 @@ dependencies = [ [[package]] name = "codex-utils-stream-parser" -version = "0.1.80" +version = "0.1.81" dependencies = [ "pretty_assertions", ] [[package]] name = "codex-utils-string" -version = "0.1.80" +version = "0.1.81" dependencies = [ "pretty_assertions", "regex-lite", @@ -4218,14 +4218,14 @@ dependencies = [ [[package]] name = "codex-utils-template" -version = "0.1.80" +version = "0.1.81" dependencies = [ "pretty_assertions", ] [[package]] name = "codex-v8-poc" -version = "0.1.80" +version = "0.1.81" dependencies = [ "pretty_assertions", "v8", @@ -4233,7 +4233,7 @@ dependencies = [ [[package]] name = "codex-web-search-extension" -version = "0.1.80" +version = "0.1.81" dependencies = [ "async-trait", "codex-api", @@ -4253,7 +4253,7 @@ dependencies = [ [[package]] name = "codex-windows-sandbox" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "base64 0.22.1", @@ -4279,7 +4279,7 @@ dependencies = [ [[package]] name = "codex-workflows" -version = "0.1.80" +version = "0.1.81" dependencies = [ "codex-prompts", "pretty_assertions", @@ -4290,7 +4290,7 @@ dependencies = [ [[package]] name = "codex-workflows-extension" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "async-trait", @@ -4554,7 +4554,7 @@ dependencies = [ [[package]] name = "core_test_support" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "assert_cmd", @@ -8991,7 +8991,7 @@ dependencies = [ [[package]] name = "mcp_test_support" -version = "0.1.80" +version = "0.1.81" dependencies = [ "anyhow", "codex-login", diff --git a/codex-rs/Cargo.toml b/codex-rs/Cargo.toml index 5897d807f7..1e793bb4e7 100644 --- a/codex-rs/Cargo.toml +++ b/codex-rs/Cargo.toml @@ -127,7 +127,7 @@ members = [ resolver = "2" [workspace.package] -version = "0.1.80" +version = "0.1.81" # Track the edition for all workspace crates in one place. Individual # crates can still override this value, but keeping it here means new # crates created with `cargo new -w ...` automatically inherit the 2024