@jay-framework/jay-stack-cli 0.21.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -51,23 +51,22 @@ src/pages/products/
51
51
 
52
52
  The static `ceramic-flower-vase/` route takes priority over `[slug]/` for that URL, but all other product URLs still use the dynamic route.
53
53
 
54
- ### Static Override Params (`jay-params`)
54
+ ### Static Override Params and Headless Component Props
55
55
 
56
- Static override routes often use the same contract as the dynamic route they override. Since the static route has no dynamic directory segment, the params must be declared explicitly using `<script type="application/jay-params">`:
56
+ Static override routes use the same headless component as the dynamic route they override. Since the static route has no dynamic directory segment, the params must be declared in the headless component's YAML body:
57
57
 
58
58
  ```html
59
59
  <!-- src/pages/products/ceramic-flower-vase/page.jay-html -->
60
60
  <html>
61
61
  <head>
62
- <script type="application/jay-params">
63
- slug: ceramic-flower-vase
64
- </script>
65
62
  <script
66
63
  type="application/jay-headless"
67
64
  plugin="wix-stores"
68
65
  contract="product-page"
69
66
  key="product"
70
- ></script>
67
+ >
68
+ slug: ceramic-flower-vase
69
+ </script>
71
70
  </head>
72
71
  <body>
73
72
  <h1>{product.productName}</h1>
@@ -75,7 +74,20 @@ Static override routes often use the same contract as the dynamic route they ove
75
74
  </html>
76
75
  ```
77
76
 
78
- The script body is YAML. The declared params are passed to the component as if extracted from a dynamic URL segment. Without this, the component would receive no param values.
77
+ The script body is YAML. Values are passed to the component as props alongside route params. This same mechanism is used for any per-component configuration:
78
+
79
+ ```html
80
+ <script
81
+ type="application/jay-headless"
82
+ plugin="@jay-framework/markdown"
83
+ contract="markdown-pages"
84
+ key="post"
85
+ >
86
+ contentDir: ./content
87
+ </script>
88
+ ```
89
+
90
+ > **Note:** `<script type="application/jay-params">` is deprecated. Move param values into the headless component's script tag body.
79
91
 
80
92
  ## Page Files
81
93
 
@@ -51,23 +51,22 @@ src/pages/products/
51
51
 
52
52
  The static `ceramic-flower-vase/` route takes priority over `[slug]/` for that URL, but all other product URLs still use the dynamic route.
53
53
 
54
- ### Static Override Params (`jay-params`)
54
+ ### Static Override Params and Headless Component Props
55
55
 
56
- Static override routes often use the same contract as the dynamic route they override. Since the static route has no dynamic directory segment, the params must be declared explicitly using `<script type="application/jay-params">`:
56
+ Static override routes use the same headless component as the dynamic route they override. Since the static route has no dynamic directory segment, the params must be declared in the headless component's YAML body:
57
57
 
58
58
  ```html
59
59
  <!-- src/pages/products/ceramic-flower-vase/page.jay-html -->
60
60
  <html>
61
61
  <head>
62
- <script type="application/jay-params">
63
- slug: ceramic-flower-vase
64
- </script>
65
62
  <script
66
63
  type="application/jay-headless"
67
64
  plugin="wix-stores"
68
65
  contract="product-page"
69
66
  key="product"
70
- ></script>
67
+ >
68
+ slug: ceramic-flower-vase
69
+ </script>
71
70
  </head>
72
71
  <body>
73
72
  <h1>{product.productName}</h1>
@@ -75,7 +74,20 @@ Static override routes often use the same contract as the dynamic route they ove
75
74
  </html>
76
75
  ```
77
76
 
78
- The script body is YAML. The declared params are passed to the component as if extracted from a dynamic URL segment. Without this, the component would receive no param values.
77
+ The script body is YAML. Values are passed to the component as props alongside route params. This same mechanism is used for any per-component configuration:
78
+
79
+ ```html
80
+ <script
81
+ type="application/jay-headless"
82
+ plugin="@jay-framework/markdown"
83
+ contract="markdown-pages"
84
+ key="post"
85
+ >
86
+ contentDir: ./content
87
+ </script>
88
+ ```
89
+
90
+ > **Note:** `<script type="application/jay-params">` is deprecated. Move param values into the headless component's script tag body.
79
91
 
80
92
  ## Page Files
81
93
 
@@ -13,8 +13,8 @@ A plugin provides headless components (data + interactions, no UI) that project
13
13
  3. **Define actions** with `.jay-action` metadata
14
14
  4. **Optionally add routes** — pages for admin tools and dashboards
15
15
  5. **Optionally add validators** — custom jay-html validation rules
16
- 6. **Optionally add setup/references handlers** — config templating, add-menu generation
17
- 7. **Set up `plugin.yaml`** — list contracts, actions, services, contexts, routes, validators, setup
16
+ 6. **Optionally add setup/agentkit handlers** — config templating, add-menu generation
17
+ 7. **Set up `plugin.yaml`** — list contracts, actions, services, contexts, routes, validators, setup, agentkit
18
18
  8. **Configure build** — dual entry points (server + client), vite.config.ts, package.json exports
19
19
  9. **Validate** with `jay-stack validate-plugin`
20
20
 
@@ -25,8 +25,8 @@ The plugin participates in four CLI commands, each running different hooks:
25
25
  | Command | When | What runs from your plugin |
26
26
  | --------------------------- | ------------------ | ---------------------------------------------------------------------------------- |
27
27
  | `jay-stack validate-plugin` | Plugin development | Checks plugin.yaml structure, contracts, exports, handler references |
28
- | `jay-stack setup <plugin>` | Project setup | `setup.handler` — creates config files, validates credentials |
29
- | `jay-stack agent-kit` | Before development | `setup.references` — generates add-menu items, reference data |
28
+ | `jay-stack setup <plugin>` | Project setup | `setup` — creates config files, validates credentials |
29
+ | `jay-stack agent-kit` | Before development | `agentkit` — generates add-menu items, reference data, skills, thumbnails |
30
30
  | `jay-stack validate` | During development | `validators[].handler` — runs your validation rules against project jay-html files |
31
31
 
32
32
  **`validate-plugin`** validates YOUR plugin's structure. Run it during plugin development.
@@ -66,12 +66,9 @@ validators:
66
66
  handler: validateMediaOptimization
67
67
  description: Ensures media URLs use resize parameters
68
68
 
69
- setup:
70
- handler: setup-handler
71
- references: references-handler
72
- configTemplate:
73
- - source: templates/config.yaml
74
- target: my-plugin.yaml
69
+ setup: setup-handler
70
+ agentkit: agentkit-handler
71
+ description: Configure My Plugin
75
72
  ```
76
73
 
77
74
  ### Contract Entry Fields
@@ -201,16 +198,16 @@ Commands are CLI operations run via `jay-stack run`. Use `makeCliCommand()` to c
201
198
 
202
199
  Validators run during `jay-stack validate` against every parsed jay-html file in the project. See [validation.md](validation.md) for implementation details.
203
200
 
204
- ### Setup Fields
201
+ ### Setup and agent-kit fields
205
202
 
206
- - `handler` — Export name (NPM) or relative path (local) for `jay-stack setup <plugin>`. Creates config files, validates credentials and services.
207
- - `references` — Export name (NPM) or relative path (local) for `jay-stack agent-kit`. Generates discovery data: add-menu items, reference files.
208
- - `description` — (optional) What this setup does
203
+ - `setup` — Export name (NPM) or relative path (local) for `jay-stack setup <plugin>`. Creates config files, validates credentials and services.
204
+ - `agentkit` — Export name (NPM) or relative path (local) for `jay-stack agent-kit`. Generates discovery data: add-menu catalogs, reference files, skills, thumbnails.
205
+ - `description` — (optional, top-level) Human-readable description of what setup validates
209
206
 
210
- **NPM plugins:** `handler` and `references` are export names from the package entry point.
207
+ **NPM plugins:** `setup` and `agentkit` are export names from the package entry point.
211
208
  **Local plugins:** relative paths to the handler modules.
212
209
 
213
- `jay-stack validate-plugin` checks that these handlers exist and are correctly exported.
210
+ `jay-stack validate-plugin` checks that declared handlers exist and are correctly exported.
214
211
 
215
212
  See [setup-guide.md](setup-guide.md) for implementation details.
216
213
 
@@ -1,36 +1,38 @@
1
- # Plugin Setup & References
1
+ # Plugin Setup & Agent-Kit
2
2
 
3
3
  Plugins can provide two hooks for project configuration and AI agent discovery:
4
4
 
5
- - **Setup handler** — runs during `jay-stack setup <plugin>`. Creates config files, validates credentials, copies AIditor assets.
6
- - **References handler** — runs during `jay-stack agent-kit`. Generates discovery data (add-menu items, reference files) using live services.
5
+ - **Setup handler** (`setup` in `plugin.yaml`) — runs during `jay-stack setup <plugin>`. Creates config files, validates credentials.
6
+ - **Agent-kit handler** (`agentkit` in `plugin.yaml`) — runs during `jay-stack agent-kit`. Generates discovery data (add-menu catalogs, reference files, skills, thumbnails) using live services when needed.
7
7
 
8
8
  ## When Each Runs
9
9
 
10
10
  ```
11
- jay-stack setup <plugin> → setup.handler()
12
- jay-stack agent-kit → setup.references() (after contract materialization)
11
+ jay-stack setup <plugin> → setup handler (config + credentials)
12
+ jay-stack agent-kit → agentkit handler (after contract materialization)
13
13
  ```
14
14
 
15
- Setup runs once when a project first installs the plugin. Agent-kit runs whenever the developer regenerates the agent kit — it can use live services to produce fresh data.
15
+ Setup runs when a project configures the plugin. Agent-kit runs whenever the developer regenerates the agent kit — it can use live services to produce fresh data.
16
16
 
17
17
  ## Declaring in plugin.yaml
18
18
 
19
19
  ```yaml
20
- setup:
21
- handler: setupMyPlugin # export name (NPM) or ./path (local)
22
- references: generateMyReferences # export name (NPM) or ./path (local)
23
- description: Install My Plugin config and AIditor catalog
20
+ name: my-plugin
21
+ setup: setupMyPlugin # export name (NPM) or ./path (local) — optional
22
+ agentkit: generateMyAgentKit # export name (NPM) or ./path (local) — optional
23
+ description: Validate credentials and install config # optional, top-level
24
24
  ```
25
25
 
26
- **NPM plugins:** both values are export names from the package entry point (`lib/index.ts`).
27
- **Local plugins:** relative paths to the handler modules.
26
+ **NPM plugins:** `setup` and `agentkit` are export names from the package entry point (`lib/index.ts`).
27
+ **Local plugins:** relative paths to handler modules (e.g. `agentkit: ./agentkit` — export `agentkit` or `default` from that module).
28
28
 
29
- `jay-stack validate-plugin` checks that these exist and are correctly exported.
29
+ `jay-stack validate-plugin` checks that declared handlers exist and are correctly exported.
30
30
 
31
31
  ## Writing a Setup Handler
32
32
 
33
- The setup handler creates config files and AIditor assets. It receives a `PluginSetupContext` and returns a `PluginSetupResult`.
33
+ The setup handler creates config files and validates services. It receives a `PluginSetupContext` and returns a `PluginSetupResult`.
34
+
35
+ **Do not** write add-menu catalogs in setup — use the agent-kit handler.
34
36
 
35
37
  ```typescript
36
38
  import type { PluginSetupContext, PluginSetupResult } from '@jay-framework/stack-server-runtime';
@@ -43,13 +45,12 @@ export async function setupMyPlugin(ctx: PluginSetupContext): Promise<PluginSetu
43
45
  }
44
46
 
45
47
  const configCreated: string[] = [];
48
+ const configPath = path.join(ctx.configDir, '.my-plugin.yaml');
46
49
 
47
- // Write AIditor add-menu catalog
48
- const addMenuPath = path.join(ctx.projectRoot, 'agent-kit/aiditor/add-menu/my-plugin.yaml');
49
- if (!fs.existsSync(addMenuPath) || ctx.force) {
50
- fs.mkdirSync(path.dirname(addMenuPath), { recursive: true });
51
- fs.writeFileSync(addMenuPath, templateContent, 'utf-8');
52
- configCreated.push('agent-kit/aiditor/add-menu/my-plugin.yaml');
50
+ if (!fs.existsSync(configPath) || ctx.force) {
51
+ fs.mkdirSync(ctx.configDir, { recursive: true });
52
+ fs.writeFileSync(configPath, '# My Plugin config\n', 'utf-8');
53
+ configCreated.push('config/.my-plugin.yaml');
53
54
  }
54
55
 
55
56
  return {
@@ -57,8 +58,8 @@ export async function setupMyPlugin(ctx: PluginSetupContext): Promise<PluginSetu
57
58
  configCreated,
58
59
  message:
59
60
  configCreated.length > 0
60
- ? 'My Plugin catalog installed.'
61
- : 'My Plugin catalog already present (use --force to rewrite).',
61
+ ? 'My Plugin config installed.'
62
+ : 'My Plugin config already present (use --force to rewrite).',
62
63
  };
63
64
  }
64
65
  ```
@@ -82,42 +83,42 @@ export async function setupMyPlugin(ctx: PluginSetupContext): Promise<PluginSetu
82
83
  | `configCreated` | `string[]?` | Config files created (relative to project root) |
83
84
  | `message` | `string?` | Human-readable status message |
84
85
 
85
- ## Writing a References Handler
86
+ ## Writing an Agent-Kit Handler
86
87
 
87
- The references handler generates discovery data at agent-kit time. It can use live services (database queries, API calls) to produce dynamic content.
88
+ The agent-kit handler generates discovery data at agent-kit time: add-menu catalogs, `agent-kit/references/<plugin>/` files, skills, thumbnails. It can use live services (database queries, API calls) to produce dynamic content.
88
89
 
89
90
  ```typescript
90
91
  import type {
91
- PluginReferencesContext,
92
- PluginReferencesResult,
92
+ PluginAgentKitContext,
93
+ PluginAgentKitResult,
93
94
  } from '@jay-framework/stack-server-runtime';
94
95
  import fs from 'node:fs';
95
96
  import path from 'node:path';
97
+ import yaml from 'yaml';
96
98
 
97
- export async function generateMyReferences(
98
- ctx: PluginReferencesContext,
99
- ): Promise<PluginReferencesResult> {
99
+ export async function generateMyAgentKit(
100
+ ctx: PluginAgentKitContext,
101
+ ): Promise<PluginAgentKitResult> {
100
102
  if (ctx.initError) {
101
- return { referencesCreated: [], message: `Skipped: ${ctx.initError.message}` };
103
+ return { agentKitCreated: [], message: `Skipped: ${ctx.initError.message}` };
102
104
  }
103
105
 
104
- // Example: generate add-menu items from live data
105
106
  const outputPath = path.join(ctx.projectRoot, 'agent-kit/aiditor/add-menu/my-plugin.yaml');
106
107
  fs.mkdirSync(path.dirname(outputPath), { recursive: true });
107
108
 
108
109
  const items = [
109
110
  { id: 'my-plugin:feature-1', title: 'Feature 1', category: 'My Plugin', prompt: '...' },
110
111
  ];
111
- fs.writeFileSync(outputPath, yaml.dump({ items }), 'utf-8');
112
+ fs.writeFileSync(outputPath, yaml.stringify({ items }), 'utf-8');
112
113
 
113
114
  return {
114
- referencesCreated: ['agent-kit/aiditor/add-menu/my-plugin.yaml'],
115
+ agentKitCreated: ['agent-kit/aiditor/add-menu/my-plugin.yaml'],
115
116
  message: `Generated ${items.length} add-menu items`,
116
117
  };
117
118
  }
118
119
  ```
119
120
 
120
- ### PluginReferencesContext
121
+ ### PluginAgentKitContext
121
122
 
122
123
  | Field | Type | Description |
123
124
  | --------------- | --------- | --------------------------------------------------------------- |
@@ -128,25 +129,25 @@ export async function generateMyReferences(
128
129
  | `initError` | `Error?` | Present if plugin init failed |
129
130
  | `force` | `boolean` | Whether `--force` flag was passed |
130
131
 
131
- ### PluginReferencesResult
132
+ ### PluginAgentKitResult
132
133
 
133
- | Field | Type | Description |
134
- | ------------------- | ---------- | ---------------------------------------- |
135
- | `referencesCreated` | `string[]` | Files created (relative to project root) |
136
- | `message` | `string?` | Human-readable status message |
134
+ | Field | Type | Description |
135
+ | ----------------- | ---------- | ---------------------------------------- |
136
+ | `agentKitCreated` | `string[]` | Files created (relative to project root) |
137
+ | `message` | `string?` | Human-readable status message |
137
138
 
138
- ## Setup vs References — When to Use Which
139
+ ## Setup vs Agent-Kit — When to Use Which
139
140
 
140
- | Use case | Handler | Why |
141
- | -------------------------------------------------------------------- | ------------------ | --------------------------------------------------------------- |
142
- | Copy static template files (add-menu catalog, skill guides) | `setup.handler` | Templates don't change copy once |
143
- | Generate data from live services (product catalogs, CMS schemas) | `setup.references` | Needs services initialized; regenerated on each `agent-kit` run |
144
- | Validate credentials / API keys | `setup.handler` | Part of initial project configuration |
145
- | Write AIditor add-menu from project-specific data (DESIGN.md tokens) | `setup.references` | Data comes from project files, not static templates |
141
+ | Use case | Hook | Why |
142
+ | -------------------------------------------------------------------- | ---------- | ----------------------------------------------------------- |
143
+ | Copy static add-menu template, skills, thumbnails | `agentkit` | Discovery dataregenerated on `jay-stack agent-kit` |
144
+ | Generate data from live services (product catalogs, CMS schemas) | `agentkit` | Needs services initialized; refreshed on each agent-kit run |
145
+ | Validate credentials / API keys | `setup` | Part of initial project configuration |
146
+ | Write AIditor add-menu from project-specific data (DESIGN.md tokens) | `agentkit` | Data comes from project files at agent-kit time |
146
147
 
147
148
  ## AIditor Add-Menu Items
148
149
 
149
- Both handlers can write to `agent-kit/aiditor/add-menu/<plugin-name>.yaml`. The AIditor discovers and loads all YAML files in this directory.
150
+ The agent-kit handler writes to `agent-kit/aiditor/add-menu/<plugin-name>.yaml`. The AIditor discovers and loads all YAML files in this directory.
150
151
 
151
152
  Each item:
152
153
 
@@ -163,15 +164,17 @@ items:
163
164
  Read agent-kit/designer/feature-name.md for usage guide.
164
165
  ```
165
166
 
167
+ See `agent-kit/plugin/aiditor-add-menu.md` (installed by `jay-stack setup aiditor`) for the full contributor guide.
168
+
166
169
  ## Exporting Handlers
167
170
 
168
- For NPM plugins, export the handlers from the package entry point:
171
+ For NPM plugins, export handlers from the package entry point:
169
172
 
170
173
  ```typescript
171
174
  // lib/index.ts
172
175
  export { setupMyPlugin } from './setup.js';
173
- export { generateMyReferences } from './references.js';
176
+ export { generateMyAgentKit } from './agentkit.js';
174
177
  // ... other exports (components, actions, services)
175
178
  ```
176
179
 
177
- For local plugins, use relative paths in plugin.yaml instead of export names.
180
+ For local plugins, use relative paths in `plugin.yaml` and export `agentkit` or `default` from the handler module.