@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.
- package/dist/myop-cli.js +1461 -1207
- package/dist/skills/myop-angular-host/SKILL.md +437 -0
- package/dist/skills/myop-cli/SKILL.md +147 -0
- package/dist/skills/myop-component/SKILL.md +112 -42
- package/dist/skills/myop-component/references/dev-workflow.md +74 -8
- package/dist/skills/myop-react-host/SKILL.md +407 -0
- package/dist/skills/myop-react-host/references/auto-generated-packages.md +70 -0
- package/dist/skills/myop-react-native-host/SKILL.md +438 -0
- package/dist/skills/myop-vue-host/SKILL.md +374 -0
- package/package.json +1 -1
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: myop-angular-host
|
|
3
|
+
description: "Integrate Myop components into Angular applications using @myop/angular. ALWAYS use the myop-component Angular component or auto-generated packages — NEVER create iframes manually. Covers the MyopComponent standalone component, inputs, outputs, content projection, data binding, preloading, auto-generated packages, and local dev setup. Activate when the user is building an Angular app that hosts Myop components, or when you see @myop/angular in package.json."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Myop Angular Host Integration
|
|
7
|
+
|
|
8
|
+
Embed Myop components in Angular applications using `@myop/angular`.
|
|
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/angular` SDK handles all iframe management, communication, loading, error handling, and caching. Always use `<myop-component>` or an auto-generated package.
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
// WRONG — never do this
|
|
18
|
+
this.iframe.nativeElement.contentWindow.myop_init_interface(data)
|
|
19
|
+
|
|
20
|
+
// CORRECT — always use the SDK
|
|
21
|
+
<myop-component [componentId]="'abc-123'" [data]="data" (cta)="onCta($event)" />
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## End-to-End Workflow: Angular 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 Angular 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 Angular app
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
cd my-angular-app
|
|
54
|
+
npm install @myop/angular @myop/sdk
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
import { MyopComponent } from "@myop/angular";
|
|
59
|
+
|
|
60
|
+
@Component({
|
|
61
|
+
selector: 'app-root',
|
|
62
|
+
standalone: true,
|
|
63
|
+
imports: [MyopComponent],
|
|
64
|
+
template: `
|
|
65
|
+
<myop-component
|
|
66
|
+
[componentId]="'<sidebar-componentId-from-step-2>'"
|
|
67
|
+
[data]="{ items: ['Home', 'Settings'] }"
|
|
68
|
+
(cta)="onCta($event)"
|
|
69
|
+
style="width: 300px"
|
|
70
|
+
/>
|
|
71
|
+
<myop-component
|
|
72
|
+
[componentId]="'<chart-componentId-from-step-2>'"
|
|
73
|
+
[data]="{ values: [10, 20, 30] }"
|
|
74
|
+
style="flex: 1"
|
|
75
|
+
/>
|
|
76
|
+
`
|
|
77
|
+
})
|
|
78
|
+
export class AppComponent {
|
|
79
|
+
onCta(event: any) { console.log(event.action, event.payload); }
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Working locally on existing components (componentId already in code)
|
|
84
|
+
|
|
85
|
+
When you find `componentId` values already used in the codebase and the developer wants to modify those components locally:
|
|
86
|
+
|
|
87
|
+
**Step A: Pull the component source**
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
mkdir components/sidebar && cd components/sidebar
|
|
91
|
+
npx myop pull <componentId>
|
|
92
|
+
# Downloads index.html + creates myop.config.json with the componentId
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Step B: Start the local dev server**
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
npx myop dev # Serves component on port 9292 with HMR
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Step C: Point the Angular app to local dev server**
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import { enableLocalDev } from "@myop/angular";
|
|
105
|
+
enableLocalDev(); // All <myop-component> instances load from localhost:9292
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Now edits to `index.html` are reflected instantly in the Angular app.
|
|
109
|
+
|
|
110
|
+
**Step D: Push changes when done**
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
npx myop push # Uploads updated component to the same componentId
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Remove or comment out `enableLocalDev()` to go back to loading from the Myop cloud.
|
|
117
|
+
|
|
118
|
+
**Multiple components:**
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
mkdir -p components && cd components
|
|
122
|
+
npx myop pull <sidebar-id> -o sidebar/index.html
|
|
123
|
+
npx myop pull <chart-id> -o chart/index.html
|
|
124
|
+
npx myop dev -m # Monorepo mode — select which components to serve
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## When This Skill Activates
|
|
128
|
+
|
|
129
|
+
- `@myop/angular` is in `package.json` dependencies
|
|
130
|
+
- User asks to "add a Myop component to Angular", "integrate Myop in Angular"
|
|
131
|
+
- Files import from `@myop/angular`
|
|
132
|
+
|
|
133
|
+
## Installation
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
npm install @myop/angular @myop/sdk
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Quick Start
|
|
140
|
+
|
|
141
|
+
### Option 1: Auto-Generated Package (Recommended)
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
npm install https://cloud.myop.dev/npm/{componentId}/angular
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import { MyComponentComponent } from "@myop/my-component";
|
|
149
|
+
|
|
150
|
+
@Component({
|
|
151
|
+
selector: 'app-root',
|
|
152
|
+
standalone: true,
|
|
153
|
+
imports: [MyComponentComponent],
|
|
154
|
+
template: `
|
|
155
|
+
<my-component
|
|
156
|
+
[data]="{ title: 'Hello' }"
|
|
157
|
+
(cta)="onCta($event)"
|
|
158
|
+
/>
|
|
159
|
+
`
|
|
160
|
+
})
|
|
161
|
+
export class AppComponent {
|
|
162
|
+
onCta(event: CtaEvent<MyComponentCtaPayloads>) {
|
|
163
|
+
console.log(event.action, event.payload);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
The auto-generated package bakes in the `componentId` and exports typed interfaces.
|
|
169
|
+
|
|
170
|
+
### Option 2: MyopComponent Directly
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
import { MyopComponent } from "@myop/angular";
|
|
174
|
+
|
|
175
|
+
@Component({
|
|
176
|
+
selector: 'app-root',
|
|
177
|
+
standalone: true,
|
|
178
|
+
imports: [MyopComponent],
|
|
179
|
+
template: `
|
|
180
|
+
<myop-component
|
|
181
|
+
[componentId]="'your-component-id'"
|
|
182
|
+
[data]="data"
|
|
183
|
+
(cta)="onCta($event)"
|
|
184
|
+
/>
|
|
185
|
+
`
|
|
186
|
+
})
|
|
187
|
+
export class AppComponent {
|
|
188
|
+
data = { title: 'Hello' };
|
|
189
|
+
|
|
190
|
+
onCta(event: CtaEvent) {
|
|
191
|
+
console.log(event.action, event.payload);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Component API
|
|
197
|
+
|
|
198
|
+
**Selector:** `myop-component`
|
|
199
|
+
|
|
200
|
+
**Standalone:** Yes (`standalone: true`) — import directly, no NgModule needed.
|
|
201
|
+
|
|
202
|
+
### Inputs
|
|
203
|
+
|
|
204
|
+
| Input | Type | Default | Description |
|
|
205
|
+
|-------|------|---------|-------------|
|
|
206
|
+
| `componentId` | `string` | — | Myop component ID (UUID) |
|
|
207
|
+
| `data` | `TData` | — | Data passed to `myop_init_interface`. Reactive via `ngOnChanges` |
|
|
208
|
+
| `fadeDuration` | `number` | `200` | Loader fade-out duration in ms |
|
|
209
|
+
| `autoSize` | `boolean` | `false` | Auto-size container to match iframe content |
|
|
210
|
+
| `environment` | `string` | — | Load from specific environment |
|
|
211
|
+
| `preview` | `boolean` | — | Load unpublished preview version |
|
|
212
|
+
| `on` | `(action, payload) => void` | — | Generic CTA callback |
|
|
213
|
+
| `loader` | `TemplateRef` | — | Custom loader template (input approach) |
|
|
214
|
+
| `fallback` | `TemplateRef` | — | Custom fallback template (input approach) |
|
|
215
|
+
| `componentConfig` | `IComponentInstanceConfig` | — | Direct config object (advanced) |
|
|
216
|
+
|
|
217
|
+
### Outputs
|
|
218
|
+
|
|
219
|
+
| Output | Payload | Description |
|
|
220
|
+
|--------|---------|-------------|
|
|
221
|
+
| `(load)` | `ITypedMyopComponent<TData, TCtaPayloads>` | Component finished loading |
|
|
222
|
+
| `(error)` | `string` | Load failure message |
|
|
223
|
+
| `(sizeChange)` | `SizeInfo` | Auto-sized component changed dimensions |
|
|
224
|
+
| `(cta)` | `CtaEvent<TCtaPayloads>` | CTA event from component |
|
|
225
|
+
|
|
226
|
+
The `CtaEvent` type:
|
|
227
|
+
```typescript
|
|
228
|
+
interface CtaEvent<TCtaPayloads> {
|
|
229
|
+
action: keyof TCtaPayloads | string;
|
|
230
|
+
payload: TCtaPayloads[keyof TCtaPayloads] | any;
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Content Projection (Loader & Fallback)
|
|
235
|
+
|
|
236
|
+
Two approaches — content projection or input binding:
|
|
237
|
+
|
|
238
|
+
### Content Projection (ng-template)
|
|
239
|
+
|
|
240
|
+
```html
|
|
241
|
+
<myop-component [componentId]="'...'">
|
|
242
|
+
<ng-template #loader>
|
|
243
|
+
<div class="spinner">Loading...</div>
|
|
244
|
+
</ng-template>
|
|
245
|
+
<ng-template #fallback>
|
|
246
|
+
<div class="error">Failed to load</div>
|
|
247
|
+
</ng-template>
|
|
248
|
+
</myop-component>
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Input Binding
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
@Component({
|
|
255
|
+
template: `
|
|
256
|
+
<myop-component [componentId]="'...'" [loader]="loaderTpl">
|
|
257
|
+
</myop-component>
|
|
258
|
+
|
|
259
|
+
<ng-template #loaderTpl>
|
|
260
|
+
<div class="spinner">Loading...</div>
|
|
261
|
+
</ng-template>
|
|
262
|
+
`
|
|
263
|
+
})
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Input binding takes precedence over content projection.
|
|
267
|
+
|
|
268
|
+
## Data Binding
|
|
269
|
+
|
|
270
|
+
The `data` input is tracked via `ngOnChanges`. When the reference changes, `myop_init_interface(data)` is called:
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
@Component({
|
|
274
|
+
template: `
|
|
275
|
+
<button (click)="increment()">+1</button>
|
|
276
|
+
<myop-component [componentId]="'counter'" [data]="counterData" />
|
|
277
|
+
`
|
|
278
|
+
})
|
|
279
|
+
export class AppComponent {
|
|
280
|
+
count = 0;
|
|
281
|
+
counterData = { count: 0 };
|
|
282
|
+
|
|
283
|
+
increment() {
|
|
284
|
+
this.count++;
|
|
285
|
+
this.counterData = { count: this.count }; // New reference triggers update
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
**Important:** You must create a new object reference for Angular change detection to trigger. Mutating the existing object won't work with `OnPush` change detection.
|
|
291
|
+
|
|
292
|
+
## Preloading
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
import { preloadComponents, isPreloaded } from "@myop/angular";
|
|
296
|
+
|
|
297
|
+
// In app initializer or route guard
|
|
298
|
+
await preloadComponents(["component-id-1", "component-id-2"]);
|
|
299
|
+
await preloadComponents(["component-id-1"], "staging");
|
|
300
|
+
|
|
301
|
+
if (isPreloaded("component-id-1")) {
|
|
302
|
+
console.log("Will render instantly");
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
## Configuration Functions
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
import {
|
|
310
|
+
enableLocalDev,
|
|
311
|
+
setCloudRepositoryUrl,
|
|
312
|
+
setEnvironment,
|
|
313
|
+
} from "@myop/angular";
|
|
314
|
+
|
|
315
|
+
enableLocalDev(); // localhost:9292
|
|
316
|
+
setCloudRepositoryUrl("https://custom"); // Custom URL
|
|
317
|
+
setEnvironment("staging"); // Default environment
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## CTA Event Handling
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
import { CtaEvent } from "@myop/angular";
|
|
324
|
+
|
|
325
|
+
// Define your component's CTA types
|
|
326
|
+
interface MyCtaPayloads {
|
|
327
|
+
'task-toggled': { taskId: string; completed: boolean };
|
|
328
|
+
'task-deleted': { taskId: string };
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
@Component({
|
|
332
|
+
template: `
|
|
333
|
+
<myop-component
|
|
334
|
+
[componentId]="'task-list'"
|
|
335
|
+
[data]="{ tasks }"
|
|
336
|
+
(cta)="onCta($event)"
|
|
337
|
+
/>
|
|
338
|
+
`
|
|
339
|
+
})
|
|
340
|
+
export class TaskListHost {
|
|
341
|
+
tasks = [{ id: '1', title: 'Review PR', completed: false }];
|
|
342
|
+
|
|
343
|
+
onCta(event: CtaEvent<MyCtaPayloads>) {
|
|
344
|
+
switch (event.action) {
|
|
345
|
+
case 'task-toggled':
|
|
346
|
+
// event.payload typed as { taskId: string; completed: boolean }
|
|
347
|
+
break;
|
|
348
|
+
case 'task-deleted':
|
|
349
|
+
// event.payload typed as { taskId: string }
|
|
350
|
+
break;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
## Auto-Generated Angular Package
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
npm install https://cloud.myop.dev/npm/{componentId}/angular
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
The generated package exports:
|
|
363
|
+
- `MyComponentComponent` — standalone Angular component with `componentId` baked in
|
|
364
|
+
- `MyComponentData` — typed data interface (from `MyopInitData`)
|
|
365
|
+
- `MyComponentCtaPayloads` — typed CTA payloads
|
|
366
|
+
- `MyComponentTypedComponent` — typed component instance interface
|
|
367
|
+
- `COMPONENT_ID` — the component ID constant
|
|
368
|
+
|
|
369
|
+
The generated component:
|
|
370
|
+
- Selector is auto-derived from name (e.g., `my-component`)
|
|
371
|
+
- `standalone: true`, imports `MyopComponent` from `@myop/angular`
|
|
372
|
+
- All inputs/outputs forwarded
|
|
373
|
+
|
|
374
|
+
## Complete Example
|
|
375
|
+
|
|
376
|
+
```typescript
|
|
377
|
+
import { Component } from '@angular/core';
|
|
378
|
+
import { MyopComponent, preloadComponents, type CtaEvent } from '@myop/angular';
|
|
379
|
+
|
|
380
|
+
preloadComponents(['sidebar-abc123']);
|
|
381
|
+
|
|
382
|
+
@Component({
|
|
383
|
+
selector: 'app-dashboard',
|
|
384
|
+
standalone: true,
|
|
385
|
+
imports: [MyopComponent],
|
|
386
|
+
template: `
|
|
387
|
+
<div style="display: flex; height: 100vh">
|
|
388
|
+
<myop-component
|
|
389
|
+
[componentId]="'sidebar-abc123'"
|
|
390
|
+
[data]="{ tasks: tasks }"
|
|
391
|
+
(cta)="handleCta($event)"
|
|
392
|
+
(load)="onLoaded($event)"
|
|
393
|
+
(error)="onError($event)"
|
|
394
|
+
style="width: 300px"
|
|
395
|
+
>
|
|
396
|
+
<ng-template #loader>
|
|
397
|
+
<div>Loading sidebar...</div>
|
|
398
|
+
</ng-template>
|
|
399
|
+
</myop-component>
|
|
400
|
+
</div>
|
|
401
|
+
`
|
|
402
|
+
})
|
|
403
|
+
export class DashboardComponent {
|
|
404
|
+
tasks = [
|
|
405
|
+
{ id: '1', title: 'Review PR', completed: false },
|
|
406
|
+
{ id: '2', title: 'Deploy', completed: true },
|
|
407
|
+
];
|
|
408
|
+
|
|
409
|
+
handleCta(event: CtaEvent) {
|
|
410
|
+
if (event.action === 'task-toggled') {
|
|
411
|
+
const task = this.tasks.find(t => t.id === event.payload.taskId);
|
|
412
|
+
if (task) task.completed = event.payload.completed;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
onLoaded(component: any) {
|
|
417
|
+
console.log('Component loaded:', component.id);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
onError(error: string) {
|
|
421
|
+
console.error('Failed:', error);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
## TypeScript Types
|
|
427
|
+
|
|
428
|
+
```typescript
|
|
429
|
+
import type {
|
|
430
|
+
IPropTypes, // Full props type
|
|
431
|
+
ITypedMyopComponent, // Component instance with typed props
|
|
432
|
+
IMyopComponentProps, // myop_init_interface + myop_cta_handler
|
|
433
|
+
CtaEvent, // { action, payload } event type
|
|
434
|
+
SizeInfo, // { width, height, autoSizingWidth, autoSizingHeight }
|
|
435
|
+
IComponentInstanceConfig,
|
|
436
|
+
} from "@myop/angular";
|
|
437
|
+
```
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: myop-cli
|
|
3
|
+
description: "Myop CLI tool for creating, developing, and deploying Myop components. Myop is a platform for building isolated, independently deployable UI components that integrate into any host application. Components can be built with any framework or architecture. Covers all CLI commands: create, dev, push, pull, list, train, mcp, login. Activates when the user needs CLI operations or when myop.config.json exists."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Myop CLI
|
|
7
|
+
|
|
8
|
+
Command-line tool for creating, developing, and deploying Myop components.
|
|
9
|
+
|
|
10
|
+
## CRITICAL: Package Name
|
|
11
|
+
|
|
12
|
+
The npm package is **`myop`**. Always use `npx myop <command>`.
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npx myop create # Correct
|
|
16
|
+
npx myop dev # Correct
|
|
17
|
+
npx myop push # Correct
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**NEVER use** `npx @anthropic/myop`, `npx @myop/cli`, or any other package name — the package is simply **`myop`**.
|
|
21
|
+
|
|
22
|
+
## Immediate Action Required
|
|
23
|
+
|
|
24
|
+
**Check `myop.config.json` in the current directory:**
|
|
25
|
+
- **EXISTS** → This is an existing Myop component project. You can use `myop dev`, `myop push`, `myop pull`.
|
|
26
|
+
- **DOESN'T EXIST** → Either create a new component with `myop create`, or pull one with `myop pull <id>`.
|
|
27
|
+
|
|
28
|
+
**When to use this skill vs `myop-component`:**
|
|
29
|
+
- **This skill (myop-cli):** Operations — deploying, downloading, serving, listing, authenticating
|
|
30
|
+
- **myop-component:** Building — implementing `myop_init_interface`/`myop_cta_handler`, component architecture, styling
|
|
31
|
+
|
|
32
|
+
## Commands
|
|
33
|
+
|
|
34
|
+
### Create a new component
|
|
35
|
+
```bash
|
|
36
|
+
npx myop create
|
|
37
|
+
```
|
|
38
|
+
Interactive: prompts for name, creates `index.html` + `myop.config.json`, starts dev server.
|
|
39
|
+
|
|
40
|
+
### Start dev server
|
|
41
|
+
```bash
|
|
42
|
+
npx myop dev
|
|
43
|
+
```
|
|
44
|
+
- Port **9292** — serves the component
|
|
45
|
+
- Port **9293** — management dashboard
|
|
46
|
+
- Watches `.js`, `.css`, `.html` files for changes
|
|
47
|
+
- HMR: changes reflect instantly in the browser
|
|
48
|
+
- Single-file mode: serves `index.html` directly (no build step)
|
|
49
|
+
- Multi-file mode: runs `npm run build` or `node build.js` on change
|
|
50
|
+
|
|
51
|
+
### Push (deploy) to Myop
|
|
52
|
+
```bash
|
|
53
|
+
# Push using componentId from myop.config.json
|
|
54
|
+
npx myop push
|
|
55
|
+
|
|
56
|
+
# Push to a specific component ID
|
|
57
|
+
npx myop push <componentId>
|
|
58
|
+
```
|
|
59
|
+
Uploads the component to Myop platform. First push assigns a `componentId` and updates `myop.config.json`.
|
|
60
|
+
|
|
61
|
+
### Pull (download) from Myop
|
|
62
|
+
```bash
|
|
63
|
+
# Pull using componentId from myop.config.json
|
|
64
|
+
npx myop pull
|
|
65
|
+
|
|
66
|
+
# Pull by ID
|
|
67
|
+
npx myop pull <componentId>
|
|
68
|
+
|
|
69
|
+
# Pull to a specific output path
|
|
70
|
+
npx myop pull <componentId> -o ./output/index.html
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Browse & batch operations
|
|
74
|
+
```bash
|
|
75
|
+
# Interactive search, multi-select, batch pull or push
|
|
76
|
+
npx myop list
|
|
77
|
+
|
|
78
|
+
# Specify organization
|
|
79
|
+
npx myop list --org <orgId>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Install AI skills for coding assistants
|
|
83
|
+
```bash
|
|
84
|
+
npx myop train
|
|
85
|
+
```
|
|
86
|
+
Installs SKILL.md files into all AI agent directories (Claude Code, Cursor, Windsurf, VS Code Copilot, Kiro, Goose, Augment, and more) so they understand Myop conventions.
|
|
87
|
+
|
|
88
|
+
### Configure MCP server
|
|
89
|
+
```bash
|
|
90
|
+
npx myop mcp
|
|
91
|
+
```
|
|
92
|
+
Interactive setup for connecting Myop MCP to Claude Code, Cursor, Windsurf, or VS Code Copilot.
|
|
93
|
+
|
|
94
|
+
### Authentication
|
|
95
|
+
```bash
|
|
96
|
+
npx myop login # Opens browser for OAuth
|
|
97
|
+
npx myop logout # Clears stored credentials
|
|
98
|
+
npx myop whoami # Show current user
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Common Workflows
|
|
102
|
+
|
|
103
|
+
### Deploy a component
|
|
104
|
+
```bash
|
|
105
|
+
npx myop push
|
|
106
|
+
# Dashboard: https://dashboard.myop.dev/dashboard/2.0/component/<componentId>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Download all components from an org
|
|
110
|
+
```bash
|
|
111
|
+
mkdir components && cd components
|
|
112
|
+
npx myop list
|
|
113
|
+
# Select components → Pull
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Set up AI tooling
|
|
117
|
+
```bash
|
|
118
|
+
npx myop train # Install skills for all AI agents
|
|
119
|
+
npx myop mcp # Configure MCP server for your IDE
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Local development
|
|
123
|
+
```bash
|
|
124
|
+
npx myop dev # Start dev server at localhost:9292
|
|
125
|
+
# Edit index.html → changes reflect instantly
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Configuration
|
|
129
|
+
|
|
130
|
+
### myop.config.json
|
|
131
|
+
```json
|
|
132
|
+
{
|
|
133
|
+
"name": "My Component",
|
|
134
|
+
"componentId": "DEV",
|
|
135
|
+
"type": "html",
|
|
136
|
+
"author": "@myop-cli",
|
|
137
|
+
"HMR": true
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
- `componentId` is `"DEV"` until first push, then becomes a UUID
|
|
141
|
+
- After push, `organization` field is added
|
|
142
|
+
|
|
143
|
+
### Dev Server
|
|
144
|
+
- Component: `http://localhost:9292`
|
|
145
|
+
- Management: `http://localhost:9293`
|
|
146
|
+
- Single-file mode: serves `index.html` directly (no build)
|
|
147
|
+
- Multi-file mode: watches files, runs `npm run build` or `node build.js` on change
|