@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.
- package/agent-kit-template/designer/routing.md +19 -7
- package/agent-kit-template/developer/routing.md +19 -7
- package/agent-kit-template/plugin/INSTRUCTIONS.md +4 -4
- package/agent-kit-template/plugin/plugin-structure.md +9 -12
- package/agent-kit-template/plugin/setup-guide.md +53 -50
- package/dist/index.js +844 -61
- package/package.json +11 -11
|
@@ -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
|
|
54
|
+
### Static Override Params and Headless Component Props
|
|
55
55
|
|
|
56
|
-
Static override routes
|
|
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
|
-
|
|
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.
|
|
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
|
|
54
|
+
### Static Override Params and Headless Component Props
|
|
55
55
|
|
|
56
|
-
Static override routes
|
|
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
|
-
|
|
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.
|
|
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/
|
|
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
|
|
29
|
-
| `jay-stack agent-kit` | Before development | `
|
|
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
|
-
|
|
71
|
-
|
|
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
|
|
201
|
+
### Setup and agent-kit fields
|
|
205
202
|
|
|
206
|
-
- `
|
|
207
|
-
- `
|
|
208
|
-
- `description` — (optional)
|
|
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:** `
|
|
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
|
|
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 &
|
|
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
|
|
6
|
-
- **
|
|
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
|
|
12
|
-
jay-stack agent-kit →
|
|
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
|
|
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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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:**
|
|
27
|
-
**Local plugins:** relative paths to
|
|
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
|
|
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
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
|
61
|
-
: 'My Plugin
|
|
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
|
|
86
|
+
## Writing an Agent-Kit Handler
|
|
86
87
|
|
|
87
|
-
The
|
|
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
|
-
|
|
92
|
-
|
|
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
|
|
98
|
-
ctx:
|
|
99
|
-
): Promise<
|
|
99
|
+
export async function generateMyAgentKit(
|
|
100
|
+
ctx: PluginAgentKitContext,
|
|
101
|
+
): Promise<PluginAgentKitResult> {
|
|
100
102
|
if (ctx.initError) {
|
|
101
|
-
return {
|
|
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.
|
|
112
|
+
fs.writeFileSync(outputPath, yaml.stringify({ items }), 'utf-8');
|
|
112
113
|
|
|
113
114
|
return {
|
|
114
|
-
|
|
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
|
-
###
|
|
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
|
-
###
|
|
132
|
+
### PluginAgentKitResult
|
|
132
133
|
|
|
133
|
-
| Field
|
|
134
|
-
|
|
|
135
|
-
| `
|
|
136
|
-
| `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
|
|
139
|
+
## Setup vs Agent-Kit — When to Use Which
|
|
139
140
|
|
|
140
|
-
| Use case |
|
|
141
|
-
| -------------------------------------------------------------------- |
|
|
142
|
-
| Copy static
|
|
143
|
-
| Generate data from live services (product catalogs, CMS schemas) | `
|
|
144
|
-
| Validate credentials / API keys | `setup
|
|
145
|
-
| Write AIditor add-menu from project-specific data (DESIGN.md tokens) | `
|
|
141
|
+
| Use case | Hook | Why |
|
|
142
|
+
| -------------------------------------------------------------------- | ---------- | ----------------------------------------------------------- |
|
|
143
|
+
| Copy static add-menu template, skills, thumbnails | `agentkit` | Discovery data — regenerated 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
|
-
|
|
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
|
|
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 {
|
|
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
|
|
180
|
+
For local plugins, use relative paths in `plugin.yaml` and export `agentkit` or `default` from the handler module.
|