# Admin Agent — Plan

**Goal:** manage the site through an AI agent (headless Claude) — create pages,
edit content, upload images — from two surfaces: a full **/admin dashboard** and
an **in-page console** ("open a page, tell it what to change").

**Decisions locked (2026-07-23):**
- **Full-builder agent** — can create pages, edit any file, restructure. Highest
  ceiling, highest risk; sandboxing is mandatory, not optional.
- **Both surfaces** — /admin dashboard + in-page console.
- **Long-lived token** — `claude setup-token` on the server; agent reuses it.

---

## What already exists (don't rebuild)

- `app/src/components/DevConsole.astro` — the in-page console UI (prompt box,
  element picker, preview link, Publish). Already on every live page, dormant.
- `astroagent.config.json` — engine config: model, tools
  (`Read Write Edit Glob Grep WebSearch`), confined `agentUser`
  (`carlos-arias-agent`), skills (`brand`, `ui-ux`, `seo`), console route/port.
- `api/` auth — `account.php` sessions + `ADMIN_TOKEN`.
- Structured content already DB-driven and agent-friendly: `cja_projects`,
  `cja_changelog`, `cja_contact`, plus the seed scripts that write them.
- Server has the `claude` CLI and Node 22. Project is a git repo on `main`.

## What's missing (the build)

- The **runner service** the console talks to (`/devconsole/run|publish|...`) —
  frontend exists, backend does not.
- **Image upload** anywhere in the flow.
- **Model selector** and the structured **draft + prompt + images** panel.
- The **/admin dashboard**.
- **Media pipeline** (`cja_media` + optimisation).
- **Hardening** — the code-writing agent is the highest-risk surface on the site.

---

## Architecture

```
Browser (you, authed)
  ├── /admin  ................ dashboard SPA: pages, media, agent chat
  └── in-page console ........ DevConsole.astro on any page
        │  (same-origin fetch, session-authed)
        ▼
  nginx  ── /devconsole/* , /admin/* ──►  localhost-only runner (Node, :3011)
        │  auth gate on every request        │
        │                                     ├── headless Claude Code
        │                                     │     (agentUser, confined to repo,
        │                                     │      tools: Read/Write/Edit/Glob/Grep/WebSearch)
        │                                     ├── preview build → public-preview/<jobId>/
        │                                     ├── publish → build public/ + chown + git commit
        │                                     └── media: optimise → app/public/media/ + cja_media
        ▼
  Static site (public/) — unchanged for visitors
```

**Content model — hybrid:**
- Freeform pages (`about`, `services/*`) → the agent edits `.astro` files directly.
- New pages → the agent writes new `.astro` files.
- Structured content (projects, changelog, services data) → DB, edited via
  structured tools or the seed JSON/scripts.
- Images → `app/public/media/` (survives rebuilds) + `cja_media` rows.

**Why preview-first matters:** the site is static. Every agent run builds to an
isolated `public-preview/<jobId>/` you can open and review; **nothing goes live
until you press Publish**, which rebuilds `public/` and commits to git.

---

## Phases

### Phase 0 — Foundation & safety  *(do first, no features yet)*
- Commit the current working tree as a clean baseline (75 files) so every future
  publish is a diff you can roll back.
- Create/confirm the confined `carlos-arias-agent` OS user: can write only the
  repo, no sudo, no interactive shell. Install/point `claude` for that user.
- `claude setup-token` on the server → store in `agents/.env` (git-ignored).
- Admin auth: session login (reuse `api/account.php` or a dedicated admin login).
- nginx: `/devconsole/*` and `/admin/*` → localhost runner, **auth-gated**, never
  exposed directly. Runner binds `127.0.0.1` only.
- Audit log table (`cja_admin_log`): who ran what, when, published or discarded.

### Phase 1 — In-page console (finish the astroagent)
- Build the runner service: `run` (spawn headless Claude with prompt + page
  context, stream output), `preview`, `publish`, `discard`, `ping`, `auth`,
  `logout`. Conversation state so follow-ups work ("now make it bigger").
- Wire `DevConsole.astro` to it. Element picker already works.
- Publish pipeline: build → verify build passes → chown → git commit.
- Milestone: open /about, "tighten the opening paragraph," preview, publish.

### Phase 2 — Media
- `cja_media` table + `POST /devconsole/upload`.
- Optimise on upload (resize/compress, like the manual ffmpeg step), write to
  `app/public/media/`, return URL + agent-generated alt text.
- Image upload in the console; agent can place uploaded images in a page.
- Milestone: on a project page, "add these three screenshots to the gallery."

### Phase 3 — Admin dashboard  (/admin)
- Login → dashboard.
- **Pages**: list (filesystem scan of `app/src/pages` + DB content types),
  create-page flow ("make a page for my accounting services"), edit (hands off
  to the console or a structured form).
- **Media library**: browse/upload/reuse.
- **Agent panel — your exact spec**: model selector · draft-content box · prompt
  box · image-upload area. Draft + prompt + images post to the same runner.
- **Activity log** from `cja_admin_log`.

### Phase 4 — Guardrails & polish
- Feed the agent the brand guide + `brand`/`ui-ux`/`seo` skills so edits stay
  on-brand automatically.
- "Build passes" gate is required before Publish is offered.
- One-click **rollback** (git revert the last publish).
- Per-session run/token limits; rate limiting.

---

## Risks & mitigations

1. **Security is the whole game.** A code-writing agent on a public server is the
   highest-value target here — a breach means full server control. Mitigations:
   admin auth on every request, runner bound to localhost, confined OS user,
   audit log, no direct exposure of the agent, rate limits.
2. **The agent can break the build.** → preview-first, build-passes gate, git
   commit per publish, one-click rollback.
3. **Unbounded token spend.** → per-session limits; the long-lived token is one
   account we can watch.
4. **On-brand drift.** → brand guide + skills injected into every agent run;
   preview-before-publish is the human gate.

## Not in scope (yet)
- Multi-user / roles (single admin for now).
- Scheduled autonomous edits (the `agents/` content pipeline is separate and
  currently tuned for the old blog — re-tune later if wanted).

## To start Phase 0, I need
- Your go-ahead to commit the current tree as the baseline.
- A decision on admin login: reuse the existing account system, or a simple
  single-user admin password to start.
