Runcastle

Landing Page Copy (AIDA) + Edit

MIT0 downloads

by runcastle

v1.0.1

A mixed-provider copy pipeline: a Claude Code writer turns your product brief into full AIDA-structured landing page copy, then a Codex editor cuts fluff, makes claims concrete, and tightens headlines on the same warm branch, looping until it ships.

Topology

Disclosures

Disclosures — declared side-effect surface

Everything below runs on your machine or inside the sandbox when you use this workflow. Mismatches between these declarations and the actual code block publishing.

Host hooks

Commands executed on YOUR host machine by Sandcastle lifecycle hooks.

None declared.

Sandbox hooks

Commands executed inside the sandbox container.

None declared.

Network access

None. Both agents operate only on the local repository inside the sandbox; the copy is written from BRIEF.md with no web fetching.

Shell expansion

No shell-expansion blocks in prompt files.

Files

Diff vs the stock Sandcastle 0.12.0 template Dockerfile — green lines were added by the author, red lines were removed from stock.

+# Sandbox image for the Landing Page Copy (AIDA) + Edit workflow.
+# Installs both agent CLIs — Claude Code (writer) and Codex (editor).
FROM node:22-bookworm
# System dependencies.
RUN apt-get update && apt-get install -y --no-install-recommends \
git \
curl \
jq \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
-# Claude Code CLI (the agent runtime).
-RUN npm install -g @anthropic-ai/claude-code
+# Agent CLIs: Claude Code (writer) and Codex (editor).
+RUN npm install -g @anthropic-ai/claude-code @openai/codex
# Non-root agent user. `sandcastle docker build-image` aligns AGENT_UID/GID to
# the host user via --build-arg to avoid permission errors on bind mounts.
+# node:22-bookworm already ships a "node" user at UID/GID 1000, so we RENAME it
+# (the stock Sandcastle template pattern) — groupadd/useradd would collide with
+# the existing IDs on a default build.
ARG AGENT_UID=1000
ARG AGENT_GID=1000
-RUN groupadd --gid ${AGENT_GID} agent \
- && useradd --uid ${AGENT_UID} --gid ${AGENT_GID} --create-home --shell /bin/bash agent
+RUN groupmod -o -g ${AGENT_GID} node \
+ && usermod -o -u ${AGENT_UID} -g ${AGENT_GID} -d /home/agent -m -l agent node
-USER agent
-WORKDIR /workspace
+USER ${AGENT_UID}:${AGENT_GID}
+WORKDIR /home/agent
+
+# Sandcastle bind-mounts the worktree and sets the working directory at
+# container start; the container just needs to stay alive until then.
+ENTRYPOINT ["sleep", "infinity"]
Show full Dockerfile (highlighted)
# Sandbox image for the Landing Page Copy (AIDA) + Edit workflow.
# Installs both agent CLIs — Claude Code (writer) and Codex (editor).
FROM node:22-bookworm

# System dependencies.
RUN apt-get update && apt-get install -y --no-install-recommends \
      git \
      curl \
      jq \
      ca-certificates \
 && rm -rf /var/lib/apt/lists/*

# Agent CLIs: Claude Code (writer) and Codex (editor).
RUN npm install -g @anthropic-ai/claude-code @openai/codex

# Non-root agent user. `sandcastle docker build-image` aligns AGENT_UID/GID to
# the host user via --build-arg to avoid permission errors on bind mounts.
# node:22-bookworm already ships a "node" user at UID/GID 1000, so we RENAME it
# (the stock Sandcastle template pattern) — groupadd/useradd would collide with
# the existing IDs on a default build.
ARG AGENT_UID=1000
ARG AGENT_GID=1000
RUN groupmod -o -g ${AGENT_GID} node \
 && usermod -o -u ${AGENT_UID} -g ${AGENT_GID} -d /home/agent -m -l agent node

USER ${AGENT_UID}:${AGENT_GID}
WORKDIR /home/agent

# Sandcastle bind-mounts the worktree and sets the working directory at
# container start; the container just needs to stay alive until then.
ENTRYPOINT ["sleep", "infinity"]

README

Landing Page Copy (AIDA) + Edit

Hand it a product brief; get back landing page copy that's structured to convert and edited until it's tight. A Claude Code writer drafts the full page using the classic AIDA framework, then a Codex editor tears into it — cutting fluff, demanding specifics, and sharpening the headline — on the same warm branch, looping until it's ready to ship.

What it does

One prompt asking an AI to "write landing page copy" gives you generic mush. This workflow splits writing from editing, the way a real copy team does:

  1. Write (Claude Opus) reads your BRIEF.md and produces the complete page, labelled by AIDA stage — hero (headline, subhead, CTA), the problem, how it works, benefits framed as outcomes, proof, objection handling, and a final CTA. It offers headline alternatives and refuses to fabricate stats or testimonials, flagging missing proof instead. Committed to content/landing.md.
  2. Edit (Codex) revises that file in place: cutting 10–20% of the words, replacing every vague claim with something concrete, fixing passive voice and weak CTAs, checking the AIDA flow builds in order, and verifying every claim traces back to the brief. It loops until it's satisfied, then emits <promise>SHIP_IT</promise>.

How it works

main.ts opens one warm Docker sandbox with createSandbox() on the content/landing branch. The Claude writer runs once; then the Codex editor runs on the same container and branch for up to four iterations, stopping early when it signals SHIP_IT. Because both agents share the branch, the editor is working on the exact file the writer committed. The topology is write → edit → (loop) → ship.

Requirements

Add a BRIEF.md at your repo root with the product facts: what it is, who it's for, the problem it solves, what makes it different, any real proof points, and the one action you want visitors to take. Set both CLAUDE_CODE_OAUTH_TOKEN (run claude setup-token) and OPENAI_API_KEY in .sandcastle/.env. Build the image once with npx @ai-hero/sandcastle docker build-image, then run it with npx tsx .sandcastle/main.ts. The finished copy is at content/landing.md.