@myop/cli 0.1.45 → 0.1.47

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.
@@ -0,0 +1,374 @@
1
+ ---
2
+ name: myop-vue-host
3
+ description: "Integrate Myop components into Vue 3 applications using @myop/vue. ALWAYS use the MyopComponent Vue component or auto-generated packages — NEVER create iframes manually. Covers MyopComponent props, events, slots, data binding, preloading, auto-generated packages, and local dev setup. Activate when the user is building a Vue app that hosts Myop components, or when you see @myop/vue in package.json."
4
+ ---
5
+
6
+ # Myop Vue Host Integration
7
+
8
+ Embed Myop components in Vue 3 applications using `@myop/vue`.
9
+
10
+ ## CRITICAL: Always Use the SDK
11
+
12
+ **NEVER create `<iframe>` elements manually. NEVER call `myop_init_interface()` or wire `myop_cta_handler()` directly.**
13
+
14
+ The `@myop/vue` SDK handles all iframe management, communication, loading, error handling, and caching. Always use `<MyopComponent>` or an auto-generated package.
15
+
16
+ ```vue
17
+ <!-- WRONG — never do this -->
18
+ <iframe ref="myIframe" src="/component.html" />
19
+
20
+ <!-- CORRECT — always use the SDK -->
21
+ <MyopComponent component-id="abc-123" :data="data" @cta="handleCta" />
22
+ ```
23
+
24
+ ## End-to-End Workflow: Vue App with Myop Components
25
+
26
+ Each Myop component is a **separate project** in its own directory. You create them, develop them, push them to get a `componentId`, then reference that ID in your Vue host app.
27
+
28
+ ### Step 1: Create component projects
29
+
30
+ ```bash
31
+ # Each component gets its own directory
32
+ mkdir components/sidebar && cd components/sidebar
33
+ npx myop create # Scaffolds index.html + myop.config.json
34
+ # Build the component UI (see myop-component skill), then Ctrl+C
35
+
36
+ cd ../ && mkdir chart && cd chart
37
+ npx myop create
38
+ ```
39
+
40
+ ### Step 2: Push components to get IDs
41
+
42
+ ```bash
43
+ cd components/sidebar
44
+ npx myop push # Uploads → componentId written to myop.config.json
45
+
46
+ cd ../chart
47
+ npx myop push
48
+ ```
49
+
50
+ ### Step 3: Use in your Vue app
51
+
52
+ ```bash
53
+ cd my-vue-app
54
+ npm install @myop/vue @myop/sdk
55
+ ```
56
+
57
+ ```vue
58
+ <script setup>
59
+ import { MyopComponent } from "@myop/vue";
60
+ </script>
61
+
62
+ <template>
63
+ <MyopComponent
64
+ component-id="<sidebar-componentId-from-step-2>"
65
+ :data="{ items: ['Home', 'Settings'] }"
66
+ @cta="(action, payload) => console.log(action, payload)"
67
+ style="width: 300px"
68
+ />
69
+ <MyopComponent
70
+ component-id="<chart-componentId-from-step-2>"
71
+ :data="{ values: [10, 20, 30] }"
72
+ style="flex: 1"
73
+ />
74
+ </template>
75
+ ```
76
+
77
+ ### Working locally on existing components (componentId already in code)
78
+
79
+ When you find `componentId` values already used in the codebase and the developer wants to modify those components locally:
80
+
81
+ **Step A: Pull the component source**
82
+
83
+ ```bash
84
+ mkdir components/sidebar && cd components/sidebar
85
+ npx myop pull <componentId>
86
+ # Downloads index.html + creates myop.config.json with the componentId
87
+ ```
88
+
89
+ **Step B: Start the local dev server**
90
+
91
+ ```bash
92
+ npx myop dev # Serves component on port 9292 with HMR
93
+ ```
94
+
95
+ **Step C: Point the Vue app to local dev server**
96
+
97
+ ```ts
98
+ import { enableLocalDev } from "@myop/vue";
99
+ enableLocalDev(); // All <MyopComponent> instances load from localhost:9292
100
+ ```
101
+
102
+ Now edits to `index.html` are reflected instantly in the Vue app.
103
+
104
+ **Step D: Push changes when done**
105
+
106
+ ```bash
107
+ npx myop push # Uploads updated component to the same componentId
108
+ ```
109
+
110
+ Remove or comment out `enableLocalDev()` to go back to loading from the Myop cloud.
111
+
112
+ **Multiple components:**
113
+
114
+ ```bash
115
+ mkdir -p components && cd components
116
+ npx myop pull <sidebar-id> -o sidebar/index.html
117
+ npx myop pull <chart-id> -o chart/index.html
118
+ npx myop dev -m # Monorepo mode — select which components to serve
119
+ ```
120
+
121
+ ## When This Skill Activates
122
+
123
+ - `@myop/vue` is in `package.json` dependencies
124
+ - User asks to "add a Myop component to Vue", "integrate Myop in Vue"
125
+ - Files import from `@myop/vue`
126
+
127
+ ## Installation
128
+
129
+ ```bash
130
+ npm install @myop/vue @myop/sdk
131
+ ```
132
+
133
+ Requires **Vue 3.5+**.
134
+
135
+ ## Quick Start
136
+
137
+ ### Option 1: Auto-Generated Package (Recommended)
138
+
139
+ ```bash
140
+ npm install https://cloud.myop.dev/npm/{componentId}/vue
141
+ ```
142
+
143
+ ```vue
144
+ <script setup lang="ts">
145
+ import { MyComponent } from "@myop/my-component";
146
+ </script>
147
+
148
+ <template>
149
+ <MyComponent
150
+ :data="{ title: 'Hello', items: ['a', 'b'] }"
151
+ @cta="(action, payload) => console.log(action, payload)"
152
+ />
153
+ </template>
154
+ ```
155
+
156
+ The auto-generated package bakes in the `componentId` and exports typed props and events.
157
+
158
+ ### Option 2: MyopComponent Directly
159
+
160
+ ```vue
161
+ <script setup lang="ts">
162
+ import { MyopComponent } from "@myop/vue";
163
+ </script>
164
+
165
+ <template>
166
+ <MyopComponent
167
+ component-id="your-component-id"
168
+ :data="{ title: 'Hello' }"
169
+ @cta="(action, payload) => console.log(action, payload)"
170
+ />
171
+ </template>
172
+ ```
173
+
174
+ ## MyopComponent Props
175
+
176
+ | Prop | Type | Default | Description |
177
+ |------|------|---------|-------------|
178
+ | `componentId` | `string` | — | Myop component ID (UUID) |
179
+ | `data` | `TData` | — | Data passed to `myop_init_interface`. Reactive — deep-watched |
180
+ | `on` | `(action, payload) => void` | — | Generic CTA callback (alternative to `@cta` event) |
181
+ | `fadeDuration` | `number` | `200` | Loader fade-out duration in ms |
182
+ | `autoSize` | `boolean` | `false` | Auto-size container to match iframe content |
183
+ | `environment` | `string` | — | Load from specific environment |
184
+ | `preview` | `boolean` | `false` | Load unpublished preview version |
185
+ | `componentConfig` | `IComponentInstanceConfig` | — | Direct config object (advanced) |
186
+
187
+ ## Events
188
+
189
+ | Event | Payload | Description |
190
+ |-------|---------|-------------|
191
+ | `@load` | `ITypedMyopComponent` | Component finished loading |
192
+ | `@error` | `string` | Load failure message |
193
+ | `@sizeChange` | `SizeInfo` | Auto-sized component changed dimensions |
194
+ | `@cta` | `action: string, payload: any` | CTA event from component |
195
+
196
+ ```vue
197
+ <MyopComponent
198
+ component-id="..."
199
+ :data="data"
200
+ @load="onComponentLoaded"
201
+ @error="onError"
202
+ @cta="handleCta"
203
+ />
204
+ ```
205
+
206
+ ```ts
207
+ function handleCta(action: string, payload: any) {
208
+ switch (action) {
209
+ case 'item-selected':
210
+ console.log(payload.itemId);
211
+ break;
212
+ case 'form-submitted':
213
+ console.log(payload);
214
+ break;
215
+ }
216
+ }
217
+ ```
218
+
219
+ ## Slots
220
+
221
+ | Slot | Purpose |
222
+ |------|---------|
223
+ | `loader` | Custom loading indicator |
224
+ | `fallback` | Custom error fallback UI |
225
+
226
+ ```vue
227
+ <MyopComponent component-id="...">
228
+ <template #loader>
229
+ <div class="spinner">Loading...</div>
230
+ </template>
231
+ <template #fallback>
232
+ <div class="error">Failed to load component</div>
233
+ </template>
234
+ </MyopComponent>
235
+ ```
236
+
237
+ ## Data Binding
238
+
239
+ The `data` prop is **deep-watched**. Vue reactivity changes automatically call `myop_init_interface`:
240
+
241
+ ```vue
242
+ <script setup>
243
+ import { ref } from 'vue';
244
+
245
+ const count = ref(0);
246
+ </script>
247
+
248
+ <template>
249
+ <button @click="count++">+1</button>
250
+ <MyopComponent
251
+ component-id="counter-display"
252
+ :data="{ count }"
253
+ />
254
+ </template>
255
+ ```
256
+
257
+ **Important:** Vue reactive proxies are automatically stripped (via `JSON.parse(JSON.stringify())`) before passing data to the SDK, so no Vue internals leak into the iframe.
258
+
259
+ ## Preloading
260
+
261
+ ```ts
262
+ import { preloadComponents, isPreloaded } from "@myop/vue";
263
+
264
+ await preloadComponents(["component-id-1", "component-id-2"]);
265
+ await preloadComponents(["component-id-1"], "staging");
266
+
267
+ if (isPreloaded("component-id-1")) {
268
+ console.log("Will render instantly");
269
+ }
270
+ ```
271
+
272
+ ## Configuration Functions
273
+
274
+ ```ts
275
+ import { enableLocalDev, setCloudRepositoryUrl, setEnvironment } from "@myop/vue";
276
+
277
+ enableLocalDev(); // localhost:9292
278
+ setCloudRepositoryUrl("https://custom"); // Custom URL
279
+ setEnvironment("staging"); // Default environment
280
+ ```
281
+
282
+ ## Accessing Component Instance
283
+
284
+ Via template ref:
285
+
286
+ ```vue
287
+ <script setup>
288
+ import { ref } from 'vue';
289
+
290
+ const myopRef = ref(null);
291
+
292
+ function updateManually() {
293
+ myopRef.value?.myopComponent?.props?.myop_init_interface({ title: 'Updated' });
294
+ }
295
+ </script>
296
+
297
+ <template>
298
+ <MyopComponent ref="myopRef" component-id="..." />
299
+ </template>
300
+ ```
301
+
302
+ Exposed properties: `myopComponent` (SDK component instance), `isLoaded` (boolean ref).
303
+
304
+ ## Generics (TypeScript)
305
+
306
+ The component supports Vue 3 generics for typed `data` and events:
307
+
308
+ ```vue
309
+ <script setup lang="ts" generic="TData, TCtaPayloads extends Record<string, any>">
310
+ // TypeScript generics flow through to props and events
311
+ </script>
312
+ ```
313
+
314
+ ## Complete Example
315
+
316
+ ```vue
317
+ <script setup lang="ts">
318
+ import { ref } from 'vue';
319
+ import { MyopComponent, preloadComponents } from '@myop/vue';
320
+
321
+ preloadComponents(['sidebar-abc123']);
322
+
323
+ const tasks = ref([
324
+ { id: '1', title: 'Review PR', completed: false },
325
+ { id: '2', title: 'Deploy', completed: true },
326
+ ]);
327
+
328
+ function handleCta(action: string, payload: any) {
329
+ if (action === 'task-toggled') {
330
+ const task = tasks.value.find(t => t.id === payload.taskId);
331
+ if (task) task.completed = payload.completed;
332
+ }
333
+ if (action === 'task-deleted') {
334
+ tasks.value = tasks.value.filter(t => t.id !== payload.taskId);
335
+ }
336
+ }
337
+ </script>
338
+
339
+ <template>
340
+ <div style="display: flex; height: 100vh">
341
+ <MyopComponent
342
+ component-id="sidebar-abc123"
343
+ :data="{ tasks }"
344
+ @cta="handleCta"
345
+ style="width: 300px"
346
+ >
347
+ <template #loader>
348
+ <div>Loading...</div>
349
+ </template>
350
+ </MyopComponent>
351
+ </div>
352
+ </template>
353
+ ```
354
+
355
+ ## Auto-Generated Vue Package
356
+
357
+ ```bash
358
+ npm install https://cloud.myop.dev/npm/{componentId}/vue
359
+ ```
360
+
361
+ The generated package uses `defineComponent` with the `componentId` baked in. It emits `load`, `error`, `sizeChange`, and `cta` events — same API as `MyopComponent` but without needing a `componentId` prop.
362
+
363
+ ## TypeScript Types
364
+
365
+ ```ts
366
+ import type {
367
+ IPropTypes, // Full props type
368
+ ITypedMyopComponent, // Component instance with typed props
369
+ IMyopComponentProps, // myop_init_interface + myop_cta_handler
370
+ SizeInfo, // { width, height, autoSizingWidth, autoSizingHeight }
371
+ EventHandlerProps, // Generated event handler types
372
+ KebabToPascal, // Utility type
373
+ } from "@myop/vue";
374
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myop/cli",
3
- "version": "0.1.45",
3
+ "version": "0.1.47",
4
4
  "description": "Myop cli",
5
5
  "type": "module",
6
6
  "repository": {