@myop/cli 0.1.10 β†’ 0.1.11

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.
Files changed (2) hide show
  1. package/dist/myop-cli.js +1342 -456
  2. package/package.json +2 -1
package/dist/myop-cli.js CHANGED
@@ -1,10 +1,16 @@
1
1
  #!/usr/bin/env node
2
- import be from "ora";
3
- import { Separator as xe, select as $e } from "@inquirer/prompts";
4
- import { Command as Me, Option as Z } from "commander";
5
- import K from "path";
6
- import re from "fs";
7
- const Pe = `
2
+ import A from "ora";
3
+ import { select as $e, Separator as de } from "@inquirer/prompts";
4
+ import { Command as ze, Option as me } from "commander";
5
+ import { execSync as ne } from "child_process";
6
+ import Z from "path";
7
+ import E from "fs";
8
+ import ue from "crypto";
9
+ import We from "http";
10
+ import { URL as Me, URLSearchParams as je } from "url";
11
+ import Ye from "open";
12
+ import Ge from "os";
13
+ const Ve = `
8
14
  Usage: myop [OPTIONS] COMMAND [ARGS]...
9
15
 
10
16
  A powerful command-line interface for managing your Myop projects.
@@ -38,7 +44,7 @@ Examples:
38
44
 
39
45
 
40
46
 
41
- `, a = {
47
+ `, l = {
42
48
  program: null,
43
49
  executionPath: "",
44
50
  options: {
@@ -46,89 +52,89 @@ Examples:
46
52
  verbose: !1
47
53
  },
48
54
  myopConfig: null
49
- }, ae = {
55
+ }, Oe = {
50
56
  name: "πŸ“₯ Install Myop generated dependencies",
51
57
  value: "myopInstall",
52
58
  description: "Fetch and generates Myop dependencies. flows including components, refs and props.",
53
59
  action: async () => {
54
60
  console.info("installing... ");
55
- for (const i of a.myopConfig.flows) {
56
- const s = K.join(a.executionPath, "/node_modules/@myop/flow-types/");
57
- console.info(`Generate flow at ${s}`), console.info(`Generated flow at ${s}`);
61
+ for (const e of l.myopConfig.flows) {
62
+ const o = Z.join(l.executionPath, "/node_modules/@myop/flow-types/");
63
+ console.info(`Generate flow at ${o}`), console.info(`Generated flow at ${o}`);
58
64
  }
59
65
  process.exit();
60
66
  }
61
- }, He = (i) => {
62
- const s = K.join(a.executionPath, i);
63
- console.info(`reading config file from: ${s}`);
64
- const m = re.readFileSync(s, "utf8"), d = JSON.parse(m);
65
- return console.info("config file loaded, ", d), d;
66
- }, q = (i, s) => {
67
- const m = K.join(a.executionPath, i);
68
- console.info(`writing config file to: ${m}`);
67
+ }, Ke = (e) => {
68
+ const o = Z.join(l.executionPath, e);
69
+ console.info(`reading config file from: ${o}`);
70
+ const n = E.readFileSync(o, "utf8"), a = JSON.parse(n);
71
+ return console.info("config file loaded, ", a), a;
72
+ }, fe = (e, o) => {
73
+ const n = Z.join(l.executionPath, e);
74
+ console.info(`writing config file to: ${n}`);
69
75
  try {
70
- const d = JSON.stringify(s, null, 2);
71
- re.writeFileSync(m, d), console.info(`config file updated ${d}`);
72
- } catch (d) {
73
- throw console.info(`error ${d} while writing to ${m}, JSON: ${s}`), console.log(`
74
- ⚠️ Failed write config file to ${m}, for more info use verbose flag`), d;
76
+ const a = JSON.stringify(o, null, 2);
77
+ E.writeFileSync(n, a), console.info(`config file updated ${a}`);
78
+ } catch (a) {
79
+ throw console.info(`error ${a} while writing to ${n}, JSON: ${o}`), console.log(`
80
+ ⚠️ Failed write config file to ${n}, for more info use verbose flag`), a;
75
81
  }
76
- }, ce = {
82
+ }, ke = {
77
83
  name: "🌟 Add flow definition to your project",
78
84
  value: "addFlow",
79
85
  description: "Adds flow to yours myop.config.json",
80
- _action: (i) => {
81
- a.myopConfig.flows.includes(i) || a.myopConfig.flows.push(i), q(a.options.configPath, a.myopConfig);
86
+ _action: (e) => {
87
+ l.myopConfig.flows.includes(e) || l.myopConfig.flows.push(e), fe(l.options.configPath, l.myopConfig);
82
88
  },
83
89
  action: async () => {
84
90
  }
85
- }, le = {
91
+ }, Ie = {
86
92
  name: "🚫 Remove flow definition from your project",
87
93
  value: "removeFlow",
88
94
  description: "Removes flow to yours myop.config.json",
89
- _action: (i) => {
90
- a.myopConfig.flows = a.myopConfig.flows.filter((s) => s !== i), q(a.options.configPath, a.myopConfig);
95
+ _action: (e) => {
96
+ l.myopConfig.flows = l.myopConfig.flows.filter((o) => o !== e), fe(l.options.configPath, l.myopConfig);
91
97
  },
92
98
  action: () => {
93
99
  }
94
- }, Te = {
100
+ }, Xe = {
95
101
  name: "πŸ‘‹ Quit",
96
102
  value: "quit",
97
103
  description: "Quit and continue coding.",
98
104
  action: () => {
99
105
  process.exit();
100
106
  }
101
- }, Re = {
107
+ }, Qe = {
102
108
  name: "🟒 Create new component",
103
109
  value: "-",
104
110
  disabled: "(not available yet)"
105
- }, Ae = {
111
+ }, Ze = {
106
112
  name: "πŸ”΅ Create new experience",
107
113
  value: "-",
108
114
  disabled: "(not available yet)"
109
- }, Ie = {
115
+ }, qe = {
110
116
  name: "🟑 Create new skin",
111
117
  value: "-",
112
118
  disabled: "(not available yet)"
113
- }, _e = {
119
+ }, et = {
114
120
  name: "πŸ”΄ Create new flow",
115
121
  value: "-",
116
122
  disabled: "(not available yet)"
117
- }, Ne = {
123
+ }, tt = {
118
124
  name: "πŸ†• Define new custom Myop message",
119
125
  value: "generateMyopMessage",
120
126
  description: "️Help you creates the right structure for a new Myop message, including types and handlers.",
121
127
  disabled: "(not available yet)"
122
- }, je = [Ne, Re, Ae, Ie, _e];
123
- function Fe(i, s, m, d) {
128
+ }, ot = [tt, Qe, Ze, qe, et];
129
+ function nt(e, o, n, a) {
124
130
  return `<!DOCTYPE html>
125
131
  <html lang="en">
126
132
  <head>
127
133
  <meta charset="UTF-8">
128
134
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
129
- <title>Myop DevTools - localhost:${i}</title>
135
+ <title>Myop DevTools - localhost:${e}</title>
130
136
  <style>
131
- ${m}
137
+ ${n}
132
138
  </style>
133
139
  </head>
134
140
  <body>
@@ -136,8 +142,8 @@ ${m}
136
142
  <div class="toolbar">
137
143
  <div class="toolbar-title">Myop DevTools</div>
138
144
  <div class="toolbar-info">
139
- <span><div class="status-dot"></div> localhost:${i}</span>
140
- <span>Management: ${s}</span>
145
+ <span><div class="status-dot"></div> localhost:${e}</span>
146
+ <span>Management: ${o}</span>
141
147
  </div>
142
148
  </div>
143
149
 
@@ -203,33 +209,33 @@ ${m}
203
209
 
204
210
  <script>
205
211
  // Inject PORT as a global variable for the app to use
206
- window.PORT = ${i};
212
+ window.PORT = ${e};
207
213
 
208
- ${d}
214
+ ${a}
209
215
  <\/script>
210
216
  </body>
211
217
  </html>`;
212
218
  }
213
- async function Ee() {
214
- const i = await import("fs"), s = await import("path"), { exec: m } = await import("child_process"), d = await import("http"), { createHash: I } = await import("node:crypto");
215
- let P;
219
+ async function Pe() {
220
+ const e = await import("fs"), o = await import("path"), { exec: n } = await import("child_process"), a = await import("http"), { createHash: u } = await import("node:crypto");
221
+ let c;
216
222
  if (import.meta.url.startsWith("file://")) {
217
- const o = import.meta.url.slice(7);
218
- P = s.default.dirname(o);
223
+ const s = import.meta.url.slice(7);
224
+ c = o.default.dirname(s);
219
225
  } else
220
- P = s.default.dirname(import.meta.url);
221
- const _ = s.default.join(P, "commands", "dev", "management-website"), E = i.default.readFileSync(s.default.join(_, "styles.css"), "utf-8"), J = i.default.readFileSync(s.default.join(_, "app.js"), "utf-8"), S = 9292, h = 9293, y = "./dist";
222
- let N = !1, Y = !1;
223
- const V = /* @__PURE__ */ new Map(), me = a.program.getOptionValue("config") || "./myop.config.json";
224
- let g, x, D = !1;
226
+ c = o.default.dirname(import.meta.url);
227
+ const p = o.default.join(c, "commands", "dev", "management-website"), v = e.default.readFileSync(o.default.join(p, "styles.css"), "utf-8"), j = e.default.readFileSync(o.default.join(p, "app.js"), "utf-8"), g = 9292, y = 9293, w = "./dist";
228
+ let I = !1, C = !1;
229
+ const _ = /* @__PURE__ */ new Map(), B = l.program.getOptionValue("config") || "./myop.config.json";
230
+ let S, P, f = !1;
225
231
  try {
226
- const o = i.default.readFileSync(me, "utf-8"), e = JSON.parse(o);
227
- g = e.componentId, x = e.componentName || null, D = e.HMR === !0, g || (console.error("❌ Error: componentId not found in myop.config.json"), process.exit(1)), D && console.log("πŸ”₯ HMR enabled");
228
- } catch (o) {
229
- console.error("❌ Error reading myop.config.json:", o.message), process.exit(1);
232
+ const s = e.default.readFileSync(B, "utf-8"), t = JSON.parse(s);
233
+ S = t.componentId, P = t.componentName || null, f = t.HMR === !0, S || (console.error("❌ Error: componentId not found in myop.config.json"), process.exit(1)), f && console.log("πŸ”₯ HMR enabled");
234
+ } catch (s) {
235
+ console.error("❌ Error reading myop.config.json:", s.message), process.exit(1);
230
236
  }
231
- const L = process.cwd(), fe = (o) => {
232
- const e = s.default.extname(o).toLowerCase();
237
+ const b = process.cwd(), H = (s) => {
238
+ const t = o.default.extname(s).toLowerCase();
233
239
  return {
234
240
  ".html": "text/html",
235
241
  ".js": "text/javascript",
@@ -240,314 +246,314 @@ async function Ee() {
240
246
  ".gif": "image/gif",
241
247
  ".svg": "image/svg+xml",
242
248
  ".ico": "image/x-icon"
243
- }[e] || "application/octet-stream";
244
- }, u = /* @__PURE__ */ new Map(), U = [], ge = 50, $ = [], T = /* @__PURE__ */ new Map(), H = /* @__PURE__ */ new Map(), ue = (o, e, t) => {
245
- if (o.url.startsWith("/_hmr/")) {
246
- const n = o.url.split("/_hmr/")[1], c = o.headers["sec-websocket-key"], r = I("sha1").update(c + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").digest("base64");
247
- e.write(
249
+ }[t] || "application/octet-stream";
250
+ }, $ = /* @__PURE__ */ new Map(), F = [], Ne = 50, L = [], z = /* @__PURE__ */ new Map(), D = /* @__PURE__ */ new Map(), Ae = (s, t, r) => {
251
+ if (s.url.startsWith("/_hmr/")) {
252
+ const i = s.url.split("/_hmr/")[1], m = s.headers["sec-websocket-key"], d = u("sha1").update(m + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").digest("base64");
253
+ t.write(
248
254
  `HTTP/1.1 101 Switching Protocols\r
249
255
  Upgrade: websocket\r
250
256
  Connection: Upgrade\r
251
- Sec-WebSocket-Accept: ${r}\r
257
+ Sec-WebSocket-Accept: ${d}\r
252
258
  \r
253
259
  `
254
- ), H.has(n) || H.set(n, /* @__PURE__ */ new Set()), H.get(n).add(e), console.log(`πŸ”Œ HMR client connected: ${n}`), e.on("close", () => {
255
- const l = H.get(n);
256
- l && (l.delete(e), l.size === 0 && H.delete(n)), console.log(`πŸ”Œ HMR client disconnected: ${n}`);
257
- }), e.on("error", () => {
258
- const l = H.get(n);
259
- l && l.delete(e);
260
+ ), D.has(i) || D.set(i, /* @__PURE__ */ new Set()), D.get(i).add(t), console.log(`πŸ”Œ HMR client connected: ${i}`), t.on("close", () => {
261
+ const h = D.get(i);
262
+ h && (h.delete(t), h.size === 0 && D.delete(i)), console.log(`πŸ”Œ HMR client disconnected: ${i}`);
263
+ }), t.on("error", () => {
264
+ const h = D.get(i);
265
+ h && h.delete(t);
260
266
  });
261
267
  }
262
- }, X = d.default.createServer((o, e) => {
263
- if (e.setHeader("Content-Type", "application/json"), o.method === "POST" && o.url === "/_register") {
264
- let t = "";
265
- o.on("data", (n) => t += n), o.on("end", () => {
268
+ }, ae = a.default.createServer((s, t) => {
269
+ if (t.setHeader("Content-Type", "application/json"), s.method === "POST" && s.url === "/_register") {
270
+ let r = "";
271
+ s.on("data", (i) => r += i), s.on("end", () => {
266
272
  try {
267
- const { componentId: n, distPath: c, componentName: r } = JSON.parse(t);
268
- u.set(n, { path: c, name: r || null });
269
- const l = r ? ` (${r})` : "";
270
- console.log(`βœ… Registered: ${n}${l} -> ${c}`), e.writeHead(200), e.end(JSON.stringify({ success: !0, registered: Array.from(u.keys()) }));
271
- const w = Array.from(u.entries()).map(([C, j]) => ({
272
- id: C,
273
- path: j.path,
274
- name: j.name
273
+ const { componentId: i, distPath: m, componentName: d } = JSON.parse(r);
274
+ $.set(i, { path: m, name: d || null });
275
+ const h = d ? ` (${d})` : "";
276
+ console.log(`βœ… Registered: ${i}${h} -> ${m}`), t.writeHead(200), t.end(JSON.stringify({ success: !0, registered: Array.from($.keys()) }));
277
+ const O = Array.from($.entries()).map(([T, V]) => ({
278
+ id: T,
279
+ path: V.path,
280
+ name: V.name
275
281
  }));
276
- $.forEach((C) => {
282
+ L.forEach((T) => {
277
283
  try {
278
- C.write(`data: ${JSON.stringify({
284
+ T.write(`data: ${JSON.stringify({
279
285
  type: "components",
280
- components: w
286
+ components: O
281
287
  })}
282
288
 
283
289
  `);
284
290
  } catch {
285
291
  }
286
292
  });
287
- } catch (n) {
288
- e.writeHead(400), e.end(JSON.stringify({ error: n.message }));
293
+ } catch (i) {
294
+ t.writeHead(400), t.end(JSON.stringify({ error: i.message }));
289
295
  }
290
296
  });
291
- } else if (o.method === "POST" && o.url === "/_unregister") {
292
- let t = "";
293
- o.on("data", (n) => t += n), o.on("end", () => {
297
+ } else if (s.method === "POST" && s.url === "/_unregister") {
298
+ let r = "";
299
+ s.on("data", (i) => r += i), s.on("end", () => {
294
300
  try {
295
- const { componentId: n } = JSON.parse(t);
296
- u.delete(n), console.log(`❌ Unregistered: ${n}`), e.writeHead(200), e.end(JSON.stringify({ success: !0 }));
297
- const c = Array.from(u.entries()).map(([r, l]) => ({
298
- id: r,
299
- path: l.path,
300
- name: l.name
301
+ const { componentId: i } = JSON.parse(r);
302
+ $.delete(i), console.log(`❌ Unregistered: ${i}`), t.writeHead(200), t.end(JSON.stringify({ success: !0 }));
303
+ const m = Array.from($.entries()).map(([d, h]) => ({
304
+ id: d,
305
+ path: h.path,
306
+ name: h.name
301
307
  }));
302
- $.forEach((r) => {
308
+ L.forEach((d) => {
303
309
  try {
304
- r.write(`data: ${JSON.stringify({
310
+ d.write(`data: ${JSON.stringify({
305
311
  type: "components",
306
- components: c
312
+ components: m
307
313
  })}
308
314
 
309
315
  `);
310
316
  } catch {
311
317
  }
312
318
  });
313
- } catch (n) {
314
- e.writeHead(400), e.end(JSON.stringify({ error: n.message }));
319
+ } catch (i) {
320
+ t.writeHead(400), t.end(JSON.stringify({ error: i.message }));
315
321
  }
316
322
  });
317
- } else o.method === "GET" && o.url === "/_list" ? (e.writeHead(200), e.end(JSON.stringify({ components: Array.from(u.entries()) }))) : (e.writeHead(404), e.end(JSON.stringify({ error: "Not found" })));
318
- }), k = d.default.createServer((o, e) => {
319
- if (o.url.includes("..")) {
320
- e.writeHead(403, { "Content-Type": "text/plain" }), e.end("Forbidden");
323
+ } else s.method === "GET" && s.url === "/_list" ? (t.writeHead(200), t.end(JSON.stringify({ components: Array.from($.entries()) }))) : (t.writeHead(404), t.end(JSON.stringify({ error: "Not found" })));
324
+ }), q = a.default.createServer((s, t) => {
325
+ if (s.url.includes("..")) {
326
+ t.writeHead(403, { "Content-Type": "text/plain" }), t.end("Forbidden");
321
327
  return;
322
328
  }
323
- const t = new URL(o.url, `http://localhost:${S}`), n = t.pathname, c = n.split("/").filter((v) => v);
324
- if (n.startsWith("/consume")) {
325
- const v = t.searchParams.get("id");
326
- if (!v) {
327
- e.writeHead(400, { "Content-Type": "application/json" }), e.end(JSON.stringify({ error: "Component ID required. Use /consume?id=<componentId>" }));
329
+ const r = new URL(s.url, `http://localhost:${g}`), i = r.pathname, m = i.split("/").filter((k) => k);
330
+ if (i.startsWith("/consume")) {
331
+ const k = r.searchParams.get("id");
332
+ if (!k) {
333
+ t.writeHead(400, { "Content-Type": "application/json" }), t.end(JSON.stringify({ error: "Component ID required. Use /consume?id=<componentId>" }));
328
334
  return;
329
335
  }
330
- const b = u.get(v), M = b ? b.path : null, ie = (R) => {
331
- let p = "Unknown", O = "Unknown";
332
- if (o.headers.referer || o.headers.referrer) {
333
- const f = o.headers.referer || o.headers.referrer;
336
+ const N = $.get(k), J = N ? N.path : null, Ce = (W) => {
337
+ let x = "Unknown", R = "Unknown";
338
+ if (s.headers.referer || s.headers.referrer) {
339
+ const M = s.headers.referer || s.headers.referrer;
334
340
  try {
335
- const A = new URL(f);
336
- p = A.origin, O = A.hostname || A.origin;
341
+ const Y = new URL(M);
342
+ x = Y.origin, R = Y.hostname || Y.origin;
337
343
  } catch {
338
- p = f, O = f;
344
+ x = M, R = M;
339
345
  }
340
- } else if (o.headers.origin)
346
+ } else if (s.headers.origin)
341
347
  try {
342
- const f = new URL(o.headers.origin);
343
- p = f.origin, O = f.hostname || f.origin;
348
+ const M = new URL(s.headers.origin);
349
+ x = M.origin, R = M.hostname || M.origin;
344
350
  } catch {
345
- p = o.headers.origin, O = o.headers.origin;
351
+ x = s.headers.origin, R = s.headers.origin;
346
352
  }
347
- else if (o.socket.remoteAddress) {
348
- const f = o.socket.remoteAddress;
349
- f === "::1" || f === "::ffff:127.0.0.1" ? (p = "localhost", O = "localhost (direct)") : (p = f, O = f.replace("::ffff:", ""));
353
+ else if (s.socket.remoteAddress) {
354
+ const M = s.socket.remoteAddress;
355
+ M === "::1" || M === "::ffff:127.0.0.1" ? (x = "localhost", R = "localhost (direct)") : (x = M, R = M.replace("::ffff:", ""));
350
356
  }
351
- const Q = o.headers.referer || o.headers.referrer || p, W = {
357
+ const le = s.headers.referer || s.headers.referrer || x, te = {
352
358
  type: "request",
353
- componentId: v,
359
+ componentId: k,
354
360
  timestamp: Date.now(),
355
- servedLocally: R,
356
- referrer: Q,
357
- origin: p,
358
- originLabel: O
361
+ servedLocally: W,
362
+ referrer: le,
363
+ origin: x,
364
+ originLabel: R
359
365
  };
360
- T.has(p) || (T.set(p, {
361
- url: p,
362
- label: O,
366
+ z.has(x) || (z.set(x, {
367
+ url: x,
368
+ label: R,
363
369
  firstSeen: Date.now(),
364
370
  requestCount: 0
365
- }), $.forEach((f) => {
371
+ }), L.forEach((M) => {
366
372
  try {
367
- f.write(`data: ${JSON.stringify({
373
+ M.write(`data: ${JSON.stringify({
368
374
  type: "origins",
369
- origins: Array.from(T.values())
375
+ origins: Array.from(z.values())
370
376
  })}
371
377
 
372
378
  `);
373
379
  } catch {
374
380
  }
375
381
  }));
376
- const Oe = T.get(p);
377
- Oe.requestCount++, $.forEach((f) => {
382
+ const Be = z.get(x);
383
+ Be.requestCount++, L.forEach((M) => {
378
384
  try {
379
- f.write(`data: ${JSON.stringify({
385
+ M.write(`data: ${JSON.stringify({
380
386
  type: "origins",
381
- origins: Array.from(T.values())
387
+ origins: Array.from(z.values())
382
388
  })}
383
389
 
384
390
  `);
385
391
  } catch {
386
392
  }
387
- }), U.push(W), U.length > ge && U.shift(), $.forEach((f) => {
393
+ }), F.push(te), F.length > Ne && F.shift(), L.forEach((M) => {
388
394
  try {
389
- f.write(`data: ${JSON.stringify(W)}
395
+ M.write(`data: ${JSON.stringify(te)}
390
396
 
391
397
  `);
392
398
  } catch {
393
399
  }
394
400
  });
395
401
  };
396
- if (M) {
397
- const R = s.default.join(M, "index.html");
398
- i.default.readFile(R, "utf-8", (p, O) => {
399
- if (p) {
400
- console.log(`❌ File not found: ${R}`), e.writeHead(404, { "Content-Type": "application/json" }), e.end(JSON.stringify({ error: "index.html not found" }));
402
+ if (J) {
403
+ const W = o.default.join(J, "index.html");
404
+ e.default.readFile(W, "utf-8", (x, R) => {
405
+ if (x) {
406
+ console.log(`❌ File not found: ${W}`), t.writeHead(404, { "Content-Type": "application/json" }), t.end(JSON.stringify({ error: "index.html not found" }));
401
407
  return;
402
408
  }
403
- const Q = `dev-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`, W = {
409
+ const le = `dev-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`, te = {
404
410
  item: {
405
- name: v,
406
- id: v,
411
+ name: k,
412
+ id: k,
407
413
  consume_variant: [
408
414
  {
409
- id: Q,
415
+ id: le,
410
416
  name: "dev version",
411
417
  loader: {
412
418
  type: "HTMLLoader",
413
419
  shadowRootMode: "localFrame",
414
- HTML: O
420
+ HTML: R
415
421
  }
416
422
  }
417
423
  ]
418
424
  }
419
425
  };
420
- console.log(`βœ… Serving consume JSON for: ${v}`), ie(!0), e.writeHead(200, {
426
+ console.log(`βœ… Serving consume JSON for: ${k}`), Ce(!0), t.writeHead(200, {
421
427
  "Content-Type": "application/json",
422
428
  "Access-Control-Allow-Origin": "*"
423
- }), e.end(JSON.stringify(W, null, 2));
429
+ }), t.end(JSON.stringify(te, null, 2));
424
430
  });
425
431
  } else {
426
- console.log(`πŸ“‘ Proxying consume request to cloud.myop.dev for: ${v}`);
427
- const R = `https://cloud.myop.dev/consume${t.search}`;
428
- ie(!1), fetch(R).then((p) => p.text()).then((p) => {
429
- e.writeHead(200, {
432
+ console.log(`πŸ“‘ Proxying consume request to cloud.myop.dev for: ${k}`);
433
+ const W = `https://cloud.myop.dev/consume${r.search}`;
434
+ Ce(!1), fetch(W).then((x) => x.text()).then((x) => {
435
+ t.writeHead(200, {
430
436
  "Content-Type": "application/json",
431
437
  "Access-Control-Allow-Origin": "*"
432
- }), e.end(p);
433
- }).catch((p) => {
434
- console.error(`❌ Proxy error: ${p.message}`), e.writeHead(502, { "Content-Type": "application/json" }), e.end(JSON.stringify({ error: "Failed to fetch from cloud.myop.dev" }));
438
+ }), t.end(x);
439
+ }).catch((x) => {
440
+ console.error(`❌ Proxy error: ${x.message}`), t.writeHead(502, { "Content-Type": "application/json" }), t.end(JSON.stringify({ error: "Failed to fetch from cloud.myop.dev" }));
435
441
  });
436
442
  }
437
443
  return;
438
444
  }
439
- if (n === "/events") {
440
- e.writeHead(200, {
445
+ if (i === "/events") {
446
+ t.writeHead(200, {
441
447
  "Content-Type": "text/event-stream",
442
448
  "Cache-Control": "no-cache",
443
449
  Connection: "keep-alive",
444
450
  "Access-Control-Allow-Origin": "*"
445
- }), $.push(e);
446
- const v = Array.from(u.entries()).map(([b, M]) => ({
447
- id: b,
448
- path: M.path,
449
- name: M.name
451
+ }), L.push(t);
452
+ const k = Array.from($.entries()).map(([N, J]) => ({
453
+ id: N,
454
+ path: J.path,
455
+ name: J.name
450
456
  }));
451
- e.write(`data: ${JSON.stringify({
457
+ t.write(`data: ${JSON.stringify({
452
458
  type: "components",
453
- components: v
459
+ components: k
454
460
  })}
455
461
 
456
- `), e.write(`data: ${JSON.stringify({
462
+ `), t.write(`data: ${JSON.stringify({
457
463
  type: "origins",
458
- origins: Array.from(T.values())
464
+ origins: Array.from(z.values())
459
465
  })}
460
466
 
461
- `), e.write(`data: ${JSON.stringify({
467
+ `), t.write(`data: ${JSON.stringify({
462
468
  type: "requestLog",
463
- log: U
469
+ log: F
464
470
  })}
465
471
 
466
- `), o.on("close", () => {
467
- const b = $.indexOf(e);
468
- b !== -1 && $.splice(b, 1);
472
+ `), s.on("close", () => {
473
+ const N = L.indexOf(t);
474
+ N !== -1 && L.splice(N, 1);
469
475
  });
470
476
  return;
471
477
  }
472
- if (c.length === 0) {
473
- e.writeHead(200, { "Content-Type": "text/html" }), e.end(Fe(S, h, E, J));
478
+ if (m.length === 0) {
479
+ t.writeHead(200, { "Content-Type": "text/html" }), t.end(nt(g, y, v, j));
474
480
  return;
475
481
  }
476
- if (c[0] !== "view") {
477
- e.writeHead(404, { "Content-Type": "text/plain" }), e.end("Not found. Use /view/<componentId>/ to access components.");
482
+ if (m[0] !== "view") {
483
+ t.writeHead(404, { "Content-Type": "text/plain" }), t.end("Not found. Use /view/<componentId>/ to access components.");
478
484
  return;
479
485
  }
480
- if (c.length < 2) {
481
- e.writeHead(400, { "Content-Type": "text/plain" }), e.end("Component ID required. Use /view/<componentId>/");
486
+ if (m.length < 2) {
487
+ t.writeHead(400, { "Content-Type": "text/plain" }), t.end("Component ID required. Use /view/<componentId>/");
482
488
  return;
483
489
  }
484
- const r = c[1], l = u.get(r);
485
- if (!l) {
486
- e.writeHead(404, { "Content-Type": "text/plain" }), e.end(`Component not found: ${r}`);
490
+ const d = m[1], h = $.get(d);
491
+ if (!h) {
492
+ t.writeHead(404, { "Content-Type": "text/plain" }), t.end(`Component not found: ${d}`);
487
493
  return;
488
494
  }
489
- const w = l.path, C = c.slice(2), j = C.length === 0 ? "index.html" : C.join("/"), F = s.default.join(w, j);
490
- console.log(`πŸ“₯ Request: ${o.url} -> ${F}`), i.default.readFile(F, (v, b) => {
491
- if (v) {
492
- console.log(`❌ File not found: ${F}`), e.writeHead(404, { "Content-Type": "text/plain" }), e.end("Not Found");
495
+ const O = h.path, T = m.slice(2), V = T.length === 0 ? "index.html" : T.join("/"), K = o.default.join(O, V);
496
+ console.log(`πŸ“₯ Request: ${s.url} -> ${K}`), e.default.readFile(K, (k, N) => {
497
+ if (k) {
498
+ console.log(`❌ File not found: ${K}`), t.writeHead(404, { "Content-Type": "text/plain" }), t.end("Not Found");
493
499
  return;
494
500
  }
495
- const M = fe(F);
496
- console.log(`βœ… Serving: ${F} (${M})`), e.writeHead(200, {
497
- "Content-Type": M,
501
+ const J = H(K);
502
+ console.log(`βœ… Serving: ${K} (${J})`), t.writeHead(200, {
503
+ "Content-Type": J,
498
504
  "Access-Control-Allow-Origin": "*"
499
- }), e.end(b);
505
+ }), t.end(N);
500
506
  });
501
- }), ee = () => new Promise((o, e) => {
502
- const t = JSON.stringify({
503
- componentId: g,
504
- distPath: s.default.resolve(L, y),
505
- componentName: x
506
- }), n = {
507
+ }), ye = () => new Promise((s, t) => {
508
+ const r = JSON.stringify({
509
+ componentId: S,
510
+ distPath: o.default.resolve(b, w),
511
+ componentName: P
512
+ }), i = {
507
513
  hostname: "localhost",
508
- port: h,
514
+ port: y,
509
515
  path: "/_register",
510
516
  method: "POST",
511
517
  headers: {
512
518
  "Content-Type": "application/json",
513
- "Content-Length": Buffer.byteLength(t)
519
+ "Content-Length": Buffer.byteLength(r)
514
520
  }
515
- }, c = d.default.request(n, (r) => {
516
- let l = "";
517
- r.on("data", (w) => l += w), r.on("end", () => {
518
- r.statusCode === 200 ? o(JSON.parse(l)) : e(new Error(`Registration failed: ${r.statusCode}`));
521
+ }, m = a.default.request(i, (d) => {
522
+ let h = "";
523
+ d.on("data", (O) => h += O), d.on("end", () => {
524
+ d.statusCode === 200 ? s(JSON.parse(h)) : t(new Error(`Registration failed: ${d.statusCode}`));
519
525
  });
520
526
  });
521
- c.on("error", e), c.write(t), c.end();
522
- }), he = () => new Promise((o, e) => {
523
- const t = JSON.stringify({ componentId: g }), n = {
527
+ m.on("error", t), m.write(r), m.end();
528
+ }), Ee = () => new Promise((s, t) => {
529
+ const r = JSON.stringify({ componentId: S }), i = {
524
530
  hostname: "localhost",
525
- port: h,
531
+ port: y,
526
532
  path: "/_unregister",
527
533
  method: "POST",
528
534
  headers: {
529
535
  "Content-Type": "application/json",
530
- "Content-Length": Buffer.byteLength(t)
536
+ "Content-Length": Buffer.byteLength(r)
531
537
  }
532
- }, c = d.default.request(n, (r) => {
533
- o();
538
+ }, m = a.default.request(i, (d) => {
539
+ s();
534
540
  });
535
- c.on("error", () => o()), c.write(t), c.end();
536
- }), ye = () => {
537
- if (!D) return;
538
- const o = s.default.join(y, "index.html");
541
+ m.on("error", () => s()), m.write(r), m.end();
542
+ }), He = () => {
543
+ if (!f) return;
544
+ const s = o.default.join(w, "index.html");
539
545
  try {
540
- let e = i.default.readFileSync(o, "utf-8");
541
- if (e.includes("<!-- MYOP HMR -->")) {
542
- const n = e.indexOf("<!-- MYOP HMR -->"), c = e.indexOf("<\/script>", n) + 9;
543
- e = e.slice(0, n) + e.slice(c);
546
+ let t = e.default.readFileSync(s, "utf-8");
547
+ if (t.includes("<!-- MYOP HMR -->")) {
548
+ const i = t.indexOf("<!-- MYOP HMR -->"), m = t.indexOf("<\/script>", i) + 9;
549
+ t = t.slice(0, i) + t.slice(m);
544
550
  }
545
- const t = `
551
+ const r = `
546
552
  <!-- MYOP HMR -->
547
553
  <script>
548
554
  (function() {
549
- const componentId = '${g}';
550
- const wsUrl = 'ws://localhost:${h}/_hmr/' + componentId;
555
+ const componentId = '${S}';
556
+ const wsUrl = 'ws://localhost:${y}/_hmr/' + componentId;
551
557
  let ws;
552
558
  let reconnectAttempts = 0;
553
559
  const maxReconnectAttempts = 10;
@@ -648,318 +654,1198 @@ Sec-WebSocket-Accept: ${r}\r
648
654
  })();
649
655
  <\/script>
650
656
  `;
651
- e.includes("</body>") ? e = e.replace("</body>", `${t}</body>`) : e.includes("</html>") ? e = e.replace("</html>", `${t}</html>`) : e += t, i.default.writeFileSync(o, e, "utf-8"), console.log("πŸ”₯ HMR script injected");
652
- } catch (e) {
653
- console.error("❌ Failed to inject HMR script:", e.message);
657
+ t.includes("</body>") ? t = t.replace("</body>", `${r}</body>`) : t.includes("</html>") ? t = t.replace("</html>", `${r}</html>`) : t += r, e.default.writeFileSync(s, t, "utf-8"), console.log("πŸ”₯ HMR script injected");
658
+ } catch (t) {
659
+ console.error("❌ Failed to inject HMR script:", t.message);
654
660
  }
655
- }, we = (o) => {
656
- const e = Buffer.from(o), t = e.length;
657
- let n;
658
- return t < 126 ? n = Buffer.concat([
659
- Buffer.from([129, t]),
661
+ }, Le = (s) => {
662
+ const t = Buffer.from(s), r = t.length;
663
+ let i;
664
+ return r < 126 ? i = Buffer.concat([
665
+ Buffer.from([129, r]),
660
666
  // FIN + text frame, length
661
- e
662
- ]) : t < 65536 ? n = Buffer.concat([
667
+ t
668
+ ]) : r < 65536 ? i = Buffer.concat([
663
669
  Buffer.from([129, 126]),
664
670
  // FIN + text frame, extended length
665
- Buffer.from([t >> 8, t & 255]),
671
+ Buffer.from([r >> 8, r & 255]),
666
672
  // 16-bit length
667
- e
668
- ]) : n = Buffer.concat([
673
+ t
674
+ ]) : i = Buffer.concat([
669
675
  Buffer.from([129, 127]),
670
676
  // FIN + text frame, extended length
671
- Buffer.from([0, 0, 0, 0, t >> 24, t >> 16 & 255, t >> 8 & 255, t & 255]),
677
+ Buffer.from([0, 0, 0, 0, r >> 24, r >> 16 & 255, r >> 8 & 255, r & 255]),
672
678
  // 64-bit length
673
- e
674
- ]), n;
675
- }, ve = () => {
676
- if (!D) return;
677
- const o = H.get(g);
678
- if (!o || o.size === 0)
679
+ t
680
+ ]), i;
681
+ }, Je = () => {
682
+ if (!f) return;
683
+ const s = D.get(S);
684
+ if (!s || s.size === 0)
679
685
  return;
680
- console.log(`πŸ”₯ Notifying ${o.size} HMR client(s)`);
681
- const e = s.default.join(y, "index.html");
686
+ console.log(`πŸ”₯ Notifying ${s.size} HMR client(s)`);
687
+ const t = o.default.join(w, "index.html");
682
688
  try {
683
- let t = i.default.readFileSync(e, "utf-8");
684
- if (t.includes("<!-- MYOP HMR -->")) {
685
- const r = t.indexOf("<!-- MYOP HMR -->"), l = t.indexOf("<\/script>", r) + 9;
686
- t = t.slice(0, r) + t.slice(l);
689
+ let r = e.default.readFileSync(t, "utf-8");
690
+ if (r.includes("<!-- MYOP HMR -->")) {
691
+ const d = r.indexOf("<!-- MYOP HMR -->"), h = r.indexOf("<\/script>", d) + 9;
692
+ r = r.slice(0, d) + r.slice(h);
687
693
  }
688
- const n = JSON.stringify({
694
+ const i = JSON.stringify({
689
695
  type: "update",
690
- html: t
691
- }), c = we(n);
692
- o.forEach((r) => {
696
+ html: r
697
+ }), m = Le(i);
698
+ s.forEach((d) => {
693
699
  try {
694
- r.write(c);
700
+ d.write(m);
695
701
  } catch {
696
- o.delete(r);
702
+ s.delete(d);
697
703
  }
698
704
  });
699
- } catch (t) {
700
- console.error("❌ Failed to read HTML for HMR:", t.message);
705
+ } catch (r) {
706
+ console.error("❌ Failed to read HTML for HMR:", r.message);
701
707
  }
702
- }, B = () => {
703
- if (N) {
704
- Y = !0;
708
+ }, ce = () => {
709
+ if (I) {
710
+ C = !0;
705
711
  return;
706
712
  }
707
- N = !0, console.log(`
708
- πŸ”¨ Building...`), m("npm run build", (o, e, t) => {
709
- N = !1, o ? (console.error("❌ Build failed:", o.message), t && console.error(t)) : (console.log("βœ… Build completed"), e && console.log(e), ye(), ve()), Y && (Y = !1, B());
713
+ I = !0, console.log(`
714
+ πŸ”¨ Building...`), n("npm run build", (s, t, r) => {
715
+ I = !1, s ? (console.error("❌ Build failed:", s.message), r && console.error(r)) : (console.log("βœ… Build completed"), t && console.log(t), He(), Je()), C && (C = !1, ce());
710
716
  });
711
- }, oe = (o) => {
712
- i.default.readdir(o, { withFileTypes: !0 }, (e, t) => {
713
- e || t.forEach((n) => {
714
- const c = s.default.join(o, n.name);
715
- if (n.isDirectory())
716
- n.name !== "node_modules" && n.name !== "dist" && !n.name.startsWith(".") && oe(c);
717
- else if (n.isFile()) {
718
- const r = s.default.extname(n.name);
719
- if (r === ".js" || r === ".css" || r === ".html") {
717
+ }, we = /* @__PURE__ */ new Set(), ve = (s) => {
718
+ e.default.readdir(s, { withFileTypes: !0 }, (t, r) => {
719
+ t || (r.forEach((i) => {
720
+ const m = o.default.join(s, i.name);
721
+ if (i.isDirectory())
722
+ i.name !== "node_modules" && i.name !== "dist" && !i.name.startsWith(".") && ve(m);
723
+ else if (i.isFile()) {
724
+ const d = o.default.extname(i.name);
725
+ if (d === ".js" || d === ".css" || d === ".html")
720
726
  try {
721
- const l = i.default.readFileSync(c, "utf-8");
722
- V.set(c, l);
727
+ const h = e.default.readFileSync(m, "utf-8");
728
+ _.set(m, h);
723
729
  } catch {
724
730
  }
725
- i.default.watch(c, (l) => {
726
- if (l === "change")
727
- try {
728
- const w = i.default.readFileSync(c, "utf-8"), C = V.get(c);
729
- w !== C && (V.set(c, w), console.log(`πŸ“ File changed: ${c}`), B());
730
- } catch {
731
- console.log(`πŸ“ File changed: ${c}`), B();
732
- }
733
- });
734
- }
735
731
  }
736
- });
732
+ }), we.has(s) || (we.add(s), e.default.watch(s, (i, m) => {
733
+ if (!m) return;
734
+ const d = o.default.extname(m);
735
+ if (d !== ".js" && d !== ".css" && d !== ".html") return;
736
+ const h = o.default.join(s, m);
737
+ setTimeout(() => {
738
+ try {
739
+ const O = e.default.readFileSync(h, "utf-8"), T = _.get(h);
740
+ O !== T && (_.set(h, O), console.log(`πŸ“ File changed: ${h}`), ce());
741
+ } catch {
742
+ }
743
+ }, 50);
744
+ })));
737
745
  });
738
- }, te = () => {
746
+ }, Se = () => {
739
747
  console.log(`
740
- πŸ”¨ Component: ${g}`), B(), oe(L), console.log("πŸ‘€ Watching .js, .css, and .html files for changes..."), console.log(`Press Ctrl+C to stop
748
+ πŸ”¨ Component: ${S}`), ce(), ve(b), console.log("πŸ‘€ Watching .js, .css, and .html files for changes..."), console.log(`Press Ctrl+C to stop
741
749
  `);
742
- }, Se = () => new Promise((o) => {
743
- const e = {
750
+ }, De = () => new Promise((s) => {
751
+ const t = {
744
752
  hostname: "localhost",
745
- port: h,
753
+ port: y,
746
754
  path: "/_list",
747
755
  method: "GET",
748
756
  timeout: 1e3
749
- }, t = d.default.request(e, (n) => {
750
- o(!0);
757
+ }, r = a.default.request(t, (i) => {
758
+ s(!0);
751
759
  });
752
- t.on("error", () => o(!1)), t.on("timeout", () => {
753
- t.destroy(), o(!1);
754
- }), t.end();
755
- }), Ce = () => new Promise((o) => {
756
- const e = d.default.createServer((t, n) => {
757
- if (n.setHeader("Content-Type", "application/json"), t.method === "POST" && t.url === "/_register") {
758
- let c = "";
759
- t.on("data", (r) => c += r), t.on("end", () => {
760
+ r.on("error", () => s(!1)), r.on("timeout", () => {
761
+ r.destroy(), s(!1);
762
+ }), r.end();
763
+ }), Ue = () => new Promise((s) => {
764
+ const t = a.default.createServer((r, i) => {
765
+ if (i.setHeader("Content-Type", "application/json"), r.method === "POST" && r.url === "/_register") {
766
+ let m = "";
767
+ r.on("data", (d) => m += d), r.on("end", () => {
760
768
  try {
761
- const { componentId: r, distPath: l, componentName: w } = JSON.parse(c);
762
- u.set(r, { path: l, name: w || null });
763
- const C = w ? ` (${w})` : "";
764
- console.log(`βœ… Registered: ${r}${C} -> ${l}`), n.writeHead(200), n.end(JSON.stringify({ success: !0, registered: Array.from(u.keys()) }));
765
- } catch (r) {
766
- n.writeHead(400), n.end(JSON.stringify({ error: r.message }));
769
+ const { componentId: d, distPath: h, componentName: O } = JSON.parse(m);
770
+ $.set(d, { path: h, name: O || null });
771
+ const T = O ? ` (${O})` : "";
772
+ console.log(`βœ… Registered: ${d}${T} -> ${h}`), i.writeHead(200), i.end(JSON.stringify({ success: !0, registered: Array.from($.keys()) }));
773
+ } catch (d) {
774
+ i.writeHead(400), i.end(JSON.stringify({ error: d.message }));
767
775
  }
768
776
  });
769
- } else if (t.method === "POST" && t.url === "/_unregister") {
770
- let c = "";
771
- t.on("data", (r) => c += r), t.on("end", () => {
777
+ } else if (r.method === "POST" && r.url === "/_unregister") {
778
+ let m = "";
779
+ r.on("data", (d) => m += d), r.on("end", () => {
772
780
  try {
773
- const { componentId: r } = JSON.parse(c);
774
- u.delete(r), console.log(`❌ Unregistered: ${r}`), n.writeHead(200), n.end(JSON.stringify({ success: !0 }));
775
- } catch (r) {
776
- n.writeHead(400), n.end(JSON.stringify({ error: r.message }));
781
+ const { componentId: d } = JSON.parse(m);
782
+ $.delete(d), console.log(`❌ Unregistered: ${d}`), i.writeHead(200), i.end(JSON.stringify({ success: !0 }));
783
+ } catch (d) {
784
+ i.writeHead(400), i.end(JSON.stringify({ error: d.message }));
777
785
  }
778
786
  });
779
- } else t.method === "GET" && t.url === "/_list" ? (n.writeHead(200), n.end(JSON.stringify({ components: Array.from(u.entries()) }))) : (n.writeHead(404), n.end(JSON.stringify({ error: "Not found" })));
787
+ } else r.method === "GET" && r.url === "/_list" ? (i.writeHead(200), i.end(JSON.stringify({ components: Array.from($.entries()) }))) : (i.writeHead(404), i.end(JSON.stringify({ error: "Not found" })));
780
788
  });
781
- e.on("error", () => {
782
- o(!1);
783
- }), e.listen(h, () => {
789
+ t.on("error", () => {
790
+ s(!1);
791
+ }), t.listen(y, () => {
784
792
  console.log(`
785
- πŸ”„ Taking over as server...`), console.log(`πŸ“‘ Management server on port ${h}`), k.on("error", () => {
786
- e.close(), o(!1);
787
- }), k.listen(S, () => {
788
- console.log(`πŸ“‘ Main server running at http://localhost:${S}`), u.set(g, {
789
- path: s.default.resolve(L, y),
790
- name: x
793
+ πŸ”„ Taking over as server...`), console.log(`πŸ“‘ Management server on port ${y}`), q.on("error", () => {
794
+ t.close(), s(!1);
795
+ }), q.listen(g, () => {
796
+ console.log(`πŸ“‘ Main server running at http://localhost:${g}`), $.set(S, {
797
+ path: o.default.resolve(b, w),
798
+ name: P
791
799
  });
792
- const t = x ? ` (${x})` : "";
793
- console.log(`βœ… Registered component: ${g}${t}`), console.log(`πŸ“‘ Access at: http://localhost:${S}/view/${g}/`), o(!0);
800
+ const r = P ? ` (${P})` : "";
801
+ console.log(`βœ… Registered component: ${S}${r}`), console.log(`πŸ“‘ Access at: http://localhost:${g}/view/${S}/`), s(!0);
794
802
  });
795
803
  });
796
804
  });
797
- let G;
798
- const ne = () => {
799
- G = setInterval(async () => {
800
- await Se() || (clearInterval(G), console.log(`
801
- ⚠️ Server appears to be down, attempting to take over...`), await Ce() ? console.log("βœ… Successfully took over as server") : (console.log("ℹ️ Another instance took over, re-registering..."), setTimeout(async () => {
805
+ let ee;
806
+ const be = () => {
807
+ ee = setInterval(async () => {
808
+ await De() || (clearInterval(ee), console.log(`
809
+ ⚠️ Server appears to be down, attempting to take over...`), await Ue() ? console.log("βœ… Successfully took over as server") : (console.log("ℹ️ Another instance took over, re-registering..."), setTimeout(async () => {
802
810
  try {
803
- await ee(), console.log(`βœ… Re-registered component: ${g}`), ne();
804
- } catch (t) {
805
- console.error("❌ Failed to re-register:", t.message);
811
+ await ye(), console.log(`βœ… Re-registered component: ${S}`), be();
812
+ } catch (r) {
813
+ console.error("❌ Failed to re-register:", r.message);
806
814
  }
807
815
  }, 2e3)));
808
816
  }, 3e3);
809
- }, se = async () => {
817
+ }, xe = async () => {
810
818
  console.log(`
811
819
 
812
- πŸ›‘ Shutting down...`), G && clearInterval(G), await he(), process.exit(0);
820
+ πŸ›‘ Shutting down...`), ee && clearInterval(ee), await Ee(), process.exit(0);
813
821
  };
814
- process.on("SIGINT", se), process.on("SIGTERM", se), X.on("error", async (o) => {
815
- if (o.code === "EADDRINUSE") {
822
+ process.on("SIGINT", xe), process.on("SIGTERM", xe), ae.on("error", async (s) => {
823
+ if (s.code === "EADDRINUSE") {
816
824
  console.log(`
817
825
  πŸ”— Connecting to existing dev server...`);
818
826
  try {
819
- const e = await ee();
820
- console.log(`βœ… Registered component: ${g}`), console.log(`πŸ“‘ Access at: http://localhost:${S}/view/${g}/`), console.log(`πŸ“‹ All registered components: ${e.registered.join(", ")}`), te(), ne();
821
- } catch (e) {
822
- console.error("❌ Failed to register component:", e.message), process.exit(1);
827
+ const t = await ye();
828
+ console.log(`βœ… Registered component: ${S}`), console.log(`πŸ“‘ Access at: http://localhost:${g}/view/${S}/`), console.log(`πŸ“‹ All registered components: ${t.registered.join(", ")}`), Se(), be();
829
+ } catch (t) {
830
+ console.error("❌ Failed to register component:", t.message), process.exit(1);
823
831
  }
824
832
  } else
825
- console.error("❌ Management server error:", o.message), process.exit(1);
826
- }), X.on("upgrade", ue), X.listen(h, async () => {
833
+ console.error("❌ Management server error:", s.message), process.exit(1);
834
+ }), ae.on("upgrade", Ae), ae.listen(y, async () => {
827
835
  console.log(`
828
- πŸš€ Starting shared dev server...`), console.log(`πŸ“‘ Management server on port ${h}`), k.on("error", (o) => {
829
- console.error("❌ Main server error:", o.message), process.exit(1);
830
- }), k.listen(S, async () => {
831
- console.log(`πŸ“‘ Main server running at http://localhost:${S}`), u.set(g, {
832
- path: s.default.resolve(L, y),
833
- name: x
836
+ πŸš€ Starting shared dev server...`), console.log(`πŸ“‘ Management server on port ${y}`), q.on("error", (s) => {
837
+ console.error("❌ Main server error:", s.message), process.exit(1);
838
+ }), q.listen(g, async () => {
839
+ console.log(`πŸ“‘ Main server running at http://localhost:${g}`), $.set(S, {
840
+ path: o.default.resolve(b, w),
841
+ name: P
834
842
  });
835
- const o = x ? ` (${x})` : "";
836
- console.log(`βœ… Registered component: ${g}${o}`), console.log(`πŸ“‘ Access at: http://localhost:${S}/view/${g}/`), te();
843
+ const s = P ? ` (${P})` : "";
844
+ console.log(`βœ… Registered component: ${S}${s}`), console.log(`πŸ“‘ Access at: http://localhost:${g}/view/${S}/`), Se();
845
+ });
846
+ });
847
+ }
848
+ const pe = Z.join(Ge.homedir(), ".myop"), Q = Z.join(pe, "credentials.json");
849
+ function st() {
850
+ E.existsSync(pe) || E.mkdirSync(pe, { recursive: !0, mode: 448 });
851
+ }
852
+ function ge() {
853
+ try {
854
+ if (!E.existsSync(Q))
855
+ return null;
856
+ const e = E.readFileSync(Q, "utf8");
857
+ return JSON.parse(e);
858
+ } catch (e) {
859
+ return console.info("Failed to read credentials:", e.message), null;
860
+ }
861
+ }
862
+ function _e(e) {
863
+ st();
864
+ const o = {
865
+ ...e,
866
+ savedAt: (/* @__PURE__ */ new Date()).toISOString()
867
+ };
868
+ E.writeFileSync(Q, JSON.stringify(o, null, 2), {
869
+ mode: 384
870
+ // Read/write for owner only
871
+ });
872
+ }
873
+ function Te() {
874
+ try {
875
+ return E.existsSync(Q) && E.unlinkSync(Q), !0;
876
+ } catch (e) {
877
+ return console.error("Failed to clear credentials:", e.message), !1;
878
+ }
879
+ }
880
+ function rt(e) {
881
+ if (!e || !e.expiresAt)
882
+ return !0;
883
+ const o = 5 * 60 * 1e3, n = new Date(e.expiresAt).getTime();
884
+ return Date.now() > n - o;
885
+ }
886
+ function Re() {
887
+ const e = ge();
888
+ return e ? {
889
+ email: e.userEmail,
890
+ userId: e.userId
891
+ } : null;
892
+ }
893
+ const G = process.env.MYOP_MCP_URL || "https://mcp.myop.dev", se = 19284, he = `http://localhost:${se}/callback`, it = "myop-cli";
894
+ function at() {
895
+ return ue.randomBytes(32).toString("base64url");
896
+ }
897
+ function ct(e) {
898
+ return ue.createHash("sha256").update(e).digest("base64url");
899
+ }
900
+ async function lt() {
901
+ const e = await fetch(`${G}/oauth/register`, {
902
+ method: "POST",
903
+ headers: { "Content-Type": "application/json" },
904
+ body: JSON.stringify({
905
+ client_name: it,
906
+ redirect_uris: [he],
907
+ grant_types: ["authorization_code", "refresh_token"],
908
+ response_types: ["code"]
909
+ })
910
+ });
911
+ if (!e.ok) {
912
+ const o = await e.text();
913
+ throw new Error(`Failed to register client: ${o}`);
914
+ }
915
+ return e.json();
916
+ }
917
+ function oe(e, o, n, a = null) {
918
+ const u = {
919
+ success: `<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="#4ade80" stroke-width="2">
920
+ <circle cx="12" cy="12" r="10"/>
921
+ <path d="M8 12l2.5 2.5L16 9"/>
922
+ </svg>`,
923
+ error: `<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="#f87171" stroke-width="2">
924
+ <circle cx="12" cy="12" r="10"/>
925
+ <path d="M15 9l-6 6M9 9l6 6"/>
926
+ </svg>`,
927
+ warning: `<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="#fbbf24" stroke-width="2">
928
+ <path d="M12 2L2 22h20L12 2z"/>
929
+ <path d="M12 9v4M12 17h.01"/>
930
+ </svg>`
931
+ }, c = {
932
+ success: { accent: "#4ade80", glow: "rgba(74, 222, 128, 0.1)" },
933
+ error: { accent: "#f87171", glow: "rgba(248, 113, 113, 0.1)" },
934
+ warning: { accent: "#fbbf24", glow: "rgba(251, 191, 36, 0.1)" }
935
+ }, { accent: p, glow: v } = c[e] || c.error;
936
+ return `<!DOCTYPE html>
937
+ <html lang="en">
938
+ <head>
939
+ <meta charset="UTF-8">
940
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
941
+ <title>myop-cli | ${o}</title>
942
+ <style>
943
+ * {
944
+ margin: 0;
945
+ padding: 0;
946
+ box-sizing: border-box;
947
+ }
948
+
949
+ body {
950
+ font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Roboto Mono', 'Consolas', monospace;
951
+ background: #1e1e1e;
952
+ color: #e8eaed;
953
+ min-height: 100vh;
954
+ display: flex;
955
+ align-items: center;
956
+ justify-content: center;
957
+ padding: 20px;
958
+ }
959
+
960
+ .container {
961
+ background: #292a2d;
962
+ border: 1px solid #3c4043;
963
+ border-radius: 8px;
964
+ padding: 48px;
965
+ max-width: 480px;
966
+ width: 100%;
967
+ text-align: center;
968
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
969
+ animation: slideUp 0.3s ease-out;
970
+ }
971
+
972
+ @keyframes slideUp {
973
+ from {
974
+ opacity: 0;
975
+ transform: translateY(20px);
976
+ }
977
+ to {
978
+ opacity: 1;
979
+ transform: translateY(0);
980
+ }
981
+ }
982
+
983
+ .icon {
984
+ margin-bottom: 24px;
985
+ animation: pulse 2s ease-in-out infinite;
986
+ }
987
+
988
+ @keyframes pulse {
989
+ 0%, 100% { opacity: 1; }
990
+ 50% { opacity: 0.7; }
991
+ }
992
+
993
+ h1 {
994
+ font-size: 20px;
995
+ font-weight: 500;
996
+ color: ${p};
997
+ margin-bottom: 12px;
998
+ letter-spacing: -0.5px;
999
+ }
1000
+
1001
+ .message {
1002
+ color: #9aa0a6;
1003
+ font-size: 14px;
1004
+ line-height: 1.6;
1005
+ margin-bottom: 24px;
1006
+ }
1007
+
1008
+ .details {
1009
+ background: #1e1e1e;
1010
+ border: 1px solid #3c4043;
1011
+ border-radius: 4px;
1012
+ padding: 12px 16px;
1013
+ font-size: 12px;
1014
+ color: #f87171;
1015
+ text-align: left;
1016
+ margin-bottom: 24px;
1017
+ word-break: break-all;
1018
+ }
1019
+
1020
+ .details code {
1021
+ color: #fbbf24;
1022
+ }
1023
+
1024
+ .hint {
1025
+ display: inline-flex;
1026
+ align-items: center;
1027
+ gap: 8px;
1028
+ background: ${v};
1029
+ border: 1px solid ${p}33;
1030
+ border-radius: 4px;
1031
+ padding: 10px 16px;
1032
+ font-size: 12px;
1033
+ color: #9aa0a6;
1034
+ }
1035
+
1036
+ .hint kbd {
1037
+ background: #3c4043;
1038
+ border: 1px solid #5f6368;
1039
+ border-radius: 3px;
1040
+ padding: 2px 6px;
1041
+ font-size: 11px;
1042
+ color: #e8eaed;
1043
+ }
1044
+
1045
+ .logo {
1046
+ margin-top: 32px;
1047
+ padding-top: 24px;
1048
+ border-top: 1px solid #3c4043;
1049
+ }
1050
+
1051
+ .logo span {
1052
+ font-size: 12px;
1053
+ color: #5f6368;
1054
+ letter-spacing: 1px;
1055
+ }
1056
+
1057
+ .logo .brand {
1058
+ color: #8ab4f8;
1059
+ font-weight: 600;
1060
+ }
1061
+ </style>
1062
+ </head>
1063
+ <body>
1064
+ <div class="container">
1065
+ <div class="icon">
1066
+ ${u[e] || u.error}
1067
+ </div>
1068
+ <h1>${o}</h1>
1069
+ <p class="message">${n}</p>
1070
+ ${a ? `<div class="details"><code>Error:</code> ${a}</div>` : ""}
1071
+ <div class="hint">
1072
+ <span>Press</span>
1073
+ <kbd>⌘</kbd><kbd>W</kbd>
1074
+ <span>to close this window</span>
1075
+ </div>
1076
+ <div class="logo">
1077
+ <span><span class="brand">myop</span>-cli</span>
1078
+ </div>
1079
+ </div>
1080
+ </body>
1081
+ </html>`;
1082
+ }
1083
+ function dt(e) {
1084
+ return new Promise((o, n) => {
1085
+ const a = We.createServer((u, c) => {
1086
+ const p = new Me(u.url, `http://localhost:${se}`);
1087
+ if (p.pathname === "/callback") {
1088
+ const v = p.searchParams.get("code"), j = p.searchParams.get("state"), g = p.searchParams.get("error");
1089
+ if (g) {
1090
+ c.writeHead(200, { "Content-Type": "text/html" }), c.end(oe(
1091
+ "error",
1092
+ "Authentication Failed",
1093
+ "Unable to complete the authentication process.",
1094
+ g
1095
+ )), a.close(), n(new Error(`OAuth error: ${g}`));
1096
+ return;
1097
+ }
1098
+ if (j !== e) {
1099
+ c.writeHead(400, { "Content-Type": "text/html" }), c.end(oe(
1100
+ "warning",
1101
+ "Security Error",
1102
+ "State mismatch detected. This could indicate a CSRF attack. Please try authenticating again.",
1103
+ "state_mismatch"
1104
+ )), a.close(), n(new Error("State mismatch"));
1105
+ return;
1106
+ }
1107
+ if (!v) {
1108
+ c.writeHead(400, { "Content-Type": "text/html" }), c.end(oe(
1109
+ "error",
1110
+ "Missing Authorization Code",
1111
+ "No authorization code was received from the server.",
1112
+ "missing_code"
1113
+ )), a.close(), n(new Error("No authorization code"));
1114
+ return;
1115
+ }
1116
+ c.writeHead(200, { "Content-Type": "text/html" }), c.end(oe(
1117
+ "success",
1118
+ "Authentication Successful",
1119
+ "You have been authenticated successfully. Return to the terminal to continue."
1120
+ )), a.close(), o(v);
1121
+ } else
1122
+ c.writeHead(404), c.end("Not found");
837
1123
  });
1124
+ a.listen(se, () => {
1125
+ console.info(`OAuth callback server listening on port ${se}`);
1126
+ }), setTimeout(() => {
1127
+ a.close(), n(new Error("Authentication timed out"));
1128
+ }, 5 * 60 * 1e3);
1129
+ });
1130
+ }
1131
+ async function pt(e, o, n) {
1132
+ const a = await fetch(`${G}/oauth/token`, {
1133
+ method: "POST",
1134
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
1135
+ body: new je({
1136
+ grant_type: "authorization_code",
1137
+ code: e,
1138
+ client_id: o,
1139
+ redirect_uri: he,
1140
+ code_verifier: n
1141
+ })
1142
+ });
1143
+ if (!a.ok) {
1144
+ const u = await a.json();
1145
+ throw new Error(u.error_description || u.error || "Token exchange failed");
1146
+ }
1147
+ return a.json();
1148
+ }
1149
+ async function mt(e, o) {
1150
+ const n = await fetch(`${G}/oauth/token`, {
1151
+ method: "POST",
1152
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
1153
+ body: new je({
1154
+ grant_type: "refresh_token",
1155
+ refresh_token: e,
1156
+ client_id: o
1157
+ })
838
1158
  });
1159
+ if (!n.ok) {
1160
+ const a = await n.json();
1161
+ throw new Error(a.error_description || a.error || "Token refresh failed");
1162
+ }
1163
+ return n.json();
1164
+ }
1165
+ async function ut(e) {
1166
+ var u, c, p;
1167
+ const o = await fetch(`${G}/mcp`, {
1168
+ method: "POST",
1169
+ headers: {
1170
+ "Content-Type": "application/json",
1171
+ Authorization: `Bearer ${e}`
1172
+ },
1173
+ body: JSON.stringify({
1174
+ jsonrpc: "2.0",
1175
+ id: 1,
1176
+ method: "tools/call",
1177
+ params: {
1178
+ name: "whoami",
1179
+ arguments: {}
1180
+ }
1181
+ })
1182
+ });
1183
+ if (!o.ok)
1184
+ throw new Error("Failed to get user info");
1185
+ const n = await o.json();
1186
+ if (n.error)
1187
+ throw new Error(n.error.message);
1188
+ const a = (p = (c = (u = n.result) == null ? void 0 : u.content) == null ? void 0 : c[0]) == null ? void 0 : p.text;
1189
+ if (a)
1190
+ return JSON.parse(a);
1191
+ throw new Error("Invalid response from whoami");
1192
+ }
1193
+ async function X() {
1194
+ const e = A("Starting authentication...").start();
1195
+ try {
1196
+ e.text = "Registering OAuth client...";
1197
+ const n = (await lt()).client_id, a = at(), u = ct(a), c = ue.randomBytes(16).toString("hex");
1198
+ e.text = "Waiting for authorization...";
1199
+ const p = dt(c), v = new Me(`${G}/oauth/authorize`);
1200
+ v.searchParams.set("response_type", "code"), v.searchParams.set("client_id", n), v.searchParams.set("redirect_uri", he), v.searchParams.set("code_challenge", u), v.searchParams.set("code_challenge_method", "S256"), v.searchParams.set("state", c), e.stop(), console.log(`
1201
+ 🌐 Opening browser for authentication...`), console.log("If the browser does not open, visit:"), console.log(` ${v.toString()}
1202
+ `), await Ye(v.toString());
1203
+ const j = await p;
1204
+ e.start("Exchanging authorization code...");
1205
+ const g = await pt(j, n, a);
1206
+ e.text = "Getting user info...";
1207
+ const y = await ut(g.access_token), w = {
1208
+ accessToken: g.access_token,
1209
+ refreshToken: g.refresh_token,
1210
+ expiresAt: new Date(Date.now() + g.expires_in * 1e3).toISOString(),
1211
+ clientId: n,
1212
+ userId: y.userId,
1213
+ userEmail: y.email
1214
+ };
1215
+ return _e(w), e.succeed(`Authenticated as ${y.email}`), w;
1216
+ } catch (o) {
1217
+ throw e.fail(`Authentication failed: ${o.message}`), o;
1218
+ }
1219
+ }
1220
+ async function Fe() {
1221
+ const e = ge();
1222
+ if (!e) {
1223
+ console.log("Not currently logged in.");
1224
+ return;
1225
+ }
1226
+ Te(), console.log(`βœ… Logged out (was: ${e.userEmail})`);
1227
+ }
1228
+ async function ft() {
1229
+ let e = ge();
1230
+ if (!e)
1231
+ return console.log(`Not logged in. Starting authentication...
1232
+ `), await X();
1233
+ if (!rt(e))
1234
+ return e;
1235
+ if (e.refreshToken) {
1236
+ const o = A("Refreshing access token...").start();
1237
+ try {
1238
+ const n = await mt(
1239
+ e.refreshToken,
1240
+ e.clientId
1241
+ );
1242
+ return e = {
1243
+ ...e,
1244
+ accessToken: n.access_token,
1245
+ refreshToken: n.refresh_token,
1246
+ expiresAt: new Date(Date.now() + n.expires_in * 1e3).toISOString()
1247
+ }, _e(e), o.succeed("Token refreshed"), e;
1248
+ } catch {
1249
+ return o.warn("Token refresh failed, please log in again"), Te(), await X();
1250
+ }
1251
+ }
1252
+ return console.log(`Session expired. Please log in again.
1253
+ `), await X();
1254
+ }
1255
+ function gt() {
1256
+ return G;
1257
+ }
1258
+ const re = "@myop/cli";
1259
+ async function ht() {
1260
+ try {
1261
+ const e = await fetch(`https://registry.npmjs.org/${re}/latest`);
1262
+ return e.ok ? (await e.json()).version : null;
1263
+ } catch {
1264
+ return null;
1265
+ }
1266
+ }
1267
+ function yt(e, o) {
1268
+ const n = e.split(".").map(Number), a = o.split(".").map(Number);
1269
+ for (let u = 0; u < Math.max(n.length, a.length); u++) {
1270
+ const c = n[u] || 0, p = a[u] || 0;
1271
+ if (c > p) return 1;
1272
+ if (c < p) return -1;
1273
+ }
1274
+ return 0;
839
1275
  }
840
- const Je = (i) => new Promise((s) => setTimeout(s, i));
841
- a.executionPath = process.cwd();
842
- const z = (i = !1) => {
843
- const s = a.program.getOptionValue("verbose");
844
- s || (console.info = () => {
845
- }), console.info("πŸ“ verbose mode on"), a.options = {
846
- configPath: a.program.getOptionValue("config"),
847
- verbose: s
1276
+ async function wt(e) {
1277
+ const o = A({
1278
+ text: "Checking for updates...",
1279
+ color: "cyan"
1280
+ }).start(), n = await ht();
1281
+ if (o.stop(), !n || yt(n, e) <= 0)
1282
+ return !1;
1283
+ if (console.log(`
1284
+ πŸ“¦ New version available: ${e} β†’ ${n}
1285
+ `), await $e({
1286
+ message: "Would you like to update now?",
1287
+ choices: [
1288
+ { name: "Yes, update now", value: !0 },
1289
+ { name: "No, continue with current version", value: !1 }
1290
+ ]
1291
+ })) {
1292
+ const u = A({
1293
+ text: `Updating ${re} to v${n}...`,
1294
+ color: "green"
1295
+ }).start();
1296
+ try {
1297
+ ne(`npm install -g ${re}@latest`, { stdio: "pipe" }), u.succeed(`Updated to v${n}`), console.log(`
1298
+ Please restart the CLI to use the new version.
1299
+ `), process.exit(0);
1300
+ } catch {
1301
+ return u.fail("Update failed"), console.log(`
1302
+ You can manually update by running: npm install -g ${re}@latest
1303
+ `), !1;
1304
+ }
1305
+ }
1306
+ return !1;
1307
+ }
1308
+ const vt = (e) => new Promise((o) => setTimeout(o, e));
1309
+ l.executionPath = process.cwd();
1310
+ const ie = (e = !1) => {
1311
+ const o = l.program.getOptionValue("verbose");
1312
+ o || (console.info = () => {
1313
+ }), console.info("πŸ“ verbose mode on"), l.options = {
1314
+ configPath: l.program.getOptionValue("config"),
1315
+ verbose: o
848
1316
  };
849
1317
  try {
850
- a.myopConfig = He(a.options.configPath);
851
- } catch (m) {
852
- if (i) {
1318
+ return l.myopConfig = Ke(l.options.configPath), { configFound: !0 };
1319
+ } catch (n) {
1320
+ if (e) {
853
1321
  console.info(`
854
- ⚠️ failed read config file from ${a.options.configPath}, trying to create new one`);
1322
+ ⚠️ failed read config file from ${l.options.configPath}, trying to create new one`);
855
1323
  try {
856
- const d = {
1324
+ const a = {
857
1325
  author: "@myop-cli",
858
1326
  flows: []
859
1327
  };
860
- q(a.options.configPath, d), a.myopConfig = d;
1328
+ return fe(l.options.configPath, a), l.myopConfig = a, { configFound: !0 };
861
1329
  } catch {
862
- console.log(`
863
- ⚠️ failed read config file from ${a.options.configPath}, for more details use verbose flag`), console.info("Error details :", m), process.exit();
1330
+ return console.info("Error details :", n), { configFound: !1, error: n };
864
1331
  }
865
1332
  } else
866
- console.log(`
867
- ⚠️ failed read config file from ${a.options.configPath}, for more details use verbose flag`), console.info("Error details :", m), process.exit();
1333
+ return console.info("Error details :", n), { configFound: !1, error: n };
868
1334
  }
869
- }, de = [
870
- ae,
871
- ce,
872
- le,
873
- Te,
874
- new xe(),
875
- ...je
876
- ], De = async () => $e({
877
- message: "Select an operation",
878
- choices: de
879
- }), pe = async () => {
880
- const i = await De(), s = de.find((m) => m.value === i);
881
- s ? s.action ? await s.action() : console.log(`⚠️ Operation ${i} has no action`) : console.log(`⚠️ Operation ${i} not found`), await pe();
882
1335
  };
883
- a.program = new Me();
884
- a.program.name("@myop/cli").description("Myop CLI - Remote UI Made Easy").version("0.1.10");
885
- a.program.addOption(new Z("-c, --config <value>", "myop.config.json file location").default("./myop.config.json", "./myop.config.json"));
886
- a.program.addOption(new Z("-h, --help", "Show helpful information"));
887
- a.program.addOption(new Z("-v, --verbose", "Enables verbose output mode for the command-line interface (CLI)."));
888
- a.program.command("add").description("Install Myop assets").addArgument("type").addArgument("id").action((i, s) => {
889
- z(!0), console.info("adding ", i, s, a.options.configPath), i === "flow" && ce._action(s), process.exit();
1336
+ [
1337
+ new de(),
1338
+ ...ot
1339
+ ];
1340
+ l.program = new ze();
1341
+ l.program.name("@myop/cli").description("Myop CLI - Remote UI Made Easy").version("0.1.10");
1342
+ l.program.addOption(new me("-c, --config <value>", "myop.config.json file location").default("./myop.config.json", "./myop.config.json"));
1343
+ l.program.addOption(new me("-h, --help", "Show helpful information"));
1344
+ l.program.addOption(new me("-v, --verbose", "Enables verbose output mode for the command-line interface (CLI)."));
1345
+ l.program.command("add").description("Install Myop assets").addArgument("type").addArgument("id").action((e, o) => {
1346
+ ie(!0), console.info("adding ", e, o, l.options.configPath), e === "flow" && ke._action(o), process.exit();
1347
+ });
1348
+ l.program.command("remove").description("Remove Myop asset").argument("<type>", "Myop asset type").argument("<id>", "Asset id").action((e, o) => {
1349
+ ie(), console.info("removing ", e, o, l.options.configPath), e === "flow" && Ie._action(o), process.exit();
890
1350
  });
891
- a.program.command("remove").description("Remove Myop asset").argument("<type>", "Myop asset type").argument("<id>", "Asset id").action((i, s) => {
892
- z(), console.info("removing ", i, s, a.options.configPath), i === "flow" && le._action(s), process.exit();
1351
+ l.program.command("install").description("Install Myop assets").action(async () => {
1352
+ ie(), await Oe.action();
893
1353
  });
894
- a.program.command("install").description("Install Myop assets").action(async () => {
895
- z(), await ae.action();
1354
+ l.program.command("login").description("Authenticate with Myop platform").action(async () => {
1355
+ try {
1356
+ await X();
1357
+ } catch (e) {
1358
+ console.error("Login failed:", e.message), process.exit(1);
1359
+ }
1360
+ process.exit(0);
1361
+ });
1362
+ l.program.command("logout").description("Clear stored credentials").action(async () => {
1363
+ await Fe(), process.exit(0);
1364
+ });
1365
+ l.program.command("whoami").description("Show current authenticated user").action(async () => {
1366
+ const e = Re();
1367
+ e && e.email ? console.log(`Logged in as: ${e.email}`) : console.log("Not logged in. Run `myop login` to authenticate."), process.exit(0);
896
1368
  });
897
- a.program.command("sync").description("Sync Myop configuration").action(async () => {
898
- const i = a.program.getOptionValue("config") || "./myop.config.json", s = await import("fs"), { execSync: m } = await import("child_process"), d = await import("http");
899
- if (s.existsSync(i)) {
900
- console.log("yes");
1369
+ l.program.command("sync").description("Build and upload component to Myop platform").option("--skip-build", "Skip the build step").action(async (e) => {
1370
+ var I, C, _, B, S, P;
1371
+ const o = l.program.getOptionValue("config") || "./myop.config.json", n = await import("fs"), { execSync: a } = await import("child_process"), u = await import("path");
1372
+ let c = {};
1373
+ if (n.existsSync(o))
901
1374
  try {
902
- const I = s.readFileSync(i, "utf-8"), P = JSON.parse(I);
903
- P.componentId && console.log(P.componentId), console.log("Running npm run build..."), m("npm run build", { stdio: "inherit" });
904
- const _ = "./dist/index.html";
905
- if (s.existsSync(_)) {
906
- const E = s.readFileSync(_, "utf-8");
907
- console.log(`
908
- Content of ./dist/index.html:`), console.log(E);
909
- const J = 3302, S = d.default.createServer((h, y) => {
910
- if (h.method === "OPTIONS") {
911
- y.writeHead(200, {
912
- "Access-Control-Allow-Origin": "*",
913
- "Access-Control-Allow-Methods": "GET, OPTIONS",
914
- "Access-Control-Allow-Headers": "Content-Type"
915
- }), y.end();
916
- return;
1375
+ const f = n.readFileSync(o, "utf-8");
1376
+ c = JSON.parse(f);
1377
+ const b = c.name || c.componentName;
1378
+ console.log(`πŸ“‹ Found config: ${b || "Unnamed component"}`), c.componentId && console.log(` Component ID: ${c.componentId}`);
1379
+ } catch (f) {
1380
+ console.error(`⚠️ Failed to parse ${o}:`, f.message);
1381
+ }
1382
+ else
1383
+ console.log("⚠️ No myop.config.json found. A new component will be created.");
1384
+ if (!e.skipBuild) {
1385
+ const f = A("Building project...").start();
1386
+ try {
1387
+ a("npm run build", { stdio: "pipe" }), f.succeed("Build completed");
1388
+ } catch (b) {
1389
+ f.fail("Build failed"), console.error(b.message), process.exit(1);
1390
+ }
1391
+ }
1392
+ const p = "./dist/index.html";
1393
+ n.existsSync(p) || (console.error("❌ Error: ./dist/index.html not found"), console.log(" Make sure your build outputs to ./dist/index.html"), process.exit(1));
1394
+ let v;
1395
+ try {
1396
+ v = await ft();
1397
+ } catch (f) {
1398
+ console.error("❌ Authentication failed:", f.message), process.exit(1);
1399
+ }
1400
+ const j = gt();
1401
+ let g = A("Requesting upload URL...").start(), y;
1402
+ try {
1403
+ const f = await fetch(`${j}/mcp`, {
1404
+ method: "POST",
1405
+ headers: {
1406
+ "Content-Type": "application/json",
1407
+ Authorization: `Bearer ${v.accessToken}`
1408
+ },
1409
+ body: JSON.stringify({
1410
+ jsonrpc: "2.0",
1411
+ id: 1,
1412
+ method: "tools/call",
1413
+ params: {
1414
+ name: "upload_component",
1415
+ arguments: {
1416
+ name: c.name || c.componentName || u.default.basename(process.cwd()),
1417
+ componentId: c.componentId || void 0,
1418
+ organization: c.organization || void 0
917
1419
  }
918
- y.writeHead(200, {
919
- "Content-Type": "text/plain",
920
- "Access-Control-Allow-Origin": "*",
921
- "Access-Control-Allow-Methods": "GET, OPTIONS",
922
- "Access-Control-Allow-Headers": "Content-Type"
923
- }), y.end(E), console.log(`
924
- Content served successfully, closing server...`), setTimeout(() => {
925
- S.close(() => {
926
- console.log("Server closed. Sync process completed.");
927
- }), setTimeout(() => {
928
- process.exit(0);
929
- }, 100);
930
- }, 100);
931
- });
932
- S.listen(J, () => {
933
- const h = `http://localhost:${J}`;
934
- console.log(`
935
- Server running at ${h}`), console.log("Waiting for request...");
936
- const y = `http://localhost:9200/dashboard/2.0/component/${P.componentId}?upload=${encodeURIComponent(h)}`;
937
- console.log(`
938
- Opening Chrome with: ${y}`);
939
- try {
940
- m(`open -a "Google Chrome" "${y}"`, { stdio: "inherit" });
941
- } catch (N) {
942
- console.error("Error opening Chrome:", N.message), console.log(`Please open this URL manually: ${y}`);
1420
+ }
1421
+ })
1422
+ });
1423
+ if (!f.ok)
1424
+ throw new Error(`Server returned ${f.status}`);
1425
+ const b = await f.json();
1426
+ if (b.error)
1427
+ throw new Error(b.error.message);
1428
+ const H = (_ = (C = (I = b.result) == null ? void 0 : I.content) == null ? void 0 : C[0]) == null ? void 0 : _.text;
1429
+ if (y = JSON.parse(H), !y.success)
1430
+ throw new Error(y.error);
1431
+ g.succeed("Upload URL obtained");
1432
+ } catch (f) {
1433
+ g.fail("Failed to get upload URL"), console.error(" ", f.message), process.exit(1);
1434
+ }
1435
+ g = A("Uploading component...").start();
1436
+ try {
1437
+ const f = n.readFileSync(p, "utf-8");
1438
+ let b;
1439
+ const H = y.curlCommand.match(/(?:"|\\")([^"\\]+(?:\\.[^"\\]*)*)(?:"|\\")$/);
1440
+ if (H)
1441
+ b = H[1];
1442
+ else {
1443
+ const F = y.curlCommand.match(/(https:\/\/[^\s"\\]+)/);
1444
+ if (F)
1445
+ b = F[1];
1446
+ else
1447
+ throw new Error("Could not parse presigned URL from: " + y.curlCommand);
1448
+ }
1449
+ console.info("Uploading to:", b.substring(0, 100) + "...");
1450
+ const $ = await fetch(b, {
1451
+ method: "PUT",
1452
+ headers: {
1453
+ "Content-Type": "text/html"
1454
+ },
1455
+ body: f
1456
+ });
1457
+ if (!$.ok) {
1458
+ const F = await $.text();
1459
+ throw new Error(`Upload failed with status ${$.status}: ${F}`);
1460
+ }
1461
+ g.succeed("Component uploaded");
1462
+ } catch (f) {
1463
+ g.fail("Upload failed"), console.error(" ", f.message), f.cause && console.error(" Cause:", f.cause), process.exit(1);
1464
+ }
1465
+ g = A("Confirming upload...").start();
1466
+ let w;
1467
+ try {
1468
+ const f = await fetch(`${j}/mcp`, {
1469
+ method: "POST",
1470
+ headers: {
1471
+ "Content-Type": "application/json",
1472
+ Authorization: `Bearer ${v.accessToken}`
1473
+ },
1474
+ body: JSON.stringify({
1475
+ jsonrpc: "2.0",
1476
+ id: 2,
1477
+ method: "tools/call",
1478
+ params: {
1479
+ name: "confirm_upload",
1480
+ arguments: {
1481
+ uploadId: y.uploadId
943
1482
  }
944
- });
945
- return;
946
- } else
947
- console.error("Error: ./dist/index.html not found");
948
- } catch (I) {
949
- console.error("Error:", I.message);
1483
+ }
1484
+ })
1485
+ });
1486
+ if (!f.ok)
1487
+ throw new Error(`Server returned ${f.status}`);
1488
+ const b = await f.json();
1489
+ if (b.error)
1490
+ throw new Error(b.error.message);
1491
+ const H = (P = (S = (B = b.result) == null ? void 0 : B.content) == null ? void 0 : S[0]) == null ? void 0 : P.text;
1492
+ if (w = JSON.parse(H), !w.success)
1493
+ throw new Error(w.error);
1494
+ g.succeed("Upload confirmed");
1495
+ } catch (f) {
1496
+ g.fail("Confirmation failed"), console.error(" ", f.message), process.exit(1);
1497
+ }
1498
+ if (w.isNewComponent || !c.componentId) {
1499
+ c.componentId = w.componentId, c.organization = w.orgId, c.name || (c.name = w.componentName);
1500
+ try {
1501
+ n.writeFileSync(o, JSON.stringify(c, null, 2)), console.log(`
1502
+ πŸ“ Updated ${o} with componentId`);
1503
+ } catch (f) {
1504
+ console.log(`
1505
+ ⚠️ Could not update ${o}: ${f.message}`), console.log(` Please add componentId: "${w.componentId}" manually`);
950
1506
  }
951
- } else
952
- console.log("no");
953
- process.exit();
1507
+ }
1508
+ console.log(`
1509
+ βœ… Sync completed successfully!`), console.log(` Component: ${w.componentName}`), console.log(` Dashboard: ${w.dashboardUrl}`), process.exit(0);
1510
+ });
1511
+ l.program.command("dev").description("Start development server with file watching").action(Pe);
1512
+ const St = () => {
1513
+ try {
1514
+ ne("git --version", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
1515
+ } catch {
1516
+ return { gitNotInstalled: !0 };
1517
+ }
1518
+ try {
1519
+ ne("git rev-parse --git-dir", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
1520
+ } catch {
1521
+ return { notARepo: !0 };
1522
+ }
1523
+ try {
1524
+ const e = ne("git diff --stat HEAD -- . 2>/dev/null || git diff --stat -- . 2>/dev/null", {
1525
+ encoding: "utf-8",
1526
+ stdio: ["pipe", "pipe", "pipe"]
1527
+ }).trim();
1528
+ if (!e)
1529
+ return {
1530
+ files: 0,
1531
+ insertions: 0,
1532
+ deletions: 0
1533
+ };
1534
+ const o = e.split(`
1535
+ `), n = o[o.length - 1], a = n.match(/(\d+) insertion/), u = n.match(/(\d+) deletion/), c = n.match(/(\d+) file/);
1536
+ return {
1537
+ files: c ? parseInt(c[1]) : 0,
1538
+ insertions: a ? parseInt(a[1]) : 0,
1539
+ deletions: u ? parseInt(u[1]) : 0
1540
+ };
1541
+ } catch {
1542
+ return null;
1543
+ }
1544
+ }, U = async (e = !1, o = !1) => {
1545
+ var y, w, I;
1546
+ const n = Re(), a = !!(n != null && n.email), u = ((y = l.myopConfig) == null ? void 0 : y.name) || ((w = l.myopConfig) == null ? void 0 : w.componentName), c = (I = l.myopConfig) == null ? void 0 : I.componentId, p = St();
1547
+ console.log(`
1548
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”`), console.log("β”‚ β”‚"), console.log("β”‚ Welcome to Myop CLI - Remote UI Made Easy β”‚"), console.log("β”‚ β”‚"), console.log(`β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
1549
+ `), e && u ? (console.log(` Component: ${u}`), c ? (console.log(` ID: ${c}`), console.log(` Dashboard: https://dashboard.myop.dev/dashboard/2.0/component/${c}`)) : console.log(" ID: (not yet pushed)")) : console.log(" Component: No myop.config.json found"), console.log(` User: ${a ? n.email : "Not logged in"}`), p != null && p.gitNotInstalled ? (console.log(" Changes: Git not installed"), console.log(" Install: https://git-scm.com/downloads"), console.log(" Mac: brew install git | Windows: https://gitforwindows.org")) : p != null && p.notARepo ? console.log(" Changes: Not a git repository") : p && (p.insertions > 0 || p.deletions > 0) ? console.log(` Changes: ${p.files} file${p.files !== 1 ? "s" : ""} | \x1B[32m+${p.insertions}\x1B[0m \x1B[31m-${p.deletions}\x1B[0m`) : p && console.log(" Changes: No uncommitted changes"), console.log("");
1550
+ const j = [
1551
+ {
1552
+ emoji: "πŸš€",
1553
+ label: "Initialize new component",
1554
+ value: "init",
1555
+ help: "Creates myop.config.json in current directory",
1556
+ disabled: e ? "(config already exists)" : !1
1557
+ },
1558
+ {
1559
+ emoji: "πŸ“¦",
1560
+ label: u ? `Push "${u}"` : "Push component",
1561
+ value: "sync",
1562
+ help: "Builds project & uploads dist/index.html to Myop",
1563
+ disabled: e ? a ? !1 : "(login required)" : "(no config file)"
1564
+ },
1565
+ {
1566
+ emoji: "πŸ› οΈ ",
1567
+ label: u ? `Start dev mode for "${u}"` : "Start dev mode",
1568
+ value: "dev",
1569
+ help: "Starts dev server with HMR for instant preview of changes",
1570
+ disabled: e ? !1 : "(no config file)"
1571
+ }
1572
+ ].map((C) => ({
1573
+ name: o && !C.disabled ? `${C.emoji} ${C.label}
1574
+ ${C.help}` : `${C.emoji} ${C.label}`,
1575
+ value: C.value,
1576
+ disabled: C.disabled
1577
+ }));
1578
+ switch (j.push(
1579
+ new de(),
1580
+ {
1581
+ name: o && a ? `πŸ”“ Logout (${n.email})
1582
+ Clears stored credentials from this machine` : o && !a ? `πŸ” Login to Myop
1583
+ Opens browser to authenticate with Myop` : a ? `πŸ”“ Logout (${n.email})` : "πŸ” Login to Myop",
1584
+ value: a ? "logout" : "login"
1585
+ },
1586
+ {
1587
+ name: o ? "πŸ“– Hide help" : "πŸ“– Show help",
1588
+ value: "help"
1589
+ },
1590
+ new de(),
1591
+ {
1592
+ name: "πŸ‘‹ Exit",
1593
+ value: "exit"
1594
+ }
1595
+ ), await $e({
1596
+ message: "What would you like to do?",
1597
+ choices: j
1598
+ })) {
1599
+ case "init":
1600
+ await bt();
1601
+ break;
1602
+ case "sync":
1603
+ console.log(`
1604
+ Running sync...
1605
+ `);
1606
+ const { execSync: C } = await import("child_process");
1607
+ try {
1608
+ C("node " + process.argv[1] + " sync", { stdio: "inherit" });
1609
+ } catch {
1610
+ }
1611
+ await U(!0, o);
1612
+ break;
1613
+ case "dev":
1614
+ await Pe();
1615
+ break;
1616
+ case "login":
1617
+ try {
1618
+ await X(), console.log(`
1619
+ `), await U(e, o);
1620
+ } catch (_) {
1621
+ console.error("Login failed:", _.message), await U(e, o);
1622
+ }
1623
+ break;
1624
+ case "logout":
1625
+ await Fe(), console.log(`
1626
+ `), await U(e, o);
1627
+ break;
1628
+ case "help":
1629
+ await U(e, !o);
1630
+ break;
1631
+ case "exit":
1632
+ process.exit(0);
1633
+ }
1634
+ }, bt = async () => {
1635
+ const { input: e, select: o } = await import("@inquirer/prompts"), n = await import("fs"), u = (await import("path")).default.basename(process.cwd()), c = await e({
1636
+ message: "Component name:",
1637
+ default: u
1638
+ }), p = await o({
1639
+ message: "Component type:",
1640
+ choices: [
1641
+ { name: "πŸ“„ HTML", value: "html", description: "Plain HTML/JS/CSS component" },
1642
+ { name: "βš›οΈ React", value: "react", disabled: "(coming soon)" },
1643
+ { name: "πŸ’š Vue", value: "vue", disabled: "(coming soon)" },
1644
+ { name: "πŸ…°οΈ Angular", value: "angular", disabled: "(coming soon)" }
1645
+ ]
1646
+ }), v = {
1647
+ name: c,
1648
+ type: p,
1649
+ author: "@myop-cli"
1650
+ }, j = l.program.getOptionValue("config") || "./myop.config.json";
1651
+ try {
1652
+ n.writeFileSync(j, JSON.stringify(v, null, 2)), console.log(`
1653
+ βœ… Created ${j}`);
1654
+ const g = {
1655
+ name: c.toLowerCase().replace(/\s+/g, "-"),
1656
+ version: "1.0.0",
1657
+ type: "module",
1658
+ scripts: {
1659
+ build: "node build.js",
1660
+ dev: "myop dev"
1661
+ },
1662
+ devDependencies: {
1663
+ esbuild: "^0.24.0"
1664
+ }
1665
+ };
1666
+ n.writeFileSync("package.json", JSON.stringify(g, null, 2)), console.log("βœ… Created package.json"), n.mkdirSync("src/modules", { recursive: !0 }), n.mkdirSync("src/styles", { recursive: !0 }), n.writeFileSync("build.js", `import * as esbuild from 'esbuild';
1667
+ import fs from 'fs';
1668
+ import path from 'path';
1669
+
1670
+ // Auto-discover all JS modules and CSS files
1671
+ const getAllFiles = (dir, ext) => {
1672
+ const files = [];
1673
+ const items = fs.readdirSync(dir, { withFileTypes: true });
1674
+ for (const item of items) {
1675
+ const fullPath = path.join(dir, item.name);
1676
+ if (item.isDirectory()) {
1677
+ files.push(...getAllFiles(fullPath, ext));
1678
+ } else if (item.name.endsWith(ext)) {
1679
+ files.push(fullPath);
1680
+ }
1681
+ }
1682
+ return files;
1683
+ };
1684
+
1685
+ // Generate temp entry that imports all modules
1686
+ const jsFiles = getAllFiles('src/modules', '.js');
1687
+ const jsImports = jsFiles.map((f, i) => \`import * as mod\${i} from './\${f.replace(/\\\\/g, '/')}';\`).join('\\n');
1688
+ const jsExports = jsFiles.map((_, i) => \`mod\${i}\`).join(', ');
1689
+ const tempJsEntry = \`// Auto-generated entry point
1690
+ \${jsImports}
1691
+ import { init } from './src/modules/app.js';
1692
+ import { setupMyopInterface } from './src/modules/myop.js';
1693
+ export { \${jsExports} };
1694
+ document.addEventListener('DOMContentLoaded', () => { init(); setupMyopInterface(); });
1695
+ \`;
1696
+ fs.writeFileSync('.temp-entry.js', tempJsEntry);
1697
+
1698
+ // Generate temp CSS entry that imports all styles
1699
+ const cssFiles = getAllFiles('src/styles', '.css').filter(f => !f.endsWith('index.css'));
1700
+ const cssImports = cssFiles.map(f => \`@import './\${f.replace(/\\\\/g, '/')}';\`).join('\\n');
1701
+ const tempCssEntry = \`/* Auto-generated - imports all CSS files */\\n\${cssImports}\\n\`;
1702
+ fs.writeFileSync('.temp-styles.css', tempCssEntry);
1703
+
1704
+ // Bundle JS (includes all modules)
1705
+ const jsResult = await esbuild.build({
1706
+ entryPoints: ['.temp-entry.js'],
1707
+ bundle: true,
1708
+ minify: true,
1709
+ write: false,
1710
+ format: 'iife'
1711
+ });
1712
+
1713
+ // Bundle CSS (includes all styles)
1714
+ const cssResult = await esbuild.build({
1715
+ entryPoints: ['.temp-styles.css'],
1716
+ bundle: true,
1717
+ minify: true,
1718
+ write: false
1719
+ });
1720
+
1721
+ // Cleanup temp files
1722
+ fs.unlinkSync('.temp-entry.js');
1723
+ fs.unlinkSync('.temp-styles.css');
1724
+
1725
+ // Read HTML template
1726
+ let html = fs.readFileSync('index.html', 'utf-8');
1727
+
1728
+ // Remove dev script/link tags
1729
+ html = html.replace(/<link rel="stylesheet" href="[^"]*">[\\n\\r]*/g, '');
1730
+ html = html.replace(/<script[^>]*src="[^"]*"[^>]*><\\/script>[\\n\\r]*/g, '');
1731
+
1732
+ // Inline JS and CSS
1733
+ const js = jsResult.outputFiles[0].text;
1734
+ const css = cssResult.outputFiles[0].text;
1735
+
1736
+ html = html.replace('</head>', \`<style>\${css}</style></head>\`);
1737
+ html = html.replace('</body>', \`<script>\${js}<\/script></body>\`);
1738
+
1739
+ // Write to dist
1740
+ fs.mkdirSync('dist', { recursive: true });
1741
+ fs.writeFileSync('dist/index.html', html);
1742
+
1743
+ console.log('βœ… Built dist/index.html');
1744
+ console.log(\` Bundled \${jsFiles.length} JS modules, \${cssFiles.length} CSS files\`);
1745
+ `), console.log("βœ… Created build.js");
1746
+ const w = `<!DOCTYPE html>
1747
+ <html lang="en">
1748
+ <head>
1749
+ <meta charset="UTF-8">
1750
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
1751
+ <title>${c}</title>
1752
+ <link rel="stylesheet" href="./src/styles/index.css">
1753
+ </head>
1754
+ <body>
1755
+ <div id="app">
1756
+ <h1>${c}</h1>
1757
+ <p>Your Myop component is ready!</p>
1758
+ </div>
1759
+ <script type="module" src="./src/index.js"><\/script>
1760
+ </body>
1761
+ </html>
1762
+ `;
1763
+ n.writeFileSync("index.html", w), console.log("βœ… Created index.html");
1764
+ const I = `// ${c} - Entry Point
1765
+ import { init } from './modules/app.js';
1766
+ import { setupMyopInterface } from './modules/myop.js';
1767
+
1768
+ document.addEventListener('DOMContentLoaded', () => {
1769
+ init();
1770
+ setupMyopInterface();
954
1771
  });
955
- a.program.command("dev").description("Start development server with file watching").action(Ee);
956
- a.program.command("default", { isDefault: !0 }).action(async () => {
957
- a.program.getOptionValue("help") && (console.log(Pe), process.exit());
958
- let s = be({
1772
+ `;
1773
+ n.writeFileSync("src/index.js", I), console.log("βœ… Created src/index.js");
1774
+ const C = `// ${c} - Main Application Logic
1775
+
1776
+ export function init() {
1777
+ console.log('${c} loaded');
1778
+
1779
+ // Your component logic here
1780
+ }
1781
+ `;
1782
+ n.writeFileSync("src/modules/app.js", C), console.log("βœ… Created src/modules/app.js"), n.writeFileSync("src/modules/myop.js", `// Myop Interface - Communication with host app
1783
+
1784
+ export function setupMyopInterface() {
1785
+ // Called when host app sends data to this component
1786
+ window.myop_init_interface = (data) => {
1787
+ console.log('Received data from host:', data);
1788
+ // Initialize your component with data from the host app
1789
+ };
1790
+
1791
+ // Called to set up CTA (Call-to-Action) handler
1792
+ window.myop_cta_handler = (callback) => {
1793
+ // Store callback to trigger actions back to host
1794
+ // Example: callback({ action: 'button-click', data: { id: 123 } });
1795
+ };
1796
+ }
1797
+ `), console.log("βœ… Created src/modules/myop.js");
1798
+ const B = `/* ${c} - Styles Entry Point */
1799
+ /* Add your CSS imports here - they will be auto-bundled */
1800
+ @import './main.css';
1801
+ `;
1802
+ n.writeFileSync("src/styles/index.css", B), console.log("βœ… Created src/styles/index.css");
1803
+ const S = `/* ${c} - Main Styles */
1804
+
1805
+ * {
1806
+ box-sizing: border-box;
1807
+ margin: 0;
1808
+ padding: 0;
1809
+ }
1810
+
1811
+ body {
1812
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
1813
+ padding: 20px;
1814
+ color: #333;
1815
+ }
1816
+
1817
+ #app {
1818
+ max-width: 600px;
1819
+ margin: 0 auto;
1820
+ }
1821
+
1822
+ h1 {
1823
+ margin-bottom: 16px;
1824
+ color: #1a1a1a;
1825
+ }
1826
+
1827
+ p {
1828
+ color: #666;
1829
+ line-height: 1.5;
1830
+ }
1831
+ `;
1832
+ n.writeFileSync("src/styles/main.css", S), console.log("βœ… Created src/styles/main.css"), console.log(`
1833
+ πŸ“¦ Next steps:`), console.log(" 1. npm install"), console.log(" 2. npm run build"), console.log(` 3. myop sync
1834
+ `), l.myopConfig = v, await U(!0);
1835
+ } catch (g) {
1836
+ console.error(`Failed to initialize component: ${g.message}`), process.exit(1);
1837
+ }
1838
+ };
1839
+ l.program.command("default", { isDefault: !0 }).action(async () => {
1840
+ l.program.getOptionValue("help") && (console.log(Ve), process.exit());
1841
+ let o = A({
959
1842
  text: "Loading Myop CLI...",
960
1843
  color: "green"
961
1844
  }).start();
962
- z(), await Je(1e3), s.succeed("Myop CLI Loaded"), await pe();
1845
+ const n = ie();
1846
+ await vt(500), o.stop();
1847
+ const a = l.program.version();
1848
+ await wt(a), await U(n.configFound);
963
1849
  });
964
- a.program.parse(process.argv);
965
- a.program.opts();
1850
+ l.program.parse(process.argv);
1851
+ l.program.opts();