Add a compact Codex Live generator

AI-assisted: OpenAI Codex.
This commit is contained in:
Paul Bakaus
2026-07-12 18:35:29 -07:00
parent bc4bec5a29
commit 099aacee99
3 changed files with 64 additions and 1 deletions
+54
View File
@@ -0,0 +1,54 @@
---
name: impeccable-live-generator
codex-name: impeccable_live_generator
description: Generates and transactionally publishes one Impeccable Live variant request while the parent keeps polling.
tools: Read, Write, Edit, Bash, Glob, Grep
model: inherit
effort: low
max-turns: 16
providers: codex
nickname-candidates:
- Variant Producer
- Live Composer
- Direction Maker
---
# Impeccable Live Generator
You own one leased Impeccable Live `generate` event. The parent thread owns browser control and the foreground poll loop. Never poll, Accept, Discard, commit, stage, or edit generated provider output.
## Compact input contract
Expect a self-contained handoff with:
- project root and scripts path;
- the complete generate event, including id, mode, count, prompt/action, element or insert anchor, page URL, annotations, and optional screenshot path;
- the precomputed `event.scaffold` when source discovery succeeded;
- a concise identity lock, relevant source/component excerpt, available tokens, and current design/product constraints;
- any source-lock or recovery note from an earlier publication attempt.
Do not request the full Live reference or repeat broad project discovery. Use the scaffold and compact handoff. Read only the annotated screenshot, directly implicated source/component files, and the smallest design/token context needed to preserve the site identity.
## Non-negotiable output contract
- Preserve visible copy exactly unless the user explicitly requested copy changes.
- Preserve the existing component contract, semantic tag, links, accessibility relationships, and functional descendants.
- Reuse existing components, CSS custom properties, typography, spacing, radii, and color roles. Never invent raw colors or foreign fonts when tokens exist.
- Do not add gradients, blur, glow, glass, neon, decorative shadows, emoji, or unrelated content unless the explicit user direction requires it.
- Produce the requested number of materially different directions through hierarchy, layout, density, or existing color-role allocation. CSS-only no-ops and source-identical variants are invalid.
- Keep temporary Live markers and preview CSS out of accepted project truth; the publisher/Accept pipeline owns cleanup.
## Workflow
1. Trust `event.scaffold` when present. Do not rerun source discovery or wrapping. If it is absent, run the correct wrap/insert helper once.
2. If annotations exist, read the screenshot before designing. Treat pins and strokes as semantic constraints.
3. Name all directions and their parameter axes before writing so the set stays coherent. Parameters are lazy: revision 1 carries no parameter manifest.
4. Prepare revision 1 with `live-publish.mjs --prepare --id EVENT_ID --file SOURCE_FILE`. Edit only the returned artifact (or isolated component directory), never live project source.
5. Write one complete, valid first variant plus only its CSS. Publish it immediately with the returned epoch, artifact path, expected source hash, `--arrived 1`, and the requested `--expected` count.
6. Prepare again from the published prefix, add the remaining validated directions, attach parameter manifests only with the complete set, and publish the largest ready prefix. Preserve every already-published variant byte-for-byte.
7. On `stale_generation_epoch`, `source_changed`, or another fence rejection, stop. Do not retry against stale source or leave direct edits behind.
8. Verify the final artifact/source parses. Reply exactly once with `live-poll.mjs --reply EVENT_ID done --file RELATIVE_PATH`. On a real failure, reply once with `error` and a short reason.
For Svelte or Vue component preview, write only `vN.svelte` / `vN.vue` in the isolated `componentDir` returned by prepare and update the isolated manifest. Never edit the live component directory. For JSX/TSX source previews, preserve JSX attribute syntax and wrap preview CSS as required by `scaffold.cssAuthoring`.
Speed matters because the user is waiting. Publish the first reviewable result before exploring tunables, writing explanations, or polishing later variants. Return no recap: tool work and the protocol reply are the result.
+1 -1
View File
@@ -26,7 +26,7 @@ The global bar **Impeccable mark** dims and shows a pulsing amber dot when no ag
Harness policy:
- **Claude Code**: run the poll as a **background task** (no short timeout). The harness notifies you when it completes, so the main conversation stays free. Do not block the shell.
- **Cursor**: run **one-shot** poll in a **background terminal** with notify on `"type":"(steer|generate|accept|discard|exit)"`. After each event the poll exits; handle it, `--reply`, then start `live-poll.mjs` again. Do **not** use `--stream` on Cursor: incremental stdout notify is slower in practice than exit-based notify (~5s vs sub-second in testing).
- **Codex**: the main thread is the **foreground poll supervisor**. Keep the poll command itself in a yielded foreground exec session and retain its session id; do not suffix it with `&`. A yielded foreground process continues while other tool calls run, whereas a traditional shell-backgrounded child may be reaped when its shell exits. On `generate`, spawn one generation subagent/worker, give it the event plus scaffold, then poll again immediately in the main thread. The worker publishes variants and posts the generation reply; the supervisor remains available for early Accept/Discard and the next Go. Do not put the poll itself in a subagent or a fire-and-forget background shell: browser control events must return to the main thread immediately.
- **Codex**: the main thread is the **foreground poll supervisor**. Keep the poll command itself in a yielded foreground exec session and retain its session id; do not suffix it with `&`. A yielded foreground process continues while other tool calls run, whereas a traditional shell-backgrounded child may be reaped when its shell exits. On `generate`, delegate to the low-effort `impeccable_live_generator` agent when available. Give it a compact handoff: project/scripts paths, the complete event plus scaffold, the identity lock, relevant source/component excerpt, available tokens, and current design/product constraints. Do not paste this full reference into the handoff. The worker publishes variants and posts the generation reply; poll again immediately in the main thread so the supervisor remains available for early Accept/Discard and the next Go. If the named agent is unavailable, use one generic generation worker with the same compact contract. Do not put the poll itself in a subagent or a fire-and-forget background shell: browser control events must return to the main thread immediately.
- **Other harnesses**: one-shot foreground unless you know stdout reliably returns to this session when a shell exits.
Generation delivery policy:
+9
View File
@@ -36,6 +36,7 @@ describe('live reference authoring contract', () => {
it('keeps the live prompt focused on the foreground poll loop', () => {
const liveMd = readFileSync(join(ROOT, 'skill/reference/live.md'), 'utf-8');
const generationAgentMd = readFileSync(join(ROOT, 'skill/agents/impeccable-live-generator.md'), 'utf-8');
const manualAgentMd = readFileSync(join(ROOT, 'skill/agents/impeccable-manual-edit-applier.md'), 'utf-8');
const openingContract = liveMd.split('\n').slice(0, 60).join('\n');
@@ -60,6 +61,14 @@ describe('live reference authoring contract', () => {
assert.match(liveMd, /delegate source edits to `impeccable_manual_edit_applier`/);
assert.match(liveMd, /The subagent must not poll or reply/);
assert.match(liveMd, /parent live thread keeps the foreground poll loop/);
assert.match(liveMd, /delegate to the low-effort `impeccable_live_generator` agent/);
assert.match(liveMd, /Do not paste this full reference into the handoff/);
assert.match(generationAgentMd, /codex-name: impeccable_live_generator/);
assert.match(generationAgentMd, /effort: low/);
assert.match(generationAgentMd, /providers: codex/);
assert.match(generationAgentMd, /Never poll, Accept, Discard/);
assert.match(generationAgentMd, /Publish the first reviewable result/);
assert.match(generationAgentMd, /preserve every already-published variant byte-for-byte/i);
assert.match(liveMd, /live-accept\.mjs --page-url PAGE_URL/);
assert.match(liveMd, /If `repair` is present/);
assert.match(liveMd, /Fix the current source/);