Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/design-mode-on.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@reddb-io/redcode": minor
---

Design mode is on by default, and `design_export` is available to the design agent

The `REDCODE_EXPERIMENTAL_DESIGN_MODE` flag is gone: the `design` agent's tools — `design_preview`, `design_playbook`, `design_export`, `design_exit` — are always there, and the mode's system prompt is added whenever the design agent runs. The README gains a tutorial for the whole loop: starting, reviewing (annotations, images, live reload, layout issues, whiteboards, export, another device), finishing, the files it leaves, and the settings.
79 changes: 79 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ it**. Read [The Session Model](#the-session-model) first — the rest of this do

- [Install](#install) — one binary, nothing else
- [Use](#use) — every command, and what it is for
- [Design Mode](#design-mode) — prototype in the browser, review it there, come out with a plan

**Reference**

Expand Down Expand Up @@ -237,6 +238,84 @@ HTTP endpoint. Set `REDCODE_RPC_URL` to the printed URL. It reuses
`OPENCODE_SERVER_USERNAME`/`OPENCODE_SERVER_PASSWORD`, or accepts a complete
`REDCODE_AUTHORIZATION` header.

## Design Mode

Design mode is for working out what something should be by building it. The agent writes an
interactive prototype, you review it in your browser — clicking, annotating, drawing on diagrams —
and what you decide becomes a plan. The agent cannot edit the product in this mode, only the
prototype, so nothing you say here changes code until you leave.

### Start

1. In the TUI, press `Tab` until the agent reads `design` (`Shift+Tab` goes back). In the web UI
(`redcode web`), pick the `design` agent the same way. Describe what you want built.
2. The agent writes the prototype into `.redcode/designs/<timestamp>-<slug>/` — `index.html` plus
whatever sits beside it — and calls `design_preview`. Your browser opens on the review page;
its URL is also in the tool's output, and the web UI shows the same page in a **Design** tab.

The prototype runs with no network. A CDN link will not load, so the agent uses what the project
already has (it reads `DESIGN.md` or `.red/DESIGN.md` for the project's design system) or the
Tailwind, DaisyUI and Mermaid that ship with Redcode.

### Review

Everything on the review page is a proposal until you press **Send to Agent**; the agent's next
turn starts only then.

- **Annotate** is the default mode. Click an element, select some text, click a table cell or a
node of a diagram, and a card opens. `Enter` queues the note, `Cmd/Ctrl+Enter` queues and sends,
`Shift+Enter` is a line break, `Esc` closes an empty card. Paste or drop an image onto the card
to attach a reference. `Cmd/Ctrl+I` switches to **Explore**, where the prototype behaves like a
page; `Alt+click` still annotates there.
- **The conversation panel** on the right holds the queue (each note is a pill you can remove),
the agent's replies, and a composer. **Hold** keeps what you typed in the queue without sending;
**Send & End** sends and closes the review. Below 860px the panel is a sheet you pull up.
- **Live reload.** When the agent saves, the page reloads and keeps your place: scroll position,
unsent notes, the text of an open card, and answers inside `data-redcode-question` groups.
- **Layout issues.** After every load the browser audits the layout — text cut off by its
container, controls outside the viewport, a page that scrolls sideways, text covered by another
element — and lists what it found under the **Layout issues** button. Nothing there reaches
the agent on its own. Select the ones you want fixed and press **Queue selected fixes**; they
become one note. **Dismiss** hides a warning for the current revision only; it comes back if a
later revision still has it. A warning is cleared only when a newer revision no longer shows it.
- **Whiteboard.** A Mermaid diagram gets an Excalidraw whiteboard beside it. Click it to edit,
drag nodes, redraw arrows, add shapes or freehand marks; **Fullscreen** opens it over the page.
**Queue feedback** turns your edits into a note with a summary of what moved and a PNG for the
agent, which then edits the Mermaid source — the whiteboard is how you talk about a diagram,
never a second copy of it. The first whiteboard on a machine downloads the editor bundle
(about 3MB) from the release; until then diagrams are plain.
- **The `⋮` menu**: copy the prototype's directory, reload it, copy a DOM snapshot, **Export
standalone HTML** (one file with everything local inlined, which opens from disk), **Open on
another device** (when the server listens beyond loopback), and **End review**.

### Finish

End the review from the `⋮` menu or with **Send & End**; the agent stops waiting for notes. When
the design is settled, the agent calls `design_exit`, which writes the plan from what it recorded
in `design.json` — the decisions, the open questions, a link to the prototype — and offers to
switch to the plan agent to refine it. The agent may also call `design_export` when you ask for a
file to share.

### Files

| Path | What it is |
| --- | --- |
| `.redcode/designs/<name>/index.html` | The prototype, with its assets beside it |
| `.redcode/designs/<name>/design.json` | `kind` (`screen`, `flow`, `comparison`, `deck`), `decisions`, `questions` — the reasoning the plan is written from |
| `.redcode/designs/<name>/.review/` | Review state, whiteboard scenes and exports; never served, not part of the design |
| `DESIGN.md` or `.red/DESIGN.md` | The project's design system as the agent understands it; edit it to correct the agent |

### Settings

Everything is on by default. Under `experimental.design` in the config: `attachments` (per-image,
per-note and disk caps for pasted images), `viewports` (which of `mobile`, `compact`, `desktop` the
layout audit reports on), `gate` and `gate_timeout` (the short curtain before a prototype is
shown), `export` (size caps for the standalone file), and `hosts` (extra names the review surface
answers to). `REDCODE_DESIGN_NO_OPEN=1` stops the browser from opening;
`REDCODE_DISABLE_WHITEBOARD_DOWNLOAD=1` never fetches the whiteboard bundle, and
`REDCODE_WHITEBOARD_DIR` points at a local build of it. To review from a phone, run
`redcode serve --hostname 0.0.0.0` and use the network URL `design_preview` prints.

## Architecture

```
Expand Down
1 change: 0 additions & 1 deletion packages/redcode/src/effect/runtime-flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ export class Service extends ConfigService.Service<Service>()("@redcode/RuntimeF
experimentalLspTool: enabledByExperimental("REDCODE_EXPERIMENTAL_LSP_TOOL"),
experimentalOxfmt: enabledByExperimental("REDCODE_EXPERIMENTAL_OXFMT"),
experimentalPlanMode: enabledByExperimental("REDCODE_EXPERIMENTAL_PLAN_MODE"),
experimentalDesignMode: enabledByExperimental("REDCODE_EXPERIMENTAL_DESIGN_MODE"),
experimentalCodeMode: enabledByExperimental("REDCODE_EXPERIMENTAL_CODE_MODE"),
experimentalEventSystem: enabledByExperimental("REDCODE_EXPERIMENTAL_EVENT_SYSTEM"),
experimentalWorkspaces: enabledByExperimental("REDCODE_EXPERIMENTAL_WORKSPACES"),
Expand Down
2 changes: 1 addition & 1 deletion packages/redcode/src/session/reminders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export const apply = Effect.fn("SessionReminders.apply")(function* (input: {
})
}

if (flags.experimentalDesignMode && input.agent.name === "design" && assistantMessage?.info.agent !== "design") {
if (input.agent.name === "design" && assistantMessage?.info.agent !== "design") {
const ctx = yield* InstanceState.context
const root = Session.design(input.session, ctx)
const exists = yield* fsys.existsSafe(root)
Expand Down
7 changes: 4 additions & 3 deletions packages/redcode/src/tool/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,9 +263,10 @@ const layer = Layer.effect(
...(tool.execute ? [tool.execute] : []),
tool.lsp,
...(flags.experimentalPlanMode && flags.client === "cli" ? [tool.plan] : []),
// Behind a flag while the review surface settles: it opens a browser window and serves
// model-written HTML, which is not something to switch on for everyone by surprise.
...(flags.experimentalDesignMode ? [tool.design_preview, tool.design_exit, tool.design_playbook] : []),
tool.design_preview,
tool.design_exit,
tool.design_playbook,
tool.design_export,
// The goal loop's only tool: a claim of completion, judged at the end of the turn.
tool.goal_complete,
],
Expand Down
2 changes: 1 addition & 1 deletion packages/redcode/test/design/mode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const synthetic = (parts: readonly { synthetic?: boolean; text?: string }[]) =>
.map((part) => part.text ?? "")
.join("\n")

const flags = RuntimeFlags.layer({ experimentalDesignMode: true })
const flags = RuntimeFlags.layer({})
const it = testEffect(
LayerNode.compile(
LayerNode.group([
Expand Down
Loading