@jay-framework/jay-stack-cli 0.10.0 → 0.12.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/README.md +134 -10
- package/agent-kit-template/INSTRUCTIONS.md +116 -0
- package/agent-kit-template/cli-commands.md +229 -0
- package/agent-kit-template/contracts-and-plugins.md +229 -0
- package/agent-kit-template/jay-html-syntax.md +312 -0
- package/agent-kit-template/project-structure.md +242 -0
- package/agent-kit-template/routing.md +112 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +847 -136
- package/package.json +14 -6
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
# Project Structure
|
|
2
|
+
|
|
3
|
+
## Directory Layout
|
|
4
|
+
|
|
5
|
+
A jay-stack project follows this structure:
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
my-project/
|
|
9
|
+
├── .jay # Dev server configuration (optional)
|
|
10
|
+
├── package.json # Dependencies and scripts
|
|
11
|
+
├── tsconfig.json # TypeScript config
|
|
12
|
+
├── public/ # Static assets (images, fonts, etc.)
|
|
13
|
+
├── config/ # Plugin configuration (generated by jay-stack setup)
|
|
14
|
+
│ ├── project.conf.yaml # Project metadata (name, etc.)
|
|
15
|
+
│ └── <plugin-name>.yaml # Plugin-specific config files
|
|
16
|
+
├── src/
|
|
17
|
+
│ ├── pages/ # Pages (directory-based routing)
|
|
18
|
+
│ │ ├── page.jay-html # Homepage → /
|
|
19
|
+
│ │ ├── page.jay-contract # Homepage contract (optional)
|
|
20
|
+
│ │ ├── products/
|
|
21
|
+
│ │ │ ├── page.jay-html # Products list → /products
|
|
22
|
+
│ │ │ └── [slug]/
|
|
23
|
+
│ │ │ └── page.jay-html # Product detail → /products/:slug
|
|
24
|
+
│ │ └── cart/
|
|
25
|
+
│ │ └── page.jay-html # Cart → /cart
|
|
26
|
+
│ └── styles/
|
|
27
|
+
│ └── theme.css # Global theme stylesheet
|
|
28
|
+
└── agent-kit/ # Generated by jay-stack agent-kit
|
|
29
|
+
├── INSTRUCTIONS.md
|
|
30
|
+
├── materialized-contracts/ # Contracts and indexes
|
|
31
|
+
└── references/ # Plugin reference data (product catalogs, schemas)
|
|
32
|
+
└── <plugin-name>/ # Per-plugin discovery data
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## What You Create
|
|
36
|
+
|
|
37
|
+
As an agent building pages, you typically create:
|
|
38
|
+
|
|
39
|
+
1. **`src/pages/**/\*.jay-html`\*\* — Page templates (the main output)
|
|
40
|
+
2. **`src/pages/**/\*.jay-contract`\*\* — Page-level contracts (when the page has its own data)
|
|
41
|
+
3. **`src/styles/*.css`** — Theme stylesheet (one per project, reused across pages)
|
|
42
|
+
|
|
43
|
+
You do **not** need to create: `package.json`, `tsconfig.json`, `.jay`, `page.conf.yaml`, `src/init.ts`, server actions, or services — these are set up by the project scaffolding, the Figma plugin, or provided by plugins.
|
|
44
|
+
|
|
45
|
+
## Styling
|
|
46
|
+
|
|
47
|
+
### Global Theme (src/styles/)
|
|
48
|
+
|
|
49
|
+
Each project has a theme CSS file in `src/styles/` with CSS custom properties (design tokens):
|
|
50
|
+
|
|
51
|
+
```css
|
|
52
|
+
:root {
|
|
53
|
+
/* Colors */
|
|
54
|
+
--bg-primary: #faf8f5;
|
|
55
|
+
--bg-card: #ffffff;
|
|
56
|
+
--text-primary: #2d2a26;
|
|
57
|
+
--text-secondary: #6b665e;
|
|
58
|
+
--accent: #c45c3e;
|
|
59
|
+
--accent-hover: #d4704f;
|
|
60
|
+
--border: #e8e4dd;
|
|
61
|
+
|
|
62
|
+
/* Typography */
|
|
63
|
+
--font-serif: 'Cormorant Garamond', Georgia, serif;
|
|
64
|
+
--font-sans: 'DM Sans', -apple-system, sans-serif;
|
|
65
|
+
|
|
66
|
+
/* Spacing & Layout */
|
|
67
|
+
--radius-md: 10px;
|
|
68
|
+
--radius-lg: 14px;
|
|
69
|
+
--container-max: 1400px;
|
|
70
|
+
--page-padding: 48px;
|
|
71
|
+
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.04);
|
|
72
|
+
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.06);
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The theme provides reusable CSS classes for common UI patterns:
|
|
77
|
+
|
|
78
|
+
- **Layout**: `.container`, `.container-narrow`
|
|
79
|
+
- **Cards**: `.card`, `.card-elevated`
|
|
80
|
+
- **Buttons**: `.btn`, `.btn-primary`, `.btn-secondary`, `.btn-ghost`, `.btn-sm`, `.btn-lg`
|
|
81
|
+
- **Forms**: `.input`, `.select`, `.checkbox`
|
|
82
|
+
- **Badges**: `.badge`, `.badge-accent`, `.badge-success`, `.badge-error`
|
|
83
|
+
- **Typography**: `.page-title`, `.section-title`, `.label`
|
|
84
|
+
- **Product components**: `.product-card`, `.product-card-image`, `.product-card-content`, `.product-card-price`
|
|
85
|
+
|
|
86
|
+
### Linking the Theme from Pages
|
|
87
|
+
|
|
88
|
+
Use a relative path from the page to the theme file:
|
|
89
|
+
|
|
90
|
+
```html
|
|
91
|
+
<!-- From src/pages/page.jay-html (depth 1) -->
|
|
92
|
+
<link rel="stylesheet" href="../styles/theme.css" />
|
|
93
|
+
|
|
94
|
+
<!-- From src/pages/products/page.jay-html (depth 2) -->
|
|
95
|
+
<link rel="stylesheet" href="../../styles/theme.css" />
|
|
96
|
+
|
|
97
|
+
<!-- From src/pages/products/[slug]/page.jay-html (depth 3) -->
|
|
98
|
+
<link rel="stylesheet" href="../../../styles/theme.css" />
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Page-Specific Styles
|
|
102
|
+
|
|
103
|
+
Add page-specific styles in `<style>` tags within the jay-html `<head>`:
|
|
104
|
+
|
|
105
|
+
```html
|
|
106
|
+
<head>
|
|
107
|
+
<link rel="stylesheet" href="../../styles/theme.css" />
|
|
108
|
+
<style>
|
|
109
|
+
.hero {
|
|
110
|
+
padding: 80px 0;
|
|
111
|
+
text-align: center;
|
|
112
|
+
}
|
|
113
|
+
.featured-grid {
|
|
114
|
+
display: grid;
|
|
115
|
+
grid-template-columns: repeat(3, 1fr);
|
|
116
|
+
gap: 24px;
|
|
117
|
+
}
|
|
118
|
+
</style>
|
|
119
|
+
</head>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### External Fonts
|
|
123
|
+
|
|
124
|
+
Import fonts in the theme CSS or via `<link>` in jay-html:
|
|
125
|
+
|
|
126
|
+
```css
|
|
127
|
+
/* In theme.css */
|
|
128
|
+
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Responsive Design
|
|
132
|
+
|
|
133
|
+
Use media queries in the theme CSS or page-specific styles:
|
|
134
|
+
|
|
135
|
+
```css
|
|
136
|
+
@media (max-width: 1024px) {
|
|
137
|
+
.product-page-layout {
|
|
138
|
+
grid-template-columns: 1fr;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
@media (max-width: 768px) {
|
|
142
|
+
.products-grid {
|
|
143
|
+
grid-template-columns: 1fr;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Configuration Files
|
|
149
|
+
|
|
150
|
+
### config/ (Plugin Configuration)
|
|
151
|
+
|
|
152
|
+
The `config/` folder holds plugin configuration files, typically generated by `jay-stack setup`:
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
config/
|
|
156
|
+
├── project.conf.yaml # Project name and metadata
|
|
157
|
+
└── wix-data.yaml # Plugin-specific config (auto-generated by setup)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Plugins create their config files here during setup. The location is configured via `configBase` in the `.jay` file (defaults to `./config`).
|
|
161
|
+
|
|
162
|
+
You generally don't need to create files here manually — plugins handle this via `jay-stack setup`. However, you may need to read these files to understand how a plugin is configured.
|
|
163
|
+
|
|
164
|
+
### .jay (Dev Server Config)
|
|
165
|
+
|
|
166
|
+
Optional YAML file at project root:
|
|
167
|
+
|
|
168
|
+
```yaml
|
|
169
|
+
devServer:
|
|
170
|
+
portRange:
|
|
171
|
+
- 3000
|
|
172
|
+
- 3100
|
|
173
|
+
pagesBase: ./src/pages
|
|
174
|
+
componentsBase: ./src/components
|
|
175
|
+
publicFolder: ./public
|
|
176
|
+
editorServer:
|
|
177
|
+
portRange:
|
|
178
|
+
- 3101
|
|
179
|
+
- 3200
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### package.json (Scripts)
|
|
183
|
+
|
|
184
|
+
Standard scripts for jay-stack projects:
|
|
185
|
+
|
|
186
|
+
```json
|
|
187
|
+
{
|
|
188
|
+
"scripts": {
|
|
189
|
+
"dev": "jay-stack-cli dev",
|
|
190
|
+
"validate": "jay-stack-cli validate",
|
|
191
|
+
"definitions": "jay-cli definitions src",
|
|
192
|
+
"build": "npm run definitions"
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Common Page Patterns
|
|
198
|
+
|
|
199
|
+
### Product List / Search Page
|
|
200
|
+
|
|
201
|
+
Uses a product search contract with filters, sorting, and pagination:
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
src/pages/products/
|
|
205
|
+
└── page.jay-html # Search input, filters sidebar, product grid, load more
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Product Detail Page (Dynamic Route)
|
|
209
|
+
|
|
210
|
+
Uses a product page contract with media gallery, options, and add-to-cart:
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
src/pages/products/[slug]/
|
|
214
|
+
└── page.jay-html # Gallery, options, quantity, actions
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Category Page
|
|
218
|
+
|
|
219
|
+
Uses a category contract with product grid:
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
src/pages/categories/[slug]/
|
|
223
|
+
└── page.jay-html # Category hero, product grid, load more
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Cart Page
|
|
227
|
+
|
|
228
|
+
Uses a cart contract with line items and checkout:
|
|
229
|
+
|
|
230
|
+
```
|
|
231
|
+
src/pages/cart/
|
|
232
|
+
└── page.jay-html # Line items, quantity controls, summary, coupon, checkout
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Homepage
|
|
236
|
+
|
|
237
|
+
Combines multiple headless components:
|
|
238
|
+
|
|
239
|
+
```
|
|
240
|
+
src/pages/
|
|
241
|
+
└── page.jay-html # Hero, featured products, categories, etc.
|
|
242
|
+
```
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Directory-Based Routing
|
|
2
|
+
|
|
3
|
+
## Route Structure
|
|
4
|
+
|
|
5
|
+
Pages live under `src/pages/`. Directory names become URL segments.
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
src/pages/
|
|
9
|
+
├── page.jay-html → /
|
|
10
|
+
├── about/
|
|
11
|
+
│ └── page.jay-html → /about
|
|
12
|
+
├── products/
|
|
13
|
+
│ ├── page.jay-html → /products
|
|
14
|
+
│ └── [slug]/
|
|
15
|
+
│ └── page.jay-html → /products/:slug
|
|
16
|
+
├── blog/
|
|
17
|
+
│ ├── page.jay-html → /blog
|
|
18
|
+
│ └── [[slug]]/
|
|
19
|
+
│ └── page.jay-html → /blog/:slug (optional)
|
|
20
|
+
└── files/
|
|
21
|
+
└── [...path]/
|
|
22
|
+
└── page.jay-html → /files/* (catch-all)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Dynamic Routes
|
|
26
|
+
|
|
27
|
+
| Syntax | Meaning | Example |
|
|
28
|
+
| ------------ | ------------------ | --------------------------------------- |
|
|
29
|
+
| `[param]` | Required parameter | `[slug]` → `/products/:slug` |
|
|
30
|
+
| `[[param]]` | Optional parameter | `[[slug]]` → `/blog` or `/blog/my-post` |
|
|
31
|
+
| `[...param]` | Catch-all | `[...path]` → matches any sub-path |
|
|
32
|
+
|
|
33
|
+
## Route Priority
|
|
34
|
+
|
|
35
|
+
Static routes match before dynamic routes (most specific first):
|
|
36
|
+
|
|
37
|
+
1. **Static segments** (exact match) — highest priority
|
|
38
|
+
2. **`[param]`** — required dynamic param
|
|
39
|
+
3. **`[[param]]`** — optional param
|
|
40
|
+
4. **`[...param]`** — catch-all — lowest priority
|
|
41
|
+
|
|
42
|
+
Static override alongside a dynamic route:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
src/pages/products/
|
|
46
|
+
├── [slug]/page.jay-html # dynamic: /products/:slug
|
|
47
|
+
└── ceramic-flower-vase/page.jay-html # static override for this specific product
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Page Files
|
|
51
|
+
|
|
52
|
+
Each page directory can contain:
|
|
53
|
+
|
|
54
|
+
| File | Purpose |
|
|
55
|
+
| ------------------- | ----------------------------------- |
|
|
56
|
+
| `page.jay-html` | Template (required for rendering) |
|
|
57
|
+
| `page.jay-contract` | Page-level data contract (optional) |
|
|
58
|
+
|
|
59
|
+
### page.jay-contract
|
|
60
|
+
|
|
61
|
+
Defines the page's own ViewState — data that the page's server-side code provides:
|
|
62
|
+
|
|
63
|
+
```yaml
|
|
64
|
+
name: Page
|
|
65
|
+
tags:
|
|
66
|
+
- tag: title
|
|
67
|
+
type: data
|
|
68
|
+
dataType: string
|
|
69
|
+
phase: slow
|
|
70
|
+
- tag: items
|
|
71
|
+
type: sub-contract
|
|
72
|
+
repeated: true
|
|
73
|
+
trackBy: id
|
|
74
|
+
tags:
|
|
75
|
+
- tag: id
|
|
76
|
+
type: data
|
|
77
|
+
dataType: string
|
|
78
|
+
- tag: name
|
|
79
|
+
type: data
|
|
80
|
+
dataType: string
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Dynamic Routes and Contract Params
|
|
84
|
+
|
|
85
|
+
When a contract declares `params`, it means the component expects those URL parameters to be provided by the route. This tells you that the page using this contract **should be placed in a matching dynamic route directory**.
|
|
86
|
+
|
|
87
|
+
For example, if a contract declares:
|
|
88
|
+
|
|
89
|
+
```yaml
|
|
90
|
+
name: product-page
|
|
91
|
+
params:
|
|
92
|
+
slug: string
|
|
93
|
+
tags:
|
|
94
|
+
- ...
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Then the page using this contract should live at a route that provides a `slug` param:
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
src/pages/products/[slug]/page.jay-html
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Discovering Param Values
|
|
104
|
+
|
|
105
|
+
For SSG with dynamic routes, the plugin component provides a `loadParams` generator that yields all valid param combinations. Use it to discover what routes will be generated:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
jay-stack params wix-stores/product-page
|
|
109
|
+
# Output: [{"slug": "blue-shirt"}, {"slug": "red-hat"}, ...]
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Params are always strings (URL params).
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
|
+
import { LogLevel } from '@jay-framework/logger';
|
|
1
2
|
import { PublishMessage, PublishResponse, SaveImageMessage, SaveImageResponse, HasImageMessage, HasImageResponse, GetProjectInfoMessage, GetProjectInfoResponse } from '@jay-framework/editor-protocol';
|
|
3
|
+
export { ContractIndexEntry, ContractsIndex, MaterializeContractsOptions, MaterializeResult, listContracts, materializeContracts } from '@jay-framework/stack-server-runtime';
|
|
2
4
|
|
|
3
5
|
interface StartDevServerOptions {
|
|
4
6
|
projectPath?: string;
|
|
7
|
+
/** Enable test endpoints (/_jay/health, /_jay/shutdown) */
|
|
8
|
+
testMode?: boolean;
|
|
9
|
+
/** Auto-shutdown after N seconds */
|
|
10
|
+
timeout?: number;
|
|
11
|
+
/** Log level for output */
|
|
12
|
+
logLevel?: LogLevel;
|
|
5
13
|
}
|
|
6
14
|
declare function startDevServer(options?: StartDevServerOptions): Promise<void>;
|
|
7
15
|
|