From 497f55364bc480bf957fddaa99e311dd9c497f9a Mon Sep 17 00:00:00 2001 From: Carlos Arias Date: Fri, 24 Jul 2026 01:28:09 +0000 Subject: [PATCH] changelog: admin + Web Designer arc; document the engine update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - seed-changelog: 5 entries (admin console, self-editing agent, uploads, project builder, Web Designer + task queue) - .memory/webdesigner.md: core Astroagent console update — architecture, decisions, safety model, files, and the site-coupling caveat --- .memory/webdesigner.md | 116 +++++++++++++++++++++++++++++++++++++ api/cli/seed-changelog.php | 5 ++ 2 files changed, 121 insertions(+) create mode 100644 .memory/webdesigner.md diff --git a/.memory/webdesigner.md b/.memory/webdesigner.md new file mode 100644 index 0000000..c42a23f --- /dev/null +++ b/.memory/webdesigner.md @@ -0,0 +1,116 @@ +# The Web Designer — a core Astroagent console update + +**Status:** Implemented · **Date:** 2026-07-24 +**Related:** [../agents/console/PLAN.md](../agents/console/PLAN.md) · [../agents/console/SETUP.md](../agents/console/SETUP.md) · [../brand/BRAND.md](../brand/BRAND.md) · [../.claude/skills/brand/SKILL.md](../.claude/skills/brand/SKILL.md) + +--- + +## What it is + +The **Web Designer** is a new capability of the **astroagent console** — the base's +in-site authoring engine (`agents/console/server.mjs`). It is not a separate OS agent; it +is a new *mode* of the existing confined runner (`carlos-arias-agent`), reached through the +already-gated `/devconsole/` nginx prefix. + +You hand it a **brief for any page** — a prompt/instructions, a draft, uploaded images, and +links to short videos — and it does real design work (edit a section, restyle a component, +lay out a new page) and publishes. Briefs are **queued**; the agent drains the queue one task +at a time. + +This is a **core engine change**, not site content — a fresh SeedProject clone that runs the +migration + `configure.mjs` inherits the whole thing. (See the site-coupling caveat below for +the one thing that is not yet fully clone-clean.) + +It coexists with two sibling surfaces built earlier in the same arc: +- the **in-page console** (the ▲ handle) — freeform, contextual, preview→publish by hand; +- the **project builder** (`/admin/projects/new` → `/devconsole/build-project`) — the + *structured* path that writes a `cja_projects` row. + +The Web Designer is the *freeform, queued* path for everything else. + +## Architecture + +``` +/admin/designer ──create task──▶ cja_tasks (queued) [PHP: admintasks controller] + │ poll status ▲ + └──kick──▶ /devconsole/tasks/run ── drainTasks() loop [Node runner] + │ claim next (php api/cli/tasks-next.php) + │ run design agent: claude -p (skills + brief, Write/Edit) + │ build → git commit LIVE (auto-publish) + │ mark finished (php api/cli/tasks-finish.php) + └─ next task … +``` + +The Node runner is deliberately dependency-free (no DB driver), so it reads/updates the queue +by shelling out to small **PHP CLI helpers** — keeping MariaDB behind the single PHP data +layer. The design work itself is a `claude -p` spawn, the same harness as the in-page console. + +### Locked decisions + +| Question | Decision | +|---|---| +| Scope of the agent | **Full builder** — may edit any page and create new pages (updating the nav in `Header.astro` + `Footer.astro`). | +| Publish model | **Auto-publish & continue.** Each task builds, commits live, and the queue advances hands-off. Safety net = git history (one revert per task) + a build-must-pass gate. | +| Skills | **CLI-native.** Skills live under `.claude/skills/` so `claude` auto-discovers them; the persona also reads them explicitly for headless reliability. | +| Queue store | **DB table `cja_tasks`** (durable, survives restart), not the in-memory `jobs` Map. | +| Runner ↔ DB | **PHP CLI bridge** (`tasks-next.php` / `tasks-finish.php`); the runner stays dependency-free. | +| Progress UX | **Polling** `admintasks/list`, not SSE — sidesteps the drifted server/DevConsole event contract. | + +## Skills (the CLI-native design brain) + +`.claude/skills/` is new and is what makes the agent design rather than merely edit: +- `brand/SKILL.md` — the sumi-e brand system distilled from `brand/BRAND.md` (the seal rule, + palette tokens, type scale, radii, do/don'ts). **This file is the site-specific piece** — a + clone swaps its contents. +- `ui-ux/` — a symlink to the existing generic `app/.astroagent/skills/ui-ux` (reusable). + +Before my change the console passed **no** skill wiring at all; the skills array in +`astroagent.config.json` was inert. The runner still passes no `--skill` flag — discovery is +by location (`.claude/skills/`) plus an explicit "read these SKILL.md files" instruction in +the design persona. + +## Safety model + +- **Clean-tree guard.** A task refuses to run if the git scope (`app brand api/db api/cli`) is + dirty — otherwise the auto-publish `git add` would sweep unrelated WIP into the task's + commit. Uploaded assets under `app/public/media/` are exempt (they *are* the task's images + and get committed with it). This guard exists because exactly that hazard bit during the + build: an uncommitted file was swept into a task commit and a revert then deleted it. +- **Build-must-pass gate** before any commit; a failing task reverts its own edits + (`git checkout` + `clean`) and the queue continues. +- **Scoped commits** — `git add` never touches secrets/config, only `app brand api/db api/cli` + (+ media). The agent runs confined, Write/Edit within the repo only. +- **Single-flight** — the queue shares the runner's global `busy` lock, so a draining queue and + the in-page console can never run at once (the console returns 429 while draining). + +## Files + +| File | Role | Core / site | +|---|---|---| +| `agents/console/server.mjs` | `buildDesignPrompt`, `runDesignTask`, `drainTasks`, `POST /devconsole/tasks/run` | **core** | +| `api/db/migrations/011_create_cja_tasks.sql` | queue table | **core** | +| `api/public/controllers/admintasks.php` | create / list / get / cancel | **core** | +| `api/cli/tasks-next.php` | atomic claim (queued → running) | **core** | +| `api/cli/tasks-finish.php` | mark published / failed + result | **core** | +| `app/src/pages/admin/designer.astro` | submit brief + poll the queue | **core** | +| `app/src/layouts/AdminLayout.astro` | "Web Designer" nav link | **core** | +| `.claude/skills/ui-ux` (symlink) | generic design skill | **core** | +| `.claude/skills/brand/SKILL.md` | this site's brand | **site-specific** | + +## Site-coupling caveat (not yet clone-clean) + +The prompt-builders in `server.mjs` — both the new `buildDesignPrompt` and the pre-existing +`buildPrompt` — **hardcode** "the Carlos Arias website" and "sumi-e" directly in the engine. +This site identity was already baked into the console before this change; the Web Designer +matches that pattern rather than adding new debt. For a truly clone-clean base, those strings +should be sourced from `site.config.json` / `astroagent.config.json` + the `brand` skill, +leaving the runner site-agnostic. Deferred — flagged, not done. + +## How to run it + +1. Sign in to the admin (secret link), open **/admin/designer**. +2. Submit a brief: pick a page (or "New page"), write instructions, optionally a draft, + upload images, paste short-video links → **Add to queue & run**. +3. The queue drains automatically; each row shows `queued → running… → published` + (with a live link + commit) or `failed` (with the reason). +4. Undo any task with `git revert ` on `main`, then rebuild. diff --git a/api/cli/seed-changelog.php b/api/cli/seed-changelog.php index 35257e8..b3ce649 100644 --- a/api/cli/seed-changelog.php +++ b/api/cli/seed-changelog.php @@ -44,6 +44,11 @@ $entries = [ ['added', 'Services page', 'Automation, website design, and digital marketing — built for law firms and service businesses.', '2026-07-23 16:05'], ['updated', 'Contact form aligned to services', 'Enquiry types now mirror the three core services offered.', '2026-07-23 16:10'], ['updated', 'Navigation', 'Added Services to the main menu, front and centre.', '2026-07-23 16:12'], + ['added', 'Private admin console', 'A secret-link sign-in to manage the site — pages, projects, and media — from one place.', '2026-07-23 22:30'], + ['added', 'A site that edits itself', 'A confined AI agent takes a request, edits the relevant page, builds a preview, and publishes once you approve.', '2026-07-23 23:10'], + ['added', 'Image and video uploads', 'Drop in a photo or clip; it is optimised on upload and placed straight into the page.', '2026-07-23 23:40'], + ['added', 'Projects built from a brief', 'Describe a project and hand over the images — the agent writes the case study, groups the skills, and captions each shot.', '2026-07-24 00:05'], + ['added', 'The Web Designer agent', 'A design agent for any page: give it a brief — instructions, a draft, images, video links — and it designs and publishes, working through a task queue.', '2026-07-24 00:40'], ]; Db::execute('TRUNCATE TABLE cja_changelog');