Wakeflow
A disciplined control loop for multi-window agent work — every step traced, every result reviewable.
English | 简体中文
Wakeflow turns "I want this built" into a traceable line of work: a requirement
package, a Demand, task packages, deliveries, results, reviews, and an archive
that still makes sense months later.
It is local and closed-world. Wakeflow holds state, evidence and history; your
agent holds judgment and performs every effect on your machine. Wakeflow never
opens a window, never sends a prompt, and never edits your product
repositories.
It ships as one plugin in two host editions — Codex and Claude Code — built
from a single TypeScript source.
- What you get
- How a piece of work flows
- Install
- Initialize a workspace
- Deactivating Wakeflow
- The tool surface
- Two hosts, one model
- Working in this repository
- Releasing
- Design principles
What you get
- A workspace — a controller directory, separate from your product
repositories, holding the configuration, the active state and the durable
ledger.
- Four window roles — controller, design, test, and one product window per
repository. Each is an agent window you launch; Wakeflow records which is
which.
- Four skills —
wakeflow-controller, wakeflow-design,
wakeflow-target, wakeflow-test. Each window loads the one for its role.
- Twenty MCP tools — every state change is a preview-then-apply or an
append-only call with a stable result shape; reads never write.
- Pods — a second complete window set working in its own worktree, for
running two pieces of work at once without them colliding.
- Evidence you can re-read — deliveries are proven by the host's own hook
observations, results are immutable records, and every accept, rework or
escalation is a decision written in the Controller's words.
How a piece of work flows
- In the Controller window, ask to initialize the workspace, then launch the
windows it asks for and let the agent register them.
- In the Design window, work out the requirement with the agent. It reads your
code read-only, drafts the package, and shows you a one-page summary. You
confirm it, and it is published to the board.
- In the Controller window, the agent claims the package, plans the task,
prepares the delivery and sends it to a product window.
- The product window does the work, imports its report, and wakes the
Controller.
- The Controller reads the result and the evidence, decides, and either sends
rework or moves on. When the requirement asks for real-environment testing,
a Test window runs the contract and the Controller reviews that too.
- When everything is accepted, the Demand is completed and archived in one
transaction.
You are asked to confirm twice: once on the requirement summary, and once on
the task plan when the package asks for it. Nothing is built off a requirement
you did not confirm.
Install
Requirements on the machine that runs the agent host:
- Node.js 24 (
>=24.19.0 <25) on the PATH the host launches with. The tool
server and the observation hooks are started as node; a shell that cannot
find it fails silently.
git.
- For the Claude Code edition,
tmux: the fleet lives in tmux windows.
- macOS with a local file system. Linux and Windows are not supported; the
plugins declare
os: ["darwin"] and the runtime relies on POSIX file
semantics that are only exercised on macOS.
The repository root is the development workspace; the installable plugins are
the two generated directories under plugins/:
| Host | Artifact | Catalog | Status |
|---|
| Codex | plugins/codex-wakeflow/ | .agents/plugins/marketplace.json | Preview: the native project-creation entry has not been exercised in a real Codex session yet |
| Claude Code | plugins/claude-code-wakeflow/ | .claude-plugin/marketplace.json | Supported on macOS |
Claude Code, from inside Claude Code:
/plugin marketplace add GxFn/Wakeflow
/plugin install wakeflow@gxfn
Codex:
npx codex-marketplace add GxFn/Wakeflow/plugins/codex-wakeflow --plugin
For local development, register this checkout as its own marketplace in your
Codex configuration:
[marketplaces.gxfn]
source_type = "local"
source = "/absolute/path/to/Wakeflow"
[plugins."wakeflow@gxfn"]
enabled = true
Each artifact carries its own runtime dependency closure under node_modules/;
nothing has to be installed after the plugin is placed.
One-time host actions after install
Codex. Open /hooks and trust Wakeflow's four hooks after reviewing them by
their definition hash. Until you do, all four are skipped: no session is
observed, so no window can be registered and no delivery can be shown to have
landed. If a plugin update changes the hook definition bytes, Codex asks you to
trust them again.
Claude Code. The first time you start Claude Code in the workspace
directory, accept the workspace trust dialog. Without it neither the plugin's
hooks nor the status line run. wakeflow_maintain_workspace writes the status
line command into a managed block in .claude/settings.local.json; that block
belongs to Wakeflow.
When wakeflow_verify reports its host-hook-channel gate as absent or
records-0, check these actions first. That gate is how Wakeflow knows a window
really received what was sent to it.
Updating
Claude Code. Refresh the catalog with /plugin marketplace update gxfn
(shell: claude plugin marketplace update gxfn), then update the plugin: in a
session open /plugin, pick Wakeflow under Installed and choose Update now, or
run claude plugin update wakeflow@gxfn from a shell. Claude Code replaces the
installed copy (~/.claude/plugins/cache/gxfn/wakeflow/<version>/) only when
the manifest version changed; every release changes it. Running sessions keep
the old hooks and MCP server until /reload-plugins or a new session, so
wakeflow_status then reports runtime-artifact-outdated for the Controller's
own server and windows-stale:<n> for peer windows; the Controller refreshes
them through the tmux helper (skill section "After a plugin update").
Codex. Codex documents no plugin update command (checked 2026-10-14):
codex plugin marketplace upgrade <marketplace> refreshes a Git marketplace,
and the codex-marketplace helper documents only add and remove. Refresh,
re-run the add command above, restart the Codex app (only an app restart
reloads the MCP server), resume the existing chats and open /hooks once in
case the hook definitions changed.
From 0.9.x. The current workspace format is the first supported baseline
(ADR-0018): a workspace initialized by 0.9.x is refused
(fresh-legacy-residue-present) and wakeflow_status lists its leftovers under
legacyResidue. Archive or remove them by hand and initialize again; 0.9.x
history is not migrated.
Initialize a workspace
Open your agent in the directory you want as the workspace — it must not be a
product repository root — and say "initialize a Wakeflow workspace". The agent
previews the plan, asks you to confirm the selection, then applies it. What
appears:
| Path | Owner | Purpose |
|---|
wakeflow.config.json | Wakeflow, tracked | Program identity, topology (repositories, support surfaces, windows, pods), ledger root, governance, host preferences. Only fresh-initialize, reconfigure (which can also add a product repository), detach-repository and wakeflow_pod write it; detach-workspace renames it to wakeflow.detached.json. |
.wakeflow-active/ | Wakeflow, ignored | Active state: index.md, current/workspace-current-status.md, per-Demand roots and progress projections, the requirement board. |
.wakeflow-local/ | Wakeflow, ignored | Host-private runtime: window bindings (the only place a real session or thread id lives), hook observations, pod receipts, maintenance journals. |
../wakeflow-ledger/ (configurable) | Wakeflow, tracked | Requirement package records and Demand archives. |
Design/, Test/ | Wakeflow-managed or external | The support surfaces the Design and Test windows work in. |
AGENTS.md / CLAUDE.md | Yours, with a managed block | Wakeflow keeps one block in the workspace instruction file; everything outside it is yours. |
Reconcile (wakeflow_maintain_workspace with reconcile) repairs Wakeflow-owned
files and reports drift; it never changes the configuration, registers a
window, or deletes something it does not own. If the private trees
(.wakeflow-local, .wakeflow-active) were opened up in a safe way - say by
chmod -R go+rX - its first plan takes them back to 0700 / 0600; a private
node someone else owns or can write is only reported.
Deactivating Wakeflow
Leaving is a maintenance intent, not a manual clean-up. Say it in the
Controller window; the agent previews, shows you the plan and its blockers, and
applies only when you confirm (wakeflow_maintain_workspace, ADR-0024):
- "Take repository X out of Wakeflow" —
detach-repository. Removes
Wakeflow's managed block from that repository's instruction file (only a
block whose body Wakeflow wrote), retires the repository's window projections
and publishes the configuration without the repository and its product
window.
- "Stop using Wakeflow here" —
detach-workspace. Does that for every
repository and window, removes the Wakeflow block from the workspace
.gitignore and from the workspace CLAUDE.md/AGENTS.md, on Claude Code removes Wakeflow's allow rules from
.claude/settings.json and its own statusLine entry from
.claude/settings.local.json at the workspace root and the managed Design
and Test surfaces (your own rules and status line stay), then renames
wakeflow.config.json to wakeflow.detached.json.
Both refuse while a worktree pod is open (detach-pod-open:<podId>) or a
Demand is active (detach-demand-active:<demandId>): close the pod or finish
the Demand first. A managed block whose body Wakeflow cannot prove it wrote is
left alone and reported (detach-unknown-managed-body:<targetKey>), as is a
settings file that cannot be read (detach-settings-unreadable:<root>).
Not touched, and listed in the result as leftBehind: .wakeflow-active/,
.wakeflow-local/, the ledger, the Design and Test surface directories,
worktree checkouts, branches, and the plugin's own hooks. Archive or delete
them yourself if you want them gone.
Afterwards the directory is a detached workspace: wakeflow_status reports
overall: detached with no owner in next, wakeflow_verify does not fail
and reports the same, reconcile and reconfigure are blocked
(workspace-detached), and a fresh initialization is blocked
(detached-file-present) while wakeflow.detached.json is there. The file is
deliberate evidence that Wakeflow was here. To use Wakeflow here again, rename it
back to wakeflow.config.json and reconcile: the blocks, rules and status line
return. A fresh initialization instead needs the file moved out and the items
listed in leftBehind removed too; it names each leftover (fresh-*-present).
The tool surface
Twenty public MCP tools. Effect tools run as preview then apply against the
previewed plan digest; append tools take an idempotency key and replay cleanly;
read tools never write.
| Area | Tools |
|---|
| Workspace | wakeflow_maintain_workspace — fresh-initialize, reconfigure, reconcile, detach-repository, detach-workspace |
| Windows | wakeflow_register_window_binding — inspect a launch intent, register a handshake, replace a window, release a work claim |