| name | jay-agent-kit |
| description | Main entry point for AI agents building jay-stack applications. Use when creating pages, working with headless components, or generating jay-html from contracts. Covers the full workflow from reading contracts to producing valid jay-html pages. |
Jay Agent Kit
This is the main entry point for building jay-stack applications. Read the relevant sub-skills as needed.
Overview
Jay Stack is a full-stack framework where:
- Plugins provide headless components (data + interactions, no UI)
- Contracts define the data shape and interaction points of each component
- jay-html templates provide the UI that binds to contract data
- Rendering phases determine when data is available (build-time, request-time, client-side)
Workflow
- Discover what plugins and contracts are available
- Read contracts to understand data shapes and phases
- Read references — check
agent-kit/references/<plugin>/ for pre-generated discovery data (product catalogs, collection schemas). Faster than CLI commands.
- Create jay-html pages that bind to contract data
- Validate your files
- Test with the dev server
Sub-Skills
Read these as needed:
Also see the agent-kit generated docs (run jay-stack agent-kit):
agent-kit/project-structure.md — Project layout, styling patterns, CSS themes, configuration |
Quick Reference
Rendering Phases
| Phase | When | Use For |
|---|
| slow | Build time (SSG) | Static content, SEO data, pre-rendered lists |
| fast | Request time (SSR) | Per-request data (prices, stock, personalization) |
| fast+interactive | Request + client | Data that also updates on the client |
There is no standalone "interactive" phase. Any tag with type: interactive is automatically fast+interactive. Tags without an explicit phase are available in all phases.
Page File Structure
Each page lives in a directory under src/pages/:
src/pages/
├── page.jay-html → /
├── products/
│ ├── page.jay-html → /products
│ └── [slug]/
│ └── page.jay-html → /products/:slug
Each page directory can contain:
page.jay-html — template (required for rendering)
page.jay-contract — page-level data contract (optional)
page.conf.yaml — configuration: which headless components to use (optional, used when jay-html is missing)
Headless Components — Two Patterns
1. Key-based (data merged into parent ViewState under a key):
<script
type="application/jay-headless"
plugin="my-plugin"
contract="my-contract"
key="data"
></script>
2. Instance-based (multiple instances with props, inline template):
<script type="application/jay-headless" plugin="my-plugin" contract="my-widget"></script>
<jay:my-widget productId="123">
<h3>{name}</h3>
<button ref="addToCart">Add</button>
</jay:my-widget>
Headfull Full-Stack Components
Headfull components own their UI template and participate in three-phase rendering. Add contract to a headfull import:
<script
type="application/jay-headfull"
src="./header/header"
contract="./header/header.jay-contract"
names="header"
></script>
<jay:header logoUrl="/logo.png" />
Headfull FS components can nest other headfull FS or headless components in their own <head>:
<head>
<script type="application/jay-headless" plugin="my-plugin" contract="cart-indicator"></script>
</head>
<body>
<header>
<jay:cart-indicator><span>{itemCount}</span></jay:cart-indicator>
</header>
</body>
All nested imports are hoisted to the page level. Nesting depth is unlimited. Key-based headless imports are not allowed inside headfull FS components.
Discovery Commands
yarn jay-stack setup
yarn jay-stack agent-kit
yarn jay-stack params <plugin>/<contract>
yarn jay-stack action <plugin>/<action> --input '{"query":"shoes"}'
yarn jay-stack validate
Key Directories
| Path | Purpose |
|---|
src/pages/ | Page routes (directory-based routing) |
agent-kit/materialized-contracts/ | Generated contracts, indexes (run jay-stack agent-kit) |
agent-kit/references/<plugin>/ | Pre-generated discovery data (run jay-stack agent-kit) |
node_modules/<plugin>/ | Plugin packages with plugin.yaml |
DOM access (page.ts and headfull components)
Jay Stack owns rendering. When adding interactivity beyond jay-html bindings:
- Put structure in jay-html; put state in ViewState signals returned from
.withInteractive.
- Use refs for events and imperative DOM (
exec$ inside handlers only).
- Avoid
document.querySelector, imperative createElement UI, and document-level drag listeners.
Read jay-dom-refs before reaching for document.*.