21 Commits
Author SHA1 Message Date
Pranit ae687a4879 Merge pull request #1425 from vercel-labs/fazxes/encode-inline-fuzz-seeds
Encode inline fuzz seeds the way the tests read them
2026-10-23 11:56:30 -04:00
Pranit a7ad972621 Encode inline fuzz seeds the way the tests read them
A fuzz test reads its input through std.testing.Smith, which reads a slice
as a little-endian u32 length and then that many bytes. The inline seeds of
the older fuzz tests were plain strings, so each lost its first four bytes
to the length: "one" replayed as an empty input, and "split every field"
read "spli" as a length. The fx tests now wrap their seeds in
fuzz_seed.slices, which writes that length first. The session manager
imports nothing from fx, so its two targets keep their seeds as saved
inputs in tests/fuzz/corpus.
2026-10-22 18:44:46 -04:00
Pranit cb203d19b0 Let ThreadSanitizer see pages that mremap releases
ThreadSanitizer does not intercept mremap, so when std.heap.PageAllocator shrinks or moves a block on Linux, the released pages keep their access history and the next thread to use those addresses appears to race with the one that released them. That produced the race reports in the MCP HTTP large-answer test. Sanitized x86_64 and aarch64 Linux builds now link an mremap that makes the same change with munmap, and with mmap, a copy, and munmap when a block moves.
2026-10-22 17:04:04 -04:00
Pranit 4625e465c6 Stop the build with a message when fuzz setup runs out of memory
The fuzz corpus setup in `build.zig` reports a failed allocation with `std.process.fatal`, as it does every other failure, instead of panicking.
2026-10-22 13:01:27 -04:00
Pranit 3bdf08a8fa Keep frame pointers and symbols in sanitized builds 2026-10-22 11:52:55 -04:00
Pranit 37e79dcdd5 Add a nightly ThreadSanitizer run of the unit tests 2026-10-22 11:52:55 -04:00
Pranit 7ae4d4107b Add a fuzz build step, nightly fuzzing, and shell parity tests
- `zig build fuzz` builds only the fuzz tests listed in `tests/fuzz/targets.json`. `-Dfuzz-target=<name>` picks one target, and `--fuzz=N` searches for new failing inputs.
- `zig build test` replays each target's saved inputs from `tests/fuzz/corpus/<target>/` on every pull request.
- A nightly Fuzz workflow fuzzes every target for about 20 minutes, uploads any failing input, and opens or updates an issue for that target. A pull request that changes the fuzzing setup fuzzes each target for two minutes.
- The shell parity tests run every command form fx runs without review through sh, dash, bash, and zsh, with and without `extendedglob`, and check that each one runs exactly as fx parsed it. The `shell_parity` target checks generated commands the same way.
2026-10-22 11:52:23 -04:00
Pranit fb57a68063 Merge branch 'fazxes/update-mcp-tla-models' into fazxes/remove-mcp-v1
# Conflicts:
#	src/builtins/tools.zig
2026-10-21 03:47:44 -04:00
Pranit 4b0818343a Run every unit test in zig build test
Three host files, the approval review benchmark, and the session manager's
hooks-only tests were never compiled into a `zig build test` binary. Their
35 tests never ran, locally or in CI, and 5 more always skipped.

- The host files that only the browser build uses join `main.zig`'s test
  block, next to `js_host_workspace.zig`.
- The approval review benchmark's tests join the `test` step, as the
  activity benchmark's already do.
- A second session manager test build, with its fault and trace hooks
  compiled in, joins `test` and `test-session-manager`. Shipped artifacts
  still leave the hooks out.
2026-10-20 18:20:34 -04:00
Pranit ba0ea4a9a9 Remove the MCP v1 client
Every MCP server now runs on the engine in src/mcp. The v1 client is gone,
with its stdio dispatcher, feature catalogs, HTTP+SSE transport and Docker
cleanup. The config parsing and shared contracts the new host still uses stay
in src/core/mcp.

Also:
- An mcp.json with both "mcp" and "mcpServers" notes each server it skips.
- An ACP session that names two MCP servers alike is refused at session/new.
- A server an editor supplies gets the editor's sign-in hint.
- /mcp logout says a server wasn't signed in when no login was saved.
2026-10-17 16:51:12 -04:00
Pranit ee3cc485e0 Keep CLI-only code out of the libfx builds
- `libfx.node` and `fx-core.wasm` no longer contain the ACP E2E test controls, which wrote marker files and waited on a release file when their `FX_E2E_ACP_PROMPT_*` variables were set. The fx binary keeps them for its E2E tests.
- The libfx builds no longer compile `src/main.zig`. The terminal UI reads the version from the build options, which `build.zig` takes from the same `pub const version` in `src/main.zig`, so a change to the CLI's composition root can no longer break a libfx build.
2026-10-15 20:36:10 -04:00
Pranit 01f2683f7e Read the app version through the build root directory
Open src/main.zig relative to the build root handle instead of joining
the root path by hand, so reading the version needs no separate
allocation failure path.
2026-10-06 03:37:47 -04:00
Pranit f63adfe0ff Build the MCP dispatcher driver before its E2E tests
Zig 0.17 compiles its build runner the first time zig build runs
against an empty cache, which takes about 50 seconds. The macOS
platform E2E job starts without a Zig cache, so the first MCP test
that ran the dispatcher driver timed out and was killed before the
cache was written, leaving every later test cold as well.

Build the driver once in a beforeAll with a longer timeout through a
new build-only step. The MCP auth tests also keep Zig's global cache
when they isolate HOME, so local runs stop rebuilding it per test.
2026-10-05 22:13:28 -04:00
Pranit b1d515851a Upgrade to Zig 0.17
Build fx with Zig 0.17.0. build.zig.zon requires it, every workflow
installs it, and PGSO qualification uses LLVM 22.1.8 to match.

Zig 0.17 removes `**`, `errdefer |err|`, `@cImport`, and the old type
info field lists. The source moves to `@splat`, a comptime
`text_utils.repeat` helper, split cleanup functions, and the new
field_names and field_types arrays. The Node-API addon translates
node_api.h with a build step. Test fakes checked with `@hasDecl` become
pub, because `@hasDecl` no longer sees private declarations.

`zig build test` gives the test binary its fx and source paths through
a generated test_paths module, since the build no longer exposes install
paths for environment variables.

Zig 0.17's SafeAllocator grows a small allocation in place only when it
sits at the end of a bucket, and buckets are never reused, so an
allocation-failure sweep could count a different number of allocations
on each run. Sweeps and allocation-count tests now use
testing_allocator.no_resize, which never resizes in place.

allocRemaining now treats its limit as inclusive. readFileToEnd keeps
rejecting a file of exactly max_bytes by reading through
appendRemaining. Direct allocRemaining callers for remote responses now
accept a body exactly at their limit.

Zig 0.17's memset stores a full vector per iteration, so the Linux
memset replacement is removed. macOS release binaries now require macOS
15, Zig 0.17's default minimum.
2026-10-05 19:44:53 -04:00
Pranit 73559f73db Add an experimental v2 session store to fx ask
- Add --sessions-v2 to fx ask (before or after ask) and FX_SESSIONS_V2=1. With either, fx ask saves the session as an append-only log in ~/.fx/sessions/v2/<id>/.
- Resume those sessions with --resume last and --resume-id; they are only visible with the flag on. --no-save still writes nothing.
- Save each finished exchange while the turn runs. After a crash, the prompt and finished tool calls are kept, and the next resume marks that turn interrupted.
- Store tool output side files in ~/.fx/session-files/<id>/, owner-only like the log.
- On resume, cut a half-written last line. A damaged line elsewhere stops the resume with InvalidSessionFormat and leaves the file unchanged. A session another process holds fails with SessionBusy.
- Report a missing session with the current store's errors, NoSavedSessions and SessionNotFound.
- Recover profile usage from v2 sessions after a crash, as for current sessions.
- Leave subagents off in fx ask while the flag is on.
- Keep the current store as the default; it now ignores the v2 folder.
2026-09-30 17:47:36 -04:00
Pranit 071a574486 Rework MCP startup, discovery, and results 2026-09-04 06:25:48 -04:00
Pranit ae50ab1ff5 Wake libfx native runtimes without polling 2026-09-04 00:52:01 -04:00
Pranit 293dfd07f7 Report Node header discovery failures cleanly
Use build-time fatal diagnostics when automatic Node header discovery cannot run or allocate its result. This keeps expected configuration failures out of panic paths.
2026-08-16 08:31:14 -04:00
Pranit 09deb7f30d Embed fx in Node.js
Add a Node-API addon for running headless fx agents inside Node.js while keeping fetch streaming and cancellation in JavaScript.

Expose Node and browser package entry points with WebAssembly fallback and terminal support. Build, test, and package native macOS/Linux addons alongside ReleaseSmall WebAssembly artifacts.
2026-08-16 04:06:49 -04:00
Pranit d0dff24b1a build: expose opt-in LLVM bitcode artifacts 2026-08-15 03:38:34 -04:00
Pranit 439f83ce94 Initial commit 2026-08-11 17:29:04 -04:00