Goose has changed the engine behind a useful agent trick: writing a short program that calls several tools, works through their results and returns only what the model needs next. An October 16 change in aaif-goose/goose replaces PCTX and its Deno/V8 dependencies with a Goose-owned integration of the Boa JavaScript engine. Tool discovery and batching remain.
That separates a capability from the machinery previously used to deliver it. An agent can look up several records, compare them and prepare a result without bringing each intermediate answer back through the model. Goose is keeping that pattern while shrinking the execution environment around it.
The change is merged development work. The latest stable release checked for this article, v1.55.0, was published later on October 16, but its dependency file still uses PCTX. A release timestamp after a merge does not mean the release contains it.
A smaller job for the interpreter
In September, we reported a lean Goose build that left optional features—including code mode—out. This change takes a different route: it retains code mode’s tool-composition pattern and replaces the machinery underneath. Its interface changes too, from generated TypeScript functions to JavaScript calling tools by their exact names.
Goose adopted PCTX on February 3. Its code mode already discovered tools on demand and chained their outputs. October’s change is therefore a replacement of the implementation, not the invention of batched tool use.
The new interface has three steps: list the available tools, inspect the unfamiliar ones, then execute JavaScript. Discovery returns the tools’ original JSON schemas—the structured descriptions of their inputs and outputs—instead of turning those descriptions into TypeScript definitions. The script calls a tool by its exact name through tools.call.
Imagine checking stock for several orders. A script can request independent records together, compare the replies locally and return a short list of shortages. The model need not read every unfiltered record to decide what to do next. That is an example of the retained pattern, not a task we ran. In the new implementation, independent calls can overlap through Promise.all; an upstream test requires two callbacks to start before either can complete.
The interpreter itself has no direct filesystem, shell, network or package access. External work goes through discovered tools and Goose’s existing dispatch path, including its permission handling. A new context is created for each execution, so JavaScript variables do not persist into the next call. This is a deliberately limited tool-composition environment, not a general Node.js workspace.
The removed machinery is the clearest gain
The dependency change reaches beyond the interpreter. The patch deletes a V8 cache-repair script and its CI callers, removes V8-specific Nix fetching, and replaces RISC-V vendoring and patching instructions with a much shorter build guide. Those are concrete maintenance obligations removed from this path. They do not establish that every remaining platform build works: the author explicitly says Nix and RISC-V builds were not run.
The pull request also reports a smaller matched debug binary and better token and elapsed-time figures in a small comparison: three synthetic workflows, repeated twice per runtime. The author observed no quality regression. But the schema presentation and calling instructions changed along with the engine, so those observations cannot isolate a Boa speed advantage. The old runtime’s one failed trial had reached the correct fulfillment state but ran out of turns before delivering its final answer.
Nor does a smaller runtime automatically mean stronger containment. The merged code bounds instructions, output and concurrent workers, but a review raised the absence of a heap-allocation limit. The author left that issue for later work. Synchronous engine operations can also continue after the caller’s cancellation wait ends. We inspected the implementation and test definitions; we did not execute Goose, reproduce the comparison or audit the engine’s security.
What an upgrade will change
Recipe authors will need to distinguish saved history from executable instructions. The new entry point is execute_javascript, replacing execute_typescript. Instructions that rely on generated namespaces or PCTX-specific facilities need revision. Goose can still display saved TypeScript calls, but display compatibility does not preserve the old execution interface. PCTX’s own Bash tool is removed; the ordinary developer shell remains available through Goose.
For builders, the larger lesson is a practical design choice: the language engine can do a narrow job while the surrounding agent owns tools, permissions and external effects. Goose has made that separation more explicit. The next useful receipt is a containing release completing a real workflow across the migration, with the same acceptance criteria and an interruption along the way. That would show how much of the promised simplification reaches the person using it.