A coding agent is a control loop that lets a model observe a codebase, request actions, learn from their results, and stop with evidence.

This article explains how I built Froe, a small coding agent. The goal was to build a genuinely usable implementation whose complete behavior can still be understood from the repository.

Froe has six actions, one production model adapter, a run loop, and a command sandbox. It can inspect files, edit code, run checks, and hold an interactive conversation. It also records enough structured information to explain what happened after a run.

The control loop

The smallest useful coding agent has four participants:

  1. A user supplies a task.
  2. A model decides what information or action it needs next.
  3. A runtime executes that action and returns a structured result.
  4. The loop repeats until the model finishes or the host stops it.

In Froe, that loop lives in src/run.ts.

Give the model a small action vocabulary

Froe exposes six actions from src/action-runtime.ts:

Action Purpose
list_files List one directory level.
read_file Read a range from a UTF-8 text file.
search Find literal, case-sensitive text in the workspace.
apply_patch Create, replace, or delete text through exact-match changes.
run_command Run one executable with an argument array.
finish End the run with an outcome and verification records.

This vocabulary is enough for a practical investigation and edit cycle:

list -> read -> search -> patch -> validate -> finish

Running Froe

Froe requires Node.js 22 or later. Command execution currently requires macOS.

Install the published package:

npm install --global @xfq/froe

Then run it inside a repository:

cd /path/to/project
froe "Fix the failing parser tests"

Run froe without a task to start an interactive conversation. On the first interactive run, it asks for an OpenAI API key and an OpenAI-compatible base URL, then saves them in an owner-readable credential file under the user’s configuration directory.

To work on Froe itself:

git clone https://github.com/xfq/froe.git
cd froe
pnpm install
pnpm typecheck
pnpm test
pnpm build

What I would keep if the project grew

Froe’s first release deliberately omits persisted conversation resume, multiple inference providers, and non-macOS command sandboxes. Those features may be useful, but adding them before the core behavior was coherent would have made the implementation harder to inspect.

That structure leaves clear extension points. A second provider can implement the model interface. A Linux sandbox can implement the command sandbox interface. Stronger verification can be added at the finish boundary. A resume protocol can persist provider-neutral conversation state once its privacy and compatibility rules are defined.