Plugin Agent-Kit
Design Log #125 — Plugin Agent-Kit
Written for AI agents. See Log Methodology Note below for details.
Background
The existing jay-stack agent-kit command generates instructions and reference data for AI agents that build jay-stack projects — creating jay-html pages that consume plugins. But creating a plugin is a fundamentally different task: defining contracts, writing headless components, setting up plugin.yaml, implementing server actions, etc.
There is no agent-kit support for this workflow today. AI agents creating plugins have no structured guidance, which leads to issues like contracts missing props and params declarations (see DL#124).
Related design logs: #39 (Plugin package), #60 (plugin system refinement), #84 (headless props), #85 (agent-kit for projects), #124 (contract consistency).
Problem
An AI agent tasked with creating or modifying a jay plugin has no equivalent of the project agent-kit. It must rely on general knowledge or .cursor/skills/ files (which are local to the jay framework repo, not installed into consumer projects). This leads to:
- Contracts that are incomplete (missing props, params, phases)
- Components that don't match their contracts
- Missing or malformed
plugin.yaml - Actions without
.jay-actionmetadata files
Questions
Q: Should
--mode plugingenerate into the sameagent-kit/folder or a different one (e.g.,agent-kit-plugin/)? A:SeparateRevised: all three agent-kits (designer, developer, plugin) live under oneagent-kit-plugin/folder.agent-kit/folder as subfolders. See point 3 below.Q: What reference data should the plugin agent-kit generate? A: Documentation/skills focused on plugin authoring:
- Component state hooks:
createSignal,createMemo,createEffect,createEventfor the interactive phase - Refs: how to use refs, collection refs
- Immutable data: data is immutable, examples of using JSON Patch to update data, the
maphook - Contract data types: all tag types (data, variant, interactive, sub-contract), async data types (
Promise<T>), linked sub-contracts, repeated sub-contracts withtrackBy - Interactive elements: interactive refs, element types
- Phase guidance: how to decide if data is
slow,fast, orfast+interactive— what belongs at build time vs request time vs client-side - Props vs params: when to use
props(component configuration, passed by parent) vsparams(URL route segments, passed by routing)
- Component state hooks:
Q: Should the plugin agent-kit include validation instructions (run
jay-stack validate-plugin)? A: Yes.Q: Is a plugin always developed inside a standalone package, or can it be developed inline within a project? A: It can be developed inline within a project. See
examples/jay-stack/fake-shopfor an example.Q: How does a plugin describe which contract/action to use when? A: Add a
descriptionfield to.jay-contractfiles (.jay-actionalready has one). Theagent-kitcommand extracts descriptions into the materialized index, giving agents a quick overview without opening every file.plugin.yamlkeeps its shortdescriptionper contract as a summary for indexing.Q: How does a plugin tell the agent about its reference files? A: Two parts: (1) plugin declares its references in
plugin.yamlso the system knows they exist, (2) theagent-kitcommand generates anINDEX.mdper plugin inreferences/<plugin>/describing what each reference file contains and how to use it.Q: Should there be three agent-kits instead of two? A: Yes. Three roles: designer (creates jay-html UI), developer (builds the project, wiring, config), plugin (creates contracts, components, actions). All under one
agent-kit/folder as subfolders.Q: Should
agent-kitwork beforesetup? A: Yes. Before setup: generates instruction/guide files only, notes which plugins are not initialized (as info, not errors). After setup: also materializes contracts and references.Q: Should plugins be able to contribute skills to each agent-kit? A: Yes. A plugin package can include an
agent-kit/folder with subfolders matching the three roles (designer/,developer/,plugin/). Theagent-kitcommand merges these into the project's agent-kit.Q: What should we call the three folders and their instruction files? A: Folders:
designer/,developer/,plugin/— these are roles, not agents. Instruction files: guides (not "skills" to avoid confusion with.cursor/skills/). Each folder has anINSTRUCTIONS.mdas the index pointing to the guides.
Design
CLI Interface
jay-stack agent-kit # generates all three roles
jay-stack agent-kit --mode plugin # generate only plugin guides
jay-stack agent-kit --mode designer # generate only designer guides
jay-stack agent-kit --mode developer # generate only developer guides
Before jay-stack setup: generates guide files only, notes uninitialized plugins as info (not errors).
After jay-stack setup: also materializes contracts and references.
Document Size Guideline
Each guide file should aim for 100–200 lines. If a document exceeds ~250 lines, split it into focused sub-documents. The structure below is the initial split — it is flexible and should be adjusted based on actual content length during implementation.
Unified Agent-Kit Output
agent-kit/
├── references/ # Plugin-generated reference data
│ └── <plugin-name>/
│ ├── INDEX.md # Describes each reference file
│ └── ...reference files
├── materialized-contracts/ # Materialized contract files
│
├── designer/ # Role: creates jay-html UI
│ ├── INSTRUCTIONS.md # Workflow + index of guides
│ ├── jay-html-syntax.md
│ ├── jay-html-template-syntax.md
│ ├── jay-html-components.md
│ ├── jay-html-styling.md
│ ├── routing.md
│ ├── contracts-and-plugins.md # Reading contracts, mapping to jay-html
│ ├── cli-commands.md
│ └── <plugin-contributed>*.md # Plugins can add designer guides
│
├── developer/ # Role: builds the project + page components
│ ├── INSTRUCTIONS.md
│ ├── project-structure.md
│ ├── routing.md
│ ├── configuration.md # .jay, plugin config, init
│ ├── page-contracts.md # Page-level contracts (page.jay-contract)
│ ├── page-components.md # page.ts: makeJayStackComponent for pages
│ ├── component-state.md # createSignal, createMemo, createEffect, etc.
│ ├── component-refs.md # Refs, collection refs
│ ├── component-data.md # Immutable data, JSON Patch, map
│ ├── render-results.md # phaseOutput, RenderPipeline, errors, redirects
│ ├── cli-commands.md
│ └── <plugin-contributed>*.md # Plugins can add developer guides
│
└── plugin/ # Role: creates plugins (contracts, components, actions)
├── INSTRUCTIONS.md
├── contracts-guide.md
├── plugin-structure.md
├── component-structure.md
├── component-state.md
├── component-refs.md
├── component-data.md
├── component-context.md
├── render-results.md
├── actions-guide.md
├── services-guide.md
├── validation.md
└── <plugin-contributed>*.md # Plugins can add plugin-author guides
Contract Description Field
Add description to .jay-contract files:
name: product-page
description: Full product detail page with gallery, options, and add-to-cart. Use for individual product routes like /products/[slug].
params:
slug: string
tags: ...
The agent-kit command extracts descriptions into the materialized index.
Plugin-Contributed Guides
A plugin package can include an agent-kit/ folder:
my-plugin/
├── plugin.yaml
├── agent-kit/
│ ├── designer/
│ │ └── my-plugin-usage.md # "How to use this plugin's contracts in jay-html"
│ ├── developer/
│ │ └── my-plugin-config.md # "How to configure this plugin"
│ └── plugin/
│ └── my-plugin-extending.md # "How to extend this plugin"
└── lib/
└── ...
The agent-kit command merges these into the project's agent-kit.
Plugin Reference Declaration
Plugins declare references in plugin.yaml:
references:
- name: product-catalog
description: All products with IDs, slugs, names, and prices
file: product-catalog.json
- name: collection-schemas
description: Collection field schemas for filtering
file: collection-schemas.json
The agent-kit command generates references/<plugin>/INDEX.md from these declarations.
Key Content Areas — Developer Guides
The developer role includes creating page-level full-stack components (page.ts) with their own contracts (page.jay-contract). Many component guides are shared with the plugin role — the content is the same, but scoped to page components rather than plugin components.
Page Contracts (page-contracts.md)
- When a page needs its own contract (page-level data, not from a plugin)
page.jay-contractformat — same as plugin contracts but for page-owned data- Props and params in page contracts
- Combining page contract with headless plugin contracts
Page Components (page-components.md)
page.tsfile:makeJayStackComponentfor page-level logic- Three-phase rendering in a page context
loadParamsfor route params- Combining page component with headless plugin components on the same page
Component State, Refs, Data, Render Results
Same content as plugin guides (component-state.md, component-refs.md, component-data.md, render-results.md) — shared template files between developer and plugin roles.
Key Content Areas — Plugin Guides
Contract Authoring (contracts-guide.md)
- Full
.jay-contractYAML format with all tag types (data, variant, interactive, sub-contract) - Async data types:
Promise<T>for data fetched asynchronously - Sub-contracts: nested and linked, repeated with
trackBy - Interactive elements: refs, element types
- Props vs params: when to use each — props for component configuration (passed by parent), params for URL route segments (passed by routing)
- Phase guidance: how to decide
slowvsfastvsfast+interactive— what belongs at build time vs request time vs client-side - Description field: always include a description explaining when to use this contract
- Examples of good and bad contracts
Component Structure (component-structure.md)
makeJayStackComponentwith three-phase rendering- Builder API:
.withProps(),.withServices(),.withContexts() - Props parameter and how it maps to contract
props loadParamsand how it maps to contractparams
Component State (component-state.md)
createSignalandcreatePatchableSignal— reactive statecreateMemo— computed valuescreateEffect— side effects with cleanupcreateDerivedArray— optimized array mappingcreateEvent— component event emitters
Component Refs (component-refs.md)
- How to use refs for interactive elements
- Collection refs for repeated elements
- Element types (HTMLButtonElement, HTMLInputElement, etc.)
Component Data (component-data.md)
- Data is immutable — never mutate directly
- Using JSON Patch to update data
- The
maphook for transforming data
Component Context (component-context.md)
provideContext/provideReactiveContextcreateReactiveContext/registerReactiveGlobalContext
Render Results (render-results.md)
phaseOutputfor successful phase outputRenderPipelinefor composable render flows- Error responses:
notFound,badRequest,unauthorized,forbidden,serverError5xx,clientError4xx - Redirects:
redirect3xx
Plugin Structure (plugin-structure.md)
plugin.yamlformat: contracts, actions, services, contexts, config templates, references- Listing services and contexts in
plugin.yamlwithname,marker, anddescription - Package layout:
lib/,dist/, exports - NPM package requirements (
package.jsonexports field) - Inline plugins within a project (see
examples/jay-stack/fake-shop) - Contributing agent-kit guides for each role
Actions (actions-guide.md)
makeJayAction/makeJayQuery.jay-actionfile format with typed schemas- Action registry and service injection
Services (services-guide.md)
createJayService— service markers for dependency injectionmakeJayInit— server/client initialization- Listing services in
plugin.yaml:name,marker,description - Services provide server-side APIs (e.g., product catalog queries) for other plugins or page components to consume via
.withServices(MARKER)
Contexts (component-context.md)
provideContext/provideReactiveContextcreateReactiveContext/registerReactiveGlobalContext- Listing contexts in
plugin.yaml:name,marker,description - Contexts provide client-side reactive state (e.g., cart state) for other plugins or page components to consume via
.withContexts(MARKER)
Validation (validation.md)
- Running
jay-stack validate-plugin - Common validation errors and how to fix them
Workflow in Plugin INSTRUCTIONS.md
- Read INSTRUCTIONS.md for overview
- Read the relevant guides for the task at hand
- Define contracts first (source of truth) — include
descriptionfield - Implement components matching the contracts
- Define services and contexts if the plugin provides APIs for other plugins
- Define actions with
.jay-actionmetadata - Set up
plugin.yaml— list contracts, actions, services, contexts (each withname,description) - Optionally add agent-kit guides for designer/developer roles
- Run
jay-stack validate-pluginto check correctness
Implementation Plan
Phase 1: Unified folder structure + plugin guides
- Restructure
agent-kit-template/to output intoagent-kit/designer/(move existing project guides there) - Create
agent-kit-plugin-template/with plugin guide files, output intoagent-kit/plugin/ - Create
agent-kit-developer-template/with developer guide files, output intoagent-kit/developer/
Phase 2: CLI integration
- Add
--modeflag toagent-kitcommand (designer,developer,plugin, or all) - Support running before setup (guides only, no materialized contracts/references)
Phase 3: Contract description field
- Add
descriptionto.jay-contractparser - Extract descriptions into materialized index during
agent-kit
Phase 4: Plugin-contributed guides
- Read
agent-kit/folder from each plugin package - Merge contributed guides into the project's agent-kit under the appropriate role folder
Phase 5: Plugin reference declarations
- Add
referencessection toplugin.yamlschema - Generate
references/<plugin>/INDEX.mdfrom declarations duringagent-kit
Trade-offs
- Unified
agent-kit/folder with role subfolders keeps everything discoverable - Three roles may seem heavy but reflects real workflow separation — most projects will only use one or two
- Before-setup support means guide files are static templates (no plugin-specific content), but still valuable for bootstrapping
- Plugin-contributed guides require plugins to opt in — no extra burden on plugins that don't need it
Implementation Results
Phase 3: Contract description field — completed
Contract type (compiler-jay-html/lib/contract/contract.ts): Added optional description?: string field to Contract interface.
Contract parser (contract-parser.ts): Parses top-level description from .jay-contract YAML. Added to ParsedYaml interface.
PluginContractEntry (contract-materializer.ts): Added optional description?: string field.
Materialization: Contract descriptions are resolved from two sources:
plugin.yamlmanifest entrydescription(preferred).jay-contractfile top-leveldescription(fallback — reads and parses the contract file)
Both static and dynamic contract paths include the description in plugins-index.yaml. The listing path (used by CLI) also resolves descriptions.
Boolean attribute agent-kit documentation
Added "Boolean Attributes" section to agent-kit-template/designer/jay-html-template-syntax.md explaining disabled="boolField" and disabled="!boolField" patterns.
Open: Services and contexts in plugin.yaml and plugins-index.yaml
Services and contexts provide APIs that allow one plugin to provide functionality for other plugins to consume (e.g., WIX_STORES_SERVICE provides product data that other plugins can use). Currently these are not listed in plugin.yaml or plugins-index.yaml.
Needed:
Purpose: Services provide server-side APIs (e.g., product queries). Contexts provide client-side reactive state (e.g., cart state). One plugin provides them, other plugins consume them via
withServices(MARKER)/withContexts(MARKER).Listing with description — Add to
plugin.yaml:services: - name: wix-stores marker: WIX_STORES_SERVICE_MARKER description: Provides Wix Stores product catalog API (query products, collections, variants) contexts: - name: wix-stores marker: WIX_STORES_CONTEXT description: Client-side cart and store interaction contextPropagate to
plugins-index.yamlso agents know what services/contexts each plugin offers. The provider function is an internal concern — not listed.Validation — In
validate-plugin:- If a component uses
.withServices(MARKER), verify the service is listed in the plugin'splugin.yaml(or a dependency's) - If a component uses
.withContexts(MARKER), verify the context is listed
- If a component uses
Documentation (optional) — If a plugin provides a markdown doc for a service/context:
services: - name: wix-stores marker: WIX_STORES_SERVICE_MARKER description: ... doc: ./docs/wix-stores-service.md # optional- Referenced from
plugin.yamlandplugins-index.yaml - Validated: if
docis specified, the file must exist and be exported from the package
- Referenced from
Addendum: Plugin-contributed agent-kit guides
Problem
Plugins need to ship guides for AI agents — how to use the plugin's components in jay-html (designer role), how to configure the plugin (developer role), etc. The framework's built-in agent-kit only covers generic patterns.
Design
Plugins include an agent-kit/ folder with role subfolders. During jay-stack agent-kit, the CLI scans all installed plugins for agent-kit/{role}/*.md files and copies them into the project's agent-kit/{role}/ alongside the framework guides.
my-plugin/
├── agent-kit/
│ ├── designer/
│ │ └── my-plugin-usage.md
│ └── developer/
│ └── my-plugin-config.md
├── plugin.yaml
└── package.json # files: ["dist", "plugin.yaml", "agent-kit"]
No plugin.yaml declaration needed — the CLI discovers guides by scanning the directory.
Implementation
Added mergePluginAgentKitGuides() in stack-cli/lib/cli.ts. Called after ensureAgentKitDocs() in the agent-kit command. Uses scanPlugins() to find all installed plugins, checks each for agent-kit/{role}/ directories, copies .md files to the project's agent-kit.
Notes on INSTRUCTIONS.md
Plugin-contributed guides are NOT automatically added to the role's INSTRUCTIONS.md table. The framework's INSTRUCTIONS.md is overwritten each time agent-kit runs (from the template). Plugin guides are discovered by the agent through file listing or the plugins-index — they don't need explicit INSTRUCTIONS.md entries.
Log Methodology Note
Note: These design logs are written primarily for AI agents as part of the Design Log methodology and made accessible here for human readers. The language and structure are optimized for machine consumption — expect precise, specification-style prose rather than narrative documentation.