Skip to content

Christoph/iterator

Repository files navigation

iterator

Iterate on code with AI — one reviewable feature at a time.

Plan → Features → Red tests → Implement → Review, driven from a browser dashboard. Every piece of state is plain markdown in an Open Knowledge Format (OKF) bundle you can read, edit, and diff without any tooling.

The ideaThe flowThe memory bundleInstallationConfiguration

The /iterator hub — plan, feature cards with red/green test badges, and the dependency graph

The /iterator hub: the whole plan at a glance — every feature with its status, size, and 🔴🟢 test badges — and buttons that dispatch each step.


The idea

Classical diff tools group changes by file. A developer's mental model is organized around what changed and why — a unit of work usually touches several files at once. iterator makes the feature the primary unit: a meaningful, vertical slice of implementation (code and its tests) of roughly 200 lines, in dependency order. Review-effectiveness research shows defect detection degrades past ~200–400 changed lines, so ~200 is a conservative, reviewable default.

You still lean on AI for planning and implementation — but the unit of change stays human-reviewable, dependency-ordered, and durable across sessions:

  • The browser UI is the control plane. One local server renders every step's view — dashboard, plan review, feature breakdown, test plan, diff review — on one fixed port. No clipboard, no temp files.
  • Everything mechanical is deterministic code, not prompt instructions. gather.mjs computes every step's payload (bundle state, parsed git diffs mapped to features, test-runner detection); write.mjs owns every bundle write (frontmatter, timestamps, topological indexes, the update log, cycle/reference validation). The model only supplies the semantic text: plan prose, feature descriptions, test cases, and the code itself.
  • All persistent state is an OKF v0.1 bundle in your repo's memory/ directory — self-describing markdown with YAML frontmatter. Nothing is locked away in a database or a proprietary format.

Inspired by Plannotator.

The flow

/iterator            dashboard hub — pick a feature, press Test / Implement / Review
      ▼
/iterator-plan       create/revise the plan               → memory/plan.md
      │  (accept auto-continues)
      ▼
/iterator-feature    break the plan into features         → memory/features/<slug>.md
      │
      ├─ (optional) /iterator-test   write RED tests from the feature's contract
      ▼
/iterator-implement  build the dependency-ready wave, drive tests GREEN,
      │              auto-start one review over the wave
      ▼
/iterator-review     feature-vs-git-diff review           → outcome recorded in the feature file

Plan in the browser, not in the scrollback

Plan review — click-to-edit sections, per-section comments, editable dependency chips

/iterator-plan turns a goal into a plan you review in the browser: click-to-edit markdown sections, per-section comments, editable dependency chips. On accept it writes the memory/ bundle and auto-continues into the feature breakdown.

Features, cut as vertical slices — not files

Feature breakdown — dependency graph, snippets, drag-to-move files, Split/Merge

/iterator-feature splits the plan into features — one OKF file each — in a UI with a dependency-graph visualization, snippets, drag-to-move files, and LLM-backed Split/Merge. Each feature is a vertical slice: one user-visible capability including its own tests, implementable and reviewable on its own.

Size Color Meaning
small 🟢 green One focused change
medium 🟡 yellow A feature touching a few files
large 🔴 red Probably two features — should be split

Red → green testing

/iterator-test is decided by the feature's status: on a pending feature it writes intentionally-failing tests from the feature's contract (red — the implement step drives them green); on a done feature it writes passing tests against the real code. Either way it commits the tests (test(<slug>)) and records tests/tests_status in the feature file.

/iterator-implement builds the dependency-ready wave — every pending feature whose dependencies are done — with each feature's tests as its definition of done (implement → run → fix until green, never weakening a test). On Accept and commit each feature is committed separately (feature(<slug>)) and flipped to done, with its commit shas recorded.

Review the diff the way you think about it

Review — the git diff grouped by feature, with size warnings and pitfall cards

/iterator-review shows the git diff grouped by feature, not by file, with est-vs-actual line counts and amber cards for known pitfalls matched to the touched files. It warns when a feature's actual diff exceeds ~200 changed code lines — reviewability enforced where it can actually be measured. Done features are reviewable too: the diff is rebuilt from the feature's recorded commits.

Knowledge that flows back in

Knowledge view — areas, concepts with file anchors and stale flags, memorize status

The same bundle carries knowledge areas (architecture/, decisions/, patterns/, pitfalls/, setup/). Knowledge is not write-only: pitfalls resurface as cards during review, architecture notes feed the feature breakdown, and relevant memories are injected into implementation.

  • /iterator-knowledge — the Knowledge view: area cards, every concept with its files: anchors and stale flag, memorize status.
  • /iterator-init — analyze the repo and draft the initial memories per area, reviewed in the browser before anything is written.
  • /iterator-consolidate — re-review existing memories against the current code: stale anchors, dead concepts, merges.
  • /iterator-memorize — study commits made outside the iterator flow and draft create/update/delete cards, with conflict detection.

Knowledge also flows automatically: when /iterator-implement lands a wave, the accepted diff is evaluated for durable knowledge, and proposed memory creates/updates appear as reviewable cards in the same commit review — with an explicit Apply/Skip toggle before anything is written.

The memory bundle (OKF)

All state lives in a memory/ directory in your project root — a self-describing Open Knowledge Format (OKF) v0.1 bundle, plain markdown with YAML frontmatter:

memory/
├── index.md          # bundle root index (okf_version)
├── format.md         # the metadata schema, copied into every bundle
├── plan.md           # the plan (type: Plan)
├── design.md         # optional — the project's design params (type: Design)
├── log.md            # chronological history of what the AI did
├── features/
│   ├── index.md      # feature listing with status
│   └── <slug>.md     # one document per feature (type: Feature)
└── architecture/ decisions/ patterns/ pitfalls/ setup/
                      # knowledge areas (one concept per file)

An example feature document:

---
type: Feature
title: Auth middleware
description: JWT-based auth middleware for all protected routes.
status: pending
size: small
depends_on: [config-module]
files: ["src/auth.ts", "src/middleware/*.ts"]
tests: ["test/auth.test.ts"]
tests_status: red
---

# Implementation notes
Verify the token from the config secret; wrap protected routes.

# Blast radius
Every route behind the auth guard.

The feature slug (the filename without .md) is the feature's identity: its OKF concept ID, its depends_on key, and its commit-message name. One file per feature means per-feature git history and no fragile line-number indexes. The full schema is in templates/format.md; the format itself is specified in docs/OKF_SPEC.md.

Installation

iterator currently supports two harnesses: pi (the full experience) and Claude Code (everything except the pi-only runtime features).

pi

Install the repo as a pi package — the manifest in package.json points at skills/ and extensions/, so the install registers the /iterator… commands and the pi extension runtime:

pi install git:github.com/<user>/iterator@<tag>   # or: pi -e … for one session

The pi extension unlocks the full feature set: auto mode (test → implement → review driven automatically, with a reviewer agent standing in for you), per-role models & thinking (planner/implementer/tester/reviewer each pin a model and thinking level), live pause (aborting the in-flight stream), a session dashboard with Work | Knowledge tabs, and token capture into the usage ledger.

For running iterator inside a Docker sandbox, use pi-docker-sandbox-setup: a pi sandbox image that installs iterator, sets ITERATOR_REMOTE=1, and forwards port 7777 to the host via its pisbx script — open the printed URL in the host browser and everything works as if local.

Claude Code

Load the plugin for a session with --plugin-dir:

claude --plugin-dir /path/to/iterator

To install it persistently, add the directory as a local marketplace and install from it (inside Claude Code):

/plugin marketplace add /path/to/iterator
/plugin install iterator

All skills (/iterator + the six /iterator-* steps + the four knowledge skills) are auto-discovered from skills/*/SKILL.md.

In Claude Code, iterator runs in Agent-Skills mode — a reduced feature set: the guided flow, all browser UIs, red/green testing, settings storage, the review guards, archive browsing, and the Usage view all work unchanged; the pi-only features (auto mode, per-role model/thinking switching, live pause, token capture) are stored in settings but inert.

Requirements

  • Node.js ≥ 18 (the servers use only Node built-ins — no npm install needed)
  • pi or Claude Code
  • A git repository (the memory/ bundle is resolved relative to the git root)

Project settings

Per-project behavior lives in memory/settings.md, edited from the dashboard (gear icon, or /iterator-settings in pi) and written only by the deterministic writer:

  • auto mode (pi) — after the feature set is approved, the driver runs test → implement → review automatically; a reviewer agent's verdicts are recorded in each feature's # Review history, and after max_review_iterations needs-work rounds it pauses and escalates to you.
  • per-role models & thinking (pi) — planner/implementer/tester/reviewer can each pin a model and thinking level.
  • git flowbranch_per_plan creates iterator/<plan-slug> on plan approval, in a separate git worktree by default; block_commit_on_leftovers refuses accept-commit while changed files are neither assigned to a feature nor explicitly skipped.
  • token ledgerusage_ledger records per-step × per-model token counts into memory/usage.md (the Usage tab).

Configuration

Every interactive step runs through one tiny local HTTP server bound to 127.0.0.1 that opens a browser UI and prints your response back to the agent. The port defaults to 7777 (ITERATOR_PORT overrides) and is stable by design: a lingering iterator server from an earlier run is shut down and replaced, so back-to-back runs never drift to 7778.

  • ITERATOR_PORT — fixed port (default 7777)
  • ITERATOR_MEMORY_DIR — relocate the bundle (relative to the git root)
  • ITERATOR_NO_OPEN=1 — print the URL without opening a browser
  • ITERATOR_REMOTE=1 — force remote mode (see below)
  • ITERATOR_DISPLAY_PORT — host-side port shown in printed URLs when a sandbox publish maps a different host port onto the listen port (display only; pi-docker-sandbox-setup's pisbx sets this per sandbox)
  • ITERATOR_DISPLAY_HOST — hostname shown in printed URLs (default localhost)

The server rejects requests with a non-localhost Host header (DNS-rebinding protection). Reloading the tab is safe — only closing it cancels.

Remote sessions: SSH, Docker, devcontainers

When the agent runs inside a container or SSH session but your browser is on the host, the server detects it (SSH/container markers, or explicit ITERATOR_REMOTE=1) and switches to remote mode: binds :: (override with ITERATOR_BIND_HOST), skips the browser opener, and prints a http://localhost:<port>/ URL to open on the host. The sandbox must publish the port:

sbx ports <sandbox> --publish 7777:7777   # Docker sandboxes (explicit host:container)
docker run -p 127.0.0.1:7777:7777 …       # plain Docker — keep the host side on loopback
ssh -L 7777:localhost:7777 host           # plain SSH

With several sandboxes open at once, each needs its own host port mapped onto the sandbox's 7777 (e.g. --publish 7778:7777 for the second one). Set ITERATOR_DISPLAY_PORT=<host port> inside that sandbox so the printed URL matches — pisbx does both automatically.

MicroVM sandboxes have no container marker files, so set ITERATOR_REMOTE=1 in the sandbox image (pi-docker-sandbox-setup's image already does). Binding :: exposes the UI to whatever network the sandbox is attached to — keep the host-side publish on loopback.

:: is the dual-stack wildcard: it answers over both IPv4 and IPv6. That matters because a sandbox with an IPv6 address gets two loopback forwards (127.0.0.1:<host>->7777 and ::1:<host>->7777). Bound IPv4-only, the v6 forward has nothing behind it and resets — and a reset, unlike a refusal, stops browsers falling back to IPv4, so http://localhost:<port>/ fails on the host while http://127.0.0.1:<port>/ works. Where the kernel or container has no IPv6 stack, the listener downgrades to 0.0.0.0 on its own; set ITERATOR_BIND_HOST=0.0.0.0 to force IPv4 explicitly.

How it works

  1. A skill pipes a JSON payload to skills/iterator/server.mjs — usually the one-command form {"gather":true,"step":"<step>", …}. Nothing is written to /tmp.
  2. The server shuts down any lingering iterator server, binds the fixed port, serves a self-contained page (data embedded inline and safely escaped), and opens http://127.0.0.1:<port>/.
  3. On submit the browser POSTs structured JSON to /submit; the server prints it to stdout and exits. Closing the tab cancels cleanly; a 2h idle times out.
  4. The agent reads stdout, updates the memory/ bundle through write.mjs, and re-runs the server for the next round.

See docs/ARCHITECTURE.md for the full design and docs/OKF_SPEC.md for the bundle format.

License

MIT

About

Extension for claude-code, pi and codex that forces smaller chunks of work that can be reviewed directly by the dev and create a closer loop.

Resources

License

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors