Skip to content

dataindustry/flow-image

Repository files navigation

FlowImage

FlowImage is a Codex image feedback loop for UI work.

It lets Codex publish screenshots to a browser/iPad canvas, lets a human draw or edit on that canvas, then lets Codex collect the returned PNG results before making code changes.

The MVP is intentionally small:

  1. Codex publishes one or more PNG screenshots through flow_image_publish.
  2. FlowImage creates a session with short View, Edit, and Owner links.
  3. The Edit link opens a canvas where a human can draw, erase, zoom, and save results.
  4. Codex collects ready merged PNG results through flow_image_sync.
  5. Codex modifies code only after explicit user confirmation.

FlowImage is accountless. Permissions are capability links:

  • View Link: read-only.
  • Edit Link: can draw and submit canvas results.
  • Owner Link: can manage retention and copy View/Edit links.
  • Owner Token: stored locally by the Codex bridge so Codex can upload screenshots and collect results.

Do not post Edit or Owner links publicly. Anyone with an Edit Link can change that session. Anyone with an Owner Link can change retention and share links.

Repo Layout

flow-image/
├─ .agents/plugins/marketplace.json
├─ apps/
│  ├─ backend/       # Express + SQLite FlowImage server
│  ├─ mcp-bridge/    # MCP tools used by Codex
│  └─ web/           # Browser/iPad canvas frontend
├─ plugins/
│  └─ flow-image/    # Codex plugin package
│     ├─ .codex-plugin/plugin.json
│     ├─ .mcp.json
│     ├─ scripts/
│     └─ skills/
└─ package.json

Server state is stored in SQLite at:

apps/backend/data/flowimage.sqlite

PNG files live under:

apps/backend/data/files/

Requirements

  • Node.js 22+
  • pnpm 11+
  • Codex with plugin and MCP support
  • A reachable FlowImage server:
    • official hosted server, or
    • your self-hosted server, or
    • a local/LAN dev server

Install From GitHub

This repository is designed to be shared as a standalone GitHub repo.

On another computer, keep a local clone because the Codex plugin package is thin and starts the MCP bridge from this repo:

FLOWIMAGE_REPO_URL="https://github.com/<github-owner>/flow-image"
FLOWIMAGE_REPO_DIR="$HOME/.flowimage/flow-image-repo"

mkdir -p "$(dirname "$FLOWIMAGE_REPO_DIR")"
git clone "$FLOWIMAGE_REPO_URL" "$FLOWIMAGE_REPO_DIR"
cd "$FLOWIMAGE_REPO_DIR"
corepack pnpm@11.7.0 install --frozen-lockfile

codex plugin marketplace add "$FLOWIMAGE_REPO_DIR/.agents/plugins/marketplace.json"
codex plugin add flow-image@flow-image-local

Then configure the FlowImage server URL from Codex with FlowImage Settings, or write the config file.

macOS/Linux:

mkdir -p ~/.flowimage
cat > ~/.flowimage/config.json <<'JSON'
{
  "server_url": "https://flow-image.liujinhang.com"
}
JSON
chmod 600 ~/.flowimage/config.json

Windows PowerShell:

New-Item -ItemType Directory -Force "$env:USERPROFILE\\.flowimage" | Out-Null
'{ "server_url": "https://flow-image.liujinhang.com" }' |
  Set-Content -Encoding UTF8 "$env:USERPROFILE\\.flowimage\\config.json"

For a LAN dev server, use your server machine IP instead:

{
  "server_url": "http://192.168.2.72:3939"
}

Verify:

codex plugin list --marketplace flow-image-local
node "$FLOWIMAGE_REPO_DIR/plugins/flow-image/scripts/settings-server.mjs" --print-config

Restart Codex or open a new Codex thread after installation.

AI Agent Install Instructions

If you are an AI coding agent installing FlowImage for a user, follow this exact flow.

Assumptions:

  • The user gives you the GitHub repo URL.
  • The user gives you the FlowImage server URL, or asks you to use the default hosted server.
  • Do not ask for a pair code. FlowImage no longer uses pair codes.
  • Prefer plugin installation over naked codex mcp add.

Set variables. macOS/Linux:

FLOWIMAGE_REPO_URL="https://github.com/<github-owner>/flow-image"
FLOWIMAGE_SERVER_URL="https://flow-image.liujinhang.com"
FLOWIMAGE_REPO_DIR="$HOME/.flowimage/flow-image-repo"

Windows PowerShell:

$env:FLOWIMAGE_REPO_URL = "https://github.com/<github-owner>/flow-image"
$env:FLOWIMAGE_SERVER_URL = "https://flow-image.liujinhang.com"
$env:FLOWIMAGE_REPO_DIR = "$env:USERPROFILE\\.flowimage\\flow-image-repo"

One-block install command for macOS/Linux agents:

FLOWIMAGE_REPO_URL="https://github.com/<github-owner>/flow-image" \
FLOWIMAGE_SERVER_URL="https://flow-image.liujinhang.com" \
FLOWIMAGE_REPO_DIR="$HOME/.flowimage/flow-image-repo" \
bash <<'FLOWIMAGE_INSTALL'
set -euo pipefail

: "${FLOWIMAGE_REPO_URL:?FLOWIMAGE_REPO_URL is required}"
: "${FLOWIMAGE_SERVER_URL:?FLOWIMAGE_SERVER_URL is required}"
: "${FLOWIMAGE_REPO_DIR:?FLOWIMAGE_REPO_DIR is required}"

if [ -d "$FLOWIMAGE_REPO_DIR/.git" ]; then
  git -C "$FLOWIMAGE_REPO_DIR" fetch origin main
  git -C "$FLOWIMAGE_REPO_DIR" checkout main
  git -C "$FLOWIMAGE_REPO_DIR" pull --ff-only origin main
else
  mkdir -p "$(dirname "$FLOWIMAGE_REPO_DIR")"
  git clone "$FLOWIMAGE_REPO_URL" "$FLOWIMAGE_REPO_DIR"
fi

cd "$FLOWIMAGE_REPO_DIR"
corepack pnpm@11.7.0 install --frozen-lockfile

codex plugin marketplace add "$FLOWIMAGE_REPO_DIR/.agents/plugins/marketplace.json"
codex plugin add flow-image@flow-image-local

mkdir -p "$HOME/.flowimage"
cat > "$HOME/.flowimage/config.json" <<JSON
{
  "server_url": "$FLOWIMAGE_SERVER_URL"
}
JSON
chmod 600 "$HOME/.flowimage/config.json"

node scripts/configure-plugin-mcp.mjs "$FLOWIMAGE_REPO_DIR"

codex plugin list --marketplace flow-image-local
node "$FLOWIMAGE_REPO_DIR/plugins/flow-image/scripts/settings-server.mjs" --print-config
node "$FLOWIMAGE_REPO_DIR/apps/mcp-bridge/src/index.mjs" < /dev/null
FLOWIMAGE_INSTALL

One-block install command for Windows PowerShell agents:

$ErrorActionPreference = "Stop"
$env:FLOWIMAGE_REPO_URL = "https://github.com/<github-owner>/flow-image"
$env:FLOWIMAGE_SERVER_URL = "https://flow-image.liujinhang.com"
$env:FLOWIMAGE_REPO_DIR = "$env:USERPROFILE\\.flowimage\\flow-image-repo"

if (Test-Path "$env:FLOWIMAGE_REPO_DIR\\.git") {
  git -C $env:FLOWIMAGE_REPO_DIR fetch origin main
  git -C $env:FLOWIMAGE_REPO_DIR checkout main
  git -C $env:FLOWIMAGE_REPO_DIR pull --ff-only origin main
} else {
  New-Item -ItemType Directory -Force (Split-Path $env:FLOWIMAGE_REPO_DIR) | Out-Null
  git clone $env:FLOWIMAGE_REPO_URL $env:FLOWIMAGE_REPO_DIR
}

Set-Location $env:FLOWIMAGE_REPO_DIR
corepack pnpm@11.7.0 install --frozen-lockfile
codex plugin marketplace add "$env:FLOWIMAGE_REPO_DIR\\.agents\\plugins\\marketplace.json"
codex plugin add flow-image@flow-image-local

New-Item -ItemType Directory -Force "$env:USERPROFILE\\.flowimage" | Out-Null
"{ `"server_url`": `"$env:FLOWIMAGE_SERVER_URL`" }" |
  Set-Content -Encoding UTF8 "$env:USERPROFILE\\.flowimage\\config.json"

node scripts/configure-plugin-mcp.mjs $env:FLOWIMAGE_REPO_DIR
codex plugin list --marketplace flow-image-local
node "$env:FLOWIMAGE_REPO_DIR\\plugins\\flow-image\\scripts\\settings-server.mjs" --print-config
node "$env:FLOWIMAGE_REPO_DIR\\apps\\mcp-bridge\\src\\index.mjs" < $null

Install the marketplace and plugin:

git clone "$FLOWIMAGE_REPO_URL" "$FLOWIMAGE_REPO_DIR"
cd "$FLOWIMAGE_REPO_DIR"
corepack pnpm@11.7.0 install --frozen-lockfile
codex plugin marketplace add "$FLOWIMAGE_REPO_DIR/.agents/plugins/marketplace.json"
codex plugin add flow-image@flow-image-local

Write local config:

mkdir -p ~/.flowimage
cat > ~/.flowimage/config.json <<JSON
{
  "server_url": "$FLOWIMAGE_SERVER_URL"
}
JSON
chmod 600 ~/.flowimage/config.json

Verify installation:

codex plugin list --marketplace flow-image-local
node "$FLOWIMAGE_REPO_DIR/plugins/flow-image/scripts/settings-server.mjs" --print-config
node "$FLOWIMAGE_REPO_DIR/apps/mcp-bridge/src/index.mjs" < /dev/null

Expected:

  • flow-image appears in codex plugin list.
  • The printed config contains the selected server_url.
  • A new Codex thread exposes the FlowImage skill and bundled flow_image MCP tools.

Then tell the user:

FlowImage is installed. Restart Codex or open a new thread, then ask Codex to publish screenshots with FlowImage.

Configure With Settings Page

Instead of writing ~/.flowimage/config.json manually, you can open the plugin settings page:

node <flow-image-repo>/plugins/flow-image/scripts/settings-server.mjs --open

The settings page writes:

~/.flowimage/config.json

Only server_url is required.

Use With Codex

After installation and configuration, ask Codex to publish screenshots:

Use FlowImage to publish screenshots of the current UI.

Codex should call:

flow_image_publish

FlowImage returns:

  • View Link
  • Edit Link
  • Owner Link
  • session_id

Open the Edit Link on iPad/Web, draw on the canvas, and save or use Realtime mode.

Then ask Codex to collect results:

Collect the latest FlowImage results.

Codex should call:

flow_image_sync

Important workflow rule:

After collecting results, Codex should show or summarize the returned images first.
Codex should not modify application code until the user explicitly confirms.

Example confirmation:

确认,按这些结果修改。

Run A Local Server

Install dependencies:

corepack pnpm@11.7.0 install
cp .env.example .env

Start the dev server for LAN/iPad use:

corepack pnpm@11.7.0 dev:backend

The default dev bind host is 0.0.0.0. The backend prints a usable FlowImage public URL, such as:

FlowImage public URL http://192.168.2.72:3939

Use that URL in each Codex computer's FlowImage config:

{
  "server_url": "http://<server-lan-ip>:3939"
}

If you need to force a specific public URL:

BIND_HOST=0.0.0.0 PUBLIC_BASE_URL=http://<server-lan-ip>:3939 corepack pnpm@11.7.0 dev:backend

Windows PowerShell:

$env:BIND_HOST = "0.0.0.0"
$env:PUBLIC_BASE_URL = "http://<server-lan-ip>:3939"
corepack pnpm@11.7.0 dev:backend

For local-only testing, explicitly bind localhost:

BIND_HOST=127.0.0.1 PUBLIC_BASE_URL=http://127.0.0.1:3939 corepack pnpm@11.7.0 dev:backend

Windows PowerShell:

$env:BIND_HOST = "127.0.0.1"
$env:PUBLIC_BASE_URL = "http://127.0.0.1:3939"
corepack pnpm@11.7.0 dev:backend

Local HTTPS For Clipboard Support

Browsers only allow writing PNG images to the system clipboard in a secure context, usually HTTPS or localhost. For iPad/LAN use, run FlowImage over HTTPS with a locally trusted certificate.

Recommended local certificate flow:

corepack pnpm@11.7.0 cert:local

Install mkcert first if it is missing. On macOS you can use Homebrew; on Windows you can use Winget, Chocolatey, or Scoop.

The script creates:

.certs/flowimage.pem
.certs/flowimage-key.pem

Start the HTTPS server:

PUBLIC_BASE_URL=https://<server-lan-ip>:3939 corepack pnpm@11.7.0 dev:https

Windows PowerShell:

$env:PUBLIC_BASE_URL = "https://<server-lan-ip>:3939"
corepack pnpm@11.7.0 dev:https

Then configure each Codex computer with:

{
  "server_url": "https://<server-lan-ip>:3939"
}

For iPad, install and trust the mkcert Root CA:

mkcert -CAROOT

Copy rootCA.pem from that directory to the iPad, install the profile, then enable full trust in:

Settings -> General -> About -> Certificate Trust Settings

The certificate generated by cert:local includes the current LAN IP, localhost, 127.0.0.1, and ::1.

Copy Image On HTTP LAN

On plain HTTP LAN URLs, the Copy Image button automatically downloads a PNG instead of showing an HTTPS error. On HTTPS deployments, the same button writes the PNG to the system clipboard when the browser allows it.

Direct MCP Development Mode

For development, you can bypass plugin installation and register the MCP bridge directly:

codex mcp add flow_image \
  --env FLOWIMAGE_SERVER_URL=http://127.0.0.1:3939 \
  -- node <flow-image-repo>/apps/mcp-bridge/src/index.mjs

This is useful while editing the bridge. For normal distribution, prefer the Codex plugin install path.

Publish This Repo To GitHub

Recommended: make flow-image/ its own standalone GitHub repository.

cd /path/to/flow-image
git init
git add .
git commit -m "Package FlowImage Codex plugin"
git branch -M main
git remote add origin git@github.com:<github-owner>/flow-image.git
git push -u origin main

Another computer can then install it with:

codex plugin marketplace add https://github.com/<github-owner>/flow-image --ref main
codex plugin add flow-image@flow-image-local

If the repo is private, make sure the target computer has GitHub credentials that can clone it.

Naming

  • Product/UI name: FlowImage
  • Codex plugin name: flow-image
  • Local Codex MCP alias: flow_image
  • Package/slug name: flow-image
  • Future MCP Registry name: net.like-water/flow-image

Manual E2E

  1. Start a FlowImage server.
  2. Install the Codex plugin.
  3. Configure ~/.flowimage/config.json.
  4. Ask Codex to call flow_image_publish.
  5. Open the returned Edit Link on iPad/Web.
  6. Draw, erase, zoom, submit, or use Realtime save.
  7. Open the View Link on another browser to confirm sync.
  8. Ask Codex to call flow_image_sync.
  9. Inspect the returned images/review URL.
  10. Tell Codex explicitly: 确认,按这些结果修改.

Tests

corepack pnpm@11.7.0 test
corepack pnpm@11.7.0 dev:check
git diff --check

dev:check checks localhost and the detected LAN URL by default. For production hosts or CI jobs that only bind localhost, set FLOWIMAGE_CHECK_LAN=0.

Troubleshooting

If the plugin is installed but tools do not appear:

  1. Restart Codex or open a new thread.
  2. Check that the plugin is installed:
codex plugin list --marketplace flow-image-local
  1. Check config:
cat ~/.flowimage/config.json
  1. Check server reachability:
curl -i "$(node -e 'console.log(JSON.parse(require("fs").readFileSync(process.env.HOME + "/.flowimage/config.json", "utf8")).server_url)')/"
  1. If another bare MCP server named flow_image was registered before, remove it:
codex mcp remove flow_image

Then restart Codex.

About

Codex image feedback loop with iPad/Web canvas review

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors