# AgenticAmit Carousel Studio — staged build prompts

Public edition — September 13, 2026. Adapted from the original build prompts to remove machine-specific dependencies. Run these in a NEW project to build from scratch; the bundled app already contains Stages 1 and 2. Stage 3 is a repeatable acceptance procedure, not a claim that every check has passed. The original build prompt selected GPT-6 Astra. Use an available coding model; separately verify your browser agent supports native site tools. Run the stages separately so the video captures the app before and after WebMCP.

## Research checkpoint

OpenAI calls its WebMCP implementation **site tools**. Current documentation uses `document.modelContext.registerTool` in top-level JavaScript. It does not support iframe registration or declarative form tools. Its documented runtime models are Sol and Terra; Astra compatibility needs a live check. Keep the build model and browser-operation model distinct. [OpenAI site tools](https://learn.chatgpt.com/docs/webmcp)

The protocol is a proposed web standard, not an OpenAI invention. Consult the live [WebMCP specification](https://webmachinelearning.github.io/webmcp/) before implementing lifecycle handling; older examples can use different APIs.

Inspiration: Owain Lewis's [video](https://www.youtube.com/watch?v=6YHPZ9IJotk) and [Vertica source](https://github.com/owainlewis/vertica). His app combines a visual carousel editor with browser-driven automation. Our contribution is an AgenticAmit editor with explicit native agent actions. Build independently; if reusing MIT-licensed code, retain attribution and license notices.

## Prompt 1 — build the application

### Portable workspace — read first

Create a local folder named `webmcp-carousel-studio` and use `app/` for the application and `evidence/` for test outputs. Inspect existing files before scaffolding and preserve unrelated work. Do not deploy.

This public edition does not require Amit's private folders, connected asset tools, or brand repository. The brand bullets below are self-contained; the downloadable reference implementation also bundles the selected fonts and their SIL OFL notices. Use your own product name, handle and permitted assets when adapting this project. Keep third-party notices. Do not ingest personal files unless individually selected. Browser storage is not arbitrary filesystem access.

Build a working local application called AgenticAmit Carousel Studio. This is a real carousel editor for my content workflow and a teaching demo about making software usable by both people and agents. Use React, TypeScript, and Vite unless the existing project requires another stack. Inspect the project first and preserve unrelated work. Do not deploy or introduce paid services.

Create an original application inspired by the workflow in https://github.com/owainlewis/vertica, not a visual clone. Use a single typed deck model and slide renderer for the preview and exports. Keep all mutations in a command layer that the UI uses; a later stage will expose that same layer to agents. Do not add WebMCP yet.

### Brand and interface

- Wordmark: AgenticAmit. Handle: @agenticamit. Working product name: Carousel Studio.
- Colors: paper #F2EEE4, ink #23241E, olive #57603E, dark olive #2B3122, clay #B07A54, darker clay #7E4E32, gold #D2A24A sparingly.
- Space Grotesk for headings; Inter for body and controls; Space Mono for slide numbers, measurements, and activity records. Bundle fonts or provide a dependable local loading strategy for export.
- Clean editorial layout, generous spacing, legible controls. No default distressed texture, purple gradients, or gratuitous glass panels. Check actual contrast combinations rather than assuming every brand pairing is accessible.
- Left slide rail, large central preview, right content/design inspector. Compact top bar for deck title, save status, undo/redo, and export. Collapsible activity panel for teaching/debugging.
- Human editing must remain complete and usable. Include keyboard-operable controls and a responsive layout.

### MVP scope

1. Create, rename, reopen, search, duplicate, update, trash, and restore posts. A post is a carousel deck plus its caption, tags, linked resource IDs, and draft/ready status; it is NOT a published social-media post. Persist posts and uploaded assets in IndexedDB across reloads. Clearly label this as local single-user storage, not cloud/team storage.
2. Create, edit, duplicate, reorder, and remove slides with undo/redo.
3. Five constrained layouts: hook, explanation, comparison, evidence, closing. Each has predictable text regions rather than arbitrary drag-and-drop geometry.
4. Default output is 1080 × 1350. Support headline/body text, small attribution, image background with crop/focal point and overlay controls, and the AgenticAmit footer.
5. A local media library for user-uploaded JPEG/PNG/WebP images. Validate MIME type, size, and dimensions. Use stable asset IDs. Do not fetch arbitrary remote URLs.
6. Real PNG ZIP export and multipage PDF export. Await fonts and image decoding before rendering. Export from a fixed-size renderer, not the scaled editor viewport. Verify dimensions, slide order, and page count by reopening the files.
7. Layout validation for text overflow, missing assets, safe areas, and contrast where computable. Mark image-background contrast as requiring visual review when it cannot be assessed reliably. Never shrink text into unreadability to hide a failure.
8. Seed a six-slide example about evaluating AI agents. Use clearly illustrative product examples, no invented customer names, metrics, quotations, or benchmark scores.

### Local resource library and portable saving

Make local saving a visible, demonstrable feature, not just an implementation detail. Add a Resources view for reusable images, plain-text/Markdown research notes, source bookmarks, and user-imported PDFs. Store actual imported file bytes as well as metadata; a file name, object URL, or external URL alone is not a saved local copy. A bookmark stores a reference only: clearly distinguish it from downloaded source material. Do not add scraping or remote downloading for this MVP.

Each resource has a stable ID, type, title, tags, description/alt text where relevant, optional source URL and attribution, created/updated timestamps, revision, and size for file resources. Support searching, filtering, previewing supported types, updating metadata or note text, linking/unlinking resources to posts, reusing images on slides, and moving unused resources to Trash. Render imported notes as inert content, not trusted instructions or executable markup. Validate file types and sizes; PDFs are attachments, not an implied OCR/research pipeline.

Show saving/saved/error states and a resource count/storage summary. Handle quota failures honestly. Request persistent browser storage when supported, but never promise that browser storage survives clearing site data or every eviction scenario. Use a stable local origin/port for the demo and explain that another browser profile or origin has separate storage.

Add an explicit **Download project backup** action: a versioned ZIP containing a JSON manifest, all posts, notes, bookmarks, original imported file bytes, and retained completed exports. Include resource references, revisions, and recoverable Trash records. Provide **Import project backup** through a user-selected file, validate its schema and archive paths/size limits, and show an import summary before applying it. Default to importing as a separate collection with remapped IDs; never silently overwrite existing work. Verify round-trip restoration of content and attachments. Also allow downloading an individual resource and a previously completed export.

Clearly distinguish **Saved in this browser** from **Backup downloaded**. Downloads use normal browser handling; do not claim a specific filesystem path or arbitrary folder-write access. Browser file selection/download permissions remain human/browser controlled. Do not require a custom local server or filesystem bridge just to demonstrate saving.

Posts and resources use recoverable Trash rather than permanent deletion. Deleting a post must not delete shared resources. A resource referenced by an active post cannot be trashed until references are explicitly removed or replaced. Slide removal is recoverable through undo/redo. Do not expose empty-trash or permanent purge in this MVP.

Defer authentication, cloud sync, social publishing, image generation, video backgrounds, FFmpeg, billing, and arbitrary SVG import. These distract from the initial WebMCP demonstration. Structure the data so media/layout extensions can come later.

### Command and state requirements

Use stable deck/slide IDs and a monotonically increasing deck revision. Mutations receive an expected revision and reject stale edits without overwriting newer work. Return typed success/error results with changed IDs, revision, and useful error codes. Validate at the command boundary, not just in forms. Reject unknown fields, excessive input sizes, invalid layouts, and invalid asset references. Treat all slide content as text, never executable HTML.

Apply the same concurrency discipline to resource and post-library operations. Persist a mutation before returning a saved receipt. Define undo/redo as a specific command reversal at an expected current revision; reject unsafe stale reversals rather than replacing the whole store. Completed exports retain their file bytes and originating deck revision so they can be reopened after reload.

Add unit tests for commands, validation, revision conflicts, and undo/redo; add browser tests for editing, reload persistence, and export. Keep tests distinct from any future native WebMCP test. Report commands run, failures, and limitations. Start the app locally and hand back its URL with a brief architecture map. Stop at this stage so I can record the human/browser baseline.

## Prompt 2 — add native WebMCP

Continue in your local `app/` directory. Read this public build prompt and preserve the existing implementation.

Add native WebMCP to the existing Carousel Studio without changing the UI's behavior or creating a second store. Recheck https://learn.chatgpt.com/docs/webmcp and https://webmachinelearning.github.io/webmcp/ before coding. Target the supported imperative API in the top-level document. Feature-detect `document.modelContext?.registerTool`. Do not assume old `navigator.modelContext`, `unregisterTool`, or a package/polyfill is the current implementation.

Implement a small adapter over the existing command layer. A normal browser must still run the editor when the API is absent. Show three distinct states: unsupported, registered locally, and native call observed. Registration alone is not proof that an agent discovered anything.

### Proposed tool surface

| Tool | Contract |
| --- | --- |
| `get_editor_context` | Read current deck, revision, slide IDs/content, selected slide, allowed layouts and brand settings. No unrelated browser or filesystem data. |
| `create_carousel` | Accept a complete structured deck with bounded slide content and a request ID; return the created deck and slide IDs. The caller writes the content; do not pretend this tool contains its own LLM. |
| `update_slide` | Accept deck ID, slide ID, a narrow patch, and expected revision. Return the new revision and changed fields. |
| `reorder_slides` | Accept deck ID, every current slide ID exactly once, and expected revision; reject missing or duplicate IDs. |
| `list_media` | Read this app's uploaded assets, including IDs, dimensions, and user-supplied descriptions. |
| `validate_carousel` | Read validation results with slide IDs, severity, and actionable explanations. Separate mechanical checks from aesthetic judgment. |
| `export_carousel` | Export a specified revision to PNG ZIP or PDF; return an export ID and honest status, not a fictional saved path. |
| `get_export_status` | Return pending/complete/failed and a usable app download link when complete. Report the revision actually exported. |

### Full workflow coverage — additional required tools

Expose the app's supported business actions, not only the original demonstration subset. Keep `carousel` as the tool-name term for posts/decks to avoid duplicate tools for the same entity. Every handler must use the same validated commands as the UI.

- `list_carousels`, `get_carousel`, `open_carousel`: search/filter/paginate active or trashed posts, read a specific post, and select it in the editor. Mark opening as a UI state change, not read-only.
- `update_carousel`: update title, caption, tags, draft/ready status, and supported deck design settings via a narrow patch and expected revision. Do not replace the entire deck to edit one property.
- `duplicate_carousel`, `trash_carousel`, `restore_carousel`: use explicit IDs and revisions, return affected IDs, and preserve shared resources. Trash is recoverable; descriptions must say so. No implicit wildcard/bulk deletion.
- `add_slide`, `duplicate_slide`, `remove_slide`: operate on explicit slide/deck IDs with insertion position and expected revision. Return stable IDs and an undoable change receipt. Pair these with existing update/reorder tools.
- `undo_change`, `redo_change`: accept explicit change IDs and expected revision; preserve intervening human edits or return a conflict. Do not silently reverse an unrelated user's latest action.
- `list_resources`, `get_resource`, `create_resource`, `update_resource`: manage resource metadata, bookmarks, and text notes. File resources can be created from an app-staged upload ID only, not arbitrary local paths or unbounded base64. If a file has not been selected/uploaded by the user, report that required step. `list_media` is the image-only convenience view over this same resource store.
- `attach_resource`, `detach_resource`: link research resources to a post; for a background image, use `update_slide` with a validated resource ID and supported crop/overlay settings. No second asset store.
- `trash_resource`, `restore_resource`: explicit resource IDs/revisions, with reference checks and no cascading deletion of posts.
- `list_exports`, `download_resource`, `download_export`: discover retained files or prepare their download using normal browser controls. Return a usable link/status, never an invented destination path or claim that browser receipt equals a completed disk write.
- `create_project_backup`, `get_backup_status`: build the portable ZIP from a consistent library snapshot, retain it for download, and report what it contains.
- `inspect_project_backup`, `import_project_backup`: inspect a user-staged archive and return a preview/import token; import only that inspected version after the user requests it, into a separate collection by default. No tool may read an arbitrary path or clear the current library.

Produce a capability matrix mapping every user-facing business action to its native tool, schema, side effects, and test. List human-only browser steps explicitly: picking local files, granting permissions, and any download dialogs. Don't claim full parity for an action lacking a tested tool. Avoid a generic `execute_action` or unrestricted object patch that bypasses validation.

Use explicit JSON object schemas with required fields, enums, bounds, and `additionalProperties: false`. Revalidate inside handlers. Mark only genuinely read-only tools read-only. Explain mutation/export side effects in descriptions. Make retried creation/export requests idempotent through a bounded request-ID cache. Serialize mutations and report revision conflicts so the agent can reread state.

For registration, implement and test lifecycle behavior against the installed browser. Prevent duplicate tools under React Strict Mode and hot reload; don't invent a cleanup API. If using registration cancellation via AbortSignal from the current specification, verify the target runtime supports it. A full-page reload is an acceptable explicit development reset when a runtime lacks the needed lifecycle feature.

Log actual handler invocations with timestamp, tool name, sanitized arguments, result status, changed IDs, and elapsed execution time. Do not log secrets or unrelated content. Label unit-test invocations separately. The log supports debugging; native browser call history is the external evidence of discovery and invocation.

Add a clearly labeled demo switch, persisted across reload, that prevents registration when off. Reload after changing it. This lets us compare the exact same application with site tools off and on. Do not use eval, arbitrary JavaScript execution, hidden filesystem access, shell commands, or an unrestricted network proxy as tools.

The app itself does not need an OpenAI API key: the browser agent provides the reasoning and passes structured content into the editor. Do not add a decorative AI chatbox or a fake generation endpoint.

Run automated tests, then report native discovery separately as NOT TESTED until the real browser agent has discovered and invoked the registered tools. Do not replace this with a remote MCP server, injected helper, direct JS call, or Playwright call and label it WebMCP.

## Prompt 3 — native acceptance test and recording

Application directory: `app/`. Record verified artifacts in `evidence/`. Read the app's documented development URL rather than assuming a port; browser permissions still control file selection and downloads.

Test the running app in the desktop built-in browser with site tools enabled. First record app/browser version, model, API presence, and whether the tools appear in the browser's available-tools view. Record the coding model used separately from the browser-operation model. Try native discovery with the intended runtime; if Astra cannot discover/call tools, report the exact observation rather than claiming Astra is universally unsupported. Use a documented Sol/Terra runtime only with an explicitly disclosed model choice.

Give the browser agent this task:

> Create a six-slide AgenticAmit carousel about why working AI demos still need evaluation. Make the hook “Your AI demo works. What happens when the prompt changes?” Explain a hotel support agent returning an invoice, why the wrong customer's invoice is a privacy problem, and why checks need realistic test cases. Keep the copy conversational, no invented statistics. Use the existing brand and a closing slide inviting people to follow for practical AI engineering. Validate it, correct any overflow, and export a PNG ZIP and PDF. Use the site's tools for editor actions; if a needed action is unavailable, tell me instead of silently switching to clicking.

Then test collaboration:

1. Manually edit a sentence in the UI.
2. Ask the agent to shorten slide 3 without changing that manual edit, and move the privacy example earlier.
3. Confirm the tool reads current state, preserves the human change, and updates the visible deck.
4. Inspect the browser's actual call history, then download and reopen both exports.

Negative tests: stale revision, nonexistent slide, unrecognized asset, oversized copy, repeated create request, export during a concurrent edit, and reload with tools disabled. All failures must be explicit and non-destructive.

### Local saving and complete editing demo

After the initial carousel test, give the agent these separate prompts. Use native site tools for application actions throughout; stop and report missing capabilities rather than silently using clicks or injected JavaScript.

> Save a research note called “AI evaluation examples” in the local resource library using the hotel invoice example we just discussed. Tag it “AI evaluations” and attach it to this post. Show me the saved resource ID and persistence status.

Manually import one permitted image and one PDF through the normal file picker. Then:

> Find the image and PDF I just uploaded, label them clearly, and link them to this post. Use the image on the cover without making the text unreadable. Update the post caption to summarize the lesson, add the tag “agentic engineering,” and keep it a draft.

Reload the app and confirm that the post, original file bytes, notes, links, and earlier export files remain available. Do not assume state survived just because the agent remembers the conversation.

> Duplicate this post as “WebMCP deletion demo.” Add an example slide, update it, then remove that slide and undo its removal. Move only the duplicate post to Trash, then restore it. Leave the original post and shared resources untouched.

> Create a downloadable project backup containing my posts, resources, and retained exports. Tell me when the ZIP is ready and what was saved.

Download the ZIP using the normal browser flow. Reimport it as a separate collection through a staged file, check the preview, and verify image/PDF bytes and post/resource references. Do not clear the original library for testing. Test referenced-resource deletion rejection, stale undo, interrupted/quota-failed saves, malformed/oversized backups, duplicate requests, and cross-tab conflicts. Verify every capability-matrix row through command tests and native calls, or mark it explicitly untested. Capture the resource library before/after reload, the real backup contents, and native update/trash/restore calls for the video.

For a before/after comparison, reset identical seed data and use the same supported runtime model and instructions. Run once with tools disabled, once enabled. Record real elapsed time, action counts, retries, human interventions, and output quality. Report a single pair as a demonstration, not a benchmark. Use repeated runs if making a performance claim. Don't conflate screenshot inspection for visual quality with clicks used to mutate content.

Deliver an evidence folder with the tested versions, sanitized native-call screenshots, application screenshots, exported ZIP/PDF, and a pass/fail report. Never fabricate unavailable timings or tokens. If the environment lacks native site tools, stop the native test with a clear blocker; passing application tests does not satisfy this acceptance test.
