Files
verse-quote-app/AGENTS.md
T
exe.dev user 0a18c774a5
CI / build (push) Successful in 4m26s
Build Verse: a poem-quote app on the agent-native chat template
Adds a Postgres-backed quotes domain (poems/quotes/favorites) exposed as
five agent-native actions (list-quotes, get-random-quote, create-quote,
toggle-favorite, list-favorites) callable from both chat and the React UI
via useActionQuery/useActionMutation. Moves the primary UI from chat to a
mobile-first Quotes/Favorites experience (chat moves to /chat), adds
manual OpenTelemetry instrumentation exporting traces/metrics/logs over
OTLP, and wires a local Docker Postgres for shared state.
2026-07-25 17:42:04 +00:00

5.5 KiB

Verse — Agent Guide

Verse is a quote app built on poems: browse, search, and favorite quotes drawn from poems, or submit new ones. It started from the agent-native chat template, but the primary surface is the quotes UI at / — chat lives at /chat and is a secondary way to reach the same actions (see "Domain & Actions" below).

Core Rules

  • Store large file/blob payloads in configured file/blob storage, not SQL: no base64, data: URLs, images, video/audio, PDFs, ZIPs, screenshots, thumbnails, or replay chunks in app tables, application_state, settings, or resources; persist URLs, ids, or handles instead.
  • Never hardcode API keys, tokens, webhook URLs, signing secrets, private Builder/internal data, customer data, or credential-looking literals. Use secrets/OAuth/runtime configuration and obvious placeholders in examples.
  • Follow the root framework contract: data in SQL, actions first, application state for navigation/selection, and shared agent chat for AI work.
  • Use actions for app operations and keep frontend/API parity.
  • Treat the chat as the default UI. When the user asks for a capability, prefer adding or improving the action surface first, then add a page, table, form, or widget only when the user needs to inspect, compare, approve, or share durable objects.
  • If the user wants to plug in their own agent backend, keep the app shell and thread UI intact and adapt the chat through the framework's AgentChatRuntime connector helpers instead of forking the transcript/composer UI.
  • Keep the action surface small and orthogonal: every action is a tool in the model's context window, so prefer one CRUD-style update (patch of fields) over many per-field actions, reach for an existing generic query / escape hatch (provider-api-*, dev db-query) before minting a new read action, mark UI-only or programmatic actions agentTool: false to hide them from the model (distinct from toolCallable: false, which only gates the extension iframe), and delete or hide actions the UI no longer uses. See the actions skill.
  • Keep database code provider-agnostic and additive.
  • Use view-screen or application state when the active page/selection is unclear.
  • For new features, update UI, actions, skills/instructions, and application state when applicable.

Domain & Actions

Data model: poems (author, title, source, year) → quotes (text, tags, is_user_submitted) → favorites (quote_id, visitor_id). visitor_id is an anonymous per-browser id (localStorage), not a login — there is no user account system in this app; AUTH_DISABLED=true by default since no Zitadel client is configured for this instance.

  • list-quotes (GET) — browse/search quotes. Optional tag, author, search (free text over quote + poem title), visitorId (marks isFavorited on each result), favoritesOnly, limit. Use this for any "show me quotes about X" / "quotes by Y" request.
  • get-random-quote (GET) — one random quote, optionally filtered by tag. Use for "quote of the day" / "surprise me" requests.
  • create-quote (POST) — submit a new quote. Requires text, author, poemTitle; optional source, year, tags. Creates the poem record if author+title doesn't already exist (case-sensitive exact match). Marks the quote is_user_submitted: true.
  • toggle-favorite (POST) — favorite/unfavorite a quote for a visitorId (toggles based on current state, no separate favorite/unfavorite actions). Returns { favorited, favoriteCount }.
  • list-favorites (GET) — all quotes a visitorId has favorited, most recent first. Requires visitorId.

All five are callable from chat and from the React UI via useActionQuery/useActionMutation — there is no separate /api/* REST layer. Every action call emits an OpenTelemetry span, a structured log line, and increments a call counter, exported over OTLP to the shared Grafana LGTM stack (see server/otel.ts).

Application State

  • navigation should describe the current view and selected entity ids. The quotes home view is quotes at /; chat is a secondary view at /chat.
  • navigate may be used to move the UI when the app supports it.
  • view-screen is the first tool to call when the user's visible context matters.

Framework Docs Lookup

  • Before implementing or explaining non-trivial Agent Native behavior, use the agent-native-docs skill and the built-in docs-search action/tool to read the version-matched framework docs bundled with @agent-native/core.
  • Use the built-in source-search action/tool, or search node_modules/@agent-native/core/corpus, when you need current core or first-party template implementation examples.
  • Prefer those installed docs over memory or public docs when package APIs, generated-app conventions, workspaces, actions, or agent surfaces are involved.
  • Before building common workspace or agent UI, read agent-native-toolkit to inventory existing public kits and installed package seams.
  • Read customizing-agent-native before overriding the chat shell or shared UI. Keep Core thread/runtime behavior and use the supported ladder: configure → compose → eject the smallest presentation unit → propose a shared seam. Preview before --apply and commit agent-native.ejections.json.

Skills

Read the relevant root skill before implementation: adding-a-feature, actions, agent-native-docs, agent-native-toolkit, customizing-agent-native, storing-data, real-time-sync, security, delegate-to-agent, frontend-design, shadcn-ui, and self-modifying-code.