@myop/cli 0.1.40 → 0.1.41
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/dist/myop-cli.js +1184 -833
- package/dist/skills/myop-component/SKILL.md +233 -0
- package/dist/skills/myop-component/references/best-practices.md +406 -0
- package/dist/skills/myop-component/references/component-api.md +357 -0
- package/dist/skills/myop-component/references/dev-workflow.md +218 -0
- package/dist/skills/myop-component/references/sizing-and-layout.md +270 -0
- package/dist/skills/myop-component/references/type-definitions.md +270 -0
- package/package.json +2 -2
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
# Sizing and Layout
|
|
2
|
+
|
|
3
|
+
Myop components run inside a container managed by the host application. Proper sizing and layout ensures the component renders without clipping, scrollbars, or layout shifts.
|
|
4
|
+
|
|
5
|
+
## Contents
|
|
6
|
+
- [Size Meta Tag](#size-meta-tag)
|
|
7
|
+
- [Required Base CSS](#required-base-css)
|
|
8
|
+
- [Layout Patterns](#layout-patterns)
|
|
9
|
+
- [Dynamic Size Requests](#dynamic-size-requests)
|
|
10
|
+
- [Common Mistakes](#common-mistakes)
|
|
11
|
+
|
|
12
|
+
## Size Meta Tag
|
|
13
|
+
|
|
14
|
+
Every component should declare its preferred dimensions in a `<meta>` tag inside `<head>`:
|
|
15
|
+
|
|
16
|
+
```html
|
|
17
|
+
<meta name="myop:size" content='{"width":"100%","height":"100%"}'>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The host reads this BEFORE rendering the component, so the container can be sized correctly from the start (no layout shift).
|
|
21
|
+
|
|
22
|
+
### Properties
|
|
23
|
+
|
|
24
|
+
All values are either a number (pixels) or the string `"100%"`:
|
|
25
|
+
|
|
26
|
+
| Property | Type | Description |
|
|
27
|
+
|----------|------|-------------|
|
|
28
|
+
| `width` | `number \| "100%"` | Preferred width in px, or `"100%"` to fill container |
|
|
29
|
+
| `height` | `number \| "100%"` | Preferred height in px, or `"100%"` to fill container |
|
|
30
|
+
| `minWidth` | `number` | Minimum acceptable width in px |
|
|
31
|
+
| `maxWidth` | `number` | Maximum useful width in px |
|
|
32
|
+
| `minHeight` | `number` | Minimum acceptable height in px |
|
|
33
|
+
| `maxHeight` | `number` | Maximum useful height in px |
|
|
34
|
+
|
|
35
|
+
### Examples
|
|
36
|
+
|
|
37
|
+
```html
|
|
38
|
+
<!-- Fill all available space (most common) -->
|
|
39
|
+
<meta name="myop:size" content='{"width":"100%","height":"100%"}'>
|
|
40
|
+
|
|
41
|
+
<!-- Fixed width sidebar component -->
|
|
42
|
+
<meta name="myop:size" content='{"width":300,"height":"100%","minWidth":200,"maxWidth":400}'>
|
|
43
|
+
|
|
44
|
+
<!-- Fixed height banner -->
|
|
45
|
+
<meta name="myop:size" content='{"width":"100%","height":80}'>
|
|
46
|
+
|
|
47
|
+
<!-- Card with constraints -->
|
|
48
|
+
<meta name="myop:size" content='{"width":350,"height":250,"minWidth":250,"maxWidth":500}'>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Required Base CSS
|
|
52
|
+
|
|
53
|
+
Every Myop component MUST include this base CSS to prevent unexpected scrollbars and ensure the component fills its container:
|
|
54
|
+
|
|
55
|
+
```css
|
|
56
|
+
* {
|
|
57
|
+
box-sizing: border-box;
|
|
58
|
+
margin: 0;
|
|
59
|
+
padding: 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
html, body {
|
|
63
|
+
width: 100%;
|
|
64
|
+
height: 100%;
|
|
65
|
+
overflow: hidden; /* Component handles its own scrolling */
|
|
66
|
+
margin: 0;
|
|
67
|
+
padding: 0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
#app-root {
|
|
71
|
+
width: 100%;
|
|
72
|
+
height: 100%;
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Why `overflow: hidden` on body?
|
|
77
|
+
|
|
78
|
+
The component is rendered inside an iframe by the host. If the body scrolls, the host has no way to control or sync that scroll. Instead, the component should manage scrolling internally with specific scrollable regions.
|
|
79
|
+
|
|
80
|
+
## Layout Patterns
|
|
81
|
+
|
|
82
|
+
### Full-height Flexbox (recommended)
|
|
83
|
+
|
|
84
|
+
Most components need a fixed header/footer with a scrollable content area:
|
|
85
|
+
|
|
86
|
+
```html
|
|
87
|
+
<div id="app-root">
|
|
88
|
+
<header class="header">Fixed Header</header>
|
|
89
|
+
<main class="content">
|
|
90
|
+
<!-- Scrollable content goes here -->
|
|
91
|
+
</main>
|
|
92
|
+
<footer class="footer">Fixed Footer</footer>
|
|
93
|
+
</div>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
```css
|
|
97
|
+
#app-root {
|
|
98
|
+
display: flex;
|
|
99
|
+
flex-direction: column;
|
|
100
|
+
height: 100%;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.header, .footer {
|
|
104
|
+
flex-shrink: 0; /* Don't collapse */
|
|
105
|
+
padding: 12px 16px;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.content {
|
|
109
|
+
flex: 1; /* Fill remaining space */
|
|
110
|
+
overflow-y: auto; /* Scroll when content overflows */
|
|
111
|
+
min-height: 0; /* CRITICAL for flex scrolling */
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**The `min-height: 0` on the scrollable area is critical.** Without it, flex items default to `min-height: auto` which prevents overflow from working correctly.
|
|
116
|
+
|
|
117
|
+
### Grid Layout
|
|
118
|
+
|
|
119
|
+
For dashboard-style components:
|
|
120
|
+
|
|
121
|
+
```css
|
|
122
|
+
#app-root {
|
|
123
|
+
display: grid;
|
|
124
|
+
grid-template-columns: 1fr 1fr;
|
|
125
|
+
grid-template-rows: auto 1fr;
|
|
126
|
+
gap: 12px;
|
|
127
|
+
height: 100%;
|
|
128
|
+
padding: 16px;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.header { grid-column: 1 / -1; }
|
|
132
|
+
.panel { overflow-y: auto; min-height: 0; }
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Centered Content
|
|
136
|
+
|
|
137
|
+
For simple display components:
|
|
138
|
+
|
|
139
|
+
```css
|
|
140
|
+
#app-root {
|
|
141
|
+
display: flex;
|
|
142
|
+
align-items: center;
|
|
143
|
+
justify-content: center;
|
|
144
|
+
height: 100%;
|
|
145
|
+
padding: 24px;
|
|
146
|
+
text-align: center;
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Dynamic Size Requests
|
|
151
|
+
|
|
152
|
+
If the component needs to change its size after initialization (e.g., content loaded, accordion expanded), use the `size-requested` CTA:
|
|
153
|
+
|
|
154
|
+
```javascript
|
|
155
|
+
// Request specific dimensions
|
|
156
|
+
window.myop_cta_handler('size-requested', {
|
|
157
|
+
width: 400,
|
|
158
|
+
height: 600,
|
|
159
|
+
required: true // true = content will be clipped without this size
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// Request only width change
|
|
163
|
+
window.myop_cta_handler('size-requested', {
|
|
164
|
+
width: 500,
|
|
165
|
+
minWidth: 350,
|
|
166
|
+
maxWidth: 700
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// Request based on content height
|
|
170
|
+
var contentHeight = document.getElementById('content').scrollHeight;
|
|
171
|
+
window.myop_cta_handler('size-requested', {
|
|
172
|
+
height: contentHeight + 40, // Add padding
|
|
173
|
+
required: false // Preference, not critical
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Size Request Payload
|
|
178
|
+
|
|
179
|
+
| Property | Type | Description |
|
|
180
|
+
|----------|------|-------------|
|
|
181
|
+
| `width` | `number \| null` | Desired width in px (`null` = no preference) |
|
|
182
|
+
| `height` | `number \| null` | Desired height in px (`null` = no preference) |
|
|
183
|
+
| `minWidth` | `number \| null` | Minimum acceptable width |
|
|
184
|
+
| `maxWidth` | `number \| null` | Maximum acceptable width |
|
|
185
|
+
| `minHeight` | `number \| null` | Minimum acceptable height |
|
|
186
|
+
| `maxHeight` | `number \| null` | Maximum acceptable height |
|
|
187
|
+
| `required` | `boolean` | `true` = content is clipped/broken without this size; `false` = preference only |
|
|
188
|
+
|
|
189
|
+
**Important:** The host application may choose to ignore size requests. Always design the component to be functional at any reasonable size, and use `required: true` sparingly.
|
|
190
|
+
|
|
191
|
+
## Common Mistakes
|
|
192
|
+
|
|
193
|
+
### Missing `min-height: 0` on flex children
|
|
194
|
+
|
|
195
|
+
```css
|
|
196
|
+
/* WRONG: Scrolling won't work */
|
|
197
|
+
.content {
|
|
198
|
+
flex: 1;
|
|
199
|
+
overflow-y: auto;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/* CORRECT: Enable flex overflow */
|
|
203
|
+
.content {
|
|
204
|
+
flex: 1;
|
|
205
|
+
overflow-y: auto;
|
|
206
|
+
min-height: 0;
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Body scrolling instead of internal scrolling
|
|
211
|
+
|
|
212
|
+
```css
|
|
213
|
+
/* WRONG: Body scrolls, host can't control it */
|
|
214
|
+
html, body {
|
|
215
|
+
overflow: auto;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/* CORRECT: Body never scrolls, content region scrolls */
|
|
219
|
+
html, body {
|
|
220
|
+
overflow: hidden;
|
|
221
|
+
}
|
|
222
|
+
.content {
|
|
223
|
+
overflow-y: auto;
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Forgetting `box-sizing: border-box`
|
|
228
|
+
|
|
229
|
+
```css
|
|
230
|
+
/* WRONG: Padding adds to width, causing overflow */
|
|
231
|
+
.panel {
|
|
232
|
+
width: 100%;
|
|
233
|
+
padding: 20px;
|
|
234
|
+
/* Actual width = 100% + 40px → overflow */
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/* CORRECT: Padding included in width */
|
|
238
|
+
* { box-sizing: border-box; }
|
|
239
|
+
.panel {
|
|
240
|
+
width: 100%;
|
|
241
|
+
padding: 20px;
|
|
242
|
+
/* Actual width = 100% → perfect fit */
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Fixed pixel dimensions instead of fluid
|
|
247
|
+
|
|
248
|
+
```css
|
|
249
|
+
/* WRONG: Breaks at different container sizes */
|
|
250
|
+
#app-root {
|
|
251
|
+
width: 500px;
|
|
252
|
+
height: 400px;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/* CORRECT: Fills whatever container the host provides */
|
|
256
|
+
#app-root {
|
|
257
|
+
width: 100%;
|
|
258
|
+
height: 100%;
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Size meta tag with invalid JSON
|
|
263
|
+
|
|
264
|
+
```html
|
|
265
|
+
<!-- WRONG: Using double quotes inside double quotes -->
|
|
266
|
+
<meta name="myop:size" content="{"width":"100%"}">
|
|
267
|
+
|
|
268
|
+
<!-- CORRECT: Single quotes wrapping, double quotes inside -->
|
|
269
|
+
<meta name="myop:size" content='{"width":"100%","height":"100%"}'>
|
|
270
|
+
```
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
# Type Definitions
|
|
2
|
+
|
|
3
|
+
Myop components declare their data contract using TypeScript interfaces inside a `<script type="myop/types">` block in the HTML `<head>`. These types are not executed by the browser - they serve as documentation for both AI agents and host application developers.
|
|
4
|
+
|
|
5
|
+
## Contents
|
|
6
|
+
- [Where Types Go](#where-types-go)
|
|
7
|
+
- [MyopInitData](#myopinitdata)
|
|
8
|
+
- [MyopCtaPayloads](#myopctapayloads)
|
|
9
|
+
- [Standard Declarations](#standard-declarations)
|
|
10
|
+
- [Common Type Patterns](#common-type-patterns)
|
|
11
|
+
- [Rules](#rules)
|
|
12
|
+
|
|
13
|
+
## Where Types Go
|
|
14
|
+
|
|
15
|
+
```html
|
|
16
|
+
<head>
|
|
17
|
+
<!-- ... other head elements ... -->
|
|
18
|
+
<script type="myop/types">
|
|
19
|
+
// =========================================================================
|
|
20
|
+
// COMPONENT-SPECIFIC TYPE DEFINITIONS
|
|
21
|
+
// =========================================================================
|
|
22
|
+
|
|
23
|
+
interface MyopInitData {
|
|
24
|
+
// Define your data shape here
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface MyopCtaPayloads {
|
|
28
|
+
// Define your actions here
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// =========================================================================
|
|
32
|
+
// DO NOT EDIT BELOW - Standard Myop type declarations
|
|
33
|
+
// =========================================================================
|
|
34
|
+
|
|
35
|
+
declare function myop_init_interface(): MyopInitData;
|
|
36
|
+
declare function myop_init_interface(data: MyopInitData): void;
|
|
37
|
+
|
|
38
|
+
declare function myop_cta_handler<K extends keyof MyopCtaPayloads>(
|
|
39
|
+
action: K,
|
|
40
|
+
payload: MyopCtaPayloads[K]
|
|
41
|
+
): void;
|
|
42
|
+
</script>
|
|
43
|
+
</head>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## MyopInitData
|
|
47
|
+
|
|
48
|
+
Defines the shape of data the component receives via `myop_init_interface(data)`.
|
|
49
|
+
|
|
50
|
+
### Simple Example
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
interface MyopInitData {
|
|
54
|
+
title: string;
|
|
55
|
+
description?: string;
|
|
56
|
+
count: number;
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Complex Example
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
interface MyopInitData {
|
|
64
|
+
user: {
|
|
65
|
+
id: string;
|
|
66
|
+
name: string;
|
|
67
|
+
avatar?: string;
|
|
68
|
+
role: 'admin' | 'editor' | 'viewer';
|
|
69
|
+
};
|
|
70
|
+
items: Array<{
|
|
71
|
+
id: string;
|
|
72
|
+
title: string;
|
|
73
|
+
status: 'active' | 'archived' | 'deleted';
|
|
74
|
+
metadata?: Record<string, string>;
|
|
75
|
+
createdAt: string;
|
|
76
|
+
}>;
|
|
77
|
+
config: {
|
|
78
|
+
theme: 'light' | 'dark';
|
|
79
|
+
locale: string;
|
|
80
|
+
pageSize: number;
|
|
81
|
+
features: {
|
|
82
|
+
canEdit: boolean;
|
|
83
|
+
canDelete: boolean;
|
|
84
|
+
canExport: boolean;
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
pagination?: {
|
|
88
|
+
page: number;
|
|
89
|
+
totalPages: number;
|
|
90
|
+
totalItems: number;
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Rules for MyopInitData
|
|
96
|
+
|
|
97
|
+
1. **Must match actual data** - Every field you define must correspond to data actually passed by the host
|
|
98
|
+
2. **Use `?` for optional fields** - Fields that may not always be present
|
|
99
|
+
3. **Use union types for enums** - `'active' | 'archived'` not `string`
|
|
100
|
+
4. **Use `Array<T>` for lists** - Be explicit about array item types
|
|
101
|
+
5. **No `any` type** - Always specify the actual type
|
|
102
|
+
|
|
103
|
+
## MyopCtaPayloads
|
|
104
|
+
|
|
105
|
+
Defines all actions the component can send via `myop_cta_handler(action, payload)`. Each key is an action ID, and its value is the payload type.
|
|
106
|
+
|
|
107
|
+
### Simple Example
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
interface MyopCtaPayloads {
|
|
111
|
+
'button-clicked': { buttonId: string };
|
|
112
|
+
'form-submitted': { name: string; email: string };
|
|
113
|
+
'refresh-requested': void;
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Complex Example
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
interface MyopCtaPayloads {
|
|
121
|
+
// User interaction actions
|
|
122
|
+
'item-selected': { itemId: string; index: number };
|
|
123
|
+
'item-deleted': { itemId: string; confirmed: boolean };
|
|
124
|
+
'items-reordered': { orderedIds: string[] };
|
|
125
|
+
|
|
126
|
+
// Form actions
|
|
127
|
+
'filter-changed': {
|
|
128
|
+
field: string;
|
|
129
|
+
operator: 'eq' | 'neq' | 'gt' | 'lt' | 'contains';
|
|
130
|
+
value: string | number | boolean;
|
|
131
|
+
};
|
|
132
|
+
'search-submitted': { query: string; scope: 'all' | 'title' | 'content' };
|
|
133
|
+
|
|
134
|
+
// Navigation actions
|
|
135
|
+
'page-changed': { page: number };
|
|
136
|
+
'tab-switched': { tabId: string };
|
|
137
|
+
|
|
138
|
+
// Standard Myop actions (always include if component needs resizing)
|
|
139
|
+
'size-requested': {
|
|
140
|
+
width?: number | null;
|
|
141
|
+
height?: number | null;
|
|
142
|
+
minWidth?: number | null;
|
|
143
|
+
maxWidth?: number | null;
|
|
144
|
+
minHeight?: number | null;
|
|
145
|
+
maxHeight?: number | null;
|
|
146
|
+
required?: boolean;
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Rules for MyopCtaPayloads
|
|
152
|
+
|
|
153
|
+
1. **Use kebab-case** for action names: `'item-selected'` not `'itemSelected'`
|
|
154
|
+
2. **Use `void`** for actions with no payload (e.g., `'refresh-requested': void`)
|
|
155
|
+
3. **Include `size-requested`** if the component ever needs to request a resize
|
|
156
|
+
4. **Payload must be JSON-serializable** - no functions, DOM elements, or class instances
|
|
157
|
+
5. **Every action called in code must be defined here** - keep types in sync with implementation
|
|
158
|
+
|
|
159
|
+
## Standard Declarations
|
|
160
|
+
|
|
161
|
+
These lines MUST appear at the bottom of every `<script type="myop/types">` block. Do not modify them.
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
// DO NOT EDIT BELOW - Standard Myop type declarations
|
|
165
|
+
|
|
166
|
+
declare function myop_init_interface(): MyopInitData;
|
|
167
|
+
declare function myop_init_interface(data: MyopInitData): void;
|
|
168
|
+
|
|
169
|
+
declare function myop_cta_handler<K extends keyof MyopCtaPayloads>(
|
|
170
|
+
action: K,
|
|
171
|
+
payload: MyopCtaPayloads[K]
|
|
172
|
+
): void;
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Common Type Patterns
|
|
176
|
+
|
|
177
|
+
### List with Selection
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
interface MyopInitData {
|
|
181
|
+
items: Array<{ id: string; label: string; selected?: boolean }>;
|
|
182
|
+
multiSelect: boolean;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
interface MyopCtaPayloads {
|
|
186
|
+
'selection-changed': { selectedIds: string[] };
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Chart / Data Visualization
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
interface MyopInitData {
|
|
194
|
+
labels: string[];
|
|
195
|
+
datasets: Array<{
|
|
196
|
+
label: string;
|
|
197
|
+
data: number[];
|
|
198
|
+
color?: string;
|
|
199
|
+
}>;
|
|
200
|
+
options?: {
|
|
201
|
+
showLegend: boolean;
|
|
202
|
+
animate: boolean;
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
interface MyopCtaPayloads {
|
|
207
|
+
'point-clicked': { datasetIndex: number; pointIndex: number; value: number };
|
|
208
|
+
'size-requested': {
|
|
209
|
+
width?: number | null; height?: number | null;
|
|
210
|
+
minWidth?: number | null; maxWidth?: number | null;
|
|
211
|
+
minHeight?: number | null; maxHeight?: number | null;
|
|
212
|
+
required?: boolean;
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Form Component
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
interface MyopInitData {
|
|
221
|
+
fields: Array<{
|
|
222
|
+
name: string;
|
|
223
|
+
label: string;
|
|
224
|
+
type: 'text' | 'number' | 'email' | 'select' | 'checkbox';
|
|
225
|
+
value?: string | number | boolean;
|
|
226
|
+
options?: Array<{ label: string; value: string }>;
|
|
227
|
+
required?: boolean;
|
|
228
|
+
placeholder?: string;
|
|
229
|
+
}>;
|
|
230
|
+
submitLabel?: string;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
interface MyopCtaPayloads {
|
|
234
|
+
'form-submitted': Record<string, string | number | boolean>;
|
|
235
|
+
'field-changed': { fieldName: string; value: string | number | boolean };
|
|
236
|
+
'form-cancelled': void;
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Settings / Configuration Panel
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
interface MyopInitData {
|
|
244
|
+
settings: Record<string, {
|
|
245
|
+
label: string;
|
|
246
|
+
type: 'toggle' | 'select' | 'range';
|
|
247
|
+
value: boolean | string | number;
|
|
248
|
+
options?: string[];
|
|
249
|
+
min?: number;
|
|
250
|
+
max?: number;
|
|
251
|
+
}>;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
interface MyopCtaPayloads {
|
|
255
|
+
'setting-changed': { key: string; value: boolean | string | number };
|
|
256
|
+
'settings-saved': Record<string, boolean | string | number>;
|
|
257
|
+
'settings-reset': void;
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Rules
|
|
262
|
+
|
|
263
|
+
1. **Keep types in sync** - If you change what `myop_init_interface` does with data, update `MyopInitData`. If you add a new `myop_cta_handler` call, add it to `MyopCtaPayloads`.
|
|
264
|
+
|
|
265
|
+
2. **Types are documentation** - The `<script type="myop/types">` block is not parsed by the browser. It exists for:
|
|
266
|
+
- AI agents to understand the component contract
|
|
267
|
+
- Host developers to know what data to send and what actions to handle
|
|
268
|
+
- IDE tooling that may parse these types
|
|
269
|
+
|
|
270
|
+
3. **One source of truth** - The type definitions should be the authoritative reference for the component's data contract. When in doubt, read the types first.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@myop/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.41",
|
|
4
4
|
"description": "Myop cli",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"scripts": {
|
|
27
27
|
"try": "myop",
|
|
28
|
-
"build": "vite build && chmod +x ./dist/myop-cli.js && mkdir -p ./dist/commands/dev/management-website && cp -R ./src/commands/dev/management-website/* ./dist/commands/dev/management-website/",
|
|
28
|
+
"build": "vite build && chmod +x ./dist/myop-cli.js && mkdir -p ./dist/commands/dev/management-website && cp -R ./src/commands/dev/management-website/* ./dist/commands/dev/management-website/ && mkdir -p ./dist/skills && cp -R ./src/skills/* ./dist/skills/",
|
|
29
29
|
"release": "npm publish --access public",
|
|
30
30
|
"cpTemplates": "cp -R ./node_modules/@myop/code-generator/dist/templates ./public"
|
|
31
31
|
},
|